Úvod do Clojure

1. Úvod

Clojure je funkčný programovací jazyk, ktorý beží výlučne na Java Virtual Machine, podobným spôsobom ako Scala a Kotlin. Clojure sa považuje za derivát Lisp a bude známy každému, kto má skúsenosti s inými jazykmi Lisp.

Tento výukový program predstavuje úvod do jazyka Clojure, základné informácie o tom, ako s ním začať a niektoré kľúčové koncepty fungovania.

2. Inštalácia Clojure

Clojure je k dispozícii ako inštalačné programy a pohodlné skripty na použitie v systémoch Linux a macOS. V tejto fáze, bohužiaľ, Windows taký inštalátor nemá.

Linuxové skripty však môžu fungovať v niečom ako Cygwin alebo Windows Bash. K dispozícii je tiež online služba, ktorú je možné použiť na vyskúšanie jazykaa staršie verzie majú samostatnú verziu, ktorú je možné použiť.

2.1. Samostatné stiahnutie

Samostatný súbor JAR je možné stiahnuť z Maven Central. Verzie novšie ako 1.8.0 už, bohužiaľ, takto nefungujú ľahko, pretože súbor JAR bol rozdelený na menšie moduly.

Po stiahnutí tohto súboru JAR ho môžeme použiť ako interaktívny dokument REPL jednoducho tak, že ho považujeme za spustiteľný súbor JAR:

$ java -jar clojure-1.8.0.jar Clojure 1.8.0 užívateľ =>

2.2. Webové rozhranie pre REPL

Webové rozhranie k Clojure REPL je k dispozícii na //repl.it/languages/clojure, kde si ho môžeme vyskúšať bez toho, aby ste si museli niečo sťahovať. V súčasnosti to podporuje iba Clojure 1.8.0 a nie novšie vydania.

2.3. Inštalátor v systéme MacOS

Ak používate macOS a máte nainštalovaný Homebrew, môžete si najnovšie vydanie Clojure nainštalovať jednoducho:

$ brew nainštalovať clojure

Toto bude podporovať najnovšiu verziu Clojure - 1.10.0 v čase písania článku. Po nainštalovaní môžeme REPL načítať jednoducho pomocou clojure alebo clj príkazy:

$ clj Clojure 1.10.0 užívateľ =>

2.4. Inštalátor v systéme Linux

Na inštaláciu nástrojov v systéme Linux je k dispozícii samoinštalačný shell skript:

$ curl -O //download.clojure.org/install/linux-install-1.10.0.411.sh $ chmod + x linux-install-1.10.0.411.sh $ sudo ./linux-install-1.10.0.411.sh

Rovnako ako inštalačný program pre macOS, aj tieto budú k dispozícii pre najnovšie vydania Clojure a dajú sa spustiť pomocou clojure alebo clj príkazy.

3. Úvod do Clojure REPL

Všetky vyššie uvedené možnosti nám umožňujú prístup k Clojure REPL. Toto je priamy ekvivalent Clojure nástroja JShell pre Java 9 a vyššie a umožňuje nám zadať kód Clojure a okamžite vidieť výsledok. Jedná sa o fantastický spôsob experimentovania a zistenia, ako fungujú určité jazykové funkcie.

Po načítaní REPL sa zobrazí výzva, v ktorej je možné zadať a okamžite vykonať akýkoľvek štandardný kód Clojure. Patria sem jednoduché konštrukcie Clojure, ako aj interakcia s inými knižnicami Java - na načítanie však musia byť k dispozícii na ceste triedy.

Výzva REPL je údajom o súčasnom mennom priestore, v ktorom pracujeme. Pre väčšinu našej práce je to používateľ menný priestor, a výzva teda bude:

užívateľ =>

Všetko vo zvyšku tohto článku bude predpokladať, že máme prístup k Clojure REPL, a všetko bude fungovať priamo v ktoromkoľvek takomto nástroji.

4. Jazykové základy

