A causa di limitazioni tecniche, non è stato possibile riprodurre correttamente la tipografia desiderabile del titolo.
F # | ||
Data della prima versione | 2002 | |
---|---|---|
Paradigma | Funzionale , imperativo , orientato agli oggetti | |
Autore | Don Syme, Microsoft Research | |
Sviluppatore | F # Software Foundation | |
Ultima versione | 5.0 (10 novembre 2020) | |
Versione di sviluppo | Anteprima 5.0 (2 aprile 2019) | |
Digitando | Statico , forte , nominativo , dedotto | |
Influenzato da | OCaml , C # , Haskell | |
Implementazioni | .NET Framework , Mono | |
Licenza | Licenza Apache | |
Sito web | fsharp.org | |
Estensione del file | fs, fsi, fsx e fsscript | |
F # è un linguaggio di programmazione funzionale , imperativo e orientato agli oggetti per la piattaforma .NET . F # è sviluppato da Microsoft Research e il suo kernel è derivato dal linguaggio OCaml , con il quale è altamente compatibile. Questi due linguaggi di programmazione fanno parte della stessa famiglia dei linguaggi ML .
Questo linguaggio è stato progettato specificamente per la piattaforma .NET , quindi fortemente orientato agli oggetti. Da novembre 2010, Microsoft ha reso disponibile a tutte le librerie di base e al suo compilatore F #, con la licenza Apache 2.
F # è un linguaggio fortemente tipizzato che utilizza l' inferenza del tipo . Questo meccanismo delega la tipizzazione di variabili e funzioni al compilatore. Tuttavia, il linguaggio consente allo sviluppatore di indicare esplicitamente il tipo nella dichiarazione. Integrato nell'ecosistema .NET, F # supporta i tipi primitivi della piattaforma così come i suoi oggetti. Inoltre, estende il sistema dei tipi e consente di distinguere tra i cosiddetti tipi immutabili e quelli che si dice modificabili. Gli oggetti sono considerati tipi modificabili (sul posto) e vengono utilizzati per impostare il modello di programmazione a oggetti all'interno del linguaggio. I tipi immutabili vengono utilizzati principalmente durante la programmazione funzionale; la modifica di un tipo immutabile crea una nuova istanza senza sovrascrivere quella vecchia.
Come la maggior parte dei linguaggi derivati da ML , F # utilizza per impostazione predefinita il meccanismo di valutazione rigoroso . Tuttavia, come Haskell , può implementare una valutazione pigra delle espressioni tramite l'uso della parola chiave lazy. Per la programmazione funzionale, fornisce diversi costrutti e un insieme di tipi immutabili: tuple, record, tipi di somma ed elenchi.
Una tupla rappresenta una raccolta di n valori, n ≥ 0. Il valore di n corrisponde all'arità della tupla. Il tipo di unità rappresenta la tupla vuota il cui unico valore possibile è (). Questo tipo viene utilizzato per digitare funzioni che non accettano un valore come input e / o ne restituiscono uno. La 3-tupla (o terzina) è rappresentata da (A, B, C), dove A, B e C possono essere di qualsiasi tipo. Una tupla può essere utilizzata per memorizzare valori solo quando il numero di valori è noto al momento della codifica e rimane costante durante l'esecuzione.
Un record è una versione specializzata di tuple in cui i campi sono denominati, come in { Nom:string; Age:int }. Le registrazioni possono essere creati nel modo seguente: { Nom="Toto"; Age=1 }. La parola chiave withviene utilizzata per creare una copia del record: { r with Nom="CD" }crea un nuovo record da un record precedente denominato r e il cui valore nel campo Nome viene modificato.
Il tipo di elenco è un elenco concatenato che può essere rappresentato sia usando la notazione head::tail(composti utilizzando l'operatore ::, l'equivalente dell'operatore cons in Lisp / Schema lingue ), oppure in una notazione abbreviata: [item1; item2; item3]. Viene annotato un elenco vuoto [].
L'ultimo tipo di tipo di dati algebrico , i tipi di somma (che sono unioni tipizzate funzionalmente equivalenti in linguaggio C) possono essere definiti come una somma di qualsiasi tipo immutabile menzionato sopra. Per esempio,
type A = | ConstructorX of string | ConstructorY of intpuò contenere valori istanziati da ConstructorXo da ConstructorY. È inoltre possibile definire il tipo di valori restituiti dai costruttori.
Ecco il tradizionale ciao mondo :
(* Ceci est un commentaire *) printfn "Hello World!"Questo altro esempio tradizionale nei linguaggi funzionali mira a mostrare la concisione che si può ottenere con questo tipo di linguaggi:
let rec factorielle n = match n with | 0 -> 1 | _ -> n * factorielle (n - 1)Questa variante, con un accumulatore, implementa la ricorsione terminale , un'ottimizzazione comune tra i linguaggi funzionali:
let factorielle n = let rec factorielle_recursive n accu = match n with | 0 -> accu | _ -> factorielle_recursive (n - 1) (n * accu) factorielle_recursive n 1