Klovn
| klovn | ||
|---|---|---|
|
| ||
| Udvikler(e) | ||
|
Richard Hickey https://clojure.org/ | ||
| Generel information | ||
| Almindelige udvidelser | clj, cljs, cljc, edn og cljr | |
| Paradigme | Funktionelt , multiparadigme programmeringssprog | |
| Dukkede op i | 2007 | |
| Designet af | Rich Hickey | |
| Seneste stabile version | (22-03-2022) | |
| type system | dynamisk , stærk | |
| implementeringer | JVM , CLR , JavaScript | |
| påvirket af | Lisp , ML , Haskell , Erlang Prolog | |
| Operativ system | Multi platform | |
| Licens | Eclipse Public License | |
Clojure er en almindelig programmeringssprogdialekt af Lisp . Det lægger særlig vægt på det funktionelle paradigme med det mål (blandt andre) at fjerne kompleksiteten forbundet med samtidig programmering . Clojure kan køres oven på Java Virtual Machine og .NET platformen virtuelle maskine , samt kompileres til JavaScript .
Principper
Rich Hickey beskriver udviklingen af Clojure som at søge efter et sprog, han ikke kunne finde: en fungerende lisp som standard, bygget oven på et robust miljø i stedet for sin egen platform, og med samtidig programmering i tankerne. [ 1 ]
Ligeledes afvises objektorientering i princippet, hvilket tilbyder en tilgang, hvor programmer udtrykkes som anvendelsen af funktioner på data, snarere end som interaktionen mellem foranderlige entiteter, der blander datarepræsentation og adfærd. På den anden side er funktioner som instantiabilitet, polymorfi og grænseflader effektivt en del af sproget.
Syntaks
Som resten af Lisp-familien er Clojures syntaks bygget på symbolske udtryk, der konverteres til datastrukturer af en læser, inden de kompileres. Udtryk er kendetegnet ved at være afgrænset af parenteser og ved at deres præfiksnotation, hvorved det første medlem af hver liste kaldes som en funktion, videregiver resten af medlemmerne som argumenter.
Denne ejendommelighed, mærkelig for dem, der er vant til de mest populære sprog baseret på C-programmeringssprogets syntaks, er grundlaget for dets fleksibilitet. Datastrukturer såsom kort , sæt og vektorer har et bogstaveligt udtryk; de kræver ingen transformation, når de inkorporeres i syntakstræet, der genereres af compileren. Clojure er en Lisp-1 og er ikke specielt designet til at være kompatibel med andre lisps .
Makro
En makro er et stykke kode, der accepterer andre udtryk som argumenter, uden at evaluere dem, transformere dem, før de evalueres. Dette giver mulighed for fremkomsten af "programmer, der skaber programmer": tilføjelser til sprog-flow-kontrolstrukturerne - eller oprettelse af et domænespecifikt sprog . Muligheder i princippet ikke opnåelige i andre sprogfamilier uden at ty til udviklingen af en compiler .
Clojures makrosystem minder meget om Common Lisp 's med den undtagelse, at Clojures version af backquote (kaldet et "syntaktisk citat") kvalificerer symboler med det navneområde, som de tilhører. Dette hjælper med at forhindre utilsigtet indfangning, da navnekvalificerede bindinger er forbudt. Det er muligt at tvinge udvidelsen af en makro, der fanger dem, men det skal gøres eksplicit. Clojure forbyder også genbinding af globale navne i andre navneområder, der er blevet importeret til det nuværende.
Et andet træk ved det syntaktiske citat er, at det giver mulighed for et skabelonsystem , hvor du kan angive, hvilke medlemmer af en liste, der skal evalueres ved hjælp af operatorerne unquote (~) og unquote-splice (~@), hvilket fører til mere præcise makroer og overskuelig.
Sprogfunktioner
- Dynamisk udvikling med en evalueringskonsol ( REPL: read eval print loop ).
- Repræsentation af funktioner som værdier og en præference for rekursion og brug af højere ordens funktioner frem for iteration baseret på bivirkninger .
- Vilkårlige præcisionstal og bogstavelig repræsentation af brøker, genereret på ikke-heltals divisioner.
- Sekvenser med doven evaluering (elementerne i sekvensen beregnes ikke, før de er nødvendige, hvilket gør det muligt at repræsentere potentielt uendelige sæt).
- Integreret system af vedvarende og uforanderlige datastrukturer.
- Statskontrol (sæt af værdier, som en enhed kan erhverve over tid) i samtidige situationer gennem transaktionssystemer, agenter og gennem lokale bindinger .
- Interaktion med java : Ved at blive kompileret til JVM bytecode kan applikationer skrevet i Clojure nemt integreres i applikationsservere eller andre Java-miljøer med lidt ekstra kompleksitet. Alle mulige grænseflader på klasse-, datastruktur- og samtidighedsniveau er implementeret som standard for at minimere den indsats, der kræves for at opnå denne portabilitet.
Eksempler
Hej verden . Bemærk, at på grund af REPL'ens natur er en printkommando ikke nødvendig .
"Hej Verden!"
En unik og fortløbende nummergenerator, der understøtter samtidige opkald:
( lad [i ( atom 0 ) ]
( defn generere-unik-id
"Returnerer en anden numerisk identifikator for hvert opkald."
[]
( swap! i inc )))
En anonym underklasse af java.io.Writerdet skriver ingen steder, og en makro der bruger den til at dæmpe alle udtryk, der evalueres med den.
( def bit-bucket-writer
( proxy [java.io.Writer] []
( skriv [buf] nil )
( luk [] nil )
( flush [] nil )))
( defmacro noprint
"Evaluerer det givne udtryk med alle udskrifter til *ud* dæmpet."
[& formularer]
` ( binding [*out* bit-bucket-writer]
~@forms ))
( noprint
( println "Hej, ingen!" ))
I dette eksempel manipulerer ti tråde en delt datastruktur, som består af hundrede vektorer, der indeholder ti sekventielle start-uniktal. Hver tråd vælger to tilfældige positioner i to tilfældige vektorer og bytter dem. Alle ændringer af vektorer udføres inden for transaktioner ved hjælp af Clojures software transaktionshukommelsessystem . Det er derfor, selv efter tusinde iterationer, går intet tal tabt.
( defn run [nvecs nitems nthreads niters]
( lad [vec-refs ( vec ( map ( comp ref vec ))
( partition nitems ( range ( * nvecs nitems )))))
bytte #( lad [v1 ( rand-int nvecs )
v2 ( rand-int nvecs )
i1 ( rand-int nitems )
i2 ( rand-int nitems ) ]
( dosync
( lad [temp ( nth @ ( vec-refs v1 ) i1 ) ]
( alter ( vec-refs v1 ) assoc i1 ( nth @ ( vec-refs v2 ) i2 ))
( alter ( vec-refs v2 ) assoc i2 temp ))))
report #( do
( prn ( map deref vec-refs ))
( println "Distinct:"
( count ( distinct ( anvend concat ( map deref vec-refs )))))) ]
( rapport )
( dorun ( anvend pcalls ( gentag nthreads #( dotimes [_ niters] ( swap )))))
( rapport )))
( kør 100 10 10 100000 )
Output fra det foregående eksempel:
( [0 1 2 3 4 5 6 7 8 9] [10 11 12 13 14 15 16 17 18 19] ...
[990 991 992 993 994 995 996 997 998 909 :)
1 Distinct
( [382 318 466 963 619 22 21 273 45 596] [808 639 804 471 394 904 952 75 289 778] ... [
484 216 622 152 139 2c : 52 52 152 139 139 239 139 2
Bibliografi
- Halloway, Stuart (28. maj 2009), Programmering Clojure (1. udgave), Pragmatic Bookshelf , s. 304 , ISBN 1934356336 .
- VanderHart, Luke (31. december 2009), Practical Clojure (1. udgave), Apress , s. 350, ISBN 1430272317 , arkiveret fra originalen 2010-09-17 , hentet 2010-02-10 .
- Rathore, Amit (december 2009), Clojure in Action (1. udgave), Manning , s. 475, ISBN 9781935182597 .
- Fogus, Michael; Houser, Chris (januar 2010), The Joy of Clojure (1. udgave), Manning , s. 300, ISBN 9781935182641 .
Eksterne links
- Clojure hovedside
- Clojure kodelager på GitHub
- En oversigt over Clojure
- video tutorials
- clojuredocs.org - Fællesskabsdrevet dokumentation og eksempler
- clojure-doc.org - Fællesskabsdrevet dokumentationsside for programmeringssproget Clojure
Referencer
- ^ "Grundlæggende principper" . Rich Hickey (på engelsk) . Hentet 2008-10-17 dette har intet paradigme .