Jazyk Clojure vyzerá veľmi odlišne od mnohých iných jazykov založených na JVM a na začiatku sa bude javiť ako veľmi neobvyklý. Považuje sa za dialekt Lispu a má veľmi podobnú syntax a funkčnosť ako iné jazyky Lisp.

Veľa kódu, ktorý napíšeme v Clojure, je rovnako ako v iných diapsoch Lispu vyjadrený vo forme Zoznamov.. Zoznamy možno potom vyhodnotiť, aby sa dosiahli výsledky - buď vo forme viacerých zoznamov, alebo jednoduchých hodnôt.

Napríklad:

(+ 1 2) ; = 3

Toto je zoznam pozostávajúci z troch prvkov. Symbol „+“ označuje, že uskutočňujeme toto volanie - pridanie. Zvyšné prvky sa potom použijú pri tomto volaní. Preto sa to hodnotí ako „1 + 2“.

Použitím syntaxe Zoznam tu je možné ju triviálne predĺžiť. Môžeme napríklad robiť:

(+ 1 2 3 4 5) ; = 15

Toto sa hodnotí ako „1 + 2 + 3 + 4 + 5“.

Všimnite si tiež bodkočiarku. Toto sa používa v Clojure na označenie komentára a nie je to koniec výrazu, ako by sme videli v Jave.

4.1. Jednoduché Typy

Clojure je postavený na vrchole JVM a ako taký máme prístup k rovnakým štandardným typom ako akákoľvek iná aplikácia Java.. Typy sú zvyčajne odvodené automaticky a nie je potrebné ich výslovne špecifikovať.

Napríklad:

123; Dlhý 1,23; Dvojité „Dobrý deň“; Reťazec pravdivý; Boolovský

Môžeme určiť aj niektoré komplikovanejšie typy pomocou špeciálnych predpôn alebo prípon:

42N; clojure.lang.BigInt 3,14159M; java.math.BigDecimal 1/3; clojure.lang.Ratio # "[A-Za-z] +"; java.util.regex.Vzor

Všimnite si, že clojure.lang.BigInt namiesto java.math.BigInteger. Je to preto, že typ Clojure obsahuje niektoré menšie optimalizácie a opravy.

4.2. Kľúčové slová a symboly

Clojure nám dáva koncept kľúčových slov aj symbolov. Kľúčové slová sa týkajú iba samých seba a často sa používajú napríklad na mapové kľúče. Symboly sú na druhej strane názvy, ktoré sa používajú na označenie iných vecí. Napríklad definície premenných a názvy funkcií sú symboly.

Kľúčové slová môžeme zostrojiť pomocou názvu s predponou dvojbodka:

user =>: kw: kw user =>: a: a

Kľúčové slová majú priamu rovnosť so sebou, a nie s ničím iným:

user => (=: a: a) true user => (=: a: b) false user => (=: a "a") false

Väčšina ostatných vecí v Clojure, ktoré nie sú jednoduchými hodnotami, sa považujú za symboly. Hodnotia sa bez ohľadu na to, na čo sa odvolávajú, keďže kľúčové slovo sa vždy vyhodnotí samo:

user => (def a 1) # 'user / a user =>: a: a user => a 1

4.3. Menné priestory

Jazyk Clojure má koncept menných priestorov na usporiadanie nášho kódu. Každá časť kódu, ktorú napíšeme, žije v mennom priestore.

Predvolene sa REPL spúšťa v používateľ menný priestor - ako je viditeľné vo výzve „user =>“.

Môžeme vytvárať a meniť menné priestory pomocou ns kľúčové slovo:

user => (ns new.ns) nil new.ns =>

Akonáhle sme zmenili menný priestor, všetko, čo je definované v starom, už pre nás nie je k dispozícii a všetko, čo je definované v novom, je už k dispozícii.

K definíciám v menných priestoroch môžeme získať ich úplnú kvalifikáciu. Napríklad menný priestor clojure.string definuje funkciu veľké písmená.

