Programmering

14 gode grunner til å bruke F #

F # er et sterkt skrevet, funksjonelt første programmeringsspråk som lar deg løse komplekse problemer ved å skrive enkel kode. Basert på ML og bygget på .NET Framework, tilbyr F # god interoperabilitet, bærbarhet og kjøretid, samt "Five Cs" - overlegenhet, bekvemmelighet, korrekthet, samtidighet og fullstendighet.

F # var i utgangspunktet bare tilgjengelig på Windows, som et Microsoft Research-prosjekt, men det er nå et førsteklasses språk på en rekke plattformer. Du kan bruke F # på Mac og Linux med verktøystøtte i Xamarin Studio, MonoDevelop, Emacs og andre; på Windows med Visual Studio, Xamarin Studio og Emacs; og på Android- og iOS-enheter og på nettet ved hjelp av HTML5. I tillegg til generell programmering, gjelder F # for GPU-kode, big data, spill og mye mer.

Hvorfor bruke F #? La meg gi deg 14 grunner.

F # er interaktiv

En av fordelene med F # er at den har en interaktiv REPL (lese, evaluere, skrive ut, løkke) der du kan prøve ut kode, som vist på skjermbildet nedenfor. Med klokken, øverst til venstre, ser vi F # Interaktive vinduer fra Visual Studio i Windows, fra TryFSharp som kjører i Chrome, og fra Xamarin Studio kjører på Mac OS X. ;; forteller F # Interactive å evaluere hva du har skrevet; på TryFSharp sender "run" -knappen det samme signalet. Å bruke en REPL til å kompilere og teste koden før den går inn i et fullstendig program, fremskynder utviklingen og reduserer feil.

F # er for skripting

F # kan brukes både som skriptspråk og som programmeringsspråk. Nedenfor ser vi et eksempel på Visual Studio der et F # -skript laster inn fire F # -programfiler og åpner to .NET-biblioteker før den utfører sin egen kode. Notasjonen [|…|] brukt her erklærer en matrise. Notasjonen |> er et fremre rør, som fører resultatet av venstre side til funksjonen på høyre side. De nye linjene her er ikke syntaktisk signifikante. De gjør bare koden lettere å lese enn å ha hele røruttrykk på en enkelt linje.

F # er funksjonell

F # støtter funksjonelle programmeringskonstruksjoner som behandling av funksjoner som verdier, bruk av ikke-navngitte funksjoner i uttrykk, sammensetning av funksjoner for å danne nye funksjoner, curried-funksjoner, og den implisitte definisjonen av funksjoner ved hjelp av delvis anvendelse av funksjonsargumenter. I det øvre skjermbildet nedenfor definerer og bruker vi en legge til funksjon. Funksjonens hoveddel er innrykket (som Python), og argumenttypene utledes som heltall på grunn av + operatør. I det nedre skjermbildet gir vi en typebetegnelse etter argumentnavnet ved hjelp av et kolon og et typenavn, så F # vet at uttrykk er en streng type.

F # er kortfattet

Koden nedenfor er en Quicksort-lignende algoritme implementert i F # (av Scott Wlaschin). De rec nøkkelord indikerer at funksjonen er rekursiv. De passe med syntaksen er en bytte om uttalelse om steroider, med | indikerer tilfeller. De [] indikerer en tom liste. De firstElem og andre elementer blir opprettet automatisk.

Merk at det ikke er noen typedeklarasjoner nevnt noe sted i koden, noe som betyr at funksjonen kan sortere lister som inneholder hvilken som helst type som støtter sammenligningsoperatorer. De moro nøkkelord er for å definere en anonym lambda-funksjon.

la rec quicksort liste =

kampliste med

| [] -> // Hvis listen er tom

[] // returner en tom liste

| firstElem :: otherElements -> // Hvis listen ikke er tom

la smallerElements = // trekke ut de mindre

andre elementer

|> List.filter (fun e -> e <firstElem)

|> kviksort // og sorter dem

la largerElements = // trekke ut de store

andre elementer

|> List.filter (fun e -> e> = firstElem)

|> kviksort // og sorter dem

// Kombiner de tre delene til en ny liste og returner den

List.concat [smallerElements; [firstElem]; largerElements]

//test

printfn "% A" (kviksort [1; 5; 23; 18; 9; 1; 3])

Til sammenligning, ta en titt på den tradisjonelle C # implementeringen nedenfor.

offentlig klasse QuickSortHelper

