OCaml - OCaml - Wikipedia
Paradigma | Multi-paradigma: funkční, rozkazovací způsob, modulární,[1] objektově orientovaný |
---|---|
Rodina | ML |
Navrhl | Xavier Leroy, Jérôme Vouillon, Damien Doligez, Didier Rémy, Ascánder Suárez |
Vývojář | INRIA |
Poprvé se objevil | 1996 |
Stabilní uvolnění | 4.11.0 / 19. srpna 2020[2] |
Psací disciplína | Odvozeno, statický, silný, strukturální |
Jazyk implementace | OCaml, C |
Plošina | IA-32, x86-64, Napájení, SPARC, RAMENO 32-64 |
OS | Cross-platform: Unix, Operační Systém Mac, Okna |
Licence | LGPLv2.1 |
Přípony názvu souboru | .ml, .mli |
webová stránka | ocaml |
Ovlivněno | |
C, Caml, Modula-3, Pascal, Standardní ML | |
Ovlivněno | |
ATS, Coq, Jilm, F#, F*, Haxe, Opa, Rez, Scala | |
|
OCaml (/oʊˈk…m.l/ Ach-KAM-əl, dříve Objektiv Caml) je univerzální, programovací jazyk pro více paradigmat který rozšiřuje Caml dialekt ML s objektově orientovaný funkce. OCaml byl vytvořen v roce 1996 společností Xavier Leroy, Jérôme Vouillon, Damien Doligez, Didier Rémy, Ascánder Suárez, a další.
OCaml řetězec nástrojů zahrnuje interaktivní nejvyšší úroveň tlumočník, a bytecode překladač, optimalizace nativní kód kompilátor, reverzibilní debugger a správce balíčků (OPAM). OCaml byl původně vyvinut v kontextu automatizované dokazování věty, a má nadměrné zastoupení v statická analýza a formální metody software. Mimo tyto oblasti našel vážné použití v programování systémů, vývoj webových aplikací, a finanční inženýrství, mimo jiné aplikační domény.
Zkratka CAML původně stál za Kategorický abstraktní strojový jazyk, ale OCaml to vynechává abstraktní stroj.[3] OCaml je a bezplatný open source software projekt řízen a hlavně udržován Francouzský institut pro výzkum v informatice a automatizaci (INRIA). Na začátku roku 2000 byly prvky z OCaml přijaty mnoha jazyky, zejména F# a Scala.
Filozofie
ML -odvozené jazyky jsou nejlépe známé svou statikou systémy typu a odvodit typ překladače. OCaml sjednocuje funkční, rozkazovací způsob, a objektově orientované programování v systému typu ML. Programátoři tedy nemusí dobře používat paradigma čistého funkčního jazyka, aby mohli používat OCaml.
Tím, že vyžaduje, aby programátor pracoval v rámci omezení svého systému statického typu, OCaml eliminuje mnoho runtime problémů souvisejících s typem souvisejících s dynamicky zadávanými jazyky. Také překladač typu OCaml odvozující typ výrazně snižuje potřebu anotací ručního typu, které jsou vyžadovány ve většině staticky psaných jazyků. Například datový typ proměnných a podpis funkcí obvykle nemusí být výslovně deklarovány, jako je tomu v jazycích jako Jáva a C#, protože je lze odvodit z operátorů a dalších funkcí, které se aplikují na proměnné a další hodnoty v kódu. Efektivní používání systému typu OCaml může vyžadovat určitou sofistikovanost programátora, ale tato disciplína je odměněna spolehlivým a vysoce výkonným softwarem.
OCaml se snad nejvíce odlišuje od jiných jazyků, které mají původ v akademické sféře, tím, že kladou důraz na výkon. Jeho statický typ systému brání neshodám typu runtime a tím předchází kontrole typu runtime a bezpečnostním kontrolám, které zatěžují výkon dynamicky psaných jazyků, a přitom stále zaručují runtime bezpečnost, kromě případů, kdy je vypnuta kontrola mezí pole nebo když jsou použity některé typicky nebezpečné funkce jako serializace . Ty jsou natolik vzácné, že v praxi je docela možné se jim vyhnout.
Kromě režie kontroly typu, Funkcionální programování jazyky jsou obecně náročné na kompilaci do efektivního kódu strojového jazyka, kvůli problémům jako je funarg problém. Spolu se standardní smyčkou, registrem a instrukcí optimalizace, Využívá optimalizační kompilátor OCaml statická analýza programu metody k optimalizaci hodnoty box a uzavření alokace, což pomáhá maximalizovat výkon výsledného kódu, i když ve velké míře využívá konstrukce funkčního programování.
Xavier Leroy uvedl, že „OCaml poskytuje alespoň 50% výkonu slušného kompilátoru jazyka C“,[4] ačkoli přímé srovnání je nemožné. Některé funkce ve standardní knihovně OCaml jsou implementovány s rychlejšími algoritmy než ekvivalentní funkce ve standardních knihovnách jiných jazyků. Například implementace množinové sady ve standardní knihovně OCaml je teoreticky asymptoticky rychlejší než ekvivalentní funkce ve standardních knihovnách imperativních jazyků (např. C ++, Java), protože implementace OCaml využívá neměnnost sad k opětovnému použití částí vstupu nastavuje na výstupu (viz trvalá datová struktura ).
Funkce
Funkce OCaml a statický typový systém, odvození typu, parametrický polymorfismus, rekurze ocasu, porovnávání vzorů, prvotřídní lexikální uzávěry, funktory (parametrické moduly), zpracování výjimek a přírůstkové generační automatický sběr odpadu.
OCaml je pozoruhodný pro rozšíření odvození typu ML stylu do objektového systému v obecném jazyce. To dovoluje strukturální subtypizace, kde typy objektů jsou kompatibilní, pokud jsou jejich podpisy metod kompatibilní, bez ohledu na jejich deklarovanou dědičnost (neobvyklá vlastnost ve staticky psaných jazycích).
A rozhraní cizí funkce pro propojení na C primitiva je poskytována, včetně jazykové podpory pro efektivní numerické pole ve formátech kompatibilních s C i Fortran. OCaml také podporuje vytváření knihoven funkcí OCaml, které lze propojit s hlavní program v jazyce C, aby mohla být knihovna OCaml distribuována programátorům C, kteří nemají žádné znalosti nebo instalaci OCaml.
Distribuce OCaml obsahuje:
- Lexikální analýza a analýza nástroje zvané ocamllex a ocamlyacc
- Debugger který podporuje krok zpět k vyšetřování chyb
- Generátor dokumentace
- Profiler - měřit výkon
- Mnoho univerzálních knihovny
Kompilátor nativního kódu je k dispozici pro mnoho platforem, včetně Unix, Microsoft Windows, a Jablko Operační Systém Mac. Přenositelnosti je dosaženo prostřednictvím nativního generování kódu podpora hlavních architektur: IA-32, X86-64 (AMD64), Napájení, SPARC, PAŽE, a ARM64.[5]
Programy OCaml bytecode a nativní kód lze zapsat do a vícevláknové styl s preventivním přepínáním kontextu. Protože však garbage collector systému INRIA OCaml (což je jediná aktuálně dostupná plná implementace jazyka) není navržen pro souběžnost, symetrické více procesů není podporován.[6] Vlákna OCaml ve stejném procesu se spouštějí pouze sdílením času. Existuje však několik knihoven pro distribuované výpočty, jako např Functory a ocamlnet / plazma.
Vývojové prostředí
Od roku 2011 bylo do vývojového prostředí OCaml přidáno mnoho nových nástrojů a knihoven:
- Vývojové nástroje
- opam je správce balíčků pro OCaml, vyvinutý společností OCamlPro.
- Merlin poskytuje funkce podobné IDE pro více editorů, včetně vrácení typu, go-to-definition a automatického dokončování.
- Duna je skládací systém sestavení pro OCaml.
- OCamlformat je automatický formátovač pro OCaml.
- Webové stránky:
- OCaml.org je primární web pro daný jazyk.
- discuss.ocaml.org je instancí Pojednání který slouží jako primární diskusní web pro OCaml.
- Alternativní překladače pro OCaml:
- js_of_ocaml, vyvinutý Ocsigen team, je optimalizační překladač z OCaml do JavaScript.
- BuckleScript, který také cílí JavaScript, se zaměřením na produkci čitelného idiomatického výstupu JavaScriptu.
- ocamlcc je kompilátor z OCaml do C, který doplňuje kompilátor nativního kódu pro nepodporované platformy.
- OCamlJava, vyvinutý společností INRIA, je překladač z OCaml do Virtuální stroj Java (JVM).
- OCaPic, vyvinutý společností Lip6, je kompilátor OCaml pro PIC mikrokontroléry.
Příklady kódu
Úryvky kódu OCaml jsou nejsnadněji studovány jejich zadáním do nejvyšší úroveň. Toto je interaktivní relace OCaml, která vytiskne odvozené typy výsledných nebo definovaných výrazů. Nejvyšší úroveň OCaml se spouští jednoduše spuštěním programu OCaml:
$ ocaml Objektivní Caml verze 3.09.0#
Kód lze poté zadat na výzvu „#“. Například pro výpočet 1 + 2 * 3:
# 1 + 2 * 3;;-: int = 7
OCaml vyvozuje typ výrazu, který má být „int“ (a strojová přesnost celé číslo ) a dává výsledek „7“.
Ahoj světe
Následující program "hello.ml":
print_endline "Ahoj světe!"
lze zkompilovat do spustitelného bytecode:
$ ocamlc ahoj.ml -o ahoj
nebo zkompilován do optimalizovaného spustitelného nativního kódu:
$ ocamlopt ahoj.ml -o ahoj
a provedeno:
$ ./AhojAhoj světe!$
První argument ocamlc, „hello.ml“, určuje zdrojový soubor ke kompilaci a příznak „-o ahoj“ určuje výstupní soubor.[7]
Shrnutí seznamu celých čísel
Seznamy jsou jedním ze základních datových typů v OCaml. Následující příklad kódu definuje a rekurzivní funkce součet který přijímá jeden argument, celá čísla, což má být seznam celých čísel. Poznamenejte si klíčové slovo rec
což znamená, že funkce je rekurzivní. Funkce rekurzivně iteruje nad daným seznamem celých čísel a poskytuje součet prvků. The zápas prohlášení má podobnosti s C je přepínač prvek, i když je mnohem obecnější.
nechat rec součet celá čísla = (* Klíčové slovo rec znamená „rekurzivní“. *) zápas celá čísla s | [] -> 0 (* Výnos 0, pokud jsou celá čísla prázdná seznam []. *) | za prvé :: zbytek -> za prvé + součet zbytek;; (* Rekurzivní volání, pokud je celá čísla non- prázdný seznam; první je první prvek seznamu a zbytek je a seznam ostatních prvků, možná []. *)
# součet [1;2;3;4;5];; - : int = 15
Dalším způsobem je použití standardu funkce skládání který pracuje se seznamy.
nechat součet celá čísla = Seznam.fold_left (zábava akumulátor X -> akumulátor + X) 0 celá čísla;;
# součet [1;2;3;4;5];; - : int = 15
Protože anonymní funkce je jednoduše aplikace operátoru +, lze ji zkrátit na:
nechat součet celá čísla = Seznam.fold_left (+) 0 celá čísla
Dále lze vynechat argument seznamu pomocí a částečná aplikace:
nechat součet = Seznam.fold_left (+) 0
Quicksort
OCaml se hodí ke stručnému vyjadřování rekurzivních algoritmů. Následující příklad kódu implementuje podobný algoritmus quicksort který třídí seznam v rostoucím pořadí.
nechat rec qsort = funkce | [] -> [] | pivot :: zbytek -> nechat is_less X = X < pivot v nechat vlevo, odjet, že jo = Seznam.rozdělit is_less zbytek v qsort vlevo, odjet @ [pivot] @ qsort že jo
Problém s narozeninami
Následující program vypočítá nejmenší počet lidí v místnosti, u nichž je pravděpodobnost zcela jedinečných narozenin menší než 50% ( narozeninový problém, kde pro 1 osobu je pravděpodobnost 365/365 (nebo 100%), pro 2 je to 364/365, pro 3 je to 364/365 × 363/365 atd.) (odpověď = 23).
nechat year_size = 365.nechat rec narozeniny_paradox prob lidé = nechat prob = (year_size -. plovák lidé) /. year_size *. prob v -li prob < 0.5 pak Printf.printf "odpověď =% d n" (lidé+1) jiný narozeniny_paradox prob (lidé+1);;narozeniny_paradox 1.0 1
Církevní číslice
Následující kód definuje a Kódování kostela z přirozená čísla, s nástupcem (succ) a sčítáním (přidat). Církevní číslo n
je funkce vyššího řádu který přijímá funkci F
a hodnotu X
a platí F
na X
přesně n
krát. Chcete-li převést církevní číslici z funkční hodnoty na řetězec, předáme jí funkci, která předchází řetězec „S“
na jeho vstup a konstantní řetězec "0"
.
nechat nula F X = Xnechat succ n F X = F (n F X)nechat jeden = succ nulanechat dva = succ (succ nula)nechat přidat n1 n2 F X = n1 F (n2 F X)nechat to_string n = n (zábava k -> „S“ ^ k) "0"nechat _ = to_string (přidat (succ dva) dva)
Faktoriální funkce s libovolnou přesností (knihovny)
Různé knihovny jsou přímo přístupné z OCaml. Například OCaml má vestavěnou knihovnu pro aritmetika s libovolnou přesností. Jelikož funkce faktoriálu roste velmi rychle, rychle přetéká čísla s přesností na stroj (obvykle 32 nebo 64 bitů). Faktoriál je tedy vhodným kandidátem na aritmetiku s libovolnou přesností.
V OCaml poskytuje modul Num (nyní nahrazený modulem ZArith) aritmetiku s libovolnou přesností a lze jej načíst do běžící nejvyšší úrovně pomocí:
# #použití "topfind";;
# #vyžadovat "num";;
# otevřeno Num;;
Faktoriální funkci lze poté zapsat pomocí numerických operátorů s libovolnou přesností =/, */ a -/ :
# nechat rec skutečnost n = -li n =/ Int 0 pak Int 1 jiný n */ skutečnost(n -/ Int 1);;val skutečnost : Num.počet -> Num.počet = <zábava>
Tato funkce dokáže vypočítat mnohem větší faktoriály, například 120 !:
# string_of_num (skutečnost (Int 120));;- : tětiva ="6689502913449127057588118054090372586752746333138029810295671352301633557244962989366874165271984981308157637893214090552534408589408121859898481114389650005964960521256960000000000000000000000000000"
Trojúhelník (grafika)
Následující program vykresluje rotující trojúhelník ve 2D pomocí OpenGL:
nechat () = ignorovat (Nadbytek.inic Sys.argv); Nadbytek.initDisplayMode ~double_buffer:skutečný (); ignorovat (Nadbytek.createWindow ~titul:„OpenGL Demo“); nechat úhel t = 10. *. t *. t v nechat poskytnout () = GlClear.Průhledná [ `barva ]; GlMat.load_identity (); GlMat.točit se ~úhel: (úhel (Sys.čas ())) ~z:1. (); GlDraw.začíná `trojúhelníky; Seznam.iter GlDraw.vertex2 [-1., -1.; 0., 1.; 1., -1.]; GlDraw.končí (); Nadbytek.swapBuffers () v GlMat.režimu `modelový pohled; Nadbytek.displayFunc ~cb:poskytnout; Nadbytek.idleFunc ~cb:(Nějaký Nadbytek.postRedisplay); Nadbytek.mainLoop ()
Vazby LablGL na OpenGL jsou povinné. Program lze poté zkompilovat do bytecode s:
$ ocamlc -I + lablGL lablglut.cma lablgl.cma simple.ml -o simple
nebo nativní kód pomocí:
$ ocamlopt -I + lablGL lablglut.cmxa lablgl.cmxa simple.ml -o jednoduché
nebo jednodušeji pomocí příkazu ocamlfind build
$ ocamlfind opt simple.ml -balíček lablgl.glut -linkpkg -o jednoduchý
a spustit:
$ ./simple
V OCamlu lze vyvíjet mnohem propracovanější, vysoce výkonné 2D a 3D grafické programy. Díky použití OpenGL a OCaml mohou být výsledné programy multiplatformní a kompilace beze změn na mnoha hlavních platformách.
Fibonacciho sekvence
Následující kód vypočítá Fibonacciho sekvence čísla n zadáno. Využívá to rekurze ocasu a porovnávání vzorů.
nechat fib n = nechat rec fib_aux m A b = zápas m s | 0 -> A | _ -> fib_aux (m - 1) b (A + b) v fib_aux n 0 1
Funkce vyššího řádu
Ve výsledku mohou funkce brát funkce jako funkce vstupu a návratu. Například přihlášením dvakrát na funkci F poskytuje funkci, která platí F dvakrát na jeho argument.
nechat dvakrát (F : 'A -> 'A) = zábava (X : 'A) -> F (F X);;nechat vč (X : int) : int = X + 1;;nechat přidat2 = dvakrát vč;;nechat inc_str (X : tětiva) : tětiva = X ^ " " ^ X;;nechat add_str = dvakrát(inc_str);;
# přidat2 98;; - : int = 100 # add_str "Test";; - : tětiva = „Test Test Test Test“
Funkce dvakrát používá proměnnou typu 'A k označení, že jej lze použít na jakoukoli funkci F mapování z typu 'A pro sebe, spíše než jen pro sebe int-> int funkce. Zejména, dvakrát lze dokonce aplikovat na sebe.
# nechat čtyřikrát F = (dvakrát dvakrát) F;; val čtyřikrát : ('A -> 'A) -> 'A -> 'A = <zábava> # nechat přidat4 = čtyřikrát vč;; val přidat4 : int -> int = <zábava> # přidat4 98;; - : int = 102
Odvozené jazyky
MetaOCaml
MetaOCaml[8] je vícestupňové programování rozšíření OCaml umožňující přírůstkové kompilace nových strojový kód za běhu. Za určitých okolností je možné pomocí vícestupňového programování dosáhnout značných zrychlení, protože podrobnější informace o datech ke zpracování jsou k dispozici za běhu než v běžném čase kompilace, takže přírůstkový kompilátor může optimalizovat mnoho případů kontroly stavu atd.
Jako příklad: pokud je v době kompilace známo, že některé funkce napájení X -> X^n
je často potřeba, ale hodnota n
je známo pouze za běhu, lze v MetaOCamlu použít dvoustupňovou funkci napájení:
nechat rec Napájení n X = -li n = 0 pak .<1>. jiný -li dokonce n pak čtv (Napájení (n/2) X) jiný .<.~X *. .~(Napájení (n - 1) X)>.
Jakmile n
je známo za běhu, lze vytvořit specializovanou a velmi rychlou funkci napájení:
.<zábava X -> .~(Napájení 5 .<X>.)>.
Výsledek je:
zábava x_1 -> (x_1 * nechat y_3 = nechat y_2 = (x_1 * 1) v (y_2 * y_2) v (y_3 * y_3))
Nová funkce je automaticky kompilována.
Jiné odvozené jazyky
- AtomCaml poskytuje synchronizační primitiv pro atomové (transakční) provádění kódu.
- Emily (2006) je podmnožinou OCaml 3.08, která k vynucování používá ověřovací pravidlo návrhu model objektové schopnosti bezpečnostní zásady.
- F# je .NET Framework jazyk založený na OCaml.
- Čerstvý OCaml usnadňuje manipulaci se jmény a pořadači.
- GCaml přidává do OCaml rozšiřující polymorfismus, což umožňuje přetížení a bezpečné zařazení typu.
- JoCaml integruje konstrukce pro vývoj souběžných a distribuovaných programů.
- OCamlDuce rozšiřuje OCaml o funkce, jako jsou výrazy XML a typy regulárních výrazů.
- OCamlP3l je paralelní programování systém založený na OCaml a jazyce P3L.
- I když to není opravdu samostatný jazyk, Důvod je alternativní OCaml syntax a řetězec nástrojů pro OCaml vytvořen v Facebook.
Software napsaný v OCaml
- 0 nainstalovat, multiplatformový správce balíčků.
- Coccinelle, nástroj pro transformující se the zdrojový kód z C programy.
- Coq, a formální důkaz systém řízení.
- FFTW, a knihovna pro výpočet diskrétní Fourierovy transformace. Programem OCaml s názvem bylo vygenerováno několik rutin C.
genfft
. - Webová verze Facebook Messenger.[9]
- Flow, a statický analyzátor vytvořeno v Facebook který vyvozuje a kontroluje statické typy pro JavaScript.[10]
- Owl Scientific Computing, vyhrazený systém pro vědecké a technické výpočty.
- Frama-C, rámec pro analýzu programů C.
- GeneWeb, bezplatný a open-source multiplatformní genealogický software.
- The Zaseknout překladač programovacího jazyka, vytvořený na Facebooku, rozšíření PHP se statickými typy.
- The Haxe překladač programovacího jazyka.
- HOL Light, asistent formálního důkazu.
- Infer, statický analyzátor vytvořený na Facebooku pro Jáva, C, C ++, a Cíl-C, slouží k detekci chyb ve Windows iOS a Android aplikace.[11]
- Lexifi Apropos, systém pro modelování komplexních derivátů.
- MirageOS, a unikernel programovací rámec napsaný v čistém OCaml.
- MLdonkey, a peer-to-peer Sdílení souborů aplikace založená na Síť EDonkey.
- Ocsigen, OCaml webový rámec.
- Opa, bezplatný a otevřený programovací jazyk pro vývoj webových aplikací.
- kontrola hranice, kontrola typu pro Krajta vytvořeno na Facebooku.[12]
- Tezos, samočinně se měnící inteligentní smluvní platforma používající XTZ jako nativní měnu
- Unisono, a synchronizace souborů program pro synchronizaci souborů mezi dvěma adresáři.
- Referenční tlumočník pro WebAssembly, nízká úroveň bytecode určeno k provedení uvnitř internetové prohlížeče.[13]
- Cloudová platforma Xen (XCP), a na klíč virtualizace řešení pro Xen hypervisor.
Uživatelé
Několik desítek společností používá OCaml do určité míry.[14] Pozoruhodné příklady zahrnují:
- Bloomberg L.P., který vytvořil BuckleScript, backend kompilátoru OCaml zaměřený na JavaScript.[15]
- Systémy Citrix, který používá OCaml v XenServer (během roku 2018 přejmenována na Citrix Hypervisor).
- Facebook, který vyvinul Flow, Hack, Infer, Pfff a Reason v OCaml.
- Jane Street Capital, a proprietární obchodování firma, která v počátcích přijala OCaml jako svůj preferovaný jazyk.[16]
- MEDIT, Francie, používá OCaml pro bioformatiku.[17]
Reference
- ^ "Moduly". Citováno 22. února 2020.
- ^ „Vydání - OCaml“. ocaml.org.
- ^ „A History of OCaml“. Citováno 24. prosince 2016.
- ^ Linux Weekly News.
- ^ „ocaml / asmcomp u kufru · ocaml / ocaml · GitHub“. GitHub. Citováno 2. května 2015.
- ^ „Archivy seznamu adresátů Caml> Zpráva od Xaviera Leroye“. Citováno 2. května 2015.
- ^ https://caml.inria.fr/pub/docs/manual-ocaml/comp.html
- ^ oleg-at-okmij.org. „BER MetaOCaml“. okmij.org.
- ^ „Messenger.com nyní 50% převedeno na Důvod · Důvod“. reasonml.github.io. Citováno 2018-02-27.
- ^ „Tok: Kontrola statického typu pro JavaScript“. Tok.
- ^ „Infer static analyzer“. Usoudit.
- ^ „GitHub - facebook / pyre-check: Performant type-check for python“. 9. února 2019 - prostřednictvím GitHub.
- ^ "Specifikace WebAssembly, referenční tlumočník a testovací sada: WebAssembly / spec". 10. února 2019 - prostřednictvím GitHub.
- ^ „Společnosti využívající OCaml“. OCaml.org. Citováno 17. srpna 2014.
- ^ „BuckleScript: Vydání 1.0 přišlo! | Tech v Bloomberg“. Tech ve společnosti Bloomberg. 8. září 2016. Citováno 21. května 2017.
- ^ Yaron Minsky (1. listopadu 2011). „OCaml pro masy“. Citováno 2. května 2015.
- ^ https://ocaml.org/learn/companies.html