F Sharp

Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2021. november 21-én felülvizsgált verziótól ; az ellenőrzések 3 szerkesztést igényelnek .
F#
Nyelvóra

több paradigma : funkcionális , objektum-orientált , általánosított ,

kötelező programozás
Megjelent 2005
Szerző Microsoft Research
Fejlesztő A Microsoft és az F Sharp Software Foundation [d]
Fájlkiterjesztés _ .fs, .fsi, .fsxvagy.fsscript
Kiadás 6.0 ( 2021. október 19. )
Típusrendszer szigorú
Befolyásolva Cél: Caml , C# , Haskell
Engedély Apache szoftverlicenc
Weboldal fsharp.org
OS Többplatformos szoftver ( .NET Framework , Mono )
 Médiafájlok a Wikimedia Commons oldalon

Az F# (ejtsd: ef-sharp ) egy többparadigmájú programozási nyelv a .NET nyelvcsaládban, amely támogatja a funkcionális programozást az imperatív ( procedurális ) és objektumorientált programozáson kívül . Az F# felépítése sok tekintetben hasonlít az OCaml -éhoz, azzal az egyetlen különbséggel, hogy az F# a .NET - könyvtárak és a futtatókörnyezet tetején van megvalósítva . A nyelvet Don Syme fejlesztette ki a cambridge - i Microsoft Researchnél , jelenleg pedig a Microsoft fejlesztői részlege fejleszti. Az F# meglehetősen szorosan integrálódik a Visual Studio fejlesztői környezetébe , és benne van a Visual Studio 2010/2012/2013/2015/2017/2019/2022 disztribúciójában; fordítóprogramokat fejlesztettek ki Macre és Linuxra is [1] .  

A Microsoft integrálta az F# fejlesztői környezetet a Visual Studio 2010 és újabb verzióiba.

2010. november 4- én az Apache License 2.0 [2] alatt megjelent az F# fordító és a hozzá tartozó alapkönyvtárak kódja .

Jellemzők

Az F# kód típusbiztos , gyakran kompaktabb, mint a hasonló C# kód , a típuskövetkeztetés miatt . Az F#-ban erős a gépelés, az implicit típuskonverziók teljesen hiányoznak, ami teljesen kiküszöböli a típusöntéssel kapcsolatos hibákat.

Az olyan szolgáltatások, mint az általános programozás és a magasabb rendű függvények, lehetővé teszik olyan elvont általános algoritmusok írását , amelyek paraméterezett adatstruktúrákat (például tömböket , listákat , grafikonokat , fákat ) manipulálnak .

Sok nyelven a legtöbb érték változó. Például a következő C++ kód xa 3-as értéket tárolja egy változóban:

int x = 2 ; x ++ ;

Ezzel szemben az F#-ban alapértelmezés szerint minden érték állandó. Az F# lehetővé teszi a változókat, ami megköveteli, hogy az értékeket mutálhatóként jelölje meg a mutable szóval:

legyen x = 2 // változtathatatlan legyen változtatható y = 2 // változó x < - 3 // y hiba <- 3 // Ok. y=3

Az F#-nak is vannak hivatkozási típusai és objektumai, amelyek változtatható értékeket is tartalmazhatnak. A kód nagy része azonban tiszta függvény , amely sok hibát elkerül, és megkönnyíti a hibakeresést. Emellett leegyszerűsödik a programok párhuzamosítása is. Mindezek mellett a kód ritkán válik bonyolultabbá, mint egy imperatív nyelvű hasonló kód.

Az F# mögött meghúzódó egyik fő gondolat az, hogy a meglévő kódok és típusok egy funkcionális programozási nyelven könnyen elérhetők legyenek más .NET nyelvekről. Az F# programok CLR-szerelvényekre (.exe és .dll kiterjesztésű fájlok) fordítanak, futtatásukhoz azonban a .NET-keretrendszer mellett egy futtatócsomagot is telepíteni kell.

Érdekes funkció (és eltérés az OCaml -től ) a kódkonstrukciók logikai egymásba ágyazásának vezérlése tetszőleges számú szóköz (és csak szóköz) behúzásával. A tabulátor karakterek nem támogatottak erre a célra. Ez folyamatos vitákhoz vezet a tapasztalt fejlesztők fórumain, akik hozzászoktak ahhoz, hogy más programozási nyelveken használják a lapokat.

Fordító és értelmező

Az F# egy olyan lefordított programozási nyelv, amely a Common Intermediate Language (CIL) nyelvet használja köztes nyelvként, akárcsak a C# vagy VB.NET nyelven írt programok .