{

offentlig statisk liste QuickSort (listeverdier)

der T: IComparable

   {

if (values.Count == 0)

      {

returner ny liste ();

      }

// få det første elementet

T firstElement = verdier [0];

// få de mindre og større elementene

var smallerElements = new List ();

var largerElements = new List ();

for (int i = 1; i <values.Count; i ++) // i starter ved 1

{// ikke 0!

var elem = verdier [i];

hvis (elem.CompareTo (firstElement) <0)

         {

smallerElements.Add (elem);

         }

ellers

         {

largerElements.Add (elem);

         }

      }

// returnere resultatet

var resultat = ny liste ();

resultat.AddRange (QuickSort (smallerElements.ToList ()));

result.Add (firstElement);

resultat.AddRange (QuickSort (largerElements.ToList ()));

returresultat;

   }

}

Du vil legge merke til hvor mye ekstra cruft C # -koden har sammenlignet med F # -koden.

F # er veldig kortfattet

I følge Scott Wlaschin har versjonen av quicksort vist nedenfor - alle fire linjene - det typiske, konsise utseendet til F # skrevet av en erfaren funksjonell koder. Selvfølgelig ville han være den første til å påpeke at den ikke sorterer på plass. Det tok meg flere målinger for å få mening om koden, men det var verdt tiden.

la rec quicksort2 = funksjon

   | [] -> []                        

| først :: hvile ->

la mindre, større = List.partition ((> =) først) hvile

List.concat [quicksort2 mindre; [først]; quicksort2 større]

// testkode

printfn "% A" (kviksort2 [1; 5; 23; 18; 9; 1; 3])

Kort fortalt returnerer den første saken en tom liste hvis den er bestått, og gir et utgangskriterium; det andre tilfellet deler listen opp i det første elementet og resten, og tilordner underlisten fra og med den mindre verdien til mindre og den andre underlisten til større. Innen sammenkoblingen av underlistene sorterer funksjonen rekursivt mindre og større lister.

F # reduserer feil gjennom sterk skriving

I motsetning til JavaScript, Ruby og Python er F # sterkt skrevet, ikke dynamisk skrevet. I motsetning til C og C ++, som også er sterkt skrevet, men krever at alle typer deklareres, utfører F # typeinferanse når det er mulig. Når typeinferanse ikke er mulig, men typen må være kjent, vil F # -kompilatoren kaste en feil og foreslå at du angir en typebemerkning, slik vi måtte gjøre i et tidligere eksempel for (setning: streng) argument til toHackerTalk funksjon. Å fange en typefeil ved kompileringstid eliminerer en hel klasse kjøretidsfeil som dynamisk skrevne språk er utsatt for.

Forresten, F # la bindinger er uforanderlige med mindre du spesifikt erklærer dem foranderlig.

F # har et stort, velvalgt sett med objekter, inkludert List, String og Array

Som du kan se fra IntelliSense nedenfor, har F # rike liste-, streng- og matrisemoduler basert på .NET Framework. I så henseende er det også et objektorientert språk, selv om det først og fremst er et funksjonelt språk. Legg merke til at det ikke betyr noe om du bruker modulnavnet eller et skrevet variabelnavn - når du legger til prikken, vil medlemsfunksjonene dukke opp. Noen hevder at eksplisitt bruk av modulnavnet er en bedre stil for et funksjonelt språk enn prikkete variabler, men jeg kjøper ikke argumentet helt.

F # er nyttig for MapReduce

MapReduce er en effektiv totrinnsprosess som ofte brukes på stordata, og som eksplisitt støttes i Hadoop. I dette F # -eksemplet kartlegger og reduserer vi en liste over heltall. Først filtrerer vi listen til partallene, deretter dobler vi hvert tall, og til slutt tar vi summen av alle elementene i listen for å samle eller redusere resultatet. List.map er en kraftig funksjon av høyere orden; en høyere ordensfunksjon er en som tar en annen funksjon som argument. I tillegg til lister og matriser støtter F # poster, sekvenser, datatypeleverandører og LINQ (språkintegrert spørring).

F # har poster

F # poster representerer enkle aggregater av navngitte verdier, eventuelt med medlemmer. I eksemplet nedenfor definerer vi først a Bok posttype med fire navngitte verdier, og så lager vi en post med de samme fire navnene. F # kompilatoren utleder riktig Bok skriv ved å matche navnene.

F # poster kan ha valgfrie verdier

Postene trenger ikke alltid å inkludere alle de navngitte verdiene. Hvis du gir en navngitt verdi, vil alternativ attributt når du definerer typen, så kan den utelates fra en post. Når du angir en valgfri verdi, kan den enten være Ingen, som ender opp som en null, eller det kan være Noen etterfulgt av verdien du vil sette. Postfelt skiller seg fra klasser ved at de automatisk blir eksponert som egenskaper. Klasser og strukturer i F # er .NET-klasser og strukturer, kompatible med C # og Visual Basic. NET, så jeg vil si fra eksempler.