Ak sme v clojure.string menný priestor, môžeme k nemu získať priamy prístup. Ak nie sme, musíme to kvalifikovať ako clojure.reťazec / veľké písmená:

user => (clojure.string / veľké "hello") "HELLO" user => (veľké "hello"); Toto nie je viditeľné v syntaxovej chybe syntaxe „používateľa“ pri kompilácii o (REPL: 1: 1). Symbol nie je možné vyriešiť: veľké písmená v tomto kontexte user => (ns clojure.string) nil clojure.string => (veľké písmená „ahoj“); Je to viditeľné, pretože sme teraz v priestore názvov „clojure.string“ „AHOJ“.

Môžeme tiež použiť vyžadovaťkľúčové slovo ľahší prístup k definíciám z iného priestoru mien. Existujú dva hlavné spôsoby, ako to môžeme použiť - definovať menný priestor s kratším názvom, aby sa používal jednoduchšie, a priamy prístup k definíciám z iného menného priestoru bez akejkoľvek predvoľby:

clojure.string => (vyžadovať '[clojure.string: ako str]) nil clojure.string => (str / veľké písmená "Hello") "AHOJ" užívateľ => (vyžadovať' [clojure.string: ako str: odkázať [veľké písmená]]) žiadny používateľ => (veľké písmená „ahoj“) „AHOJ“

Oba tieto ovplyvňujú iba aktuálny priestor mien, takže zmena na iný bude musieť mať nový vyžaduje. To pomáha udržiavať naše menné priestory čistejšie a umožní nám prístup iba k tomu, čo potrebujeme.

4.4. Premenné

Keď vieme, ako definovať jednoduché hodnoty, môžeme ich priradiť k premenným. Môžeme to urobiť pomocou kľúčového slova def:

user => (def a 123) # 'user / a

Keď to urobíme, môžeme použiť symbol akdekoľvek chceme reprezentovať túto hodnotu:

užívateľ => a 123

Definície premenných môžu byť také jednoduché alebo také zložité, ako chceme.

Napríklad na definovanie premennej ako súčtu čísel môžeme urobiť:

user => (def b (+ 1 2 3 4 5)) # 'user / b user => b 15

Všimnite si, že nikdy nemusíme deklarovať premennú alebo označovať, o aký typ ide. To všetko pre nás automaticky určuje Clojure.

Ak sa pokúsime použiť premennú, ktorá nebola definovaná, namiesto toho sa zobrazí chyba:

user => unknown syntax error compiling at (REPL: 0: 0). Symbol nie je možné v tomto kontexte vyriešiť: user => (def c (+ 1 neznámy)) Syntaxová chyba sa kompiluje o (REPL: 1: 8). Symbol sa nepodarilo vyriešiť: v tejto súvislosti neznámy

Všimnite si, že výstup def funkcia vyzerá mierne odlišne od vstupu. Definovanie premennej a vráti reťazec „Používateľ / a. Je to preto, že výsledkom je symbol a tento symbol je definovaný v aktuálnom mennom priestore.

4.5. Funkcie

Pár príkladov, ako volať funkcie v Clojure, sme už videli. Vytvoríme zoznam, ktorý začína funkciou, ktorá sa má volať, a potom všetky parametre.

Keď sa tento zoznam vyhodnotí, dostaneme z funkcie návratovú hodnotu. Napríklad:

user => (java.time.Instant / now) #object [java.time.Instant 0x4b6690c0 "2019-01-15T07: 54: 01.516Z"] user => (java.time.Instant / parse "2019-01- 15T07: 55: 00Z ") #object [java.time.Instant 0x6b8d96d9" 2019-01-15T07: 55: 00Z "] user => (java.time.OffsetDateTime / z roku 2019 01 15 7 56 0 0 java.time. ZoneOffset / UTC) #object [java.time.OffsetDateTime 0xf80945f "2019-01-15T07: 56Z"]

