b'\n_START_ARTICLE_\nFalcon (linguaggio di programmazione)\n_START_SECTION_\nStoria\n_START_PARAGRAPH_\nLe origini risalgono ad un progetto denominato HASTE, avviato nel 2002 (Haste Advanced Simple Text Evaluator). Si trattava di un motore di scripting pensato principalmente per l\'inclusione in applicazioni dinamiche, e che mirava a realizzare una macchina virtuale veloce e leggera, con capacit\xc3\xa0 di generare un alto throughput di dati a basse latenze in ambienti fortemente multithreading, per la configurazione dinamica di applicazioni in ambito finanziario. Successivi adattamenti ed implementazioni, basate principalmente sull\'esperienza e sulle necessit\xc3\xa0 operative, e sui suggerimenti dei primi utenti hanno dato origine al Falcon attuale. La prima versione distribuita attraverso pacchetti ufficiali su distribuzioni di software Open Source \xc3\xa8 stata la 0.8.8, nel maggio del 2008.\n_START_SECTION_\nFilosofia\n_START_PARAGRAPH_\nFalcon fonde diversi stili di programmazione (detti paradigmi) in un unico ambiente._NEWLINE_Da un punto di vista implementativo Falcon si propone come linguaggio stand-alone ma con una forte predisposizione verso la cooperazione con applicativi preesistenti, meglio ancora in ambito multi-threading.\n_START_SECTION_\nHello World\n_START_PARAGRAPH_\nIl seguente esempio propone il classico "Hello, World!" utilizzando l\'operatore di stampa veloce ">", o, in forma pi\xc3\xb9 classica, attraverso la funzione printl:_NEWLINE_> "Hello World!"_NEWLINE_printl("Hello World again!")_NEWLINE_Falcon supporta tutti caratteri Unicode negli script sorgenti:_NEWLINE_// International class; name and street_NEWLINE_class \xe5\x9b\xbd\xe9\x9a\x9b(\xe3\x81\xaa\xe3\x81\xbe\xe3\x81\x88, Stra\xc3\x9fe)_NEWLINE_   // set class name and street address_NEWLINE_   \xe0\xa4\xa8\xe0\xa4\xbe\xe0\xa4\xae = \xe3\x81\xaa\xe3\x81\xbe\xe3\x81\x88_NEWLINE_   \xd8\xb4\xd9\x8e\xd8\xa7\xd8\xb1\xd9\x90\xd8\xb9   =  Stra\xc3\x9fe_NEWLINE_   // Say who am I!_NEWLINE_   function \xe8\xa8\x80\xe3\x81\x88!()_NEWLINE_     >@"I am $(self.\xe0\xa4\xa8\xe0\xa4\xbe\xe0\xa4\xae) from ",self.\xd8\xb4\xd9\x8e\xd8\xa7\xd8\xb1\xd9\x90\xd8\xb9_NEWLINE_   end_NEWLINE_end_NEWLINE_// all the people of the world!_NEWLINE_\xe6\xb0\x91\xe6\x97\x8f = [ \xe5\x9b\xbd\xe9\x9a\x9b( "\xe9\xab\x98\xe7\x94\xb0 Friederich", "\xe5\x8f\xb0\xe6\xb9\xbe" ),_NEWLINE_   \xe5\x9b\xbd\xe9\x9a\x9b( "Smith \xce\xa3\xcf\x89\xce\xba\xcf\x81\xce\xac\xcf\x84\xce\xb7\xcf\x82", "Cant\xc3\xb9" ),_NEWLINE_   \xe5\x9b\xbd\xe9\x9a\x9b( "Stanis\xc5\x82aw Lec", "po\xc5\x82udniow" ) ]_NEWLINE_for gar\xc3\xa7on in \xe6\xb0\x91\xe6\x97\x8f: gar\xc3\xa7on.\xe8\xa8\x80\xe3\x81\x88!()\n_START_SECTION_\nProcedurale\n_START_PARAGRAPH_\nLa programmazione procedurale si base sulle classiche dichiarazioni e chiamate di funzioni. Tutte le funzioni supportano implicitamente un numero variabile di parametri, oltre a parametri posizionali/nominali._NEWLINE_Il seguente \xc3\xa8 un programma completo, interamente procedurale, che illustra alcune decisioni implementative che riguardano la struttura dei loop e il processamento imperativo delle sequenze:_NEWLINE_function sayList(saying)_NEWLINE_   for elem in saying_NEWLINE_       >> elem_NEWLINE_       formiddle: >> " "_NEWLINE_       forlast: > "!"_NEWLINE_   end_NEWLINE_end_NEWLINE_sayList(List("Have", "a", "nice", "day") )\n_START_SECTION_\nFunzionale\n_START_PARAGRAPH_\nIl motore di valutazione chiamato Sigma-riduttore interno permette di scrivere programmi in puro stile funzionale, non diversamente da quanto possibile fare in linguaggi come il Lisp. Comunque, resta possibile miscelare diversi stili di programmazione (come approcci OOP o puramente imperativi) direttamente nelle sequenze funzionali._NEWLINE_Le sequenze funzionali sono costituite da normali array; questo significa che possono essere create, controllate e modificate dinamicamente dal programma stesso, sia fra valutazioni distinte che durante il corso di una valutazione di Sigma-riduzione. Il seguente esempio illustra la possibilit\xc3\xa0 di cambiare dall\'interno della sequenza un particolare tipo di referenza a variabile, chiamato late binding._NEWLINE_ pnext = [ printl, \'"\', &value, \'"\' ]_NEWLINE_ dolist(function(p); seq.value = p; eval(seq); end,_NEWLINE_         ["Have", "a", "nice", "day"] )_NEWLINE_\xc3\x88 anche possibile chiamare direttamente le sequenze funzionali se il loro primo membro \xc3\xa8 esso stesso un valore chiamabile, come nel seguente esempio:_NEWLINE_[printl "Prompt> "]( "Real data to print" )_NEWLINE_Sequenze funzionali con un solo livello di profondit\xc3\xa0 (come quelle viste in questi esempi) possono essere viste come chiamate pre-registrate (cached calls), ed una volta assegnate ad una variabile sono morfologicamente equivalenti ai simboli che identificano le funzioni stesse._NEWLINE_Il paradigma funzionale \xc3\xa8 completato dal marcatore di valore fuori banda (out of band item marker). Ogni valore pu\xc3\xb2 ricevere il marcatore oob, la cui presenza pu\xc3\xb2 essere verificata in un secondo momento attraverso operatori di linguaggio e/o funzioni di libreria. Si tratta di un segnale che indica una significanza speciale del valore marcato e che pu\xc3\xb2 alterare il comportamento delle sequenze funzionali attraverso le quali viene fatto viaggiare. Ad esempio, molti cicli funzionali, come floop o times, possono essere fatti ripartire o interrotti ritornando rispettivamente un valore oob 1 o 0 da una delle funzioni della sequenza. Oppure, la funzione map, che trasforma tutti i valori contenuti in una sequenza applicandovi una funzione di trasformazione, ignorer\xc3\xa0 (scartandolo) un valore nil marcato oob; in questo modo \xc3\xa8 possibile effettuare operazioni di mappatura e filtro in un singolo passaggio.\n_START_SECTION_\nOrientato agli oggetti (OOP)\n_START_PARAGRAPH_\nFalcon adotta un modello di Programmazione orientata agli oggetti che include classi, ereditariet\xc3\xa0, membri statici, inizializzatori di propriet\xc3\xa0 e costruttori. L\'ereditariet\xc3\xa0 multipla \xc3\xa8 supportata a condizione che al massimo una delle classi nella gerarchia sia riflessiva (cio\xc3\xa8, rifletta dati direttamente forniti dalle applicazioni o dai moduli di terze parti in modalit\xc3\xa0 nativa). \xc3\x88 supportato anche l\'accesso ai membri delle classi base._NEWLINE_La struttura delle istanze \xc3\xa8 fissa e immutabile, ma data la natura funzionale di Falcon, che vede le funzioni come un tipo particolare di dati, \xc3\xa8 possibile impostare i membri di un\'istanza come semplici dati o come funzioni (rendendoli quindi metodi) dinamicamente. Sequenze funzionali possono essere assegnate alle propriet\xc3\xa0, nel cui casi diventano metodi funzionali per la data istanza._NEWLINE_Falcon supporta oggetti primitivi, ossia oggetti non dotati di classe specifica, che possono essere sia totalmente privi di classe che parzialmente derivati da una o pi\xc3\xb9 classi parente. Gli oggetti primitivi vengono istanziati e impostati prima che la Macchina Virtuale esegua il programma principale. L\'ordine di risoluzione delle istanze \xc3\xa8 gestito dal Linker di Falcon, che assicura una corretta inizializzazione pur in caso di referenze incrociate fra oggetti primitivi nello stesso modulo._NEWLINE_Le classi possono essere istanziate anche attraverso sequenze funzionali: l\'istantazione di una classe (la creazione di un\'istanza) \xc3\xa8 morfologicamente equivalente a "chiamare" il simbolo della data classe. Quindi, valutare una sequenza funzionale che comincia con il simbolo di una classe equivale a chiederne l\'istantazione._NEWLINE_Il modello OOP di Falcon \xc3\xa8 completato dal sovraccarico degli operatori, che permette di creare classi sulle quali gli operatori di linguaggio logici e matematici si comportano in modo specializzato.\n_START_SECTION_\nOOP basata sui prototipi\n_START_PARAGRAPH_\nLa programmazione orientata ai prototipi \xc3\xa8 simile al paradigma OOP, ma \xc3\xa8 privo del concetto di classe. Le istanze sono tutte prive di classe e la loro struttura pu\xc3\xb2 essere cambiata dinamicamente. I dizionari del linguaggio Falcon (tipo primitivo costituito da collezioni di coppie chiave univoca/valore) possono includere funzioni; possono quindi essere blessed, informando cos\xc3\xac il sistema che sono da trattare come istanze prive di classe. Applicando l\'accessore punto, \xc3\xa8 possibile accedere ai loro membri come metodi o propriet\xc3\xa0. Nel seguente esempio, un dizionario diventa oggetto:_NEWLINE_dict = bless([ \'state\' => 0, \'incme\' => function(); self.state++; end ])_NEWLINE_dict.incme()_NEWLINE_> dict.state  // stampa \'1\'_NEWLINE_Un meccanismo simile pu\xc3\xb2 essere applicato agli array tramite i binding:_NEWLINE_array = [1,2,3]_NEWLINE_array.showMe = function()_NEWLINE_   for item in self: > item_NEWLINE_end_NEWLINE_array.showMe()\n_START_SECTION_\nOrientata ai messaggi\n_START_PARAGRAPH_\nLa programmazione orientata ai messaggi \xc3\xa8 costituita dall\'invocazione di uno o pi\xc3\xb9 gestori alla trasmissione di un messaggio. Il contenuto del messaggio \xc3\xa8 arbitrario, e pu\xc3\xb2 essere costituito da qualsiasi tipo di dato, incluse classi (dalle quali creare istanze al volo), sequenze funzionali o tabelle. I ricevitori possono competere per ricevere il messaggio escludendo gli altri gestori, o possono partecipare nella costruzione di una risposta comune in passaggi ordinati. I messaggi possono richiedere una gestione immediata all\'atto della trasmissione, oppure essere lasciati nell\'ambiente per essere ricevuti e gestiti da sottoscrittori tardivi (cos\xc3\xac dette "asserzioni")._NEWLINE_La programmazione orientata ai messaggi si interfaccia direttamente con la Macchina Virtuale, con la quale moduli nativi e applicazioni parente possono interagire. Ad esempio, un\'applicazione multithreaded pu\xc3\xb2 lanciare nella macchina virtuale messaggi che giungono da thread differenti per una gestione serializzata a livello di script, ed una susseguente ri-trasmissione asincrona dei messaggi elaborati direttamente dall\'interno degli script.\n_START_SECTION_\nProgrammazione tabellare\n_START_PARAGRAPH_\nLa programmazione tabellare \xc3\xa8 una speciale estensione e generalizzazione dell\'OOP, dove una classe \xc3\xa8 rappresentata da una tabella, le cui colonne sono propriet\xc3\xa0 e ogni riga \xc3\xa8 un\'istanza. Oltre a mantenere tutte le istanze ordinatamente assieme, e permettere ad ogni istanza di lavorare con quelle adiacenti accedendo alla tabella madre, modifiche sulla struttura della tabella sono immediatamente riflesse su tutte le istanze._NEWLINE_Le tabelle offrono un supporto diretto alla selezione di un comportamento o un insieme di comportamenti da una serie finita di scelte possibili, fornendo la base per sviluppare direttamente nel linguaggio motori decisionali a logica discreta o fuzzy. Ogni riga, fisicamente costituita da un dato di tipo Array, pu\xc3\xb2 contenere sia dati e logiche specifiche della tabella che dati o logiche private dell\'istanza (grazie ai Binding), quindi un\'entit\xc3\xa0 selezionata da una logica di estrazione globale pu\xc3\xb2 fornire comportamenti altamente specializzati.\n_START_SECTION_\nAltre caratteristiche\n_START_PARAGRAPH_\nOltre a fornire diversi stili di programmazione, Falcon presenta caratteristiche trasversali a diversi modelli; di seguito sono indicate le pi\xc3\xb9 rilevanti.\n_START_SECTION_\nDescrizioni di liste\n_START_PARAGRAPH_\nTipi di base e classi che espongono un\'interfaccia di sequenza verso il motore interno offrono un metodo "comp", che permette di sintetizzare insiemi a partire da una definizione matematica._NEWLINE_Il metodo "comp" richiede l\'indicazione obbligatoria di un parametro "origine", che pu\xc3\xb2 essere un\'altra sequenza, una valore di tipo "range" o una funzione generatrice che torna un valore per volta, ed un marcatore speciale per dichiarare la fine della sequenza._NEWLINE_Una funzione (o in generale un\'entit\xc3\xa0 chiamabile) pu\xc3\xb2 essere fornito come parametro opzionale, e agisce sia come filtro che come modificatore._NEWLINE_Sequenze associative (ad esempio dizionari) sono supportati._NEWLINE_Il seguente \xc3\xa8 un semplice esempio che usa un range per creare un array contenente i numeri pari tra 2 e 10, attraverso comprensione di lista:_NEWLINE_ even_array = [].comp( [2:11:2] )_NEWLINE_Per generare una lista di numeri interi casuali fra 1 e 9, di lunghezza anch\'essa casuale:_NEWLINE_random_list = List().comp(function(); n = random(1,10); return n == 10? oob(0): n; end)_NEWLINE_La funzione generatrice, fornita in linea, torna il marcatore di fine sequenza "oob(0)" quando viene generato casualmente il numero 10 (quindi, ad ogni nuova iterazione c\'\xc3\xa8 1/10 di probabilit\xc3\xa0 di terminare la lista)._NEWLINE_Il prossimo esempio, pi\xc3\xb9 completo, usa un generatore per riempire un insieme di tipo "Set" con esattamente dieci numeri interi casuali nell\'intervallo 1..100. In questa occasione \xc3\xa8 il filtro stesso che determina quando la comprensione \xc3\xa8 completa._NEWLINE_random_set = Set().comp(_NEWLINE_    [random, 1, 100],  // generator, callable array_NEWLINE_    function(number, myself)  // filter, using the optional "myself" param_NEWLINE_       if myself.len() == 10_NEWLINE_           return oob(0)  // return oob(0) as a generator to terminate_NEWLINE_       end_NEWLINE_       return number_NEWLINE_    end_NEWLINE_    )_NEWLINE_Il metodo "comp" torna lo stesso oggetto su cui \xc3\xa8 applicato, e pu\xc3\xb2 essere applicato anche su sequenze non vuote._NEWLINE_Similmente, il metodo "mfcomp" permette di creare descrizioni di liste a partire da insiemi multipli, come nel seguente esempio:_NEWLINE_ sums = [].mfcomp( {x,y=> x+y}, .[1 2 3], .[4 5 6] )\n_START_SECTION_\nDocumenti Maschera\n_START_PARAGRAPH_\nFalcon supporta script inseriti in documenti di testo tramite le direttive di preprocessore <? ..\xc2\xa0?> o <?fal...\xc2\xa0?>. Gli script salvati con estensione ".ftd" sono trattati come semplici documenti di testo e semplicemente trascritti sull\'output fino a che una delle suddette direttive di preprocessore vengono incontrate. Script inclusi nelle direttive sono eseguiti in linea, come nel seguente esempio:_NEWLINE_ Hai chiamato questo programma passando <? print(args.len() )\xc2\xa0?> parametri._NEWLINE_I documenti FTD (Falcon template documents) possono far parte di applicazioni pi\xc3\xb9 ampie, costituite in parte da normali moduli e in parte da documenti maschera dinamici, cos\xc3\xac che \xc3\xa8 possibile delegare la logica di presentazione alle maschere dinamiche e mantenere la logica applicativa in moduli Falcon._NEWLINE_I documenti FTD possono essere utilizzati nella realizzazione di siti web dinamici. Per alcuni web server (al momento, Apache 2) sono disponibili dei moduli integrati che possono eseguire direttamente documenti FTD e moduli Falcon, esponendo verso di questi l\'API del web server ospite. \xc3\x88 anche possibile usare pagine FTD dinamiche in modalit\xc3\xa0 CGI.\n_START_SECTION_\nEccezioni\n_START_PARAGRAPH_\nIl meccanismo delle eccezioni si basa sulle istruzioni "raise", "try" e "catch". L\'istruzione raise pu\xc3\xb2 sollevare qualsiasi tipo di dato, inclusi nil, numeri, stringhe, oggetti ecc. Funzioni di libreria e moduli esterni sollevano generalmente istanze della classe Error, o istanze di classi derivate da essa._NEWLINE_L\'istruzione catch pu\xc3\xb2 essere utilizzata per catturare un\'eccezione di qualsiasi tipo, o pu\xc3\xb2 filtrare le istanze di certe classi, o filtrare solo alcuni tipi di dato. La cattura delle istanze di classe \xc3\xa8 organizzata su base gerarchica; \xc3\xa8 quindi possibile fornire gestori di eccezioni pi\xc3\xb9 specifici ed eventualmente gestori generici di default, come nel seguente esempio (la classe TypeError \xc3\xa8 derivata da Error):_NEWLINE_try_NEWLINE_   ... codice che pu\xc3\xb2 generare un errore..._NEWLINE_catch TypeError in error_NEWLINE_   ... abbiamo commesso un errore di tipo..._NEWLINE_catch Error in error_NEWLINE_   ... abbiamo commesso un altro errore generico..._NEWLINE_catch StringType in error_NEWLINE_   ... \xc3\xa8 stata sollevata esplicitamente una stringa..._NEWLINE_catch in error_NEWLINE_   ... \xc3\xa8 stato sollevato qualcosa di diverso..._NEWLINE_end_NEWLINE_La clausola in dell\'istruzione catch \xc3\xa8 opzionale (questo significa che il contenuto dell\'errore pu\xc3\xb2 essere scartato)._NEWLINE_L\'istruzione catch si comporta in modo simile all\'istruzione select, che pu\xc3\xb2 essere usata per eseguire codice in base al tipo o alla classe della variabile su cui \xc3\xa8 applicato.\n_START_SECTION_\nRuntime integrabile\n_START_PARAGRAPH_\nFalcon, tramite la libreria specifica libfalcon, \xc3\xa8 in grado di interfacciarsi con altri sistemi, eventualmente estendendoli.\n_START_SECTION_\nGenerazione di documentazione\n_START_PARAGRAPH_\nFalcon dispone di uno strumento di documentazione integrato chiamato Faldoc, studiato per estrarre documentazione in-linea sia da moduli scritti in Falcon che da moduli nativi in C/C++.\n_START_SECTION_\nFilesystem virtuale\n_START_PARAGRAPH_\nTutte le operazioni di I/O che avvengono sia al livello di motore interno, sia a livello di macchina virtuale (esecuzione dei programmi) sono delegate ad un Virtual Filesystem Provider centralizzato. I Filesystem virtuali sottoscritti al provider astraggono operazioni I/O come la lettura delle directory, la creazione dei file, l\'apertura di stream ecc., e possono essere invocati attraverso il loro indirizzo URI. Questo rende possibile il caricamento di moduli o l\'apertura di risorse da qualsiasi Filesystem virtuale, (come risorse di rete o archivi compressi/crittografati), che possono fornire locazioni speciali riconosciute da moduli di terze parti o da applicazioni che integrano il motore Falcon.\n_START_SECTION_\nSupporto alla concorrenza\n_START_PARAGRAPH_\nA partire dalla versione 0.8.x \xc3\xa8 stato introdotto un pieno supporto alla concorrenza secondo una modalit\xc3\xa0 agent-oriented. \xc3\x88 possibile scambiare dati attraverso vari meccanismi di condivisione mentre ogni singolo thread gira in una propria macchina virtuale che non viene in alcun modo interessata da quanto avviene nelle altre. Questo sistema implica un pieno parallelismo e un elevato grado di sicurezza in fase di esecuzione.\n_START_SECTION_\nCoroutine\n_START_PARAGRAPH_\nFalcon supporta un sistema di concorrenza quasi-parallelo (detto coroutining). Le coroutine sono costituite da codice eseguito in frazioni di tempo differenti, o durante i tempi di pausa della Macchina Virtuale. Questo meccanismo fornisce un parallelismo software pi\xc3\xb9 leggero del multithreading a livello hardware, e permette la piena visibilit\xc3\xa0 dei dati globali in ogni agente del processo parallelo, ma richiede l\'esplicita collaborazione di ogni coroutine al processo (ad esempio, evitando di effettuare chiamate bloccanti per l\'intera macchina virtuale) e non permette di sfruttare hardware paralleli.\n_START_SECTION_\nMetacompilatore\n_START_PARAGRAPH_\nIl compilatore Falcon ha un meta-compilatore che supporta l\'espansione di macro. Il meta-compilatore \xc3\xa8 pilotato da una Macchina Virtuale Falcon applicata al compilatore di base; l\'output generato dal meta-compilatore \xc3\xa8 sovrapposto allo stream di ingresso del compilatore come se si trattasse del sorgente originale. Usando la sequenza di escape \\[...\\] \xc3\xa8 possibile creare i contenuti del programma di base dinamicamente semplicemente usando le routine di output. Ad esempio:_NEWLINE_\\[ printl( "printl( \'Ciao mondo!\' )" ) \\]_NEWLINE_La parola chiave macro fornisce una grammatica semplificata per un accesso pi\xc3\xb9 semplice alla meta-programmazione effettuata al volo durante la compilazione.\n_START_SECTION_\nInternazionalizzazione nativa\n_START_PARAGRAPH_\nLe stringhe col prefisso \'i\' sono riconosciute come stringhe internazionali per l\'esportazione. \xc3\x88 anche possibile dichiarare la lingua nel quale i messaggi internazionalizzati sono scritti tramite l\'istruzione directive lang, come nel seguente esempio:_NEWLINE_ directive lang=fr_FR           // uses 5 characters ISO language code_NEWLINE_ > i"Bonjour \xc3\xa0 tout le monde!"_NEWLINE_Un tool da riga di comando chiamato fallc consente di esportare le stringhe \'i\' in un file di definizione XML, che pu\xc3\xb2 essere usato come maschera per la traduzione delle stringhe in altre lingue._NEWLINE_La tavola delle stringhe della lingua in cui l\'applicazione deve essere tradotta \xc3\xa8 applicata dinamicamente al momento del caricamento del modulo (prima dell\'esecuzione).\n_START_SECTION_\nImplementazione\n_START_PARAGRAPH_\nFalcon in tutte le sue parti critiche, dalla VM ai moduli ufficiali, \xc3\xa8 completamente scritto in C++, tranne alcune parti a basso livello che fanno uso di C ed Assembly.'