F Sharp

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită pe 21 noiembrie 2021; verificările necesită 3 modificări .
F#
Clasa de limba

multi- paradigma : funcțională , orientată pe obiecte , generalizată ,

programare imperativă
Aparut in 2005
Autor Cercetare Microsoft
Dezvoltator Microsoft și F Sharp Software Foundation [d]
Extensie de fișier .fs, .fsi, .fsxsau.fsscript
Eliberare 6.0 ( 19 octombrie 2021 )
Tip sistem strict
A fost influențat Obiectiv Caml , C# , Haskell
Licență Licență software Apache
Site-ul web fsharp.org
OS Software multiplatform ( .NET Framework , Mono )
 Fișiere media la Wikimedia Commons

F# (pronunțat ef-sharp ) este un limbaj de programare cu mai multe paradigme din familia de limbaje .NET care acceptă programarea funcțională, pe lângă programarea imperativă ( procedurală ) și orientată pe obiecte . Structura lui F# este similară cu cea a OCaml în multe privințe, singura diferență fiind că F# este implementat peste bibliotecile .NET și runtime . Limbajul a fost dezvoltat de Don Syme la Microsoft Research din Cambridge și este în prezent dezvoltat de Microsoft Developer Division. F# se integrează destul de strâns cu mediul de dezvoltare Visual Studio și este inclus în distribuția Visual Studio 2010/2012/2013/2015/2017/2019/2022; compilatoare au fost dezvoltate și pentru Mac și Linux [1] .  

Microsoft a integrat mediul de dezvoltare F# în Visual Studio 2010 și versiuni mai noi.

Pe 4 noiembrie 2010, codul pentru compilatorul F# și bibliotecile sale de bază a fost publicat sub Licența Apache 2.0 [2] .

Caracteristici

Codul F# este de tip sigur , adesea mai compact decât codul C# similar , datorită inferenței de tip . F# are o tastare puternică, conversiile implicite ale tipului sunt complet absente, ceea ce elimină complet erorile asociate cu turnarea tipului.

Caracteristici precum programarea generică și funcțiile de ordin superior permit scrierea unor algoritmi generici abstracti care manipulează structuri de date parametrizate (de exemplu , matrice , liste , grafice , arbori ).

În multe limbi, majoritatea valorilor sunt variabile. De exemplu, următorul cod C++ xva stoca valoarea 3 într-o variabilă:

int x = 2 ; x ++ ;

În F#, prin contrast, toate valorile sunt constante în mod implicit. F# permite variabile, ceea ce vă cere să marcați în mod specific valorile ca mutabile cu cuvântul mutabil:

fie x = 2 // imuabil fie mutabil y = 2 // variabilă x <- 3 // eroare y <- 3 // Ok. y=3

F# are, de asemenea, tipuri de referință și obiecte care pot conține și valori modificabile. Cu toate acestea, cea mai mare parte a codului este pură funcții , ceea ce evită multe erori și facilitează depanarea. În plus, paralelizarea programelor este simplificată. Cu toate acestea, codul devine rareori mai complicat decât un cod similar într-un limbaj imperativ.

Una dintre ideile principale din spatele F# este să vă asigurați că codul și tipurile existente într-un limbaj de programare funcțional pot fi ușor accesate din alte limbaje .NET. Programele F# se compilează în ansambluri CLR (fișiere cu extensii .exe și .dll), cu toate acestea, pentru a le rula, trebuie să instalați un pachet de rulare în plus față de .NET Framework.

O caracteristică interesantă (și diferență față de OCaml ) este controlul imbricației logice a constructelor de cod prin indentarea unui număr arbitrar de spații (și numai spații). Caracterele tabulatoare nu sunt acceptate în acest scop. Acest lucru duce la discuții constante pe forumurile dezvoltatorilor experimentați care sunt obișnuiți să folosească file în alte limbaje de programare.

Compilator și interpret

F# este un limbaj de programare compilat care folosește Common Intermediate Language (CIL) ca limbaj intermediar, la fel ca programele scrise în C# sau VB.NET .

Alături de compilatorul F# (fsc), există și un interpret F# (fsi) care execută codul F# în mod interactiv.

