close

Klovni

Siirry navigointiin Siirry hakuun
klovni
Clojure logo.svg
Kehittäjä(t)
Richard Hickey
https://clojure.org/
Yleistä tietoa
Yleiset laajennukset clj, cljs, cljc, edn ja cljr
Paradigma Toiminnallinen , moniparadigma ohjelmointikieli
Esiintyi 2007
Suunnitellut Rikas Hickey
Uusin vakaa versio (22-03-2022)
tyyppinen järjestelmä dynaaminen , vahva
Toteutukset JVM , CLR , JavaScript
vaikuttanut Lisp , ML , Haskell , Erlang Prolog
Käyttöjärjestelmä Monialustainen
Lisenssi Eclipse julkinen lisenssi

Clojure on Lispin yleiskäyttöinen ohjelmointikielen murre . Siinä korostetaan erityisesti toiminnallista paradigmaa, jonka tavoitteena on (muun muassa) poistaa samanaikaiseen ohjelmointiin liittyvä monimutkaisuus . Clojurea voidaan käyttää Java Virtual Machinen ja .NET - alustan virtuaalikoneen päällä sekä kääntää JavaScriptiin .

Periaatteet

Rich Hickey kuvailee Clojuren kehitystä etsimään kieltä, jota hän ei löytänyt: oletusarvoisesti toimiva lisp , joka on rakennettu vankalle ympäristölle oman alustansa sijaan ja rinnakkainen ohjelmointi mielessä. [ 1 ]

Samoin olioorientaatio hylätään periaatteessa, ja se tarjoaa lähestymistavan, jossa ohjelmat ilmaistaan ​​funktioiden soveltamisena dataan, eikä datan esitystä ja käyttäytymistä sekoittavien muuttuvien entiteettien vuorovaikutuksena. Toisaalta ominaisuudet, kuten instantiability, polymorfismi ja rajapinnat, ovat tehokkaasti osa kieltä.

Syntaksi

Kuten muunkin Lisp-perheen, Clojuren syntaksi on rakennettu symbolisille lausekkeille, jotka lukija muuntaa tietorakenteiksi ennen kääntämistä. Lausekkeille on tunnusomaista se, että ne on rajattu suluilla ja niiden etuliitemerkinnöillä, joilla kunkin listan ensimmäistä jäsentä kutsutaan funktiona ja ohittaa muut jäsenet argumentteina.

Tämä erikoisuus, joka on outo niille, jotka ovat tottuneet suosituimpiin C-ohjelmointikielen syntaksiin perustuviin kieliin, on sen joustavuuden perusta. Tietorakenteilla, kuten kartoilla , joukoilla ja vektoreilla , on kirjaimellinen lauseke; ne eivät vaadi mitään muunnoksia, kun ne sisällytetään kääntäjän luomaan syntaksipuuhun. Clojure on Lisp-1 , eikä sitä ole erityisesti suunniteltu yhteensopivaksi muiden lisppien kanssa .

Makro

Makro on koodinpätkä , joka hyväksyy muut lausekkeet argumenteiksi arvioimatta niitä ja muuntaa niitä ennen niiden arviointia. Tämä mahdollistaa "ohjelmia luovien ohjelmien" syntymisen: lisäykset kieleen - virtauksen ohjausrakenteet - tai verkkoaluekohtaisen kielen luominen . Mahdollisuudet, joita ei periaatteessa saavuteta muissa kieliperheissä ilman kääntäjän kehittämistä .

Clojuren makrojärjestelmä on hyvin samanlainen kuin Common Lisp :n sillä poikkeuksella, että Clojuren versio takalainauksesta (kutsutaan "syntaktiseksi lainaukseksi") luokittelee symbolit sen nimiavaruuden kanssa, johon ne kuuluvat. Tämä auttaa estämään tahattoman sieppauksen, koska nimen mukaiset sidokset ovat kiellettyjä. On mahdollista pakottaa ne kaappaavan makron laajentaminen, mutta se on tehtävä nimenomaisesti. Clojure kieltää myös globaalien nimien uudelleensidontamisen muissa nimiavaruuksissa, jotka on tuotu nykyiseen nimiavaruuteen.

Toinen syntaktisen lainauksen ominaisuus on, että se mahdollistaa mallijärjestelmän , jossa voit määrittää, mitkä listan jäsenet tulee arvioida käyttämällä unquote (~)- ja unquote-splice (~@) -operaattoreita, mikä johtaa tiiviimpiin makroihin ja hallittavissa.