F # har sekvenser

En sekvens i F # er en logisk serie av elementer alle av en type. Sekvenser er spesielt nyttige når du har en stor, ordnet innsamling av data, men ikke nødvendigvis forventer å bruke alle elementene. Individuelle sekvenselementer beregnes bare etter behov, slik at en sekvens kan gi bedre ytelse enn en liste i situasjoner der ikke alle elementene brukes. De Sekv modul gir støtte for manipulasjoner som involverer sekvenser. På bildet nedenfor demonstrerer vi enkle sekvenser, sekvenser med uttrykk og sekvenser med filtre.

F # støtter dataleverandører og LINQ

Nedenfor bruker vi TryFSharp-redigereren til å åpne et online freebase meteorologidatasett og spørre dataleverandøren for sykloner som har registrert de høyeste vindverdiene. De spørring {} syntaksen implementerer LINQ for F #. Bruk av denne DLL er spesifikk for TryFSharp. I Visual Studio ville du gjort det åpne Microsoft.FSharp.Data.TypeProviders og bruk deretter den aktuelle datatilbydertjenesten.

Resultatet:

 [Orkanen Andrew; Orkanen Hugo; 1900 orkan i Galveston;

Tropisk storm Allison; Syklon Tracy; Orkanen Iniki; Orkanen Ivan;

1999 Odisha-syklon; Orkanen Katrina; Typhoon Talim; Orkanen Rita;

Typhoon Herb; Orkanen Wilma; Typhoon Vera; 1962 Stillehavs tyfonsesong;

Typhoon Ike; Typhoon Mireille; Typhoon Babe; Tropisk storm Arlene;

Orkanen Irene; Typhoon Zeb; Typhoon Maemi; Typhoon Bess; Typhoon Chanchu;

Typhoon Patsy; Typhoon Ewiniar; Orkanen Ioke; Typhoon Xangsane;…

F # kan analysere Hadoop-data

I dette eksemplet bruker vi TryFsharp-redigereren til å åpne en Hadoop Hive-forekomst som blant annet inneholder målinger av irisblomstfunksjoner, sammen med måleenheter. Følgelig har vi aktivert bruk av enhetskommentarer i egenskapene til HiveTypeProvider.

Denne beregningen returnerer:

val avgPetalLength: float = 0,0374966443

F # gjør mønstermatching

F # kamp uttrykk gir forgreningskontroll som er basert på sammenligningen av et uttrykk med et sett med mønstre. Linje 1-7 i eksemplet nedenfor definerer en rekursiv erPalindrome funksjon. Linje 8-10 definerer en innpakningsfunksjon for erPalindrome som kaller det første gangen ved å bruke hele strengen. Fordi "aba" er et palindrom, er deretter ledd i linje 9 fyrer og returnerer Noen s, og kamp uttalelse i linje 11 genererer "Strengen aba er palindrom". De _ mønster i linje 14 er standardtilfelle.

De kamp .. | uttalelse i F # har mange fordeler fremfor bytte..veske uttalelse i C #, C ++ og Java, hvorav det viktigste er at det forårsaker færre feil.

F # støtter asynkrone arbeidsflyter

F # har tilgang til alle .NET Framework, men den har også sin egen syntaks for asynkrone arbeidsflyter. De asynkronisering {uttrykk} syntaks definerer en ikke-blokkerende beregning. De gjøre! nøkkelord utfører en asynkron operasjon og venter på resultatet. De la! nøkkelordet venter på en asynkron operasjon og tildeler resultatet. Og bruk! venter på en asynkron operasjon, tildeler resultatet og frigjør ressursen. Async.RunSynchronously utfører en asynkron operasjon og venter på resultatet. For å legge til parallellitet, bruk Async. parallell funksjon, som tar en liste over Asynkronisering objekter, setter opp koden for hver Asynkronisering oppgaveobjekt for å kjøre parallelt, og returnerer et Asynkronisering objekt som representerer den parallelle beregningen. Rør deretter resultatet til Async.RunSynchronously. (Eksemplet nedenfor er fra F # for moro skyld og fortjeneste.)

F # ressurser

For mer informasjon om F #, følg lenkene nedenfor.

  • Prøv F #
  • F # for moro skyld og fortjeneste
  • F # Språkreferanse
  • Real World Functional Programming
  • F # bøker på Amazon
  • F # 3 Hvitbok
  • Ytterligere referanser
$config[zx-auto] not found$config[zx-overlay] not found