Caracteristica distinctivă a compilatorului F# și a interpretului F# este capacitatea de a trata codul în două moduri diferite - imediat (în mod implicit) și amânat (programatorul trebuie să specifice acest lucru în mod explicit în codul sursă). În cazul interpretării imediate, expresiile sunt evaluate în prealabil în momentul pornirii programului pentru execuție, indiferent dacă sunt apelate în timpul execuției programului sau nu. În acest caz, performanța execuției programului scade adesea, iar resursele sistemului (de exemplu, memoria) sunt irosite. În cazul interpretării codului leneș, expresiile sunt evaluate doar în momentul în care sunt accesate direct în timpul execuției programului. Acest lucru salvează programul de dezavantajele de mai sus, dar reduce predictibilitatea în ceea ce privește cantitatea și secvența utilizării resurselor (timp procesor, memorie, dispozitive I/O etc.) la diferite etape ale execuției programului.

Exemple

Sintaxa lui F# se bazează pe notația matematică, iar programarea este oarecum similară cu algebra , ceea ce face ca F# să fie similar cu Haskell . De exemplu, când definiți un tip nou, puteți specifica ca variabilele acelui tip să fie „ întregi sau șiruri ”. Iată cum arată:

tastați myType = IntVal de int | StringVal de șir

Un exemplu important de astfel de tipuri este Opțiunea, care conține fie o valoare de un anumit tip, fie nimic.

tip Opțiune <a> = Niciunul | _ _ Unele dintre a

Este un tip standard F# și este adesea folosit în situațiile în care rezultatul unui cod (cum ar fi o căutare într-o structură de date) este o valoare care ar putea să nu fie returnată.

Codul este, de asemenea, o notație matematică. Următoarea construcție este echivalentă cu f(x) = x + 1 în algebră:

fie f x = x + 1

F# funcționează astfel: tipul „ f” este „ int -> int”, adică funcția ia un număr întreg ca intrare și produce un întreg ca ieșire.

F# vă permite să accesați absolut tot ceea ce este în FCL . Sintaxa pentru lucrul cu bibliotecile .NET în acest sens este cât mai apropiată de sintaxa C# . Caracteristicile de limbă sunt vizibile atunci când utilizați întreaga gamă de caracteristici F#. De exemplu, următorul cod aplică o funcție elementelor unei liste :

let rec map func lst = potrivește lst cu | [] -> [] | head :: tail -> func head :: map func tail las myList = [ 1 ; 3 ; 5 ] let newList = map ( fun x -> x + 1 ) myList

" newList" este acum " [2;4;6]".

Analiza listei în această funcție se face folosind o altă caracteristică puternică de potrivire a modelelor . Vă permite să specificați modele, atunci când sunt potrivite, aparițiile corespunzătoare ale operatorului de potrivire sunt calculate. Primul model „[]” înseamnă o listă goală. A doua este o listă formată din primul element și coada (care poate fi o listă arbitrară, inclusiv una goală). În a doua probă, valoarea capului este asociată cu variabila cap, iar valoarea cozii cu coada (numele pot fi arbitrare). Astfel, pe lângă sarcina principală, eșantionul vă permite și să descompuneți structuri complexe de date. De exemplu, în cazul tipului Option, potrivirea modelului arată astfel:

potriviți x cu | Unele v -> printfn „Valoarea găsită %d”. v | None -> printfn „Nu s-a găsit nimic”. | Niciunul -> printfn „Bună ziua”

Limbajul acceptă expresii generatoare definite pentru seturi { … }, liste [ … ]și matrice. [| … |] De exemplu:

fie testul n = [ pentru i in 0 .. n face daca i % 2 = 0 atunci randamentul i ]

Funcția de hartă este una dintre funcțiile standard de listă conținute în modulul Listă. Există și funcții pentru alte structuri de date declarate în modulele Array, Set, Option.

Un instrument util este operatorul pipe-forward (|>), care vă permite să scrieți lanțuri de apeluri de funcție în ordine inversă. Ca urmare, are loc următorul cod (valorile intermediare sunt indicate în comentarii):

[ 1 ; 2 ; 5 ] |> Lista . harta ((+) 1 ) // [2; 3; 6] |> Lista . filtru ( fun x -> x % 2 = 0 ) // [2; 6] |> Lista . suma // 8

