Falcon (limbaj de programare)
Şoim limbaj de programare | |
---|---|
Autor | Giancarlo Niccolai |
Data de origine | 2003 |
Ultima versiune | 0.9.6.8 |
Utilizare | limbajul de scriptare |
Paradigme | multi-paradigmă |
Tastare | slab |
Influențată de | Perl , Smalltalk și PHP |
Implementare referință | |
Sistem de operare | multi-platformă |
Licență | software gratuit |
Site-ul web | www.falconpl.org |
Limbajul de programare Falcon , prescurtat ca Falcon PL , Falconpl sau Falcon , este un limbaj de scripturi multi-paradigmă open source , dezvoltat de Giancarlo Niccolai , inițial ca parte a lucrării sale, și publicat ulterior ca proiect Open Source [1] .
Istorie
Originile datează de la un proiect numit HASTE, început în 2002 (Haste Advanced Simple Text Evaluator). A fost un motor de scripting conceput în primul rând pentru includerea în aplicații dinamice și care vizează construirea unei mașini virtuale rapide și ușoare cu capacitatea de a genera un flux de date ridicat la latențe scăzute în medii extrem de multithread, pentru configurarea dinamică a aplicațiilor financiare [2] . Adaptările și implementările ulterioare, bazate în principal pe experiență și pe nevoile operaționale și pe sugestiile primilor utilizatori, au dat naștere actualului Falcon. Prima versiune distribuită prin pachete oficiale pe distribuțiile software Open Source a fost 0.8.8, în mai 2008.
Filozofie
Falcon combină diferite stiluri de programare (numite paradigme ) într-un singur mediu.
Din punct de vedere al implementării, Falcon este propus ca un limbaj autonom, dar cu o predispoziție puternică spre cooperare cu aplicații preexistente, chiar mai bine în domeniul multi-threading.
Salut Lume
Următorul exemplu oferă clasicul „Bună ziua, lume!” folosind operatorul de imprimare rapidă ">" sau, într-o formă mai clasică, prin funcția printl :
> "Hello World!" printl („Hello World again!”)
Falcon acceptă toate caracterele Unicode din scripturile sursă:
// Clasa internațională; numele și strada clasa 国際 (な ま え, Straße) // setați numele clasei și adresa străzii नाम = な ま え شَارِع = Straße // Spune cine sunt eu! funcție 言 え! () > @ "I am $ (self. नाम) from", self. شَارِع Sfârșit Sfârșit // toți oamenii lumii! 民族 = [国際 ("高田 Friederich", "台湾"), 国際 („Smith Σωκράτης”, „Cantù”), 国際 („Stanisław Lec”, „południow”)]
pentru garçon în 民族: garçon. 言 え! ()
Tipuri de date
- Nil - Clasicul „non-valoare”.
- Întreg - întreg pe 64 de biți.
- Numeric - număr pe virgulă mobilă pe 64 de biți compatibil cu specificația IEEE.
- Gama - un triplet format dintr-o limită inferioară, o limită superioară și un pas.
- MemBuf - Memorie tampon unde fiecare element este un întreg nesemnat format din 1, 2, 3 sau 4 octeți.
- Funcție - Funcțiile clasice sau porțiuni de cod care pot fi apelate în alte părți ale programului.
- Șir - Secvență mutabilă de caractere UNICODE.
- Matrice - Secvență mutabilă de instanțe de diferite tipuri.
- Dicționar - Secvență mutabilă constând dintr-o pereche cheie-valoare.
- Obiecte - Instanțe derivate din clase sau obiecte fără o clasă de derivare.
- Clasa - clase care pot genera instanțe (obiecte).
- Metodă - Acestea sunt funcțiile care trebuie aplicate oricărei instanțe.
Paradigme acceptate
Falcon acceptă în prezent 6 paradigme de programare:
- procedural
- funcţional
- orientat obiect (OOP)
- OOP bazat pe prototip
- orientat spre mesaj
- programare de masă
Procedural
Programarea procedurală se bazează pe declarații clasice și apeluri de funcții. Toate funcțiile implicit acceptă un număr variabil de parametri, precum și parametrii poziționali / nominali.
Următorul este un program complet, complet procedural, care ilustrează unele decizii de implementare privind structura buclei și procesarea secvenței imperative:
funcție sayList (spunând) pentru elem în a spune >> element formular: >> "" ultimul:> "!" Sfârșit Sfârșit
sayList (Listă („Have”, „a”, „nice”, „day”))
Funcţional
Motorul de evaluare numit Sigma-reductor intern vă permite să scrieți programe în stil funcțional pur, nu spre deosebire de ceea ce este posibil în limbi precum Lisp . Cu toate acestea, rămâne posibil să se amestece diferite stiluri de programare (cum ar fi OOP sau abordări pur imperative) direct în secvențe funcționale.
Secvențele funcționale sunt alcătuite din tablouri normale; aceasta înseamnă că pot fi create, controlate și modificate dinamic de către programul însuși, atât între evaluări separate, cât și pe parcursul unei evaluări de reducere Sigma. Următorul exemplu ilustrează posibilitatea schimbării unui anumit tip de referință variabilă, numită legare tardivă, din interiorul secvenței.
pnext = [printl, '"', & valoare, '"']
dolist (funcție (p); valoare sec. = p; eval (sec); sfârșit, ["O zi plăcută"])
De asemenea, este posibil să apelați secvențe funcționale direct dacă primul lor membru este el însuși o valoare apelabilă, ca în exemplul următor:
[printl "Prompt>"] ("Date reale de imprimat")
Secvențele funcționale cu un singur nivel de adâncime (cum ar fi cele văzute în aceste exemple) pot fi văzute ca apeluri preînregistrate ( apeluri în cache ), iar odată atribuite unei variabile, acestea sunt echivalente morfologic simbolurilor care identifică funcțiile în sine.
Paradigma funcțională este completată de marcatorul de elemente în afara benzii . Fiecare valoare poate primi markerul oob , a cărui prezență poate fi verificată ulterior prin operatorii de limbă și / sau funcțiile bibliotecii. Este un semnal care indică o semnificație specială a valorii marcate și care poate modifica comportamentul secvențelor funcționale prin care este făcut să călătorească. De exemplu, multe bucle funcționale, cum ar fi flopuri sau timpi , pot fi repornite sau întrerupte prin returnarea unei valori o sau b 1 sau respectiv 0 de la una dintre funcțiile secvenței. Sau, funcția de hartă , care transformă toate valorile conținute într-o secvență prin aplicarea unei funcții de transformare, va ignora (arunca) o valoare nulă marcată cu o sau b; în acest fel este posibilă efectuarea operațiilor de cartografiere și filtrare într-un singur pas.
Orientat pe obiect (OOP)
Falcon adoptă un model de programare orientată pe obiecte care include clase, moștenire, membri statici, inițializatori de proprietăți și constructori. Moștenirea multiplă este acceptată atâta timp cât cel mult una dintre clasele din ierarhie este reflexivă (adică reflectă datele furnizate direct de aplicații sau module de la terți în modul nativ). Accesul la membrii clasei de bază este, de asemenea, acceptat.
Structura instanțelor este fixă și imuabilă, dar având în vedere natura funcțională a Falcon, care vede funcțiile ca un anumit tip de date, este posibil să setați membrii unei instanțe ca date simple sau ca funcții (făcându-le astfel metode) dinamic. Secvențele funcționale pot fi atribuite proprietăților, caz în care devin metode funcționale pentru instanța dată.
Falcon acceptă obiecte primitive , adică obiecte fără clasă specifică, care pot fi fie total fără clase, fie parțial derivate din una sau mai multe clase părinte. Obiectele primitive sunt instanțiate și configurate înainte ca mașina virtuală să ruleze programul principal. Ordinea de rezoluție a instanțelor este gestionată de Falcon Linker, care asigură inițializarea corectă chiar și în cazul referințelor încrucișate între obiecte primitive din același modul.
Clasele pot fi, de asemenea, instanțiate prin secvențe funcționale: instanțierea unei clase (crearea unei instanțe) este morfologic echivalentă cu „apelarea” simbolului clasei date. Prin urmare, evaluarea unei secvențe funcționale care începe cu un simbol de clasă este echivalentă cu solicitarea instanțierii sale.
Modelul OOP Falcon este completat de supraîncărcarea operatorului, care vă permite să creați clase pe care operatorii de limbaj logic și matematic se comportă într-un mod specializat.
OOP bazat pe prototip
Programarea orientată către prototip este similară cu paradigma OOP, dar nu are conceptul de clasă . Instanțele sunt toate fără clase și structura lor poate fi modificată dinamic. Dicționarele de limbaj Falcon (tip primitiv format din colecții de perechi unice cheie / valoare) pot include funcții; pot fi apoi binecuvântați , informând astfel sistemul că trebuie tratați ca instanțe fără clase. Prin aplicarea accesorului punct, membrii lor pot fi accesați ca metode sau proprietăți. În exemplul următor, un dicționar devine obiect:
dict = bless (['state' => 0, 'incme' => function (); self.state ++; end]) dict.incme () > dict.state // print '1'
Un mecanism similar poate fi aplicat matricelor prin legături :
matrice = [1,2,3] array.showMe = function () pentru articol în sine:> articol Sfârșit
array.showMe ()
Orientat spre mesaj
Programarea orientată spre mesaje constă în invocarea unuia sau mai multor manageri pentru a transmite un mesaj. Conținutul mesajului este arbitrar și poate consta din orice tip de date, inclusiv clase (din care să se creeze instanțe din mers), secvențe funcționale sau tabele. Receptorii pot concura pentru a primi mesajul prin excluderea altor manageri sau pot participa la construirea unui răspuns comun în pași ordonați. Mesajele pot necesita o manipulare imediată la transmisie sau pot fi lăsate în mediu pentru a fi primite și gestionate de abonații târzii (așa-numitele „afirmații”).
Programarea orientată către mesaje se interfață direct cu mașina virtuală, cu care pot interacționa module native și aplicații conexe. De exemplu, o aplicație cu mai multe fire poate lansa mesaje în mașina virtuală care provin din fire diferite pentru o gestionare serializată la nivel de script și o retransmisie asincronă ulterioară a mesajelor procesate direct din scripturi.
Programare tabelară
Programarea tabelelor este o extensie specială și generalizarea OOP, unde o clasă este reprezentată de un tabel, ale cărui coloane sunt proprietăți și fiecare rând este o instanță. În plus față de menținerea tuturor instanțelor îngrijite și permiterea fiecărei instanțe să funcționeze cu cele adiacente accesând tabelul părinte, modificările structurii tabelului se reflectă imediat în toate instanțele.
Tabelele oferă suport direct pentru selectarea unui comportament sau a unui set de comportamente dintr-o serie finită de posibile alegeri, oferind baza pentru dezvoltarea unor motoare de decizie logice discrete sau fuzzy direct în limbă. Fiecare rând, constituit fizic de date de tip Array, poate conține atât date cât și logice specifice tabelului și date sau logică privată a instanței (datorită Bindings), prin urmare o entitate selectată printr-o logică globală de extracție poate .
Alte caracteristici
Pe lângă faptul că oferă diferite stiluri de programare, Falcon are caracteristici care sunt transversale la diferite modele; cele mai relevante sunt indicate mai jos.
Descrieri ale listelor
Tipurile și clasele de bază care expun o interfață de secvență motorului intern oferă o metodă „comp”, care vă permite să sintetizați seturi dintr-o definiție matematică.
Metoda „comp” necesită indicarea obligatorie a unui parametru „sursă”, care poate fi o altă secvență, o valoare de tip „interval” sau o funcție generatoare care returnează o valoare la un moment dat și un marker special pentru a declara sfârșitul secvenţă.
O funcție (sau, în general, o entitate apelabilă) poate fi furnizată ca parametru opțional și acționează atât ca filtru, cât și ca modificator.
Sunt acceptate secvențe asociative (de exemplu, dicționare).
Următorul este un exemplu simplu care folosește un interval pentru a crea o matrice care conține numerele pare între 2 și 10, prin înțelegerea listei:
even_array = [] .comp ([2: 11: 2])
Pentru a genera o listă de numere întregi aleatorii între 1 și 9, de asemenea, de lungime aleatoare:
random_list = List (). comp (function (); n = random (1,10); return n == 10? oob (0): n; end)
Funcția de generare, furnizată online, returnează markerul de sfârșit de secvență "oob (0)" atunci când numărul 10 este generat aleatoriu (deci la fiecare nouă iterație există o probabilitate de 1/10 de a încheia lista).
Următorul exemplu, mai complet, folosește un generator pentru a umple un set de tip „Set” cu exact zece numere întregi aleatorii în intervalul 1..100. Cu această ocazie, filtrul în sine determină momentul în care înțelegerea este completă.
random_set = Set (). comp ( [aleatoriu, 1, 100], // generator, matrice apelabilă funcție (număr, eu) // filtru, folosind parametrul opțional „eu” dacă eu.len () == 10 returnează oob (0) // returnează oob (0) ca generator pentru a termina Sfârșit numărul de retur Sfârșit )
Metoda „comp” returnează același obiect căruia i se aplică și poate fi aplicată și secvențelor care nu sunt goale.
În mod similar, metoda „mfcomp” vă permite să creați descrieri de liste din mai multe seturi, ca în exemplul următor:
sume = [] .mfcomp ({x, y => x + y} ,. [1 2 3] ,. [4 5 6])
Documente de mască
Falcon acceptă scripturi inserate în documente text prin directive preprocesor <? ..?> sau <? fal ...?>. Scripturile salvate cu extensia „.ftd” sunt tratate ca documente text simplu și pur și simplu transcrise la ieșire până când se întâlnește una dintre directivele de pre-procesor de mai sus. Scripturile incluse în directive sunt rulate online, ca în exemplul următor:
Ați numit acest program trecând <? print (args.len ())?> parametri.
Documentele FTD (documente șablon Falcon ) pot face parte din aplicații mai mari, constând parțial din module normale și parțial din documente șablon dinamic, astfel încât este posibil să delegați logica de prezentare șabloanelor dinamice și să păstrați logica aplicației în modulele Falcon.
Documentele FTD pot fi utilizate la crearea de site-uri web dinamice. Pentru unele servere web (în prezent Apache 2 ) sunt disponibile module integrate care pot executa direct documente FTD și module Falcon, expunând API-ul serverului web gazdă acestora. De asemenea, este posibil să utilizați pagini dinamice FTD în modul CGI.
Excepții
Mecanismul de excepție se bazează pe declarațiile „raise”, „try” și „catch”. Declarația de ridicare poate ridica orice tip de date, inclusiv zero , numere, șiruri, obiecte etc. Funcțiile bibliotecii și modulele externe generează în general instanțe ale clasei Error sau instanțe ale claselor derivate din aceasta.
Instrucțiunea catch poate fi utilizată pentru a prinde o excepție de orice tip sau poate filtra instanțe din anumite clase sau poate filtra doar anumite tipuri de date. Captarea instanțelor de clasă este organizată pe o bază ierarhică; prin urmare, este posibil să se furnizeze mai multe gestionare de excepție și, eventual, gestionare implicite generice, ca în exemplul următor (clasa TypeError este derivată din Eroare ):
încerca ... cod care poate genera o eroare ... prinde TypeError în eroare ... am făcut o greșeală de genul ... catch Eroare din eroare ... am mai făcut o greșeală generică ... catch StringType în eroare ... un șir a fost ridicat explicit ... prinde din greșeală ... s-a ridicat ceva diferit ... Sfârșit
Clauza in a declarației catch este opțională (aceasta înseamnă că conținutul erorii poate fi eliminat).
Instrucțiunea catch se comportă similar cu instrucțiunea select , care poate fi utilizată pentru a executa cod pe baza tipului sau clasei variabilei la care este aplicată.
Runtime integrabil
Falcon, prin biblioteca specifică libfalcon , poate interfața cu alte sisteme, eventual extinzându-le.
Generarea documentației
Falcon are un instrument de documentare integrat numit Faldoc , conceput pentru a extrage documentația online din ambele module scrise în Falcon și din modulele native C / C ++.
Sistem de fișiere virtual
Toate operațiunile I / O care apar atât la nivelul motorului intern, cât și la nivelul mașinii virtuale (execuția programului) sunt delegate unui furnizor centralizat de sistem de fișiere virtuale . Sistemele de fișiere virtuale abonate la operațiile I / O abstracte ale furnizorului, cum ar fi citirea directoarelor, crearea fișierelor, deschiderea fluxurilor etc. și pot fi invocate prin adresa lor URI. Acest lucru face posibilă încărcarea de module sau resurse deschise din orice sistem de fișiere virtual (cum ar fi resurse de rețea sau arhive comprimate / criptate), care pot oferi locații speciale recunoscute de module terțe sau de aplicații care integrează motorul Falcon.
Sprijin pentru concurs
Începând de la versiunea 0.8.x, suportul simultan complet a fost introdus într-un mod orientat către agent. Este posibil să faceți schimb de date prin diferite mecanisme de partajare, în timp ce fiecare fir rulează în propria mașină virtuală, care nu este în niciun fel afectată de ceea ce se întâmplă în celelalte. Acest sistem implică paralelism deplin și un grad ridicat de securitate în faza de execuție.
Coroutina
Falcon acceptă un sistem de concurență cvasi-paralel (numit coroutining ). Coroutinele sunt alcătuite din cod executat în diferite intervale de timp sau în timpul pauzei mașinii virtuale. Acest mecanism oferă paralelism software mai ușor decât multithreading la nivel hardware și permite vizibilitatea deplină a datelor globale în fiecare agent al procesului paralel, dar necesită colaborarea explicită a fiecărei coroutine în proces (de exemplu, evitarea efectuării apelurilor de blocare pentru întreaga mașină virtuală) și nu permite exploatarea hardware-ului paralel.
Metacompilator
Compilatorul Falcon are un meta-compilator care acceptă extinderea macro. Meta-compilatorul este condus de o mașină virtuală Falcon aplicată compilatorului de bază; ieșirea generată de meta-compilator este suprapusă asupra fluxului de intrare al compilatorului ca și cum ar fi sursa originală. Folosind secvența de evacuare \ [... \] este posibil să creați dinamic conținutul programului de bază pur și simplu folosind rutinele de ieșire. De exemplu:
\ [printl ("printl ('Hello world!')") \]
Cuvântul cheie macro oferă o gramatică simplificată pentru un acces mai ușor la meta-programare realizată din mers în timpul compilării.
Internaționalizarea nativă
Șirurile prefixate cu „i” sunt recunoscute ca șiruri internaționale pentru export. De asemenea, este posibil să declarați limba în care sunt scrise mesajele internaționalizate cu instrucțiunea directivă lang , ca în exemplul următor:
directive lang = fr_FR // folosește cod de limbă ISO de 5 caractere
> „Bonjour à tout le monde!”
Un instrument de linie de comandă numit fallc vă permite să exportați șirurile „i” într-un fișier de definiție XML, care poate fi folosit ca mască pentru traducerea șirurilor în alte limbi.
Tabelul șir al limbii în care urmează să fie tradusă aplicația este aplicat dinamic atunci când modulul este încărcat (înainte de execuție).
Pene
Falcon acceptă programarea modulară și are o suită de module standard numite Feathers, care vine cu instalarea implicită. Acesta include următoarele module:
- Compilator - vă permite să încărcați dinamic alte module sau Falcon precompilate
- Configuration Parser - interfață simplă, dar puternică pentru configurare
- funcext - Conține o serie de extensii funcționale
- jurnalizare - gestionează fișierele jurnal și instrumentele de jurnal sistem (Event Logger, Syslogd etc.)
- JSON - rutine de conversie a obiectelor Falcon către și de la reprezentarea JSON .
- MXML - Parser și generator XML
- Expresie regulată - așa cum spune numele modulului pentru gestionarea expresiilor regulate
- Socket - pentru gestionarea funcționalității TCP.
- Threading - Constructii pentru multi-threading nativ.
- Zlib - interfață cu rutinele de compresie ZLib.
Implementare
Falcon în toate părțile sale critice, de la VM la modulele oficiale, este complet scris în C ++, cu excepția unor părți de nivel scăzut care folosesc C și Assembly.
Disponibilitate
Falcon este distribuit prin instalatori specifici pe sistemele Mac OS X Leopard și MS-Windows (pe care compilarea și instalarea sunt procese mai complexe), sau prin pachete sursă auto-generatoare pe sisteme deschise precum Linux sau OpenSolaris .
Pe aceste sisteme, limbajul de programare Falcon este în general acceptat și actualizat de diferite distribuții, inclusiv:
Limbajul de programare Falcon este disponibil pe sistemeleSolaris prin proiectul Blastwave și prin distribuția OpenSolaris numită AuroraUX.
Notă
Bibliografie
- Luca Annunziata, Falcon, de la scenariu la AI , în Punto Informatico , 13 iunie 2008.
- ( EN ) Giancarlo Niccolai, The Falcon Programming Language in a Nutshell , în Linux Journal , n. 174, octombrie 2008, pp. 72-76 (arhivat din original la 15 decembrie 2008) .
- ( EN ) Giancarlo Niccolai, Dennis Clarke, Limbajul de programare Falcon: un scurt tutorial , în Free Software Magazine , nr. 23 februarie 2008. Adus la 25 februarie 2009 (arhivat din original la 28 februarie 2009) .
- ( EN ) Giancarlo Niccolai,The Falcon Programming Language - Survival Guide (0.8.14) ( PDF ), pe falconpl.org , 2008.
- (EN) Kathryn Edwards, AZ a limbajelor de programare: Falcon , 9 aprilie 2009. Adus pe 9 noiembrie 2019.
- (EN) Richard Morris, Geek of the week , pe simple-talk.com, 2010.
linkuri externe
- ( RO ) Site oficial , pe falconpl.org .
- ( EN ) Documentație , pe falconpl.org .