Môžeme tiež vnoriť volania funkcií, pretože keď chceme odovzdať výstup jedného volania funkcie ako parameter do druhého:

user => (java.time.OffsetDateTime / z roku 2018 01 15 7 57 0 0 (java.time.ZoneOffset / ofHours -5)) #object [java.time.OffsetDateTime 0x1cdc4c27 "2018-01-15T07: 57-05: 00 "]

Tiež môžeme tiež definovať naše funkcie ak si prajeme. Funkcie sa vytvárajú pomocou fn príkaz:

user => (fn [a b] (println "Pridávanie čísel" a "a" b) (+ a b)) #object [používateľ $ eval165 $ fn__166 0x5644dc81 "[chránený e-mailom]"]

Bohužiaľ toto nedáva funkcii názov, ktorý je možné použiť. Namiesto toho môžeme definovať symbol, ktorý predstavuje túto funkciu pomocou def, presne tak, ako sme to videli pri premenných:

user => (def add (fn [a b] (println "Adding numbers" a "a" b) (+ a b))) # 'user / add

Teraz, keď sme definovali túto funkciu, môžeme ju nazvať rovnako ako ktorúkoľvek inú funkciu:

užívateľ => (pridať 1 2) Sčítanie čísel 1 a 2 3

Pre pohodlie Clojure nám tiež umožňuje používať defn definovať funkciu s menom naraz.

Napríklad:

user => (defn sub [a b] (println "Odčítanie" b "od" a) (- a b)) # 'user / sub user => (sub 5 2) Odčítanie 2 od 5 3

4.6. Dovolené a miestne premenné

The def volanie definuje symbol, ktorý je globálny pre aktuálny priestor mien. Spravidla to nie je to, čo je požadované pri vykonávaní kódu. Namiesto toho Clojure ponúka nechajme volanie na definovanie lokálnych premenných bloku. To je obzvlášť užitočné pri ich použití vo vnútri funkcií, kde nechcete, aby premenné unikali mimo funkcie.

Mohli by sme napríklad definovať našu čiastkovú funkciu:

user => (defn sub [a b] (def result (- a b)) (println "Result:" result) result) # 'user / sub

Jeho použitie má však nasledujúci neočakávaný vedľajší účinok:

užívateľ => (sub 1 2) Výsledok: -1 -1 užívateľ => výsledok; Stále viditeľné mimo funkcie -1

Namiesto toho to prepíšme pomocou nechajme:

user => (defn sub [ab] (let [result (- ab)] (println "Result:" result) result)) # 'user / sub user => (sub 1 2) Výsledok: -1 -1 user = > Výsledok Syntaxová chyba kompilácia o (REPL: 0: 0). Symbol sa nepodarilo vyriešiť: výsledok v tomto kontexte

Tentokrát výsledok symbol nie je viditeľný mimo funkcie. Alebo skutočne mimo EÚ nechajme blok, v ktorom bol použitý.

5. Zbierky

Doteraz sme väčšinou komunikovali s jednoduchými hodnotami. Videli sme tiež zoznamy, ale nič viac. Clojure má celú sadu zbierok, ktoré je možné použiť, pozostávajúce zo zoznamov, vektorov, máp a súborov:

  • Vektor je usporiadaný zoznam hodnôt - do vektora je možné vložiť ľubovoľnú hodnotu, vrátane ďalších kolekcií.
  • Sada je neusporiadaná kolekcia hodnôt a nikdy nemôže obsahovať rovnakú hodnotu viac ako raz.
  • Mapa je jednoduchá sada párov kľúč / hodnota. Je veľmi bežné používať kľúčové slová ako kľúče na mape, ale môžeme použiť akúkoľvek hodnotu, ktorá sa nám páči, vrátane iných zbierok.
  • Zoznam je veľmi podobný vektoru. Rozdiel je podobný ako medzi an ArrayList a a LinkedList v Jave. Typicky je uprednostňovaný vektor, ale zoznam je lepší, ak chceme pridávať prvky na začiatok, alebo ak chceme niekedy k prvkom pristupovať iba v postupnom poradí.