Az F# fordító (fsc) mellett van egy F# értelmező (fsi), amely interaktívan hajtja végre az F# kódot.

Az F# fordító és az F# értelmező megkülönböztető jellemzője, hogy a kódot kétféle módon kezelheti - azonnali (alapértelmezés szerint) és késleltetett módon (a programozónak ezt kifejezetten meg kell adnia a forráskódban). Azonnali értelmezés esetén a kifejezések előre kiértékelésre kerülnek a program végrehajtásra való indításának pillanatában, függetlenül attól, hogy a program végrehajtása során meghívásra kerülnek-e vagy sem. Ebben az esetben a programvégrehajtás teljesítménye gyakran csökken, és a rendszer erőforrásai (például memória) elpazarolnak. Lusta kódértelmezés esetén a kifejezések csak abban a pillanatban kerülnek kiértékelésre, amikor a program végrehajtása során közvetlenül hozzáférnek. Ez megkíméli a programot a fenti hátrányoktól, de csökkenti a kiszámíthatóságot az erőforrás-felhasználás mennyisége és sorrendje (processzoridő, memória, I/O eszközök stb.) tekintetében a programvégrehajtás különböző szakaszaiban.

Példák

Az F# szintaxisa matematikai jelölésen alapul, a programozás pedig némileg hasonlít az algebrához , ami miatt az F# hasonló a Haskellhez . Például, amikor egy új típust definiál, megadhatja, hogy az adott típus változói " integers or strings " legyenek. Így néz ki:

type myType = IntVal of int | StringVal of string

Az ilyen típusok fontos példája az Option, amely vagy valamilyen típusú értéket tartalmaz, vagy semmit.

típus Opció <a> = Nincs | _ _ Néhány a _

Ez egy szabványos F# típus, és gyakran használják olyan helyzetekben, amikor egy kód eredménye (például egy adatstruktúra keresése) olyan érték, amelyet esetleg nem ad vissza.

A kód egyben matematikai jelölés is. A következő konstrukció ekvivalens f(x) = x + 1 algebrával:

legyen f x = x + 1

Az F# a következőképpen működik: a " " típus fa " int -> int", vagyis a függvény egy egész számot vesz be bemenetként, és egy egész számot ad ki kimenetként.

Az F# lehetővé teszi, hogy mindenhez hozzáférjen, ami az FCL -ben van . A .NET-könyvtárak használatának szintaxisa ebben az értelemben a lehető legközelebb áll a C# szintaxishoz . A nyelvi funkciók észrevehetők az F# funkciók teljes skálájának használatakor. Például a következő kód egy függvényt alkalmaz egy lista elemeire :

legyen rec map func lst = az lst és a | [] -> [] | head :: tail -> func head :: map func tail legyen myList = [ 1 ; 3 ; 5 ] legyen newList = map ( fun x -> x + 1 ) myList

" newList" most " [2;4;6]".

A lista elemzése ebben a függvényben a mintaillesztés egy másik hatékony funkciójával történik . Lehetővé teszi a minták megadását, egyeztetéskor az illesztési operátor megfelelő előfordulásait számítja ki. Az első minta „[]” üres listát jelent. A második egy lista, amely az első elemből és a végből áll (amely lehet tetszőleges lista, beleértve az üreset is). A második mintában a fej érték a head változóhoz, a farok pedig a farokhoz van társítva (a nevek tetszőlegesek lehetnek). Így a minta a fő feladat mellett lehetővé teszi az összetett adatszerkezetek bontását is. Például az Opció típus esetén a mintaillesztés így néz ki:

egyeztesse x -et | Néhány v -> printfn "Talált érték %d." v | Nincs -> printfn "Semmi sem található." | Nincs -> printfn "Szia"

A nyelv támogatja a készletekhez { … }, listákhoz [ … ]és tömbökhöz definiált generátorkifejezéseket. [| … |] Például:

teszteljük n = [ i - re 0 .. n do ha i % 2 = 0 , akkor i hozam ]

A térkép funkció a Lista modulban található szabványos listafunkciók egyike. Az Array, Set, Option modulokban deklarált egyéb adatstruktúrákhoz is vannak függvények.

Hasznos eszköz a pipe-forward operátor (|>), amely lehetővé teszi a függvényhívási láncok fordított sorrendben történő írását. Ennek eredményeként a következő kód játszódik le (a köztes értékek a megjegyzésekben vannak feltüntetve):

