fsharp prirucnik

Upload: halobing

Post on 06-Jul-2018

223 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/17/2019 Fsharp prirucnik

    1/57

    1  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Programski jezik  F# (I deo) 

    Uvod F#  je programski  jezik, razvijen na .NET platformi, sa izraženim funkcionalnim karakteristikama koji 

    podržava i druge paradigme programiranja poput imperativne i objektno‐orijentisane. 

    Autor F#‐a  je Don Syme, istraživač zaposlen u okviru Microsoft Research centra u Kembridžu. 

    Snaga F#‐a leži u svedenoj sintaksi koja omogućava laku čitljivost koda, kao i efikasan razvoj programa 

    koje zahtevaju primenu složenih matematičkih algoritama. Jezik omogućava brzo generisanje 

    prototipova i njihovu brzu transformaciju u produkcioni kod. Kod napisan u F#‐u lako se može 

    paralelizovati, što  je posebno značajno danas kada svi novi kompijuteri imaju više  jezgara. Korišćenjem 

    F#‐a kao osnovnog  jezika mogu se lako kreirati domensko specifični  jezici (DSL) što ga čini posebno 

    pogodnim za naučno‐istraživačku primenu. 

    F#  je kompatibilan sa svim ostalim .NET  jezicima. To znači da F# program može da koristi sve .NET 

    biblioteke. Biblioteka napisana u F#‐u može se koristiti u bilo kojoj desktop ili Web aplikaciji razvijenoj na 

    .NET platformi. 

    Instalacija 

    Da bi ste programirali u F#‐u i provežbali primere koji su prikazani u ovoj skripti potrebno  je da imate 

    instaliran F# kompajler i interpreter. 

    Ukoliko imate instaliranu neku od verzija Visual  Studio‐a 2010 (u vreme pisanja ovog teksta dostupan 

    kao Beta 2 verzija), nije potrebna nikakva dodatna instalacija. U suprotnom, možete pronaći link za 

    preuzimanje aktuelne verzije F#‐a na web adresi http://msdn.microsoft.com/en‐us/fsharp/default.aspx. 

    Sama instalacija se obavlja  jednostavno, pokretanjem instalacionog paketa ( Next,Next, ... Finish) pri 

    čemu nikakva specifična podešavanja nisu potrebna. 

    Vežbanje kroz primere 

    Koncept ove skripte  je vežbanje kroz primere. Većina primera  je napravljena tako da se mogu izvršiti u 

    F#  konzoli . 

    VS2010 

    Ukoliko imate Visual  Studio 2010, F# konzolu možete pokrenuti iz Start  menija kao što  je prikazano na 

    slici: 

    Preporuka autora  je da po izlasku zvanične verzije Visual  Studio‐a 2010 preuzmete njegovu 

    besplatnu ediciju i koristite  je za programiranje u F#‐u. 

    Imperativno programiranje  je termin koji se u literaturi često koristi za programiranje u 

    programskim  jezicma poput C‐a ili Pascal‐a. 

  • 8/17/2019 Fsharp prirucnik

    2/57

    2  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Kada se konzola pokrene potrebno  je da otkucate  fsi  i pritisnete taster Enter  da bi pokrenuli F#  

    interpreter . Kako bi testirali da li F# interpreter radi otkucajte  printfn “Hello World“;;. Dobićete prikaz 

    kao na sledećoj slici: 

    Instalacija F#‐a bez Visual Studio‐a 

    Ukoliko instalirate F# kompajler nezavisno od Visual  Studio‐a imaćete u okviru Start  menija Microsoft F# 

    grupu i u okviru nje opciju F#  Interactive (Console). 

    Izaberite ovu opciju i na ekranu će se prikazati konzola. Da bi ste testirali da li F# interpreter radi 

    otkucajte  printfn “Hello World“;;. Dobićete prikaz kao na sledećoj slici: 

  • 8/17/2019 Fsharp prirucnik

    3/57

    3  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Osnovne naredbe 

    Naredba povezivanja let  

    Naredba let   je najznačajnija i najčešće korišćena naredba u F#‐u. Služi da poveže identifikatore sa vrednostima. Sledeći primer ilustruje upotrebu ove naredbe. 

    Kao što možete da uočite naredba let  ima formu: let  ident  = expr , gde  je ident  identifikator (u ovom 

    slučaju „a“), dok  je expr  izraz ( u ovom slučaju vrednost „21“). 

    Treba uočiti da  je F# interpretatora automatski odredio da  je vrednost povezana sa identifikatorom „a“ 

    celobrojna ( int  ). Ova funkcionalnost F# interpretatora naziva se inferencija tipa. 

    Druga stvar koju ste možda uočili  je upotreba reči identifikator  za simbol „a“, umesto možda očekivane 

    reči promenljiva. Razlog za to  je što se simboli u F# podrazumevano dodeljuju vremenski nepromenljivim 

    (eng. immutable) vrednostima. Ukoliko pomoću naredbe let  povežemo identifikator „a“ sa nekom 

    drugom vrednošću, neće se promeniti sadržaj memorijske lokacije prethodno povezane sa 

    identifikatorom „a“, već će identifikator „a“ biti povezan sa drugom memorijskom lokacijom. 

  • 8/17/2019 Fsharp prirucnik

    4/57

    4  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Da bi to ilustrovali povezaćemo identifikator „a“ sa promenljivom tipa znak. 

    Pored celobrojnog i znakovnog u F# možemo koristiti i vrednosti osnovnih tipova poput realnog broja 

    ( float ), niske znakova (string) i logičkog (bool ). 

    Funkcija kao tip podataka 

    Funkcije su u F#‐u samo  jedan od tipova podataka kao što  je to slučaj sa celobrojnim ili znakovnim 

    tipovima. Šta više možemo definisati i vrednost funkcijskog tipa,  funkcijski  literal . 

  • 8/17/2019 Fsharp prirucnik

    5/57

    5  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Svaki funkcijski literal ima svoj tip, koji interpreter automatski utvrđuje kao što  je to slučaj i kod ostalih 

    tipova. Funkcijski literal (fun  x ‐>  x*x) ima tip  „int ‐>int“  što označava da predstavlja funkciju koja 

    preslikava skup celih brojeva na skup celih brojeva. 

    Naredba povezivanja funkcijske vrednosti sa identifikatorom ima i svoju kraću, prirodniju, formu. 

    Ukoliko nismo zadovoljni tipom funkcije koji  je interpreter automatski odredio, možemo mu dati 

    sugestiju (eng.

     compiler 

     hint ).

     U

     primeru

     koji

     sledi

     ova

     sugestija

      je

     namerno

     data

     u

     sredini

     izraza

     kako

      je

     

    čitalac ne bi pomešao sa definisanjem liste parametara. 

    Kako se odvija ovo automatsko utvrđivanje? Interpreter polazi od naredbe  x*x , i predpostavlja da  je operator množenja definisan nad skupom celih brojeva. Prema tome x  je ceo broj, a samim 

    tim i rezultat funkcije. 

  • 8/17/2019 Fsharp prirucnik

    6/57

    6  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Tip podataka n‐torka 

    n‐torka (eng. tuple)  je najjednostavniji i najčešće korišćeni od svih složenih tipova podataka. Koristimo ga 

    kada želimo da koristimo uređeni skup vrednosti, a da pri tome eksplicitno ne definišemo tip. 

    Sledeći primer prikazuje povezivanje uređenog para gde  je prvi član tipa string, a drugi tipa int  sa identifikatorom “s”. 

    Uređene parove možemo vezati i za više identifikatora, pri čemu se identifikatori vezuju za vrednosti 

    prema poziciji. Ukoliko neku od vrednosti iz uređenog para ne želimo da vežemo za neki identifikator, 

    umesto identifikatora stavljamo simbol “_”. 

    Navedeni oblici let  naredbe ilustrovani su sledećim primerom. 

  • 8/17/2019 Fsharp prirucnik

    7/57

    7  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Tip podataka lista 

    Kreiranje liste 

    Liste su redovni pratilac funkcionalnih programskih  jezika. Neki  jezici poput Lisp‐a koncipirani su oko 

    rada sa listama. 

    Proučavanje lista počećemo sa sledećim naredbama: 

    Prva naredba predstavlja literal za praznu listu. Kompajler naravno ne može da odredi kog tipa  je prazna lista pa automatski definiše generalizovani  tip. 

    Lista kao tip podataka označava se kao ‘a list , pri čemu ‘a predstavlja generičku definiciju za tip 

    člana liste (npr. int  list ). Za one koji poznaju programske  jezike C++, ova oznaka  je ekvivalentna 

    oznaci List. 

  • 8/17/2019 Fsharp prirucnik

    8/57

    8  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Druga naredba predstavlja literal za listu celih brojeva. Iako to nigde eksplicitno nismo naveli kompajler 

     je ispravno odredio tip literala kao int  list . 

    Treća i četvrta naredba definiše listu preko intervala, pri čemu  je u četvrtoj definisan i korak sa kojim se 

    članovi generišu. 

    Liste mogu biti i nekog drugog tipa, npr. tipa string. Međutim ono što  je važno napomenuti  je da svi 

    članovi liste moraju biti istog tipa. U suprotnom će kompajler prijaviti sintaksnu grešku. 

    Sledeći primer ovo pokazuje: 

    Rad sa listama 

    Kalkulacije sa listama izvršavaju se primenom operatora i funkicija na liste. 

    Operatori za rad sa listama su: 

      operator spajanja elementa i liste (::) 

      operator spajanja dve liste (@) 

    Sledeće naredbe ilustruju primenu navedenih operatora: 

  • 8/17/2019 Fsharp prirucnik

    9/57

    9  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Kao i većina osnovnih tipova u F#‐u liste su nepromenljive (eng. immutable). Sve operacije nad listama 

    kreiraju nove liste umesto da menjaju postojeće. 

    Sledeći primer prikazuje listu l  kojoj smo dodeli literal  [9;10]. Posle dodavanja vrednosti 8 na listu l , data 

    lista  je ostala nepromenjena što  je pokazano izvršavanjem naredbe l;;. 

    Pored operatora, F# biblioteke sadrže i veći broj funkcija za rad sa listama. U ovom poglavlju 

    prikazaćemo samo osnovne funkcije i to: 

      List.length 

    vraća

     dužinu

     liste

     

      List.head  vraća prvi element liste 

      List.tail  vraća sve elemente liste osim prvog 

    Liste u F#‐u su interno implementirane kao grupa  jednosmerno povezanih ćelija sa vrednošću, 

    pri čemu identifikator liste pokazuje na prvu ćeliju u grupi. Ovakva implementacija, uz 

    nepromenljivost članova zagarantovanu kompajlerom, omogućava efikasno izvršavanje operacija 

    nad listama kao i njihovo efikasno skladištenje u memoriji. 

  • 8/17/2019 Fsharp prirucnik

    10/57

    10  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Pored navedenih, od izuzetnog značaja za rad sa listama su i funkcije: 

      List.map  funkcija projekcije 

      List.filter  funkcija selekcije 

      List.fold  funkcija agregacije 

    Ove funkcije biće detaljnije obrađene u  jednom od narednih poglavlja. 

  • 8/17/2019 Fsharp prirucnik

    11/57

    11  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Naredba match 

    Osnovni oblik  

    Naredba match  je naredba koja u sebi kombinuje dekompoziciju složenih vrednosti i kontrolu toka. 

    U svom osnovnom obliku podseća na switch naredbu iz  jezika C++, i tada uparuje prosleđenu vrednost 

    sa nekim od datih literala. Zavisno od literala koji  je uparen izvršava se odgovarajuci segment koda. 

    Kao i kod switch naredbe  jedan segment koda  je moguće vezati za više literala. 

    Za razliku od switch naredbe, naredba match  (kao i sve ostale F# naredbe) vraća vrednost. U 

    prethodnom primeru  je ta vrednost prikazana sa “val  it  : unit  = ()” ,što  je tip povratne vrednosti funkcije 

     printfn. 

    Tip unit  odgovara tipu void  u programskom  jeziku C++. Suštinski to znači da funkcija  printfn ne 

    vraća vrednost, odnosno da se radi o proceduri. 

  • 8/17/2019 Fsharp prirucnik

    12/57

    12  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Sledeći primer ilustruje naredbu match koja umesto prikazivanja teksta u konzoli vraća tekst kao 

    rezultat. 

    Uparivanje prema obrascu 

    Naredba match nije ograničena na uparivanje sa literalima,  već je moguće da se uparivanje vrši prema obrascu. Jedan od obrazaca za uparivanje već je prikazan, iako to nije posebno istaknuto. To  je obrazac 

    za uparivanje “_”, koji se može upariti sa bilo kojom vrednošću (odgovara default  grani switch naredbe). 

    Sledeći primer ilustruje uparivanje sa obrascem za listu, pri implementaciji funkcije getFirst  koja  je 

    ekvivalentna funkciji List.head . 

    Obrazac za uparivanje može biti ograničen logičkim izrazom. U tom slučaju do uparenja sa 

    odgovarajućom granom dolazi samo ako logički izraz ima vrednost true (tačan izraz). 

    Sledeći primer ilustruje primenu ograničenja na primeru implementacije funkcije round  koja preslikava 

    ceo broj na broj iz intervala [0,100]. 

  • 8/17/2019 Fsharp prirucnik

    13/57

    13  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Možete uočiti kako  je obrazac za uparivanje bilo koje vrednosti “_”, ograničen izrazima  x>100 i  x

  • 8/17/2019 Fsharp prirucnik

    14/57

    14  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Tip podataka  sekvenca 

    Koncept  

    Sekvenca predstavlja skup vrednosti istog tipa. Prema operacijama koje se nad njom mogu primeniti 

    slična  je listi . Jednostavne sekvence se definišu na sličan način kao i liste što pokazuje sledeći primer: 

    Ono što sekvencu razlikuje od liste  je njena deklarativna priroda. Naime sekvenca ne čuva u memoriji 

    svoje članove već samo generatorski  izraz (eng. sequence expression) koji prema potrebi generiše date 

    elemente sekvence. Mogli ste da primetite da se za potrebe prikazivanja u konzoli generišu samo prva četiri elementa sekvence. 

    Generisanje sekvenci 

    Generatorski izraz ima opšti oblik seq {   for  value in expr  .. expr  do yield  expr  } . 

    Sledeći primer ilustruje generisanje sekvence kvadrata prirodnih brojeva iz intervala [1,100], primenom 

    obe sintaksne forme. 

    Umsto do yield  najčešće se koristi oznaka ‐>.

    Mnoge funkcije koje kao parametre primaju sekvence mogu kao parametar primiti i druge, 

    srodne, tipove poput liste, niza ili neke druge .NET kolekcije. 

  • 8/17/2019 Fsharp prirucnik

    15/57

    15  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Sekvence se mogu ugnežđavati, tako da rezultat primene generatorskog izraza može biti sekvenca 

    sekvenci, što  je prikazano u sledećem primeru: 

    Ukoliko želimo da umesto ugnežđenih sekvenci kao rezultat dobijemo kompoziciju sekvenci, potrebno  je 

    da umesto yield  naredbe upotrebimo naredbu yield!. 

  • 8/17/2019 Fsharp prirucnik

    16/57

    16  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Izraz za generisanje sekvenci može biti proizvoljne složenosti i sadržati u sebi druge naredbe. Sledeći 

    primer ilustruje sekvencu od 100 uređenih parova, pri čemu su neparni članovi sekvence zamenjeni 

    uređenim parom (0,0). 

    Programski jezik  F# (III deo) 

    Funkcije i njihova primena 

    Funkcionalni literali 

    Programski  jezik F# tretira vrednost funkcije nezavisno od njenog identifikatora (naziva). Pokazano  je da 

    izraz poput “let  sq  x  =  x  *  x” , predstavlja samo skraćenu formu koja objedinjuje definisanje funkcionalnog 

    literala “(fun  x ‐>  x  *  x)”  i njegovo vezivanje sa identifikatorom “sq”. 

    Funkcionalni literali mogu se upotrebiti na bilo kom mestu, na kojem se može upotrebiti vrednost nekog 

    drugog tipa, poput argumenta koji se prosleđuje drugoj funkciji ili operanda datog operatora. 

  • 8/17/2019 Fsharp prirucnik

    17/57

    17  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Funkcionalni literali često se primenjuju u kumbinaciji sa funkcijama projekcije, selekcije i agregacije. 

    Ove tri funkcije, koje služe za transformaciju liste ili sekvence čine  jedan od najmoćnijih alata “klasičnog” 

    funkcionalnog programiranja. 

    Funkcije projekcije, selekcije i agregacije 

    Seq.map 

    Seq.map  je funkcija projekcije koja na osnovu postojeće, kreira novu sekvencu primenom date funkcije. 

    Svaki element

     u

     generisanoj

     sekvenci

      je

     rezultat

     izvršavanja

     funkcije

     nad

     elementom

     postoje

    će

     

    sekvence. 

    Sledeći primer ilustruje projekciju sekvence brojeva od 1 do 1000 u sekvencu uređenih parova, pri čemu 

     je prvi član uređenog para broj iz originalne sekvence, a drugi član kvadrat datog broja. 

    Seq.filter 

    Seq.filter   je funkcija selekcije koja kreira novu sekvencu filtriranjem postojeće, korišćenjem predikatske 

    funkcije. 

    Sledeći primer ilustruje selekciju elemenata sekvence čiji  je prvi član paran broj: 

    Možete uočiti da  je kao drugi argument funkcije projekcije upotrebljen identifikator „it“, pri 

    čemu dati identifikator nije eksplicitno definisan u kodu. Napisani kod se i pored toga uspešno 

    izvršava, pošto F# konzolni interpreter automatski povezuje rezultat izvršavanja izraza sa 

    identifikatorom „it“, ukoliko dati rezultat nije eksplicitno povezan sa nekim drugim 

    identifikatorom. U prethodnom primeru identifikator „it”  je vezan sa seq {1..1000} , što se može 

    uočiti na osnovu konzolnog odgovora: val  it  : seq = seq [1;2;3;4; …] 

    Tip funkcije projekcije  je (‘a  ‐> b’)  ‐> #seq  ‐> #seq. Ova definicija označava funkciju koja 

    kao argumente prima redom funkciju i sekvencu, a kao rezultat generiše novu sekvencu. Treba 

    uočiti upotrebu znaka “#” u oznaci sekvencnog tipa #seq. Na ovaj način se označava da 

    funkcija projekcije, pored sekvence, može da primi i bilo koji drugi tip kompatibilian sa 

    sekvencom (npr. listu). 

  • 8/17/2019 Fsharp prirucnik

    18/57

    18  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    U oba prethodna primera korišćen  je funkcionalni literal kao argument funkcije. Međutim u drugom 

    primeru kao parametar funkcionalnog literala upotrebljen  je obrazac za uparivanje koji predstavlja 

    uređeni par, kod koga se prvi član para uparuje sa identifikatorom „x“, a drugi član se ne uparuje:  fun 

    (x,_)  ‐>  x%2=0 . Iako drugi član para nije važan, ovakva forma funkcionalnog literala  je neophodna zbog 

    kompatibilnosti tipova. Naime sekvenca koja se filtrira  je sekvenca uređenih parova, pa prema tome ulazni parametar predikatske funkcije mora biti uređeni par. 

    Seq.fold 

    Funkcija agregacije  je svakako najmoćnija i ujedno najkompleksnija od svih funkcija za transformaciju 

    sekvenci. Služi za izračunavanje agregirane vrednosti, primenom date funkcije na skup vrednosti (u 

    ovom slučaju sekvencu). Primena se vrši rekurzivno, tako što funkcija za agregaciju, agregira svaki član 

    sekvence sa prethodno izračunatim rezultatom. Funkcija agregacije prima tri parametra redom: funkciju 

    za agregaciju člana sekvence sa akumuliranim rezultatom, početnu vrednost akumulacije i sekvencu. 

    Sledeći primer ilustruje izračunavanje sume drugih članova (kvadrata), selektovanih uređenih parova. 

    Možete zapaziti da funkcija agregacije može zameniti naredbu ciklusa ( for,  foreach) poznatu iz 

    imperativnog i objektno orijentisanog programiranja. 

  • 8/17/2019 Fsharp prirucnik

    19/57

    19  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Operatori za rad sa funkcijama 

    F# definiše više operatora za rad sa funkcijama među kojima su najznačajniji: 

      operator ulančavanja poziva funkcija (|>) 

      operator kompozicije funkcija (>>) 

    Operator ulančavanja poziva funkcija 

    Operator ulančavanja poziva funkcija omogućava programeru da pozove funkciju na takav način da, u 

    programskom kodu,

     poslednji argument funkcije napiše pre njenog naziva. Sledeći primer ilustruje 

    navedenu sintaksu na primeru poziva kvadratne funkcije: 

    Ovakav način pisanja koda omogućava nam ulančavanje poziva funkcija, što  je ilustrovano sledećim 

    primerom: 

    Operator kompozicije funkcija 

    Operator kompozicije funkcija omogućava kreiranje nove funkcije koja predstavlja kompoziciju 

    operanada. Primer koji sledi ilustruje primenu operatora kompozicije na funkcije „sq“ i „neg“ iz 

    prethodnog primera: 

  • 8/17/2019 Fsharp prirucnik

    20/57

    20  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Mogućnosti prikazanih operatora posebno dolaze do izražaja u kombimnaciji sa funkcijama projekcije, 

    selekcije i agregacije. Sledeći primer ilustruje navedeno, na primeru rešavanja problema računanja sume 

    kvadrata brojeva od 1 do 1000 u  jednoj liniji koda: 

    Parcijalna primena funkcije 

    Parcijalna primena funkcije (engl.  function currying)  je mogućnost kreiranja nove funkcije pozivanjem 

    postojeće, pri čemu se neki argumenti izostavljaju. 

    Primer koji sledi, ilustruje kreiranje funkcija „inc“ (koja uvećava dati broj za  jedan) i „dec“ (koja umanjuje 

    dati broj za  jedan), parcijalnom primenom funkcije za izračunavanje zbira dva broja „add“. 

  • 8/17/2019 Fsharp prirucnik

    21/57

    21  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Parcijalna primena funkcije postaje posebno korisna u kombinaciji sa funkcijama projekcije, selekcije ili 

    agregacije. Sledeći primer ilustruje  jednostavno kreiranje funkcije za sumiranje elemenata sekvence: 

    Rekurzivne funkcije 

    Funkcija koja u svom telu poziva samu sebe naziva se rekurzivnom. Tipična rekurzivna funkcija  je 

     faktorijel  (n! = n x (n‐1)!). Rekurzivne funkcije se u F#‐u moraju posebno označiti upotrebom ključne reči 

    rec ispred naziva funkcije. 

    Možda zvuči neobično, ali formalno gledano funkcija u F#‐u ne može da primi više od  jednog 

    argumenta. Iako se tip funkcije „add“ int   ‐> int   ‐> int  , najčešće i prirodno tumači kao funkcija 

    koja prima dva celobrojna argumenta i vraća ceo broj, za funkciju „add“ bi bilo ispravnije reći da 

     je funkcija koja prima celobrojni argument i vraća funkciju koja ima tip int   ‐> int . 

    Sintaksna forma let add x y = x + y predstavlja samo pregledniji oblik za let add x = (fun y ‐> x+y), 

    što  je takođe pregledniji oblik za  još kompleksniju formu let add = (fun  x ‐> ( fun y ‐> x+y )). 

    Iz prikazanog sledi da  je mogućnost parcijalne primene funkcija prirodna posledica strukture 

    programskog  jezika F#. 

  • 8/17/2019 Fsharp prirucnik

    22/57

    22  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Ukoliko imamo dve funkcije koje međusobno pozivaju  jedna drugu, onda kažemo da su te dve funkcije 

    međ usobno rekurzivne. U F# kodu  je neophodno da međ usobno rekurzivne funkcije budu definisane 

    neposredno  jedna za drugom i spojene pomoću ključne reči and. To omogućava F# kompajleru da ove 

    dve funkcije posmatra kao  jednu celinu sa stanovišta automatskog utvrđivanja tipa. 

    Operatori Operatori u F#‐u su specijalne funkcije čiji se nazivi sastoje od simbola: „!%&*+-./?@^|~:“, pri čemu 

    simbol „:“ ne može biti na prvoj poziciji. Naziv operatora se prilikom definisanja funkcije piše između 

    zagrada. Primena operatora značajno povećava čitljivost koda. 

    Sledeći primer ilustruje definisanje operatora „!“ za izračunavanje faktorijela datog broja. 

    Upotreba ključne reči rec možda deluje suvišno, pošto najveći broj savremenih kompajlera 

    automatski prepoznaje rekurzivno definisane funkcije. Treba uzeti u obzir da F# kompajler ima 

    teži zadatak pošto pri kompajliranju vrši i automtsko prepoznavanje tipa. Posledica toga  je 

    neophodno označavanje rekurzivnih funkcija ključnom reči rec. 

  • 8/17/2019 Fsharp prirucnik

    23/57

    23  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Programski jezik  F# (IV deo) 

    Kompleksni  funkcionalni tipovi podataka 

    Tip podataka slog (record) 

    Tip podataka slog omogućava programeru da grupiše više vrednosti u vrednost  jednog tipa. Za razliku od 

    n‐torke slog omogućava imenovanje datih vrednosti. Imenovana vrednost u okviru sloga se naziva polje. 

    Slog definišete navođenjem parova naziv/tip kao što  je ilustrovano na sledećem primeru: 

    Pošto ste definisali tip možete definisati i vrednosti datog tipa, navođenjem vrednosti za svako polje. 

    Možete uočiti da  je F# kompajler automatski izvršio inferenciju tipa identifikatora “s”. 

    Vrednostima koje se nalaze u slogu možete pristupiti primenom operatora pristupa polju “.”. 

  • 8/17/2019 Fsharp prirucnik

    24/57

    24  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Ukoliko želite da definišete više slogova koji se razlikuju samo po vrednosti  jednog polja možete 

    upotrebiti tehniku kloniranja sloga koja  je ilustrovana na sledećem primeru: 

    Za kreiranje slogova se često koristi i generatorska funkcija koja omogućava korišćenje  jednostavnije 

    sintakse za kreiranje slogova. Pored toga u okviru same funkcije moguće  je izvršiti transformaciju 

    argumenata u vrednosti polja sloga. Sledeći primer ilustruje ovu tehniku: 

  • 8/17/2019 Fsharp prirucnik

    25/57

    25  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Tip podataka unija  diskriminatora (discriminated union) 

    Unija diskriminatora predstavlja tip podataka čija vrednost može biti u skladu sa samo  jednim od 

    definisanih diskriminatora. U svom najjednostavnijem obliku diskriminator predstavlja  jednu vrednost a 

    unija diskriminatora skup vrednosti. Tada tip unija diskriminatora semantički podseća na tip 

    “enumeracija” u programskom  jeziku C#. 

    Za razliku od elementa enumeracije diskriminatoru možemo pridružiti vrednost proizvoljnog tipa, pri 

    čemu dati tip ne mora biti isti za sve diskriminatore. Sledeći primer prikazuje definisanje unije 

    diskriminatora koja opisuje prevozno sredstvo. Pri tome  je automobilu pridružen par niski znakova koje 

    označavaju marku i model, autobusu  je pridružen broj linije, a biciklu nije pridružen nikakav podatak. 

  • 8/17/2019 Fsharp prirucnik

    26/57

    26  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Prilikom definisanja vrednosti tipa unija diskriminatora navodimo samo diskriminator, a kompajler vrši 

    inferenciju tipa. 

    Programski  jezik F# omogućava definisanje aliasa za tipove pomoću sintaksne forme: 

    type alias = tip 

    Ova funkcionalnost

     se

     često

     upotrebljava

     prilikom

     definisanja

     unije

     diskriminatora

     radi

     

    povećanja čitljivosti. Primenom aliasa, kod iz prethodnog primera ste mogli napisati na sledeći 

    način: 

  • 8/17/2019 Fsharp prirucnik

    27/57

    27  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Vrednost tipa unije diskriminatora se može uparivati prema obrascu. Pri tome se uparivanje može vršiti 

    na osnovu diskriminatora i pridruženih vrednosti. 

    Unija diskriminatora  je tip podataka koji nam omogućava da pišemo veoma efikasan funkcionalni kod. 

    Sledećih nekoliko primera ilustruju njegovu primenu. 

    Modelovanje strukture podataka 

    Prvi primer prikazuje modelovanje strukture podataka pomoću unije diskriminatora koja ima samo  jedan 

    diskriminator za koga su vezani podaci. 

  • 8/17/2019 Fsharp prirucnik

    28/57

    28  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Prednost ovakvog rešenja u odnosu na slog  je uočljiva na primeru pisanja funkcije koja kao argument 

    prima strukturu Point3D. 

    Možete uočiti da  je navedeni argument definisan preko segmenata diskriminatora Vector3D čime  je 

    omogućeno da telo funkcije bude napisano kratko i  jasno. 

    Modelovanje struktura u obliku stabla 

    Unije diskriminatora su idealne za modelovanje struktura u obliku stabla kao i za implementaciju 

    operacija nad njima. Sledeći primer ilustruje primenu unije diskriminatora za modelovanje binarnog 

    stabla. 

  • 8/17/2019 Fsharp prirucnik

    29/57

    29  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Za ovako definisano binarno stablo  jednostavno  je napisati rekurzivnu funkciju koja prolazi kroz njega. 

    Sledeći primer prikazuje funkciju koja vraća broj čvorova u stablu. 

    Modelovanje domenski specifičnih jezika 

    Sintaksa programskog  jezika F# sadrži više sintaksnih elemenata koji omogućavaju modelovanje 

    domenski specifičnih  jezika. Modelovanje domenski specifičnog  jezika pomoću unije diskriminatora  je 

    veoma  jednostavno, mada složeniji problemi iz date oblasti zahtevaju upotrebu drugih sintaksnih 

    elemenata i drugačiji pristup. 

    Sledeći primer ilustruje primenu unije diskriminatora za modelovanje predikatske logike: 

    Uočite da definicaja unije diskriminatora može biti rekurzivna. 

  • 8/17/2019 Fsharp prirucnik

    30/57

    30  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Sada  je lako definisati funkciju za evaluaciju datog izraza. 

    Tip podataka opcija (option) 

    Opcija  je tip podataka koji služi za modelovanje vrednosti koje mogu ali ne moraju da budu postavljene. 

    Predstavlja specifičan slučaj unije diskriminatora definisane kao: 

    type ‘a option = None | Some of  ‘a 

    Tip opcija se najčešće upotrebljava za povratnu vrednost funkcije koja nema definisan izlaz za sve 

    vrednosti ulaza. 

    Tipičan primer takve funkcije  je funkcija koja konvertuje nisku znakova u ceo broj. Ukoliko niska znakova 

    ne predstavlja broj, funkcija ne može da vrati smislen rezultat. 

    Programski  jezik C# koristi null  vrednost za slučaj kada vrednost nije definisana. Međutim null  vrednost može da znači i da vrednost nije inicijalizovana. Ova dualnost često dovodi do grešaka i 

    otežava razumevanje koda. 

  • 8/17/2019 Fsharp prirucnik

    31/57

    31  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Biblioteke programskog  jezika F# sadrže veći broj funkcija za rad sa opcijama. Najznačajnije od njih su: 

      Option.isSome  vraća true ukoliko argument ima vrednost, inače  false 

      Option.isNone  vraća true ukoliko argument nema vrednost, inače  false 

      Option.get  vraća vrednost ukoliko ona postoji, inače izbacuje izuzetak 

    Sledeći primer ilustruje upotrebu navedenih funkcija: 

    Programski jezik  F# (V deo) 

    Imperativno programiranje Pod imperativnim programiranjem se podrazumeva pisanje programa, koji tokom izvršavanja više puta 

    upisuju podatke na istu memorijsku lokaciju. U programskim  jezicima, kao što su C++, C# ili Visual Basic 

    to  je potpuno uobičajno. Nasuprot, tome naredba let  u F#‐u prilikom svakog povezivanja vrednosti sa 

    identifikatorom upisuje vrednost u novu memorijsku lokaciju. 

  • 8/17/2019 Fsharp prirucnik

    32/57

    32  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Naravno, ponekad postoji potreba da se i u F# programima piše imperativni kod. To  je posebno slučaj 

    kad se postojeći, složeni algoritmi, prevode sa nekog imperativnog programskog  jezika (poput C++a ili 

    Fortrana) prenose u F#. 

    Promenljive strukture 

    Osnovu imperativnog programiranja čine tipovi podataka, definisani tako da omogućavaju promenu 

    sopstvenih instanci kroz promenu memorijskog prostora koje instance zauzimaju. 

    Sintaksa programskog  jezika F# razlikuje tri vrste promenljivih struktura, i to: 

      Lokalne promenljive 

      Reference 

      Slogove sa promenljivim poljima 

    Lokalne promenljive 

    Lokalne promenljive definišu se na sličan način kao i identifikatori, pri čemu se posle naredbe 

    povezivanja let  upotrebljava ključna reč mutable. Promena lokalne promenljive vrši se pomoću 

    operatora strelica ulevo  (

  • 8/17/2019 Fsharp prirucnik

    33/57

    33  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Zbog toga se umesto lokalnih promenljivih često koriste reference (engl. reference cells). 

    Reference 

    Referenca predstavlja objektni omotač (ćeliju) u kojoj  je smeštena vrednost koja se može menjati tokom 

    izvršavanja programa. Vrednost se smešta u referencu primenom funkcije ref . 

    Sadržaju reference pristupa se pomoću operatora (!), dok se za izmenu sadržaja koristi operator (:=). 

    Slogovi sa promenljivim poljima 

    Sintaksa programskog  jezika F# omogućava definisanje slogova sa promenljivim poljima. Promenljiva 

    polja definišu se pisanjem ključne reči mutable ispred naziva polja. Sledeći primer ilustruje korišćenje 

    sloga sa promenljivim poljima kroz implementaciju imenovanog brojača. 

  • 8/17/2019 Fsharp prirucnik

    34/57

    34  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Nizovi 

    Niz (engl. array )  je kolekcija promenljivih elemenata istog tipa. Implemetacija niza  je takva da su 

    elementi koji ga čine smešteni u memoriji neposredno  jedan posle drugog. Zbog toga  je pri deklaraciji 

    niza potrebno tačno znati koliko će elemenata biti u nizu. Prednost ovakve implementacije  je u tome što 

    omogućava efikasan pristup proizvoljnom elementu niza. 

    Nizovi se mogu kreirati pomoću generatorskih izraza, poput lista i sekvenci, ili zadati kao lista vrednosti 

    odvojenih znakom  ; između znakova [| i |] . 

    Elementima niza pristupa se pomoću operatora indeksiranja (.[]) . Operator indeksiranja upotrebljava se 

    kako kod čitanja tako i kod menjanja sadržaja elementa niza. 

  • 8/17/2019 Fsharp prirucnik

    35/57

    35  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Operator indeksiranja omogućava izdvajanje podniza kada se koristi u sintaksnoj formi 

    arr.[donjaGranica .. gornjaGranica] . Ukoliko donja granica nije specificirana, za donju granicu se uzima 

    prvi element niza. Slično tome, ukoliko gornja granica nije specificirana, za gornju granicu se uzima 

    poslednji element niza. 

    F# biblioteke sadrže i veći broj funkcija za rad sa nizovima. U ovom poglavlju prikazaćemo samo osnovne 

    funkcije i to: 

      Array.length  vraća dužinu niza 

      Array.zeroCreate  kreira niz popunjen podrazumevanim vrednostima elementa za dati tip 

      Array.append  omogućava spajanje dva niza 

  • 8/17/2019 Fsharp prirucnik

    36/57

    36  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Pored navedenih, od izuzetnog značaja za rad sa nizovima  su i funkcije projekcije selekcije i agregacije: 

      Array.map  funkcija projekcije 

      Array.filter  funkcija selekcije 

      Array.fold  funkcija agregacije 

    koje su semantički ekvivalentne odgovarajućim funkcijama za rad sa listama. 

    Promenljive kolekcije 

    Promenljive kolekcije, pored mogućnosti izmene elemenata koje se u njima nalaze, imaju i mogućnost 

    dodavanja i uklanjanja elemenata. Mogućnost promene veličine kolekcije tokom vremena,  je značajna u 

    situacijama kada unapred nije poznato koliko će elemenata biti u kolekciji ( npr. kada se u kolekciju 

    smešta rezultat upita u bazu podataka ). 

    Promenljive kolekcije nisu specifične za F#, već se nalaze u standarndnim .NET bibliotekama u prostoru 

    imena System.Collections.Generic. 

    List 

    Kolekcija List predstavlja niz promenljive dužine. Interna implementacija ove kolekvcije  je zasnovana 

    na nizovima, tako da  je pristup elementima kolekcije veoma efikasan. 

    Pošto se kolekcija List nalazi u prostoru imena System.Collections.Generic pre kreiranja same 

    kolekcije potrbno  je uključiti navedeni prostor imena. 

  • 8/17/2019 Fsharp prirucnik

    37/57

    37  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    U kolekciju  je moguće dodati element korišćenjem metode  Add , odnosno sekvencu elemenata 

    korišćenjem metode  AddRange. Broj elemenata koji se nalaze u kolekciji može se očitati pomoću 

    svojstva Count . 

    Uklanjanje elementa iz kolekcije vrši se pomoću metode Remove. Ova metoda vraća logičku vrednost 

    true ukoliko  je element uklonjen iz kolekcije, a logičku vrednost  false ukoliko se element nije ni nalazio u 

    kolekciji. 

    F# konzolni interpreter ne prikazuje automatski sadržaj instance tipa List. Ukoliko postoji potreba za prikazom sadržaja, isti se može dobiti upotrebom funkcije  printfn “%A” . 

  • 8/17/2019 Fsharp prirucnik

    38/57

    38  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Elementi liste mogu se menjati na isti način kao i elementi niza. 

    Pored navedenih, metoda i svojstava od značaja za rad sa kolekcijama tipa List su i sledeće metode: 

      Contains  Vraća logičku vrednost true ako  je element sadržan u kolekciji 

      IndexOf   Vraća indeks elementa u kolekciji. Ako se element ne nalazi u kolekciji vraća ‐1 

      Insert  Dodaje element u kolekciju, na lokaciju sa datim indeksom 

    Dictionary 

    Kolekcija Dictionary  predstavlja asocijativni niz. Koristi se kada  je potrebno elementima pristupiti 

    po asociranoj vrednosti (ključu), umesto po indeksu. 

  • 8/17/2019 Fsharp prirucnik

    39/57

    39  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Asocirana vrednost za dati ključ očitava se pomoću operatora indeksiranja koji prima ključ kao 

    parametar. Ukoliko sa datim ključem nije asocirana neka vrednost, dolazi do pojave izuzetka1 i 

    eventualno do prekida programa. 

    Kad god postoji mogućnost da sa datim ključem nije asocirana vrednost, poželjno  je koristiti metodu 

    TryGetValue. Ova metoda vraća uređeni par. Prvi član uređenog para  je logičkog tipa i ima vrednost true 

    ili  false, zavisno od toga da li  je sa datim ključem asocirana neka vrednost ili ne. Drugi član uređenog 

    para  je tražena vrednost, odnosno specijalna vrednost null , ukoliko ne postoji vrednost koja  je asocirana 

    sa datim ključem. 

    1 O izuzetcima će biti više reči kasnije u ovom tekstu 

  • 8/17/2019 Fsharp prirucnik

    40/57

    40  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Ciklusi 

    Imperativno programeranje podrazumeva eksplicitnu kontrolu toka izvršavanja programa. Takva 

    kontrola podrazumeva i upotrebu ciklusa koji omogućavaju repetativno izvršavanje određenog dela 

    koda, određeni broj puta, odnosno do ispunjenja datog uslova. 

    Programski  jezik F# podržava while ciklus i dve vrste  for  ciklusa. 

    While ciklus 

    While ciklus se izvršava sve dok uslov ciklusa vraća logičku vrednost true. Sledeći primer ilustruje 

    primenu while ciklusa u funkciji za izračunavanje zbira celih brojeva u zatvorenom intervalu [n,m]. 

    For ciklus For ciklus se koristi kada  je unapred poznat broj iteracija koje treba da budu izvršene. 

    Jednostavna forma  for  ciklusa podrazumeva postojanje celobrojne ciklusne promenljive (brojača) u 

    zaglavlju ciklusa, koja uzima vrednosti između donje i gornje granice. Sledeći primer  je u funkcionalnom 

    smislu ekvivalentan prethodnom samo što  je ovaj put za rešavanje problema upotrebljena  jednostavna 

    forma  for  ciklusa. 

  • 8/17/2019 Fsharp prirucnik

    41/57

    41  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Nabrojiva forma  for  ciklusa podrazume postojanje ciklusne promenljiva koja uzima vrednosti redom iz 

    proizvoljne sekvence. U primeru koji sledi zatvoreni interval celih brojeva zadat  je sekvencom u formi 

    liste celih brojeva od n do  m. 

    Izuzetci 

    Da bi se obezbedila pouzdanost programa neophodno  je vešto upravljanje neočekivanim ili izuetnim 

    situacijama. Pod neočekivanim i izuzetnim situacijama podrazumeva se neispravnost podataka, uređaja 

    ili nedostupnost servisa ( npr. Internet konekcije ). Ukoliko se dogodi neka od napred opisanih situacija, 

    u .NET programu dolazi do genereisanja izuzetka (engl. exception). 

    Izuzetak  je neispravnost u .NET programu, koja prekida normalni tok programa, tako što dolazi do 

    automatskog prekida svake funkcije u lancu poziva, sve do obrade izuzetka u segmentu koda za obradu 

    izuzetaka (engl. exception handler ). Ako takav segment ne postoji dolazi do prekida programa. 

    Generisanje izuzetaka 

    Ukoliko funkcija ne može da vrati odgovarajuću vrednost za određene vrednosti argumenata, poželjno  je 

    da u tom slučaju generiše izuzetak. 

  • 8/17/2019 Fsharp prirucnik

    42/57

    42  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Izuzetci se najjednostavnije generišu pomoću funkcije  failwith, koja kao parametar prima odgovarajuću 

    poruku. 

    Iako  je poruka o grešci sama po sebi korisna,u skladu sa pravilima dobre prakse potrebno  je generisati 

    tipizirani izuzetak.

     Tipizirani

     izuzetci

     generišu

     se

     pomo

    ću

     funkcije

     raise.

     Pre

     koriš

    ćenja

     tipiziranih

     

    izuzetaka neophodno  je uključiti prostor imena System. 

    Čitljivost koda se može dodatno poboljšati definisanjem programski specifičnih (engl. custom) klasa 

    izuzetaka. 

  • 8/17/2019 Fsharp prirucnik

    43/57

    43  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Obrada izuzetaka 

    Obrada izuzetaka vrši se pomoću try ‐with narebe. Try ‐with naredba sastoji se iz try  bloka naredbi i with 

    skupa pravila za uparivanje po obrascu. Try  blok naredbi sadrži skup naredbi koje mogu generisati 

    izuzetak. Ukoliko neka od naredbi iz try  bloka generiše izuzetak, .NET izvršno okruženje će pokušati da 

    upari generisani izuzetak sa nekim od pravila za uparivanje iz with skupa. Ukoliko dođe do uparivanja izvršavaju se naredbe u okviru odgovarajućeg pravila za uparivanje i program nastavlja sa izvršavanjem. 

    U suprotnom prekida se izvršavanje trenutne funkcije, a izuzetak se prosleđuje sledećoj funkciji u lancu 

    poziva. 

    Ukoliko postoji potreba da se posle izvršenja skupa naredbi izvrši drugi skup naredbi, nevezano za to da 

    li  je pri izvršavanju prvog skupa naredbi došlo do generisanja izuzetka ili ne, koristi se  try ‐ finally  

    naredba. 

    Try ‐ finally  naredba sastoje iz try  bloka naredbi i  finally  bloka naredbi. Try  blok naredbi sadrži naredbe 

    koje mogu da generišu izuzetak, dok  finally  blok naredbi sadrži naredbe koje se izvršavaju po izlasku iz 

    try  bloka naredbi. 

    Karakterističan primer primene try ‐ finally  naredbe  je fragment koda koji koristi resurs koji se eksplicitno 

    mora vratiti operativnom sistemu na korišćenje (npr. datoteka). 

  • 8/17/2019 Fsharp prirucnik

    44/57

    44  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Za razliku od programskog  jezika C# čijom  je sintaksom definisana naredba try ‐catch‐ finally , sintaksa 

    programskog  jezika F# ne poznaje naredbu try ‐with‐ finally . 

    Programski jezik  F# (VI deo) 

    Objektno orijentisano programiranje 

    Najveći deo

     .NET

     platforme

     napisan

      je

     u

     objektno

     orijentisanim

     programskim

      jezicima,

     prvenstveno

     u

     

    programskom  jeziku C#. Zato  je poznavanje objektno orijentisanog programiranja (OOP) od ključne 

    važnosti za korišćenje brojnih .NET biblioteka. Cilj ovog poglavlja nije da nauči čitaoca objektno 

    orijentisanom programiranju( to bi bilo previše ambiciozno), već da prikaže kako su objektno orijentisani 

    koncepti utkani u F#. 

    Objektno orijentisan stil programiranja pogodan  je za pisanje kompleksnih softverskih sistema. 

    Navedena pogodnost se ogleda u mogućnosti da se objekti iz realnog sveta modeluju pomoću 

    softverskih abstrakcija, klasa. 

    Klasa Klasa  je sintaksni element koji povezuje funkcije i podatke. Sintaksa programskog  jezika F# definiše više 

    elemenata koji se iz objektno orijentisanih programskih  jezika, poput C#‐a, „vide“ kao klase. To su: 

      Slog 

      Unija diskriminatora 

      Izuzetak 

      Klasa 

    Obratite pažnju na liniju koda f.WriteLine(text:string). Pošto  je definisano više varijanti metode 

    WriteLine koje primaju  jedan parametar i koje se razlikuju samo po tipu parametra, kompajler 

    nije u mogućnosti da automatski odredi sa kojom od tih varijanti da poveže poziv dati poziv. Zbog 

    toga  je neophodno dati sugestiju kompajleru (eng. compiler  hint ) koja precizno definiše koja 

    varijanta metode WriteLine treba da bude pozvana. U ovom slučaju to  je WriteLine(string). 

  • 8/17/2019 Fsharp prirucnik

    45/57

    45  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

      Modul 

    Slog, unija diskriminatora i izuzetak prikazani su u prethodnim poglavljima. Ovaj odeljak bavi se 

    sintaksnim elementom koji  je označen kao klasa u specifikaciji programskog  jezika F#. 

    Sledeći primer prikazuje definisanje klase Vector2D: 

    Objekat klase Vector2D kreiramo navođenja imena klase i prosleđivanjem vrednosti parametara 

    potrebnih za inicijalizaciju objekta. 

    Broj i tip vrednosti koje se prosleđuju prilikom kreiranja objekta klase Vector2D definisan  je formom 

    zaglavlja definicije klase: 

    type Vector2D(dx:float, dy:float)= 

    Radi boljeg razumevanja biće prikazana ekvivalentna C# sintaksa: 

  • 8/17/2019 Fsharp prirucnik

    46/57

    46  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Možete uočiti da zaglavlje definicije klase u F#‐u, u semantičkom smislu, igra ulogu koju ima konstruktor 

    u C#‐u, pa se u skladu sa time i naziva implicitni konstruktor. Implicitni konstruktor, uporedo sa 

    parametrima, definiše i privatna polja istog tipa i naziva koje imaju i parametri. Ovako definisana polja 

    mogu se koristiti u svim članovima klase. 

    Pored polja članovi klase mogu biti svojstva (engl.  properties) i metode. 

    Svojstvo 

    Svojstva služe za pristup podacima. Najčešće su to “sirovi” podaci, prezentovani na način kako su 

    definisani u poljima, ali mogu biti i izračunate vrednosti (npr. svojstvo Length zavisi od veličine više 

    polja). Sledeći primer ilustruje korišćenje svojstava DX , DY  i Length. 

    Svojstva DX i DY, iz prethodnog primera, definisana su korišćenjem skraćene sintakse: member t.DX = dx 

    Ovakva sintaksna forma omogućava samo očitavanje vrednosti svojstva i ekvivalentna je sledećem C# kodu: 

    class Vector2D 

    { private readonly float dx; 

    private readonly float dy; 

    public Vector2D(float dx, float dy) 

    { this.dx = dx; 

    this.dy = dy; } 

  • 8/17/2019 Fsharp prirucnik

    47/57

    47  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Slično kao i u drugim objektno orijentisanim programskim  jezicima, svojstva mogu pripadati klasi umesto 

    pojedinim objektima date klase. Takva svojstva nazivaju se statička, a u programskom kodu označavaju 

    se pomoću ključne reči static: 

    static member Zero = Vector2D(0.,0.) 

    Statička svojstva najčešće se koriste za kreiranje specifičnih objekata date klase (npr. nula vektor). 

    Metoda 

    Metoda predstavlja operaciju koju  je moguće izvršiti nad objektom. Prilikom definisanja metode u 

    zaglavlju se pored naziva navodi  i skup parametara potrebnih za njeno pozivanje. U primeru  je data 

    metoda Scale koja prima parametar k  tipa  float  i vraća Vector2D objekat čije su dimenzije uvećane k  

    puta. 

    member t.Scale(k) = Vector2D(k*dx,k*dy) 

    class Vector2D { 

    ... 

    public float DX { get { return dx; } } 

    public float DY { get { return dy; } } public float Length { get { return (float)Math.Sqrt(dx*dx+dy*dy); } } 

  • 8/17/2019 Fsharp prirucnik

    48/57

    48  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Možete uočiti da nijedno od svojstava ili metoda prikazanih u prethodnom primeru ne menja stanje 

    postojećeg objekta već kreira novi objekat inicijalizovan na promenjeno stanje. Zbog toga za klasu 

    Vector2D kažemo da  je nepromenljiva (engl. immutable). 

    Iako  je preporučeno da F# klase budu nepromenljive, moguće  je napisati i klasu koja tokom izvršenja 

    programa menja svoje stanje. 

    Promenljiva klasa 

    Definisanje promenljive klase ilustrovano  je na primeru koji  je funkcionalno sličan prethodnom: 

    Možete uočiti da su polja klase eksplicitno definisana i definisana kao promenljiva, mada se i dalje koristi 

    implicitni konstruktor. 

    Promenljiva svojstva su definisana tako da sadrže programski kod za očitavanje (get ) i promenu (set ): 

    member t.DX with get()=dx and set(v)=dx 

  • 8/17/2019 Fsharp prirucnik

    49/57

    49  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Sada  je moguće napisati kod koji menja stanje objekta korišćenjem svojstva i operatora promene stanja 

    (

  • 8/17/2019 Fsharp prirucnik

    50/57

    50  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Testiranje metode Scale pokazuje da se njenim pozivom menja objekat nad kojim  je metoda pozvana i 

    da identifikator v2 koji  je povezan sa povratnom vrednošću metode referiše isti objekat kao i 

    identifikator v  sa kojim  je objekat povezan prilikom kreiranja. 

    Programski jezik  F# (VII deo) 

    Napredni koncepti 

    Sledeći primer ilustruje napredne koncepte poput indeksiranih svojstava, preklapanja operatora i 

    imenovanih i opcionih argumenata. 

  • 8/17/2019 Fsharp prirucnik

    51/57

    51  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Indeksirano svojstvo 

    Indeksirana svojstva (engl. indexers) omogućavaju da se podacima pristupa pomoću operatora 

    indeksiranja (.[ ]). Datu funkcionalnost treba implementirati samo ukoliko ona ima logičkog smisla. U 

    prethodnom primeru implementacija indeksiranog svojstva omogućava nam da koordinatama vektora 

    pristupimo preko indeksa, pri čemu  x  koordinati odgovara indeks 0, a y  koordinati vrednost indeksa 1. 

    Preklapanje operatora 

    Preklapanje operatora podrazumeva definisanje operatora (npr. + ili  ‐) za proizvoljnu korisnički 

    definisanu klasu. Operator se definše implementiranjem statičke metode koja umesto imena sadrži 

    simbol operatora u zagradama: 

    static member (+) (a:Vector2D,b:Vector2D) =  Vector2D(a.DX+b.DX, a.DY+b.DY) 

    Sledeći primer ilustruje upotrebu operatora: 

    Imenovani i opcioni argumenti 

    Sintaksa programskog  jezika F#, omogućava programeru, da prilikom prosleđivanja parametra metodu, 

    imenovanjem poveže vrednost sa odgovarajućim argumentom. 

  • 8/17/2019 Fsharp prirucnik

    52/57

    52  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Mogućnost da se argument proglasi za opcioni, omogućava programeru, da izbegne definisanje većeg 

    broja funkcionalno istih metoda sa različitim brojem parametara. Argument se označava kao opcioni 

    tako što se ispred njegovog naziva stavi upitnik. 

    member t.Scale(k,?k2) = 

    let defK2 = defaultArg k2 1. 

    dx 

  • 8/17/2019 Fsharp prirucnik

    53/57

    53  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Interfejs Interfejs predstavlja sintaksni element koji omogućava implementaciju  „može da“ relacije (engl. can do). 

    Ova relacija označava da objekat date klase može da izvrši skup opercija. Interfejs služi da definiše dati 

    skup operacija bez definisanja njihove implementacije. 

    Pomoću interfejsa se najčešće povezuju klase koje implementiraju skup operacija na potpuno različite 

    načine. Primer takvog interfejsa bio bi IShape interfejs koji definiše metodu Contains. Metoda Contains 

    vraća true, odnosno  false u zavisnosti od toga da li prosleđeni par realnih vrednosti predstavlja 

    koordinate tačke u okviru date figure. 

    Za razliku od C#‐a, programski  jezik F# podržava isključivo eksplicitnu implementaciju interfejsa. Sintaksa 

     je prikazana na primeru definisanja klasa Circle i Square koje implementiraju IShape interfejs. 

    Pošto  je implementacija interfejsa eksplicitna, potrebno  je pre poziva metode interfejsa izvršiti 

    konverziju objekta u dati interfejs. Konverzija se vrši pomoću operatora konverzije (:>), na način koji  je 

    prikazan u sledećem primeru: 

  • 8/17/2019 Fsharp prirucnik

    54/57

    54  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

     Anonimna klasa 

    Programski  jezik F# podržava i implementaciju interfejsa kreiranjem anonimne klase iz interfejsa. Tako 

    kreirana anonimna klasa sadrži isključivo metode interfejsa, a za objekat date klase nije potrebno vršiti 

    konverziju u interfejs kako bi se pozivale metode definisane u interfejsu. 

    Za kreiranje anonimnih klasa koristi se objektni izraz. Objektni izraz za kreiranje anonimne klase bazirane 

    na interfejsu sastoji se od para vitičastih zagrada, u okviru kojih se nalazi operator new , za kojim sledi 

    naziv interfejsa, a potom i implementacija interfejsa sintaksno identična implementaciji prikazanoj na 

    primeru definisanja klasa Circle i Square. 

    Objektni izraz se u praksi najčešće koristi u okviru generatorske funkcije koja prima parametre potrebne 

    za kreiranje objekta date anonimne klase, kao što  je to prikazano u sledećem primeru. 

     Abstraktna klasa Delimično implementirana klasa naziva se abstraktna klasa. Abstraktna klasa može da sadrži deklarisane 

    (abstraktne) i implementirane članove. Pošto abstraktni članovi nemaju implementaciju, nemoguće  je 

    kreirati objekat za datu abstraktnu klasu. Abstraktna klasa se najčešće koristi kao korena klasa u 

    hijerarhiji klasa, kada sve klase u hijerarhiji dele određenu zajedničku implementaciju. 

  • 8/17/2019 Fsharp prirucnik

    55/57

    55  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Prilikom definisanja abstraktne klase neophodno  je markirati datu klasu atributom  AbstractClass. 

    Sledeći primer prikazuje definisanje klase Shape koja sadrži abstraktnu metodu Contains i metodu Print  

    koja ima podrazumevanu implementaciju. 

    Klasa Circle nasleđuje abstraktnu klasu Shape i implementira metodu Contains. 

    Moguće  je kreirati objekat tipa Circle i pozivati metode Contains i Print  za dati objekat. 

  • 8/17/2019 Fsharp prirucnik

    56/57

    56  Micorosoft „Partner u učenju“  časopis za nastavnike http://casopis.spaces.live.com 

    Možete uočiti, da se metoda Print  izvršava na način na koji  je implementirana u Shape klasi. Metodu 

    Print  moguće  je predefinisati (engl. override) tako da se izvršava po algoritmu koji  je specifičan za datu 

    klasu. 

    Modul Modul u F#‐u predstavlja način grupisanja funkcija. U C#‐u se za tu namenu koristi statička klasa. 

    Sledeći primer ilustruje definisanje modula Vector  koji sadrži funkciju length, kao i način pozivanja 

    navedene funkcije. 

  • 8/17/2019 Fsharp prirucnik

    57/57

    Ekvivalentan C# kod glasi: 

    KRAJ SERIJALA 

    Autor: Srđan Božović

    public static class Vector 

    public static float length(Vector2D v) { 

    return (float)Math.Sqrt(v.DX * v.DX + v.DY * v.DY); }