Clean
Clean és un llenguatge de programació funcional pur, de semàntica no estricta (avaluació tardana: les expressions s'avaluen només quan se'n demana el valor), desenvolupat a la universitat Radboud[1] de Nimega, Països Baixos. DescripcióClean és un dels llenguatges de programació funcional que més optimitza la velocitat i l'espai.[2] Clean admet l'avaluació estricta (primerenca) ocasionalment per optimitzar l'execució, mitjançant anotacions específiques d'estrictesa (avaluació primerenca) i allotjament directe. Disposa de tipus d'unicitat per modelar els efectes laterals. Els treballs en el llenguatge Clean van començar[3] el 1984, com a part del projecte "parallel reduction machine". La primera versió es va posar en marxa el 1987 Va tenir una gran influència en Haskell, que més tard va influenciar Clean. Programa Hola MónAvaluació d'expressions a partir de la funció principal Start
/*
fitxer prova.icl
*/
module prova
import StdEnv
Start:: String
Start = "Hola Món!"
/* Alternativa en ''mode World'',
caldrà individualitzar les variables que comporten estat (ex.: world, console)
*/
Start:: *World -> *World
Start world1 = world3
where
(console1, world2) = stdio world1 // ''stdio'' obre consola per llegir i escriure<ref>[http://clean.cs.ru.nl/Download/Download_Libraries/Std_Env/StdFile/stdfile.html StdFile - stdio obre la cònsola per llegir i escriure]</ref>
console2 = fwrites "Hola món!\n" console1 // escriu
(ok, world3) = fclose console2 world2 // tanca
/* Equivalent a l'anterior amb clàusules # ''let-before''
i àmbits de visibilitat de variables inclosos successivament
* els àmbits de visibilitat taparan les variables anteriors
del mateix nom corresponents a estats anteriors
*/
Start:: *World -> *World
Start world
# (console, world) = stdio world // obre consola stdio; àmbit més extern
# console = fwrites "Hola món!\n" console // àmbit intermedi
# (ok, world)= fclose console world // àmbit més intern
= world // crida al darrer ''world'',
A l'entorn LinuxDesempaquetar el paquet de codi nadiu, llegir README, i fer make, que instal·la al directori actual CLEAN_HOME=/camí/al/vostre/clean
export PATH=$CLEAN_HOME/bin:$PATH
export CLEANPATH=$CLEAN_HOME/lib/stdenv
# cd al dir. de prova.icl
clm prova -o prova
./prova
dona la sortida "Hola Món!" Execution: 0.00 Garbage collection: 0.00 Total: 0.00 A l'entorn WindowsClean porta un entorn de desenvolupament IDE propi per a Windows no suportat inicialment per al Linux. No porta instal·lador. Desempaquetes a la carpeta escollida i executes el CleanIDE.exe CaracterístiquesSintaxiblocs delimitats pel sagnat (marge esquerre de les línies d'instruccions) Comentaris// comentari fins a fi de línia /* comentari multi-línia /* comentari niuat */ */ TipusTipus bàsicsBool[4] ops: not == && || Int[5] ops: == < Real[6] Char[7] Atributs: Unicitat en el tipusVegeu al manual el capítol Uniqueness typing. Un tipus amb exigència d'unicitat (*Tipus) admet només referències úniques (una sola còpia) a estructures, a fi i efecte d'assegurar que no s'estigui accedint a l'estructura des d'un altre fil d'execució, i poder fer actualitzacions destructives in situ amb seguretat. *Tipus // tipus amb atribut positiu d'unicitat (exigeix referència única)
únic <= no-únic // únic subtipus (més específic) de no-únic
v:Tipus // tipus amb variable d'atribut d'unicitat (pot avaluar a: únic / no-únic) // per a ser especificat en les clàusules de restriccions v <= w i w == únic implica v == únic v <= w i v == no-únic implica w == no-únic append :: v:[u:a] w:[u:a] -> x:[u:a], [v<=u, w<=u, x<=u, w<=x] // si els elem. a són únics, v, w i x també ho han de ser // w <= x expressa que la unicitat del resultat depèn només de la del segon paràmetre.
.Tipus // tipus amb variable d'atribut d'unicitat anònima // obviable perquè no intervé en les clàusules de restriccions
append :: [u:a] w:[u:a] -> x:[u:a], [w<=x]
append :: [.a] w:[.a] -> x:[.a], [w<=x] Altres atributs dels tipussegons prefix amb els símbols '#', '!', sense i '|' #Tipus // tipus unboxed (amb allotjament directe del valor) // altrament contindria un punter al descriptor del valor !Tipus // tipus amb avaluació estricta (primerenca) Tipus // sense les marques '!#': avaluació tardana (ang:lazy) |Tipus // overloaded: admet valors amb qualsevol atribut unboxed, estrictes o tardans (ang.:lazy) Tipus compostos:: ConstructorA Tipus_A Tipus_B .. // tipus producte :: ConstructorA Tipus_A Tipus_B .. | ConstructorB TipusC TipusD .. | .. // unió etiquetada (tipus suma) :: (Tipus_A, Tipus_B) // Tupla[8] :: { numerador :: Int, denominador :: Int } // Registre :: [Tipus] // Llista[9] :: {Tipus} // Vector (ang:Array)[10] :: [! Tipus ] // Llista amb avaluació estricta al cap :: [ Tipus !] // Llista amb avaluació estricta de la cua :: [! Tipus !] // Llista amb avaluació estricta al cap i a la cua lligams de tipus:: Complex // tipus abstracte // sinònim o àlies de tipus // :: nom :== expressió_de_tipus :: Complex :== (!Real, !Real) :: String :== {#Char} // vector de caràcters unboxed (amb allotjament directe) // definició de tipus (=) (amb variables de tipus, cas de minúscules) :: Llista a = Nil | Cons a (Llista a) // (recursiva en aquest cas) Enumeracions:: TDia = Dl | Dm | Dc | Dj | Dv | Ds | Dg ExpressionsMacros (:==)Substitució de codi Negre :== 1 Blanc :== 0 (=:) a nivell globalExpressions constants (grafs en termes de Clean) a nivell global per a ser avaluades un sol cop. quad :: Int quad =: expressio * 4 (=>) a tots els nivells i (=) a nivell globalindica funció constant o en termes de Clean "regla de reescriure grafs" (ang.: rewrite rule) FuncionsEn termes de Clean les funcions són estratègies de reducció dels grafs. // la fletxa -> separa els paràmetres del resultat suma :: Int Int -> Int suma x y = x + y polimòrfiques // després de '|' hi ha els requeriments de context per a les variables de tipus suma_i_decrement :: a a -> a | +,- a // | requeriment que, en el context d'ús, // existeixi una instància visible de (+) i (-) per al tipus a suma_i_decrement x y = x + y - 1 aplica2cops :: (t -> t) t -> t aplica2cops f x = f (f x) Guardessign x | x < 0 = -1 | x == 0 = 0 | otherwise = 1 definicions localsestil declaratiu (ús abans de la definició, clàusula where) arrels a b c = [ (~b + s)/d , (~b - s)/d ] where s = sqrt (b*b - 4.0*a*c) d = 2.0*a estil imperatiu (definició abans de l'ús) amb àmbits successius (clàusula let ... in) arrels a b c = let s = sqrt (b*b - 4.0*a*c) d = 2.0*a in [ (~b + s)/d , (~b - s)/d ] clàusules let-beforeS'executen abans de l'encaix de patrons en les definicions de funcions. No permeten definir funcions internes. Vegeu #Programa Hola Món més amunt. # selector = expressió // amb #, "let-before" d'execució tardana (ang:lazy) #! selector = expressió // amb #!, "let-before" estricte (exec. primerenca) patronssuma_llista :: [Int] -> Int suma_llista [] = 0 suma_llista [cap : cua] = cap + suma_llista cua alternativescase expressió of patró | guarda = expressió patró | guarda = expressió if expressió expressió-then expressió-else funcions anònimesambdues formes valen \ arg1 arg2 argN -> expressió \ arg1 arg2 argN = expressió Def. d'operadors(!!) infixr 2 :: Bool Bool -> Bool (!!) True False = False (!!) True True = True (!!) False _ = False ExcepcionsEl manual no en parla. expr1 = [(x,y) \\ x <- (0..2), y <- (0..2) | x >= y] // torna [(0,0), (1,0), (1,1), (2,0), (2,1), (2,2)] expr2 = [(x,y) \\ x <- (0..3) & y <- (0..2)] // torna [(0,0), (1,1), (2,2)] Classes de tipusclass Arith a where (+) infixl 6 :: a a -> a (-) infixl 6 :: a a -> a // versions d'operadors sobrecarregats (+) (-) en termes d'operadors específics del tipus instance Arith Int where (+) :: Int Int -> Int (+) x y = x +^ y (-) :: Int Int -> Int (-) x y = x -^ y instance Arith Real where (+) x y = x +. y (-) x y = x -. y amb operacions derivadesclass Eq a where (==) infix 2 :: a a -> Bool // desigual (<>) infix 2 :: a a -> Bool | Eq a // `|` introdueix el requeriment de context (<>) x y :== not (x == y) // :== (definició com a macro) exportant tipusal fitxer d'interfície (.dcl) amb la clàusula definition module definition module example class Eq a where (==) infix 2 :: a a -> Bool // special genera versions especialitzades d'operacions sobrecarregades per millorar-ne el rendiment instance Eq [a] | Eq a // `|` introdueix requeriments de context, cal una instància visible de Eq // per al tipus que prengui `a` en el context d'ús de les operacions de (Eq [a]). special a = Int // genera codi especialitzat (no genèric) per als tipus que s'esmenten a = Real instance Eq a Mòdulsd'implementacióamb extensió ".icl" [implementation] module nom_del_mòdul where ... import StdEnv, ... ... d'interfícieamb extensió ".dcl" Cal copiar-hi les declaracions de tipus de la implementació que vulguem exportar definition module nom_del_mòdul where especificacions exportades BibliotequesBiblioteca estàndard i altres[11] Einesextensions dels fitxers
Vegeu tambéReferències
Enllaços externs
|
Portal di Ensiklopedia Dunia