OCaml | |
---|---|
Semantiikka | moniparadigma : toiminnallinen , oliosuuntautunut , pakottava |
Kieliluokka | olio-ohjelmointikieli , toiminnallinen ohjelmointikieli , moniparadigmaohjelmointikieli , pakollinen ohjelmointikieli , ohjelmointikieli sekä ilmainen ja avoimen lähdekoodin ohjelmisto |
Esiintyi | 1996 |
Tekijä | Leroy, Xavier ja Damien Doligez [d] |
Kehittäjä | INRIA |
Tiedostotunniste _ | .ml, .mli |
Vapauta | 4.14.0 ( 28. maaliskuuta 2022 ) |
Tyyppijärjestelmä | tiukka , staattinen |
Murteet | F# , JoCaml , MetaOCaml, OcamlP3l |
Vaikutettu | Standard ML , Caml Light |
Lisenssi | LGPL |
Verkkosivusto | ocaml.org |
OS | Unix-tyyppinen käyttöjärjestelmä [1] |
Mediatiedostot Wikimedia Commonsissa |
OCaml ( Objective Caml ) on yleiskäyttöinen olio- toiminnallinen ohjelmointikieli . Se on suunniteltu ohjelmien suoritusturvallisuutta ja luotettavuutta ajatellen. Tukee toiminnallisia, pakottavia ja olio-ohjelmointiparadigmoja. ML -kielen yleisin murre käytännön työssä .
Ilmestyi vuonna 1996 nimellä Objective Caml, kun Didier Rémy (Didier Rémy) ja Jérôme Vouillon (Jérôme Vouillon) ottivat käyttöön tuen olioohjelmointia varten Caml-kielelle, joka oli alun perin kehitetty Ranskan instituutissa INRIA . Nimettiin virallisesti OCaml vuonna 2011 [2] .
OCaml-työkalupakki sisältää tulkin , tavukoodauksen kääntäjän ja natiivikoodiin optimoivan kääntäjän, joka on teholtaan verrattavissa Javaan ja suorituskyvyltään vain hieman huonompi kuin C ja C++ [3] .
Erityisesti Wikipedian kaavojen renderöinti <math>-tunnisteen avulla, MLDonkey-tiedostonvaihtoasiakas , Xen xapi -hypervisor -ohjauspino (osa Xen Server / Xen Cloud Platform -alustaa) ja Haxe -ohjelmointikieli on kirjoitettu OCaml- kielellä. kieli .
OCaml-kieli on yleiskäyttöinen ohjelmointikieli, mutta sillä on omat vakiintuneet sovellusalueet [4] .
Ensinnäkin se on "turvallisten" (ei vain tietoturvallisuuden kannalta) sovellusten luominen. Kieli käyttää roskienkeruuta, ja suurin osa tietotyypeistä on viittaus ( englanniksi boxed ), mikä tarkoittaa puskurin ylivuodon estämistä ohjelman suorittamisen aikana. Lisäksi staattinen kirjoitus ja käännösaikatarkistukset tekevät tietyt muut virheluokat, kuten valuvirheet , mahdottomaksi automaattisen tyyppivalun puuttumisen vuoksi. Lisäksi koodi voidaan varmentaa virallisesti . On olemassa apuohjelmia koodin tyypin oikeellisuuden automaattiseen todistamiseen, jotka ovat parempia kuin useimmissa ohjelmointikielissä. Ja mikä tärkeintä, turvatoimenpiteet eivät vaikuta suoritettavan koodin tehokkuuteen [4] .
Toinen OCamlin menestysalue on tietopohjaisissa sovelluksissa . Tämä alue sisältää tekstinkäsittelyn sekä kirjoittamisen kääntäjät. OCamlissa ei ole vain työkaluja tekstinkäsittelyyn (joista esimerkiksi Perl tai AWK ovat kuuluisia ), vaan myös työkaluja syvälle semanttiseen analyysiin ja tekstin muuntamiseen, mikä tekee OCamlista soveltuvan tiedon louhintatehtäviin [ 4 ] .
Tietenkin OCamlia, kuten muitakin ML:n murteita, käytetään tutkimus- ja varmistustehtävissä, joissa pääkoodi kirjoitetaan jollain ohjelmointikielellä, jonka jälkeen se varmennetaan ja analysoidaan muodollisesti OCaml-ohjelmalla [4] . Esimerkiksi interaktiivinen lauseiden todistusjärjestelmä Coq on kirjoitettu OCaml -kielellä .
OCamlilla on erityinen paikka ohjelmointikielten joukossa tehokkuuden, ilmeisyyden ja käytännöllisyyden yhdistelmän ansiosta. Kielen ominaisuuksia, jotka ovat kehittyneet yli 40 vuoden aikana ML :n luomisesta, ovat [5] :
OCaml juontaa juurensa ML:stä ( eng. meta language ), jonka Robin Milner toteutti Lisp - murteella vuonna 1972 ohjelmistotyökaluna lauseiden todistamiseen, metakielenä laskettavien funktioiden logiikkaa varten (LCF, eng. logic for computable) . toiminnot ). Myöhemmin tehtiin kääntäjä , ja vuoteen 1980 mennessä ML:stä oli tullut täysimittainen ohjelmointijärjestelmä [6] .
Guy Cousineau lisäsi kieleen algebrallisia tietotyyppejä ja kuvioiden sovittamista ja määritteli ML:n kategoriseksi abstraktiksi koneeksi (CAM). Näin CAM-ML voitiin kuvata, todentaa ja optimoida, mikä oli askel eteenpäin ML:lle [7] .
Jatkokehitys oli Caml -kieli (uudelleen CAM-ML) [6] [7] , jonka Ascánder Suárez loi vuonna 1987 ja jota Pierre Weis ja Michel Mauny jatkoivat .
Vuonna 1990 Xavier Leroy ja Damien Doligez julkaisivat uuden toteutuksen nimeltä Caml Light . Tämä C -toteutus käytti tavukooditulkkia ja nopeaa roskankerääjää . Kirjastojen kirjoittamisen myötä kieltä alettiin käyttää koulutus- ja tutkimuslaitoksissa [6] [7] .
C. Leroyn kehittämä Caml Special Light näki valon vuonna 1995 . Ohjelmointijärjestelmä sai konekoodeiksi kääntäjän, joka asetti suoritettavan koodin tehokkuuden muiden käännettävien kielten tasolle. Samaan aikaan kehitettiin moduulijärjestelmä , jonka idea lainattiin Standard ML :stä [6] .
OCamlin moderni muoto juontaa juurensa 1996 , jolloin Didier Rémy ja Jérôme Vouillon toteuttivat siistin ja tehokkaan objektituen kielelle . Tämän objektijärjestelmän avulla voit käyttää olio-ohjelmointikieliä käännöshetkellä tyyppiturvallisella tavalla ilman C++- ja Java - ajonaikaisia tarkistuksia [6] .
2000 -luvulla kieli on kehittynyt sujuvasti, ja se on saanut enemmän tunnustusta kaupallisissa projekteissa ja koulutuksessa. Tällä hetkellä kehitettyjen joukossa ovat polymorfiset menetelmät ja varianttityypit, nimetyt ja valinnaiset parametrit, ensimmäisen luokan moduulit , yleistetyt algebralliset tietotyypit (GADT). Kieli alkoi tukea useita laitteistoalustoja ( X86 , ARM , SPARC , PowerPC ) [6] [7] .
OCamlin laskentamalli funktionaalisena ohjelmointikielenä perustuu kolmeen lambda -laskimen päärakenteeseen : muuttujat , funktiomääritykset ja funktion soveltaminen argumenteihin [8] .
Muuttuja on tunniste, jonka arvo liittyy tiettyyn arvoon. Muuttujien nimet alkavat pienellä kirjaimella tai alaviivalla. Sidonta tehdään yleensä avainsanalla let, kuten seuraavassa esimerkissä interaktiivisessa kuoressa [9] :
olkoon v = 1 ;;Muuttujilla on laajuus . Esimerkiksi interaktiivisessa kuoressa muuttujaa voidaan käyttää sen sidontaa seuraavissa komennoissa. Samoin moduulissa määritettyä muuttujaa voidaan käyttää sen jälkeen, kun se on määritelty kyseisessä moduulissa [9] .
Muuttuva sidonta voidaan tehdä myös let-in-rakenteen määrittämässä laajuudessa, kuten seuraavassa esimerkissä ympyrän pinta-alan laskemiseksi säteestä:
# anna alueen säde = anna pi = 3 . 14 säteellä * . säde *. pi ;; val area : float -> float = < fun > # area 2 . 0 ;; - : kelluva = 12 . 56OCamlissa muuttujien sidokset ovat muuttumattomia (kuten matemaattisissa yhtälöissä), eli muuttujan arvo "määritetään" vain kerran (yksittäinen määritys). Toinen asia on, että sisääntulon sisällä voi olla toinen sisääntulo, jossa otetaan käyttöön toinen muuttuja, joka voi "varjostaa" ensimmäistä [9] .
OCamlissa on useita syntaksirakenteita funktioiden määrittämiseen.
Toiminnot voidaan määrittää käyttämällä function. Funktion lauseke näyttää tältä [10] :
funktio x -> x + 1Tässä tapauksessa funktio on anonyymi ja sitä voidaan käyttää parametreina muille funktioille tai käyttää johonkin argumenttiin, esimerkiksi:
( funktio x -> x + 1 ) 5Tämän funktion tyyppi int -> inton , eli funktio ottaa kokonaisluvun ja palauttaa kokonaisluvun.
Funktiolla voi olla useita argumentteja [11] :
funktio ( x , y ) -> x - yTässä esimerkissä sen tyyppi on: int * int -> int, eli funktion syöte on pari ja tulos on kokonaisluku.
On olemassa toinen lähestymistapa useiden argumenttien funktioiden esittämiseen - N-arvoisen funktion muuntaminen yhden argumentin N funktioiksi - currying . Seuraavat kaksi merkintää funktiolle, joka laskee kokonaislukuargumenttien tulon, ovat samanarvoisia [11] :
funktio x -> funktio y -> x * y hauska x y -> x * yNimetyt funktiot voidaan saada liittämällä muuttuja funktioon [10] . Nimetyn funktion määritelmä on niin yleinen operaatio, että sillä on erillinen syntaktinen tuki. Seuraavat kolme merkintää ovat vastaavia tapoja määrittää funktio (interaktiivisessa kuoressa):
# anna prod = funktio x -> funktio y -> x * y ;; val prod : int -> int -> int = < hauskaa > # anna prod x y = x * y ;; val prod : int -> int -> int = < hauskaa > # let prod = hauskaa x y -> x * y ;; val prod : int -> int -> int = < hauskaa >Kahden argumentin funktiot voidaan määrittää käyttämään infix-merkintää [10] :
# olkoon (^^) x y = x ** 2 . 0+ . v ** 2 . 0 ;; val ( ^^ ) : float -> float -> float = < hauskaa > # 2 . 0 ^^ 3 . 0 ;; - : kelluva = 13 . # (^^) 2 . 0 3 . 0 ;; - : kelluva = 13 .Tässä esimerkissä määritellään funktio , joka laskee kahden liukulukuluvun(^^) neliöiden summan . Kaksi viimeistä merkintätyyppiä ovat samanarvoisia.
Rekursiiviset funktiot eli funktiot, jotka viittaavat omaan määritelmäänsä, voidaan määrittää komennolla let rec[10] :
# anna rec fac n = vastaa n :ään | 0 -> 1 | x -> x * fac ( x - 1 ) ;;Samassa tekijälaskuesimerkissä käytetään kuvioiden sovitusta (konstrukti match-with).
Funktioargumentit voidaan määritellä nimetyiksi. Nimetyt argumentit voidaan määrittää missä tahansa järjestyksessä [10] :
# anna divmod ~ x ~ y = ( x / y , x mod y ) ;; val divmod : x : int -> y : int -> int * int = < fun > # divmod ~ x : 4 ~ y : 3 ;; - : int * int = ( 1 , 1 ) # divmod ~ y : 3 ~ x : 4 ;; - : int * int = ( 1 , 1 )OCamlissa voit jättää pois arvot etikettilyönnillä, jos parametrin nimi ja muuttujan nimi ovat samat [ 10] :
# anna x = 4 in Let y = 3 in divmod ~ x ~ y ;; - : int * int = ( 1 , 1 )
Operaatioiden assosiatiivisuus OCaml-lausekkeissa määräytyy etuliitteellä, mikä ulottuu käyttäjän määrittämiin toimintoihin. Etumerkki -toimii sekä etuliitteenä että infix-operaationa ja tarvittaessa käytettäväksi etuliitteenä yhdessä funktion kanssa, parametri tulee sulkea suluissa [12] .
Toiminnan etuliite | Assosiatiivisuus |
---|---|
! ? ~ | Etuliite |
. .( .[ .{ | |
funktion, rakentajan, tunnisteen, assert,lazy | Vasen |
- -. | Etuliite |
** lsl lsr asr | Oikein |
* / % mod land lor lxor | Vasen |
+ - | Vasen |
:: | Oikein |
@ ^ | Oikein |
& $ != | Vasen |
& && | Oikein |
or || | Oikein |
, | |
<- := | Oikein |
if | |
; | Oikein |
let match fun function try |
OCaml-kielellä on useita primitiivityyppejä : numeeriset tyypit ( kokonaisluku ja liukuluku), merkki , merkkijonot , looginen [13] .
Kokonaislukutyyppi edustaa kokonaislukuja alueelta [−2 30 , 2 30 − 1] ja [−2 62 , 2 62 − 1] 32- ja 64-bittisille arkkitehtuureille. Kokonaisluvuilla voit suorittaa tavanomaisia yhteen-, vähennys-, kerto- ja jakolaskuoperaatioita ja ottaa jakolaskun loppuosan :+,-,*,/,mod. Jos tulos ylittää sallitun intervallin, virhettä ei tapahdu ja tulos lasketaan modulo intervallirajasta [14] .
Liukulukuja edustaa 53-bittinen mantissa ja eksponentti välissä [−1022, 1023] IEEE 754 -standardin mukaisesti. Operaatioissa näitä lukuja ei voi sekoittaa kokonaislukuihin. Lisäksi liukulukujen operaatiot eroavat syntaktisesti kokonaislukuoperaatioista:+.,-.,*.,/.. On myös eksponentiooperaatio:**. Kokonaislukujen muuttamiseksi liukulukuiksi ja päinvastoin ovat käytettävissä seuraavat funktiot: float_of_int ja int_of_float [14] .
Liukulukuille on olemassa muita matemaattisia funktioita: trigonometriset (sin, cos, tan, asin, acos, atan), pyöristys (ceil, floor), eksponentiaalinen (exp), logaritminen (log, log10) sekä neliöjuuri (sqrt) [14] . Numeerisille tyypeille on olemassa myös polymorfisia vertailuoperaatioita [14] .
Merkkityyppi - char - vastaa merkin esitystapaa koodilla 0-255 (ensimmäiset 128 merkkiä ovat samat kuin ASCII ). Merkkijonotyyppi - merkkijono - merkkijono ( maksimipituus: 2 24 - 6) [15] . Esimerkki kokonaisluku-merkkijonomuunnosfunktiosta ja ketjutusoperaatiosta :
# "Esimerkki" ^ string_of_int ( 2 ) ;; - : string = "Esimerkki 2"Boolen tyypillä on kaksi arvoa:true(true) jafalse(false). Toiminnot Boolen arvoilla: unaari not (negataatio), binääri:&&(ja),||(tai). Binäärioperaatiot arvioivat ensin vasemman argumentin ja oikean argumentin vain tarvittaessa [16] .
Boolen arvot saadaan vertailujen tuloksena: =(rakenteellinen tasa-arvo), ==(identiteetti), <>(rakenteellisen tasa-arvon kieltäminen), !=(identiteetin kieltäminen), <, >, <=, >=. Primitiivisillä tyypeillä, paitsi merkkijonoja ja liukulukuja, rakenteellinen yhtäläisyys ja identtisyys ovat samat, muissa tyypeissä samaan osoitteeseen muistissa olevia arvoja pidetään identtisinä ja rakenteellisessa vertailussa arvot tarkistetaan komponentti kerrallaan. [16] .
Lisäksi OCamlissa on erikoistyyppinen yksikkö, jolla on vain yksi arvo - ()[16] .
ListatOCamlissa lista on rajallinen, muuttumaton sarja samantyyppisiä elementtejä, jotka on toteutettu yksitellen linkitetynä luettelona. Seuraava esimerkki havainnollistaa luettelon syntaksia [17] :
# [ 'a' ; 'b' ; 'c' ] ;; - : char list = [ 'a' ; 'b' ; 'c' ] # 'a' :: ( 'b' :: ( 'c' :: [] )) ;; - : char list = [ 'a' ; 'b' ; 'c' ] # 'a' :: 'b' :: 'c' :: [] ;; - : char list = [ 'a' ; 'b' ; 'c' ] # [] ;; - : ' lista = [ ]Toiminnon ::avulla voit rakentaa luettelon uuden elementin ja vanhan luettelon loppuosan perusteella. Tässä tapauksessa "vanha" luettelo ei muutu:
# anna lst = [ 1 ; 2 ] ;; val lst : int list = [ 1 ; 2 ] # olkoon lst1 = 0 :: lst ;; val lst1 : int lista = [ 0 ; 1 ; 2 ] # lst ;; - : int lista = [ 1 ; 2 ] # lst1 ;; - : int lista = [ 0 ; 1 ; 2 ] Esimerkki: luettelon elementtien summan laskeminenLista on yksi OCamlin tärkeimmistä tietotyypeistä. Seuraava koodiesimerkki määrittelee rekursiivisen (huomaa avainsanan rec) funktion, joka iteroi tietyn luettelon elementtien yli ja palauttaa niiden summan:
anna rec summa xs = sovita xs kanssa | [] -> 0 | x :: xs' -> x + summa xs' #summa[1;2;3;4;5];; - : int = 15Toinen tapa laskea summa on käyttää koontifunktiota:
anna summa xs = Lista . fold_left (+ ) 0xs # summa [ 1 ; 2 ; 3 ; 4 ; 5 ];; - : int = 15 MerkinnätTietueet ovat tärkeä elementti OCaml-tyyppisessä järjestelmässä. Tietue on joukko yhteen tallennettuja arvoja, joissa jokaiseen arvotietueen elementtiin pääsee käsiksi sen nimellä, tietueen kentän nimellä. Esimerkki tyyppimäärityksestä, tietueen sitomisesta muuttujaan ja tietuekentän käyttämisestä [18] :
# type user = { login : string ; salasana : merkkijono _ nimimerkki : merkkijono _ };; # anna usr = { login = "omakäyttäjäni" ; salasana = "salainen" ; nick = "aka" ; } ;; val usr : user = { login = "omakäyttäjäni" ; salasana = "salainen" ; nick = "aka" } # usr . Nick ;; - : merkkijono = "aka"On huomattava, että kääntäjä asetti automaattisesti usr-muuttujan tyypin.
Kuten muidenkin tyyppien kohdalla, tyyppi voidaan parametroida. Muut tallennusmahdollisuudet [18] :
Muunnelmatyyppi edustaa dataa, joka voi olla eri muodoissa ja jotka määritellään eksplisiittisillä tunnisteilla. Seuraava esimerkki määrittelee perusvärien tyypin [19] :
# type main_color = punainen | vihreä | sininen ;; # sininen ;; - : pääväri = Sininen # ( Punainen , Sininen ) ;; - : pääväri * pääväri = ( punainen , sininen )Yllä olevassa esimerkissä muunnelmatyyppiä käytetään lueteltuna tyyppinä . OCamlissa varianttityyppi on kuitenkin rikkaampi, koska se mahdollistaa tunnisteiden lisäksi myös datan määrittämisen, esim.
# type color_scheme = RGB of int * int * int | Kellukkeen CMYK * kellua * kellua * kellua ;; _ type color_scheme = RGB of int * int * int | Kellukkeen CMYK * float * float * float _Funktioita määritettäessä varianttityyppi pariutuu luonnollisesti kuviosovituksen kanssa.
ObjektitOCamlissa objektit ja niiden tyypit ovat täysin erillisiä luokkajärjestelmästä . Luokkia käytetään objektien rakentamiseen ja periytymisen tukemiseen , mutta ne eivät ole objektityyppejä. Objekteilla on omat objektityyppinsä , eikä sinun tarvitse käyttää luokkia objektien kanssa työskentelemiseen. Objekteja ei käytetä niin usein OCamlissa (esimerkiksi moduulijärjestelmä on ilmeisempi kuin objektit, koska moduulit voivat sisältää tyyppejä, mutta luokat ja objektit eivät). Objektien tärkein etu tietueisiin verrattuna on, että ne eivät vaadi tyyppimäärityksiä ja ovat joustavampia rivipolymorfismin ansiosta . Toisaalta olioiden edut tulevat esiin luokkajärjestelmää käytettäessä. Toisin kuin moduulit, luokat tukevat myöhäistä sidontaa, jonka avulla voit viitata objektimetodeihin ilman staattisesti määriteltyä toteutusta ja käyttää avointa rekursiota (moduulien tapauksessa voit käyttää funktioita ja funktioita, mutta syntaktisesti tällaiset kuvaukset vaativat lisää koodia) [20 ] .
TyyppipäätelmäVaikka OCaml on vahvasti kirjoitettu ohjelmointikieli , tyyppipäätelmäjärjestelmä ( englanniksi type inference ) mahdollistaa lausekkeen tyypin määrittämisen sen komponenteista saatavilla olevien tietojen perusteella. Seuraavassa pariteettifunktion esimerkissä tyyppimäärityksiä ei ole määritetty, mutta kielen kääntäjällä on kuitenkin täydelliset tiedot funktion tyypistä [21] :
# anna pariton x = x mod 2 <> 0 ;; val odd : int -> bool = < hauskaa >Toiminnallisten lisäksi kieli sisältää pakollisia ohjelmointityökaluja : sivuvaikutteisia toimintoja , muuttuvaa dataa, pakottavia syntaktisia rakenteita, erityisesti eksplisiittisiä silmukoita while ja for[22] .
Seuraava esimerkki tulostaa 11 riviä vakiotulostukseen (tämä on printf-toiminnon sivuvaikutus):
jos i = 0 - 10 , tee Printf . printf "i =%d \n " olen valmis ;;Seuraavassa (melko keinotekoisessa) esimerkissä taulukon elementtejä kasvatetaan paikoilleen ennakkoehtosilmukassa. Taulukkoindeksiä varten käytetään viitettä (ref), jota kasvatetaan silmukan rungossa:
# let incr_ar ar = anna i = ref 0 in while ! i < array . pituus ar do ar .(! i ) <- ar .(! i ) + 1 ; incr olen tehnyt ;; val incr_ar : int array -> unit = < fun > # let nums = [| 1 ; 2 ; 3 ; 4 ; 5 |];; arvo numerot : int array = [| 1 ; 2 ; 3 ; 4 ; 5 |] # incr_ar numerot ;; - : yksikkö = () # numerot ;; - : int array = [| 2 ; 3 ; 4 ; 5 ; 6 |]Sivuvaikutusten avulla voit optimoida laskelmia, varsinkin kun on kyse merkittävistä muutoksista suurissa tietojoukoissa. Niitä käytetään myös toteuttamaan laiska arviointi ja muistiinpano [22] .
OCamlin voidaan ajatella koostuvan kahdesta kielestä: ydinkielestä arvoineen ja tyypeineen sekä moduulien ja niiden allekirjoitusten kielestä . Nämä kielet muodostavat kaksi kerrosta siinä mielessä, että moduulit voivat sisältää tyyppejä ja arvoja, kun taas tavalliset arvot eivät voi sisältää moduuleja ja tyyppimoduuleja. OCaml tarjoaa kuitenkin mekanismin ensiluokkaisille moduuleille , jotka voivat olla arvoja ja tarvittaessa muuntaa normaaleista moduuleista [23] .
OCaml-moduulijärjestelmä ei rajoitu modulaariseen koodiorganisaatioon ja rajapintoihin. Yksi tärkeimmistä yleisohjelmoinnin työkaluista ovat funtorit . Yksinkertaisesti sanottuna funktionaaliset funktiot ovat toiminto moduulista moduuleihin, jonka avulla voit toteuttaa seuraavat mekanismit [24] :
Käynnistä OCaml-kielen tulkki kirjoittamalla seuraava komento konsoliin:
$ ocaml OCaml versio 4.08.1 #Laskut voidaan tehdä interaktiivisesti, esim.
# 1 + 2 * 3 ;; - : int = 7Seuraava "hello.ml" -ohjelma:
print_endline "Hei maailma!" ;;voidaan kääntää joko tavukoodiksi :
$ ocamlc hello.ml -o heitai optimoituun konekoodiin :
$ ocamlopt hello.ml -o heija käynnistettiin:
$ ./hei Hei maailma! $Seuraava esimerkki on pikalajittelualgoritmi, joka lajittelee luettelon nousevaan järjestykseen :
anna rec qsort = funktio | [] -> [] | pivot :: rest -> let is_less x = x < pivot in let left , right = List . osio is_less rest in qsort left @ [ pivot ] @ qsort rightHuomautus - Kirjassa käytetään termin " ensimmäisen luokan funktio " käännöstä " ensimmäisen asteen funktiona ". Mutta on pidettävä mielessä, että lukuisissa englanninkielisissä lähteissä (kielten semantiikasta yleensä ja erityisesti ML :stä ja Hindley-Milneristä ) erotetaan neljä käsitettä:
lisäksi " ensimmäinen luokka " on " parempi " kuin " toinen luokka " (ominaisuuksiltaan laajempi, lähempänä teoriaa ja korkeampi pääsykynnyksen suhteen ( C. Strachey – Ohjelmointikielten peruskäsitteet )), mutta " ensimmäinen luokka" ”primitiivisempi kuin ” korkeatasoinen ”. Erityisesti ML-moduulikielen laajentaminen " ensimmäisen luokan korkean asteen " tasolle on tutkijoille paljon suurempi ongelma kuin sen laajentaminen vain " ensiluokkaiseksi " tai vain " korkeaksi " ( Rossberg A. Functors and ajonaika vs käännösaika (downlink) Haettu 25. kesäkuuta 2015. Arkistoitu alkuperäisestä 26. kesäkuuta 2015 ).
Ohjelmointikielet | |
---|---|
|