Kieliominaisuudet

  • Dynaaminen kehitys arviointikonsolilla ( REPL: read eval print loop ).
  • Funktioiden esittäminen arvoina sekä rekursion ja korkeamman asteen funktioiden käyttö sivuvaikutuksiin perustuvan iteroinnin sijaan .
  • Mielivaltaiset tarkkuusluvut ja murtolukujen kirjaimellinen esitys, joka on luotu ei-kokonaislukujakoilla.
  • Sekvenssit laiskalla arvioinnilla (jonon elementtejä ei lasketa ennen kuin niitä tarvitaan, mikä mahdollistaa potentiaalisesti äärettömien joukkojen esittämisen).
  • Integroitu järjestelmä pysyvistä ja muuttumattomista tietorakenteista.
  • Valtion valvonta (arvot, jotka kokonaisuus voi hankkia ajan myötä) samanaikaisissa tilanteissa tapahtumajärjestelmien, agenttien ja paikallisten sidosten kautta .
  • Vuorovaikutus javan kanssa : Kääntämällä JVM - tavukoodiin Clojurella kirjoitetut sovellukset voidaan helposti integroida sovelluspalvelimiin tai muihin Java-ympäristöihin ilman muuta monimutkaisuutta. Kaikki mahdolliset liitännät luokka-, tietorakenne- ja samanaikaisuustasolla on toteutettu oletusarvoisesti tämän siirrettävyyden saavuttamiseksi tarvittavien ponnistelujen minimoimiseksi.

Esimerkkejä

Hei maailma . Huomaa, että REPL:n luonteen vuoksi tulostuskomentoa ei tarvita .

"Hei maailma!"

Ainutlaatuinen ja peräkkäisten numeroiden generaattori, joka tukee samanaikaisia ​​puheluita:

( anna  [i  ( atom  0 ) ] 
  ( defn genero  -unique-id 
    "Palauttaa eri numeerisen tunnisteen jokaiselle puhelulle." 
    [] 
    ( swap!  i  inc )))

Sen anonyymi alaluokka, java.io.Writerjoka ei kirjoita minnekään, ja makro, joka käyttää sitä hiljentämään kaikki sillä arvioidut lausekkeet.

( def  bit-bucket-writer 
  ( välityspalvelin  [java.io.Writer]  [] 
    ( kirjoittaa  [buf]  nolla ) 
    ( sulje  []     nolla ) 
    ( huuhtele  []     nolla )))

( defmacro  noprint 
  "Arvioi annetun lausekkeen kaikkien tulosteiden ollessa *out* mykistettynä."   
  [&  lomakkeet] 
  ` ( sitova  [*out*  bit-bucket-writer] 
     ~@forms ))

( noprint 
 ( println  "Hei, ei kukaan!" ))

Tässä esimerkissä kymmenen säiettä käsittelee jaettua tietorakennetta, joka koostuu sadasta vektorista, jotka sisältävät kymmenen peräkkäistä uniikkia aloitusnumeroa. Jokainen säie valitsee kaksi satunnaista paikkaa kahdessa satunnaisvektorissa ja vaihtaa ne. Kaikki vektorien muutokset tehdään tapahtumien sisällä käyttämällä Clojuren ohjelmiston tapahtumamuistijärjestelmää . Siksi edes tuhannen iteroinnin jälkeen mikään numero ei häviä.

( defn  run  [nvecs  nitems  nthreads  niters] 
  ( anna  [vec- refs  ( vec  ( map  ( comp  ref  vec ) 
                           ( osio  nitems  ( alue  ( *  nvecs  nitems ))))) 
        swap  #( anna  [v1  ( rand-int  nvecs ) 
                    v2  ( rand-int  nvecs ) 
                    i1  ( rand-int  nitems ) 
                    i2  ( rand-int  nitems ) ] 
                ( dosync 
                 ( anna  [temp  ( nth  @ ( vec- refs  v1 )  i1 ) ] 
                   ( alter  ( vec-refs  v1 )  assoc  i1  ( nth  @ ( vec-refs  v2 )  i2 )) 
                   ( alter  ( vec-refs  v2 )  assoc  i2  temp )))) 
        raportti  #( do 
                 ( prn  ( map  deref  vec- refs )) 
                 ( println  "Erillinen:" 
                          ( count  ( different ( käytä concat ( map deref  vec- refs )))))) ] ( report ) ( dorun ( käytä pcalls ( toista n säiettä #( dotimes [_ niters] ( swap ))))) ( raportti )))    
    
            
    

( ajaa  100  10  10  100 000 )

Edellisen esimerkin tulos:

( [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  999 :) 
100tinct  ]
 
( [ 382  318  466  963  619  22  21  273  45  596]  [ 808 639  804  471  394  904  952  75  289  778  ]  ... [ 
 484  216  622  139  75  20  20 3 2 8 2 5 9  139 139  
 

Bibliografia

Ulkoiset linkit

Viitteet

  1. ^ "Perusperiaatteet" . Rich Hickey (englanniksi) . Haettu 17.10.2008 tällä ei ole paradigmaa .