5.1. Budovanie zbierok

Vytvorenie každého z nich je možné vykonať pomocou skratkovej notácie alebo pomocou volania funkcie:

; Vektorový užívateľ => [1 2 3] [1 2 3] používateľ => (vektor 1 2 3) [1 2 3]; Zoznam používateľov => '(1 2 3) (1 2 3) používateľ => (zoznam 1 2 3) (1 2 3); Set user => # {1 2 3} # {1 3 2} user => (hash-set 1 2 3) # {1 3 2}; Map user => {: a 1: b 2} {: a 1,: b 2} user => (hash-map: a 1: b 2) {: b 2,: a 1}

Všimnite si, že Nastaviť a Mapa príklady nevracajú hodnoty v rovnakom poradí. Je to preto, lebo tieto kolekcie sú vo svojej podstate neusporiadané a to, čo vidíme, závisí od toho, ako sú reprezentované v pamäti.

Vidíme tiež, že syntax na vytvorenie zoznamu je veľmi podobná štandardnej syntaxi Clojure pre výrazy. Výraz Clojure je v skutočnosti zoznam, ktorý sa vyhodnotí, zatiaľ čo znak apostrofu tu naznačuje, že namiesto vyhodnotenia chceme skutočný zoznam hodnôt.

Môžeme samozrejme priradiť kolekciu k premennej rovnakým spôsobom ako k akejkoľvek inej hodnote. Jednu kolekciu môžeme použiť aj ako kľúč alebo hodnotu v inej kolekcii.

Zoznamy sa považujú za a nasl. To znamená, že trieda implementuje ISeq rozhranie. Všetky ostatné zbierky je možné previesť na a nasl pomocou nasl funkcia:

user => (seq [1 2 3]) (1 2 3) user => (seq # {1 2 3}) (1 3 2) user => (seq {: a 1 2 3}) ([: a 1] [2 3])

5.2. Prístup k zbierkam

Keď už máme zbierku, môžeme s ňou interagovať, aby sme dostali hodnoty späť. To, ako to môžeme urobiť, závisí mierne od príslušnej zbierky, pretože každá z nich má inú sémantiku.

Vektory sú jedinou kolekciou, ktorá nám umožňuje získať ľubovoľnú hodnotu podľa indexu. To sa deje vyhodnotením vektora a indexu ako výrazu:

užívateľ => (môj vektor 2); [1 2 3] 3

To isté môžeme urobiť pomocou rovnakej syntaxe aj pre mapy:

užívateľ => (moja mapa: b) 2

Máme tiež funkcie na prístup k vektorom a zoznamom na získanie prvej hodnoty, poslednej hodnoty a zvyšku zoznamu:

user => (prvý môj vektor) 1 užívateľ => (posledný môj zoznam) 3 užívateľ => (ďalší môj vektor) (2 3)

Mapy majú ďalšie funkcie na získanie celého zoznamu kľúčov a hodnôt:

user => (keys my-map) (: a: b) user => (vals my-map) (1 2)

Jediný skutočný prístup, ktorý musíme k množinám mať, je zistiť, či je konkrétny prvok členom.

Vyzerá to veľmi podobne ako prístup k akejkoľvek inej zbierke:

user => (my-set 1) 1 user => (my-set 5) nil

5.3. Identifikácia zbierok

Videli sme, že spôsob prístupu k zbierke sa líši v závislosti od typu zbierky, ktorú máme. Máme súbor funkcií, pomocou ktorých to môžeme určiť, a to konkrétnym aj všeobecnejším spôsobom.

Každá z našich kolekcií má špecifickú funkciu na určenie, či je daná hodnota tohto typu - zoznam? pre zoznamy, nastaviť? pre sady a tak ďalej. Okrem toho existuje seq? na určenie, či je daná hodnota a nasl akéhokoľvek druhu a asociatívny? zistiť, či daná hodnota umožňuje asociatívny prístup akéhokoľvek druhu - čo znamená vektory a mapy:

užívateľ => (vektor? [1 2 3]); Vektor je vektor skutočný používateľ => (vektor? # {1 2 3}); Sada nie je vektorový nepravý užívateľ => (zoznam? '(1 2 3)); Zoznam je zoznam skutočných používateľov => (zoznam? [1 2 3]); Vektor nie je zoznam false user => (mapa? {: A 1: b 2}); Mapa je skutočný používateľ mapy => (mapa? # {1 2 3}); Sada nie je nesprávnym používateľom mapy => (seq? '(1 2 3)); Zoznam je seq true user => (seq? [1 2 3]); Vektor nie je seq false užívateľ => (seq? (Seq [1 2 3])); Vektor je možné previesť na seq true user => (asociatívny? {: A 1: b 2}); Mapa je asociatívny skutočný používateľ => (asociatívny? [1 2 3]); Vektor je asociatívny skutočný užívateľ => (asociatívny? '(1 2 3)); Zoznam nie je asociatívny nepravdivý

5.4. Mutovanie zbierok

V Clojure sú rovnako ako väčšina funkčných jazykov všetky zbierky nemenné. Všetko, čo urobíme pre zmenu kolekcie, vyústi do vytvorenia úplne novej kolekcie, ktorá bude reprezentovať zmeny. To môže priniesť obrovské výhody z hľadiska efektívnosti a znamená to, že neexistuje riziko náhodných vedľajších účinkov.

Musíme však byť tiež opatrní, aby sme tomu porozumeli, inak sa očakávané zmeny v našich zbierkach nestanú.

Pridávanie nových prvkov do vektora, zoznamu alebo množiny sa vykonáva pomocou spoj. V každom z týchto prípadov to funguje inak, ale s rovnakým základným zámerom:

užívateľ => (konc [1 2 3] 4); Pridá na koniec [1 2 3 4] používateľ => (spoj '(1 2 3) 4); Pridá na začiatok (4 1 2 3) používateľa => (spojka # {1 2 3} 4); Neobjednané # {1 4 3 2} používateľ => (konjunktúra {1 2 3} 3); Pridanie už existujúceho záznamu nič neurobí # {1 3 2}

Môžeme tiež odstrániť záznamy z množiny pomocou disj. Upozorňujeme, že to nefunguje na zozname alebo vektore, pretože sú striktne usporiadané:

user => (disj # {1 2 3} 2); Odstráni položku # {1 3} user => (disj # {1 2 3} 4); Nerobí nič, pretože záznam nebol prítomný # {1 3 2}

Pridávanie nových prvkov do mapy sa vykonáva pomocou doc. Položky z mapy môžeme tiež odstrániť pomocou dissoc:

user => (assoc {: a 1: b 2}: c 3); Pridá nový kľúč {: a 1,: b 2,: c 3} user => (assoc {: a 1: b 2}: b 3); Aktualizuje existujúci kľúč {: a 1,: b 3} user => (dissoc {: a 1: b 2}: b); Odstráni existujúci kľúč {: a 1} user => (dissoc {: a 1: b 2}: c); Nerobí nič, pretože kľúč nebol prítomný {: a 1,: b 2}

5.5. Konštrukty funkčného programovania

Clojure je vo svojej podstate funkčným programovacím jazykom. To znamená, že máme prístup k mnohým konceptom tradičného funkčného programovania - ako napr mapa, filter, a zmenšiť. Spravidla fungujú rovnako ako v iných jazykoch. Presná syntax sa však môže mierne líšiť.

Konkrétne tieto funkcie všeobecne berú funkciu, ktorá sa má použiť ako prvý argument, a kolekciu, ktorá ju má použiť, ako druhý argument:

user => (map inc [1 2 3]); Zvýšiť každú hodnotu vo vektore (2 3 4) user => (map inc # {1 2 3}); Zvýšiť každú hodnotu v množine (2 4 3) užívateľ => (nepárny filter? [1 2 3 4 5]); Vrátiť iba nepárne hodnoty (1 3 5) user => (odstrániť nepárne? [1 2 3 4 5]); Vrátiť iba nepárne hodnoty (2 4) užívateľ => (znížiť + [1 2 3 4 5]); Sčítajte všetky hodnoty dohromady a vráťte súčet 15

6. Kontrolné štruktúry

Rovnako ako vo všetkých jazykoch na všeobecné použitie, aj v clojure sú potrebné štandardné riadiace štruktúry, napríklad podmienečné väzby a slučky.

6.1. Podmienené

S podmienkami sa zaoberá ak vyhlásenie. To vyžaduje tri parametre: test, blok, ktorý sa má vykonať, ak je test pravdaa blok, ktorý sa má vykonať, ak je test nepravdivé. Každá z nich môže byť jednoduchá hodnota alebo štandardný zoznam, ktorý sa na požiadanie vyhodnotí:

užívateľ => (ak je pravda 1 2) 1 užívateľ => (ak je nepravda 1 2) 2

Náš test môže byť čokoľvek, čo potrebujeme - nemusí to byť pravda lož hodnotu. Môže to byť aj blok, ktorý sa vyhodnotí, aby nám dal potrebnú hodnotu:

user => (if (> 1 2) "True" "False") "False"

Všetky štandardné kontroly vrátane =, >, a <, tu je možné použiť. Existuje tiež sada predikátov, ktoré sa dajú použiť z rôznych iných dôvodov - niektoré sme videli už pri prezeraní zbierok, napríklad:

užívateľ => (ak (nepárne? 1) „1 je nepárne“ „1 je párne“) „1 je nepárne“

Test môže vrátiť ľubovoľnú hodnotu - nemusí to byť len tak pravda alebo nepravdivé. Považuje sa však za pravda ak je hodnota čokoľvek okrem nepravdivé alebo nula. Líši sa to od spôsobu fungovania JavaScriptu, kde existuje veľká sada hodnôt, ktoré sa považujú za „pravda“, ale nie pravda:

user => (if 0 "True" "False") "True" user => (if [] "True" "False") "True" user => (ak nie je "True" "False") "False"

6.2. Opakovanie

Väčšinu práce so slučkami zvláda naša funkčná podpora zbierok - namiesto toho, aby sme cez kolekciu napísali slučku, použijeme štandardné funkcie a necháme jazyk, aby za nás urobil iteráciu.

Okrem toho sa vytváranie slučiek vykonáva výlučne pomocou rekurzie. Môžeme písať rekurzívne funkcie alebo môžeme použiť znak slučka a opakovať kľúčové slová na napísanie cyklu rekurzívneho štýlu:

používateľ => (slučka [akum [] i 0] (ak (= i 10) akumulovať (rekurovať (kombinovať i) (vrátane i))))) [0 1 2 3 4 5 6 7 8 9]

The slučka call spustí vnútorný blok, ktorý sa vykoná pri každej iterácii a začne nastavením niektorých počiatočných parametrov. The opakovať call potom zavolá späť do slučky a poskytne ďalšie parametre, ktoré sa majú použiť pri iterácii. Ak opakovať sa nevolá, potom sa slučka dokončí.

V takom prípade urobíme slučku zakaždým, keď i hodnota sa nerovná 10 a potom, keď sa rovná 10, namiesto toho vrátime nahromadený vektor čísel.

7. Zhrnutie

Tento článok priniesol úvod do programovacieho jazyka Clojure a ukazuje, ako funguje syntax a niektoré veci, ktoré s ním môžete robiť. Toto je iba úvodná úroveň a nejde do hĺbky všetkého, čo sa dá s jazykom urobiť.

Prečo to však nevyzdvihnúť, vyskúšať to a zistiť, čo sa s nimi dá robiť.