Utilizarea operatorului |>elimină necesitatea unui număr mare de paranteze și, de asemenea, modifică percepția vizuală a codului. Și acum acest cod se citește astfel: luați o listă cutare sau cutare, adăugați 1 la fiecare element, apoi lăsați doar elemente pare, returnați suma lor. Adică descrie secvența acțiunilor efectuate asupra obiectului original, în ordinea în care apare pe computer.

Următoarea este o mică demonstrație a modului în care caracteristicile .NET extind F#. Un exemplu este aplicațiile cu ferestre și gestionarea evenimentelor. Procesarea evenimentelor înseamnă că unele acțiuni din program apar doar ca o reacție la anumite evenimente - acțiuni ale utilizatorului, conexiune la dispozitiv etc. Proiectul poate fi creat atât în ​​Visual Studio, cât și în orice document text, care este apoi alimentat compilatorului F# ( fsc).

// deschide - conectează module și spații de nume pentru a utiliza // valorile, clasele și alte module conținute în acestea. deschide System.Windows.Forms // - clase Form (fereastră), Button (buton), etc. // Beep - un semnal sonor // Alți parametri sunt trecuți ca argumente beep pe care nu le folosim let beep _ = System . Consola . Beep () // creează o fereastră denumită în mod programatic window !trebuie să apeleze o funcție de afișare a cuvântului - de exemplu Application.Run(window)! // Vizibil - valoare booleană, dacă fereastra este vizibilă // TopMost - dacă fereastra este afișată în prim-plan (ordinea ferestrelor cu aceeași valoare în ordinea inversă a apelului) // Text - textul ferestrei title let window = new Form ( Vizibil = adevărat , TopMost = true , Text = " " , Top = 0 , Left = 0 , Height = 512 , Width = 768 ) fereastra . WindowState <- FormWindowState . Normal // Fereastra Normal (, Minimizat, Maximizat). Doar că nu este inclus în constructorul ferestrei pentru exemplu . ClientSizeChanged . Adăugați o fereastră sonoră . _ apăsarea tastei . Adăugați o fereastră sonoră . _ apăsarea tastei . Adăugați o fereastră sonoră . _ tastare . Adăugați beep Aplicație . Fereastra de rulare // fereastra de afișare

Factorial

Functie factoriala recursiva in mod nativ:

fie rec fac n = if n < 2 then 1 else n * fac ( n - 1 )

Funcție factorială recursiva optimizată pentru recursiunea cozii.

let factorial num = let rec fac num acc = potrivire num cu | x când x < 2 -> acc |_ -> fac ( num - 1 ) ( acc * num ) fac num 1

O funcție factorială, într-un stil imperativ, folosind starea mutabilă.

fie factorial num = if num < 2 then 1 else fie mutabil fac = 1 pentru i in [ 2 .. num ] do fac <- fac * i fac

Funcția factorială utilizând îndoirea listei și înmulțirea curbată:

fie fac n = Listă . pliază (*) 1 [ 1 .. n ]

Funcție recursiva pentru a calcula numerele Fibonacci folosind metoda de potrivire a modelelor:

fie rec fib n a b = potrivește n cu | 0 -> a | 1 -> b | _ -> fib ( n - 1 ) b ( a + b )

Note

  1. F# linkuri de descărcare pe site-ul Microsoft Research . Consultat la 24 iunie 2011. Arhivat din original pe 24 iunie 2011.
  2. Anunțul F# Compiler + Library Source Code Drop . Consultat la 5 noiembrie 2010. Arhivat din original pe 17 ianuarie 2013.

Vezi și

Link -uri

Literatură

  • Chris Smith (Smith, Chris). Programare în F# = Programare F#. - O'Reilly, 2011. - 448 p. — ISBN 978-5-93286-199-8 .
  • Dmitri Soșnikov. Programare funcțională în F#. - Moscova: DMK Press, 2011. - 192 p. - ISBN 978-5-94074-689-8 .
  • Syme, Don; Granicz, Adam; Cisternino, Antonio. ExpertF#. - Apress, 2007.  (engleză)