[ 1 ; 2 ; 5 ] |> Lista . térkép ((+) 1 ) // [2; 3; 6] |> Lista . szűrő ( fun x -> x % 2 = 0 ) // [2; 6] |> Lista . összeg // 8

Az operátor használata |>szükségtelenné teszi a nagyszámú zárójelet, és megváltoztatja a kód vizuális észlelését is. És most ez a kód így szól: vegyünk egy ilyen-olyan listát, adjunk hozzá 1-et minden elemhez, majd csak páros elemeket hagyjunk, és adjuk vissza az összegüket. Azaz leírja az eredeti objektumon végrehajtott műveletek sorrendjét, abban a sorrendben, ahogyan az a számítógépen történik.

Az alábbiakban bemutatjuk, hogy a .NET-szolgáltatások hogyan bővítik ki az F#-ot. Ilyen például az ablakos alkalmazások és az eseménykezelés. Az eseményfeldolgozás azt jelenti, hogy a programban bizonyos műveletek csak bizonyos eseményekre reagálnak - felhasználói műveletek, eszközcsatlakozás stb. A projekt létrehozható mind a Visual Studióban, mind bármely szöveges dokumentumban, amely az F# fordítóba kerül ( fsc).

// nyitott - modulok és névterek összekapcsolása a bennük lévő értékek, osztályok és egyéb modulok // használatához. open System.Windows.Forms // - osztályok Űrlap (ablak), Gomb (gomb), stb. // Beep - hangjelzés // Néhány további paramétert adunk át hangjelzésként, amelyeket nem használunk let beep _ = System . Konzol . Beep () // ablak létrehozása programozottan nevű ablak !meg kell hívni egy megjelenítő szó függvényt - pl. Application.Run(window)! // Látható - logikai érték, látható-e az ablak // TopMost - az ablak az előtérben jelenik-e meg (az azonos értékű ablakok sorrendje a hívás fordított sorrendjében) // Szöveg - az ablak szövege title let window = new Form ( Látható = igaz , Legfelső = igaz , Szöveg = "" , Felső = 0 , Bal = 0 , Magasság = 512 , Szélesség = 768 ) ablak . WindowState <- FormWindowState . Normál // Normál (, Minimalizált, Maximális) ablak. Csak nem szerepel a példa ablakkonstruktorában . ClientSizeChanged . Beep ablak hozzáadása . _ gombnyomás . Beep ablak hozzáadása . _ gombnyomás . Beep ablak hozzáadása . _ keyup . Hangjelzés hozzáadása . _ Futtassa az ablakot // megjelenítő ablak

Faktoriális

Rekurzív faktoriális függvény natív módon:

legyen rec fac n = ha n < 2 akkor 1 else n * fac ( n - 1 )

Rekurzív faktoriális függvény farokrekurzióra optimalizálva.

legyen faktoriális szám = legyen rec fac num acc = párosítsa a számot | x amikor x < 2 -> acc |_ -> fac ( num - 1 ) ( acc * num ) fac num 1

Faktorális függvény, imperatív stílusban, változó állapotot használva.

legyen faktoriális szám = ha szám < 2 , akkor 1 különben változtatható fac = 1 legyen i - re [ 2 .. szám ] do fac <- fac * i fac

Tényezőfüggvény listahajtással és curry szorzással:

let fac n = Lista . hajtás (*) 1 [ 1 .. n ]

Rekurzív függvény a Fibonacci-számok kiszámításához mintaillesztési módszerrel:

legyen rec fib n a b = egyeztesse n -t | 0 -> a | 1 -> b | _ -> fib ( n - 1 ) b ( a + b )

Jegyzetek

  1. F# letöltési linkek a Microsoft Research webhelyen . Letöltve: 2011. június 24. Az eredetiből archiválva : 2011. június 24..
  2. Bejelentjük az F# fordító + könyvtár forráskód ledobását . Letöltve: 2010. november 5. Az eredetiből archiválva : 2013. január 17..

Lásd még

Linkek

Irodalom

  • Chris Smith (Smith, Chris). Programozás F#-ban = Programozás F#-ban. - O'Reilly, 2011. - 448 p. — ISBN 978-5-93286-199-8 .
  • Dmitrij Szosnyikov. Funkcionális programozás F#-ban. - Moszkva: DMK Press, 2011. - 192 p. - ISBN 978-5-94074-689-8 .
  • Syme, Don; Granicz, Ádám; Cisternino, Antonio. ExpertF#. - Apress, 2007.  (angol)