Clojure
Це означає виклик функції `+` з аргументами `1`, `2`, `3`.;</syntaxhighlight> Приклад:
Clojure має невелику кількість синтаксичних форм.; (def updated-user (assoc user :age 26))
<syntaxhighlight lang="clojure">
`promise`:
Clojure має кілька умовних форм.; * Документація Datomic.; '''Leiningen''' — класичний build tool для Clojure.; Common Lisp
<div style="background:#ecfdf5; border-left:6px solid #10b981; padding:12px; margin:12px 0;">
'''Висновок:''' Scala робить ставку на статичну типізацію й type system, а Clojure — на прості інформаційні дані, runtime-гнучкість і REPL.; `def` створює var у namespace.;== Java interop ==
Приклад створення об’єкта:
Групування даних
</syntaxhighlight>
(str/lower-case (str/trim text)))
:where [:= :active true]}
Clojure належить до родини Lisp.; Це означає, що її синтаксис базується на S-expressions — списках, де першим елементом зазвичай є собою функція або оператор.; Оригінальна map не змінюється.; '(1 2 3)
(str name " is " age))
</div>
* frontend apps;
* React UI;
* dashboards;
* internal tools;
* ClojureScript interfaces;
* functional UI components.; '''Суть persistent structures:''' нова реліз даних створюється результативно, без повного копіювання всієї структури в типових випадках.; Clojure застосовується для:
[:find ?name
(print-value [x]
Потрібно контролювати:
Ring
:age 25
Для функцій зазвичай використовують `defn`:
== Multimethods ==
user
== Clojure і Python ==
{| class="wikitable"
<div style="background:#e7f3ff; border-left:6px solid #2b7cff; padding:12px; margin:12px 0;">
(defn handler [request]
!; Malli застосовується для:
</div>
* JVM-екосистема;
* Lisp-синтаксис;
* REPL-driven development;
* immutable data structures;
* persistent data structures;
* functional programming;
* compact code;
* macros;
* Java interop;
* concurrency primitives;
* data-oriented design;
* ClojureScript;
* strong community around simplicity;
* хороша придатність для складних доменних даних;
* зручність для DSL.; (:name user)
</syntaxhighlight>
<div style="background:#fff7ed; border-left:6px solid #fb923c; padding:12px; margin:12px 0;">
* асинхронних оновлень;
* background state transitions;
* serialized updates;
* event processing;
* незалежних stateful об’єктів.;</div>
(LocalDate/now)
== Malli ==
{:status 200
(update :age inc))
Clojure і Common Lisp належать до Lisp-сімейства, але мають різний фокус.; '''Практична роль:''' deps.edn став популярним сучасним способом керування залежностями й інструментами Clojure.; datasource ["select * from users"])
(defmethod describe :user [x]
* web services;
* interceptors;
* API;
* long-running services;
* enterprise backend;
* data-driven request processing.; * Документація Ring.; `->>` передає значення як останній аргумент:
(def users
backend-сервісів забезпечується через Clojure використовують; додатково реалізовано data processing, фінансових систем, web applications, інтеграцій, DSL, аналітичних інструментів, JVM-застосунків, event-driven систем і проєктів, де важлива гнучкість, композиційність і контроль стану.; * Документація Clojure CLI і deps.edn.; (async/go
Macros
(str "User: " (:name x)))
- списки `(...)`;
- вектори `[...]`;
- maps `{...}`;
- sets `#{...}`;
- symbols;
- keywords;
- functions;
- special forms;
- macros.;
Тести використовуються для: Atoms використовуються для:
</syntaxhighlight>
- виконувати код одразу;
- перевіряти функції;
- досліджувати інформаційні дані;
- працювати з running application;
- інтерактивно налагоджувати логіку;
- оперативно змінювати код;
- будувати систему поступово;
- тестувати ідеї без повного перезапуску.; "adult"
Clojure використовує persistent data structures.;=== Простий Ring handler ===
{:deps {org.clojure/clojure {:mvn/version "1.11.1"}}
Records використовуються для:
Clojure і Python обидві динамічні, але мають різні ніші.;
Clojure має змогу бути не найкращим вибором для:
'''Практична роль:''' Re-frame дає структурований підхід до великих ClojureScript frontend-застосунків.; [1 2 3 4 5])
== Перша програма на Clojure ==
42))
'''Map''' — key-value структура.; Вона добре підходить для backend-систем, інтеграцій, data processing, фінансових застосунків, DSL, ClojureScript frontend і складних доменних моделей.; Критерій
'''Clojure''' — це сучасна функціональна Lisp-мова для JVM, яка робить акцент на immutable data, простих структурах, REPL-driven development, Java interop і data-oriented design.;== State management ==
</div>
REPL або Read-Eval-Print Loop — ключовий інструмент Clojure-розробки.; (assoc :role :admin)
</syntaxhighlight>
Property-based testing перевіряє не один приклад, а загальну властивість функції на багатьох згенерованих даних.;
Поширені підходи: Приклад:
discount-value (* subtotal discount)]
(defn greet [name]
</syntaxhighlight>
user=> (+ 2 3) Головна практика: Clojure часто розробляють через REPL, поступово будуючи й перевіряючи функції на живих даних.; Compojure — routing library для Ring.; (def user
Clojure і Scala
Atoms
- боротися з дужками замість розуміння структури;
- писати Clojure як Java;
- використовувати mutable state без потреби;
- створювати занадто багато records там, де достатньо maps;
- надмірно використовувати macros;
- не розуміти lazy sequences;
- плутати `->` і `->>`;
- зловживати nested anonymous functions;
- створювати великі namespaces без структури;
- не використовувати REPL;
- не тестувати pure functions;
- ігнорувати nil;
- не валідувати external input.; {:name "Carol" :role :user}])
Практична роль: Reitit часто обирають для сучасних Clojure API через data-driven підхід і хорошу інтеграцію зі схемами.; * ClojureDocs.;
Практична роль: Compojure — класичний легкий спосіб описувати маршрути в Clojure web applications.;</syntaxhighlight>
Clojure має змогу використовувати Maven-залежності.; * Документація clojure.test.; (println "Hello, world!")
(def expensive
- команд без часу на навчання Lisp-підходу;
- проєктів із великою кількістю junior-розробників без FP-досвіду;
- Android-first розробки;
- frontend без ClojureScript-експертизи;
- проєктів, де обов’язкова сильна статична типізація;
- простих CRUD-систем, де Java/Kotlin/Go/Python простіші для команди;
- організацій, де важлива широка кадрова база.; (fn [x] (* x x))
(async/go
(print-value [x]))
Re-frame
(jdbc/execute!;</syntaxhighlight>
Практична роль: core.async надає можливість будувати системи, де компоненти обмінюються значеннями через канали.; Це означає, що при “зміні” структури створюється нова реліз, яка результативно розділяє частину пам’яті зі старою.;(defn greet [name] (->> [1 2 3 4 5]
(defn normalize [text]
Sequence abstraction — одна з ключових ідей Clojure.; (swap!; Практична роль: atom надає можливість змінювати стан без класичного shared mutable object-підходу.; Macros використовуються для:
Printable
Protocol описує набір функцій, які можуть реалізувати різні типи.;
(println "computing")
(def numbers [1 2 3 4 5])
(deftest add-test
* backend development;
* JVM applications;
* web services;
* API;
* data processing;
* financial systems;
* event-driven systems;
* distributed systems;
* scripting на JVM;
* DSL;
* REPL-driven development;
* інтеграцій з Java;
* concurrent systems;
* frontend через ClojureScript;
* full-stack функціональних застосунків.; (defmacro unless [condition & body]
(defroutes app
(is (= 5 (core/add 2 3)))))
Приклад handler:
(def p (promise))
<div style="background:#e8f8f5; border-left:6px solid #16a085; padding:12px; margin:12px 0;">
'''Перевага JVM-екосистеми:''' Clojure має змогу підключати як Clojure-бібліотеки, так і Java-бібліотеки з Maven-світу.; * Документація Compojure.; * проміжних значень;
* читабельності;
* локального scope;
* уникнення дублювання;
* розбиття складної логіки.; * frontend applications;
* React-based UI;
* single-page applications;
* Reagent;
* Re-frame;
* full-stack Clojure/ClojureScript systems;
* interactive web tools;
* dashboards;
* internal interfaces.; Scala
(map #(* % 10))
Приклад:
Keywords
(group-by :role users) (-> {:name "Alice" :age 25}
| ; :active true}) | ; Результат:
lein run
(+ 1 2 3) Приклад: </syntaxhighlight> (delayClojure робить акцент на простих структурах даних.; @counter
'''Висновок:''' Python універсальніший і популярніший, а Clojure сильніша там, де потрібні JVM, immutable data й REPL-driven functional design.;
(def account-a (ref 100)) Leiningen<div style="background:#eef2ff; border-left:6px solid #4f46e5; padding:12px; margin:12px 0;">
`assoc` створює нову map, а не змінює стару.; '''Головне правило:''' хороший Clojure-код має бути простим, data-oriented, функціональним і зрозумілим у REPL.; '''Перевага синтаксису:''' Clojure має мало спеціальних правил, з цієї причини більшість коду виглядає як виклик функцій.; roles :admin)
<div style="background:#e8f8f5; border-left:6px solid #16a085; padding:12px; margin:12px 0;">
* immutability;
* ефективні актуалізація;
* безпечне розділення даних;
* зручну історію станів;
* менше помилок від shared mutable state;
* гарну основу для concurrent programming.; Водночас вона має незвичний синтаксис, динамічну типізацію, меншу кадрову базу й потребує готовності команди працювати у функціональному стилі.;<syntaxhighlight lang="clojure">
<syntaxhighlight lang="clojure">
(:require [clojure.test :refer [deftest is testing]]
Keywords можуть додатково працювати як функції для отримання значення з map:
Приклади властивостей:
(if (> age 18) Clojure macros можливі з цієї причини, що код має структуру даних.;
ReititLists</syntaxhighlight> Property-based testingВисновок(->> [1 2 3 4 5]
істотно: logging у Clojure-системах має бути структурованим і не повинен розкривати secrets або персональні інформаційні дані.;</syntaxhighlight> Перевага: Clojure надає можливість писати компактний, композиційний і гнучкий код, зберігаючи доступ до Java-бібліотек і JVM-інфраструктури.; Виклик instance method: </syntaxhighlight> Reagent застосовується для: Головна перевага: Clojure надає можливість моделювати систему як перетворення даних, а не як мережу mutable objects.;== REPL == Практична роль: property-based testing добре поєднується з Clojure, бо мова орієнтована на інформаційні дані й чисті функції.;* писати маленькі pure functions;
* моделювати домен простими maps і values;
* використовувати REPL для дослідження;
* уникати зайвих macros;
* не зловживати global defs;
* використовувати `let` для локальних значень;
* писати тести для data transformations;
* структурувати namespaces;
* не приховувати складну логіку в threading macros;
* використовувати spec або Malli для важливих boundary;
* контролювати lazy sequences;
* документувати public functions;
* обмежувати mutable state atoms/refs/agents;
* використовувати Java interop обережно.; @log-state
(require '[compojure.core :refer [defroutes GET]])
Приклад:
'''Namespace''' організовує код і контролює імена.; (defn handler [request]
`deps.edn` описує:
Refs корисні, коли потрібно координовано змінити кілька значень у транзакції.; REPL надає можливість:
Приклад ідеї Datalog-запиту:
!; Основні структури:
(assoc user :age 26)
<div style="background:#eafaf1; border-left:6px solid #2ecc71; padding:12px; margin:12px 0;">
<syntaxhighlight lang="clojure">
Clojure функціонує на '''Java Virtual Machine'''.; Clojure
</div>
<div style="background:#fef2f2; border-left:6px solid #ef4444; padding:12px; margin:12px 0;">
'''Практична роль:''' destructuring робить роботу з maps і vectors компактною й читабельною.; Критерій
HoneySQL корисний для: застосовується для: </syntaxhighlight> :from [:users] :body "Hello from Ring"}) Приклад Java interop: Виклик: Re-frame базується на:
Практична роль: ClojureScript надає можливість використовувати Clojure-підхід у браузері й будувати frontend у функціональному стилі.;
* numbers;
* strings;
* booleans;
* nil;
* keywords;
* symbols;
* lists;
* vectors;
* maps;
* sets.; Багато колекцій можна обробляти однаково як послідовності:
<syntaxhighlight lang="clojure">
</div>
'''Практична роль:''' Datomic добре поєднується з Clojure-філософією immutable data і data-oriented design.; lein test
(defprotocol Printable
</div>
!; Clojure має кілька інструментів для відкладених або асинхронних обчислень.; '''Практична роль:''' Reagent робить React-розробку ближчою до Clojure-підходу: UI як інформаційні дані й функції.;</div>
</div>
(- subtotal discount-value)))
Clojure має вбудовану бібліотеку `clojure.test`.; '''Reitit''' — сучасна routing library для Clojure і ClojureScript.; `if`:
{:select [:id :name]
'''Практична роль:''' Malli часто використовують у сучасних Clojure-проєктах для опису й перевірки даних.; * Документація ClojureScript, Reagent і Re-frame.; (->> [1 2 3 4 5]
== Maps ==
(let [subtotal (* price quantity)
Приклад:
'''Основна ідея:''' Clojure поєднує Lisp-підхід, функціональне програмування, незмінні структури даних і доступ до JVM-екосистеми.;
</syntaxhighlight> 5 Приклад: Re-frame — framework для ClojureScript frontend-застосунків поверх Reagent.;== Безпека Clojure-застосунків == HoneySQLПриклад: Головна структура Clojure: maps часто є собою основою доменних даних, API payloads, конфігурацій і проміжних результатів.; Clojure Практична роль: vectors є собою однією з найчастіших структур Clojure для впорядкованих даних.;</syntaxhighlight> (defmethod describe :order [x] Приклад: * DSL;
* control flow;
* code generation;
* test syntax;
* web routing;
* database query DSL;
* зменшення boilerplate.;</div>
</div>
'''істотно:''' круглі дужки в Clojure зазвичай означають не “групування”, а виклик функції або special form.; Потрібно контролювати:
<syntaxhighlight lang="clojure">
<div style="background:#fff4e5; border-left:6px solid #f39c12; padding:12px; margin:12px 0;">
== Vars і def ==
(defn total-price [{:keys [price quantity discount]}]
|-
| Платформа
| JVM, ClojureScript, CLR-варіанти
| Різні реалізації Common Lisp
|-
| інформаційні дані
| Immutable persistent data structures
| Більш традиційні mutable structures
|-
| Concurrency
| Сучасні Clojure primitives
| Залежить від реалізації
|-
| програмний пакет
| JVM і Clojure libraries
| Common Lisp ecosystem
|-
| Стиль
| Data-oriented functional Lisp
| Дуже гнучкий multi-paradigm Lisp
|}
'''Практична роль:''' lifecycle-бібліотеки допомагають будувати Clojure-застосунки, які комфортно запускати, зупиняти й перезавантажувати в REPL.;== Загальний характеристика ==
== Pedestal ==
<syntaxhighlight lang="clojure">
<div style="background:#ecfdf5; border-left:6px solid #10b981; padding:12px; margin:12px 0;">
"minor")
{:name "Alice"
<div style="background:#eafaf1; border-left:6px solid #2ecc71; padding:12px; margin:12px 0;">
(testing "addition"
== Clojure і Java ==
'''ClojureScript''' — це варіант Clojure, який компілюється в JavaScript.; Потрібно розуміти, коли потрібен agent, atom, core.async або інший підхід.; * великих даних;
* нескінченних послідовностей;
* pipeline processing;
* відкладених обчислень;
* економії пам’яті.; * Документація Leiningen.;<syntaxhighlight lang="clojure">
Основні елементи:
Clojure-екосистема підтримує роботу property-based testing, зокрема через test.check.; {:name "Alice"
<div style="background:#e8f8f5; border-left:6px solid #16a085; padding:12px; margin:12px 0;">
'''Практична порада:''' Clojure варто обирати, коли команда готова працювати з функціональним data-oriented підходом і хоче використовувати JVM.; (do ~@body)))
'''Критично:''' data-oriented design не замінює security review.; Її сила розкривається в REPL, immutable structures, композиції і JVM-екосистемі.; це сучасна функціональна мова програмування з родини Lisp, яка функціонує переважно на '''JVM''' і орієнтована на immutable data, простоту моделей даних, REPL-driven development, concurrency і практичну розробку складних систем виступає ключовою рисою '''Clojure'''.;== ClojureScript ==
(s/def ::user (s/keys :req [::name ::age]))
(str "User: " (:name x))))
:age 25
<div style="background:#eef2ff; border-left:6px solid #4f46e5; padding:12px; margin:12px 0;">
(println (greet "Alice"))
'''Malli''' — популярна бібліотека для data schemas у Clojure.; * Документація core.async.; (filter odd?)
(if [] "truthy" "falsey") (let [name "Alice" Приклад: переважні аспекти Clojure</syntaxhighlight> Agents корисні для: Практична роль: Clojure не ізольована мова — вона має змогу використовувати велику JVM-екосистему й працювати поруч із Java-кодом.;== Vectors == Виклик static method: Практична роль: set зручний, коли важлива саме наявність значення, а не порядок.; (str "Hello, " name)) (def user {:name "Alice" :age 25})
<div style="background:#e7f3ff; border-left:6px solid #2b7cff; padding:12px; margin:12px 0;">
(-> user
'''Практична роль:''' Clojure добре підходить для тестування, бо багато логіки можна оформити як чисті функції над даними.; '''Atom''' — механізм для синхронної, незалежної зміни стану.; Приклад ідеї:
(def user clojure.spec — інструмент для опису структури даних і перевірки відповідності.;</div>
'''істотно:''' Clojure має змогу дати велику продуктивність сильній команді, але потребує культурної згоди щодо стилю, REPL і функціонального мислення.; {| class="wikitable"
</div>
<div style="background:#fff4e5; border-left:6px solid #f39c12; padding:12px; margin:12px 0;">
{:name "Alice"
</div>
AgentsДив.; додатково{:deps {cheshire/cheshire {:mvn/version "5.12.0"}}} CompojureSet — колекція унікальних значень.; counter inc) (require '[clojure.core.async :as async])
Protocols використовуються для:
(reduce +))
Web development</syntaxhighlight>
Clojure розроблена як практична Lisp-мова для сучасної розробки.; (map #(* % 10))) (ns my-app.core </syntaxhighlight> ДжерелаSets використовуються для: Spec має змогу використовуватися для: Приклади:
[{:name "Alice" :role :admin}
Функції(when active?; Python Функції вищого порядку дозволяють: NamespacesПриклад: </syntaxhighlight> Namespaces використовуються для: (cond Reagent:where Приклад: </syntaxhighlight>
Pedestal — web framework і набір інструментів для Clojure services.; Критично: macros дуже потужні, але їх варто писати лише тоді, коли звичайних функцій недостатньо.; Помилка: сприймати Clojure як Java з дужками.; Небезпека: Clojure надає можливість писати дуже компактний код, але надмірна компактність має змогу зробити логіку важкою для читання.; Приклад ідеї: :headers {"Content-Type" "text/plain"}
Головна ідея даних: Clojure заохочує описувати домен через прості immutable data structures, а не через складні mutable objects.; Критерій `let` корисний для: Maven dependencies |
; Окремо варто відзначити хто хоче будувати системи навколо даних і функцій, а не навколо mutable object-ієрархій.;:active true}) @expensive (require '[next.jdbc :as jdbc]) </syntaxhighlight> updated-user (async/>!;== інформаційні дані в Clojure == Clojure дає компактність, гнучкість, потужні macros, persistent data structures і доступ до JVM-екосистеми.; У Clojure інформаційні дані за замовчуванням immutable.; Vector destructuring: </syntaxhighlight> (add 2 3) |
; (str name " is " age))
(nth numbers 0) (def user {:name "Alice" :age 25}) </syntaxhighlight>
{{SEO Clojure і Common Lisp(assoc :active true) У цьому прикладі:
== Приватність даних ==
== Приклади задач на Clojure ==
<div style="background:#fdecea; border-left:6px solid #e74c3c; padding:12px; margin:12px 0;">
Reitit підтримує роботу:
Приклад:
(dosync
#(* % %)
'''Datomic''' — база даних, тісно пов’язана з Clojure-екосистемою.; '''Головна думка:''' Clojure — це мова для тих.; @p
(defmulti describe :type)
Clojure-застосунки мають звичайні security-ризики JVM і web-систем.; (defrecord User [name]
== Sets ==
Анонімна функція:
'''Висновок:''' Kotlin часто є собою практичною модернізацією Java, а Clojure — радикальнішим data-oriented і Lisp-підходом на JVM.; Ефективний Clojure-код потребує іншого мислення: інформаційні дані, функції, immutability і REPL.; Вона каже: стан має бути контрольованим, явним і відокремленим від чистих функцій.; (send log-state conj "event")
== Коли варто використовувати Clojure ==
</div>
:headers {"Content-Type" "text/plain"}
(def result
Lisp-підхід дає Clojure:
<syntaxhighlight lang="clojure">
`(if (not ~condition)
(0 1 2 3 4)
'''Суть прикладу:''' Clojure-код складається з виразів, які обчислюються й повертають значення.;<div style="background:#ecfdf5; border-left:6px solid #10b981; padding:12px; margin:12px 0;">
<syntaxhighlight lang="clojure">
`when`:
'''Увага:''' у Clojure порожня колекція не є собою false.; * Матеріали щодо functional programming, immutable data, REPL-driven development і JVM interop.; Для цього краще `let`.; * Clojure libraries;
* Java libraries;
* Maven Central;
* private Maven repositories;
* enterprise artifacts;
* JVM tooling.; Clojure
<syntaxhighlight lang="clojure">
(future
(reduce +))
* сортування зберігає кількість елементів;
* encode/decode повертає початкове значення;
* сума не залежить від порядку елементів;
* функція не падає на валідних input.; * Clojure Reference.; [:div "Hello from Reagent"])
== next.jdbc ==
(< age 18) "minor"
(>= age 18) "adult"
== Protocols ==
core.async застосовується для:
<syntaxhighlight lang="clojure">
Ring описує HTTP request і response як maps.;== Threading macros ==
(import java.time.LocalDate)
:active true})
Приклад dependency:
У функції:
updated-user
(def updated-user
:body "Hello from Clojure"})
Обмеження Clojure</syntaxhighlight> Приклад: СинтаксисПриклад: </syntaxhighlight> Висновок: Common Lisp є собою класичною потужною Lisp-системою, а Clojure — сучасним Lisp для JVM і immutable data.; ch "hello")) </syntaxhighlight> Clojure часто порівнюють із Java.; Clojure застосовується для web development, хоча зазвичай не через один монолітний framework, а через набір бібліотек.; Приклад: {:name "Bob" :role :user}
Clojure активно використовує функції вищого порядку.; Практична роль: STM надає можливість безпечніше координувати кілька пов’язаних змін стану.; |-
Clojure підтримує роботу lazy sequences — послідовності, які обчислюються поступово.; (update user :age inc) (take 5 (range)) Перевага threading macros: вони дозволяють читати послідовність перетворень зверху вниз.;</div>
* створення проєктів;
* запуску REPL;
* керування dependencies;
* запуску тестів;
* packaging;
* deployment;
* створення uberjar.; '''Практична роль:''' Leiningen довго був стандартним інструментом для Clojure-проєктів і досі часто зустрічається в existing codebase.;<syntaxhighlight lang="clojure">
'''Практична роль:''' next.jdbc надає можливість працювати з SQL у Clojure, зберігаючи data-oriented підхід.;<syntaxhighlight lang="clojure">
Pedestal застосовується для: "Unknown") У Clojure logging часто робиться через Java logging libraries або Clojure wrappers.; (defn greet [{:keys [name]}]
Clojure має сильну взаємодію з Java.;
<syntaxhighlight lang="clojure">
<syntaxhighlight lang="clojure">
<syntaxhighlight lang="clojure">
* SQL queries;
* connection pooling;
* transactions;
* result sets as data;
* JDBC integration;
* backend services.;
(defn add [a b] LoggingПрактична роль: Clojure web development часто є собою бібліотечним і data-driven, а не framework-heavy.; Agent застосовується для асинхронної зміни стану.; * персональні інформаційні дані;
</syntaxhighlight> age 25] </syntaxhighlight> ImmutabilityTestingТематичні мітки|-
| Платформа
| JVM
| JVM, Android, multiplatform
|-
| Типізація
| Динамічна
| Статична
|-
| Стиль
| Lisp, functional, data-oriented
| Pragmatic OOP/FP
|-
| Android
| Не основна ніша
| Сильна ніша
|-
| Enterprise adoption
| Нішевіша
| Ширша для Java-команд
|}
</div>
<div style="background:#e8f8f5; border-left:6px solid #16a085; padding:12px; margin:12px 0;">
== Хороші практики Clojure ==
<div style="background:#eafaf1; border-left:6px solid #2ecc71; padding:12px; margin:12px 0;">
<div style="background:#fff7ed; border-left:6px solid #fb923c; padding:12px; margin:12px 0;">
<div style="background:#fff4e5; border-left:6px solid #f39c12; padding:12px; margin:12px 0;">
Clojure часто застосовується в backend і фінансових системах, з цієї причини приватність даних важлива.; Критерій
* dependency vulnerabilities;
* authentication;
* authorization;
* SQL injection;
* XSS;
* CSRF;
* unsafe deserialization;
* secrets;
* logging sensitive data;
* Java interop with unsafe APIs;
* file access;
* command execution;
* API validation;
* dependency supply chain.; (Math/sqrt 16)
(def user (->User "Alice" 25))
</div>
<div style="background:#ecfdf5; border-left:6px solid #10b981; padding:12px; margin:12px 0;">
<div style="background:#fff7ed; border-left:6px solid #fb923c; padding:12px; margin:12px 0;">
У Clojure `nil` означає відсутність значення.;== If, when і cond ==
'''Практична роль:''' `if` підходить для двох варіантів, `when` — для дії за умовою, `cond` — для кількох умов.; Можливі складнощі:
завдяки наявності '''Практична роль:''' `let` користувачі можуть давати імена проміжним результатам без створення глобальних змінних.; '''Multimethod''' надає можливість обирати реалізацію функції за результатом dispatch-функції.; Основні переважні аспекти Clojure:
Clojure має threading macros для читабельних pipelines.; :else "unknown")
<syntaxhighlight lang="clojure">
<syntaxhighlight lang="clojure">
<syntaxhighlight lang="text">
Ring застосовується як основа для: (:name user) (def account-b (ref 50)) :age 25 Перевага Java interop: Clojure має змогу використовувати готові Java SDK, frameworks і libraries без окремого bridge-шару.; Це істотно для умов і перевірок.; істотно: Clojure не каже “стану не існує”.; (def user ClojureScript застосовується для: (s/def ::age int?) актуалізація map:
(deliver p 42) (reduce + [1 2 3 4 5]) Destructuring надає можливість комфортно діставати значення зі структур.; Refs використовуються з Software Transactional Memory або STM.; (defrecord User [name age])
:paths ["src" "resources"]} Nil і booleans
Простий приклад: (println (async/<! ch))) </syntaxhighlight> Component і Integrant(str "Hello, " name)) Висновок: Java краще знайома масовим enterprise-командам, а Clojure дає компактність, immutable data й REPL-driven development на JVM.; Правило: REPL — потужний інструмент, але доступ до production REPL або live data має бути суворо контрольований.; Leiningen застосовується для: |-
| Основна платформа
| JVM
| CPython та інші runtime
|-
| Стиль
| Functional, Lisp, immutable data
| Multi-paradigm, scripting, data science
|-
| програмний пакет
| JVM + Clojure libraries
| Дуже широка, особливо AI/Data Science
|-
| REPL
| Центральний workflow
| є собою, але менш центральний для production
|-
| Новачкам
| Синтаксис має змогу бути незвичним
| Зазвичай простіший старт
|}
(+ a b c))
Compojure застосовується для:
(get user :age)
'''Ring''' — базова web abstraction у Clojure.; (println "Active"))
<div style="background:#e8f8f5; border-left:6px solid #16a085; padding:12px; margin:12px 0;">
`delay`:
<syntaxhighlight lang="clojure">
'''Keyword''' — це іменоване значення, яке часто застосовують, коли потрібно як ключ у map.;<syntaxhighlight lang="clojure">
== Refs і STM ==
</div>
</div>
Приклад ідеї:
(def ch (async/chan))
* typed domain data;
* protocol implementations;
* Java interop;
* performance-sensitive structures;
* структур, яким потрібна ідентичність типу.; * data-driven routes;
* coercion;
* Swagger/OpenAPI;
* middleware;
* frontend і backend routing;
* nested routes;
* performance-oriented routing.; '''Увага:''' хороша структура namespaces дуже важлива для підтримуваності Clojure-проєкту.; lein new app my-app
'''Reagent''' — ClojureScript wrapper для React.; (require '[clojure.spec.alpha :as s])
<syntaxhighlight lang="clojure">
(alter account-b + 10))
<div style="background:#e7f3ff; border-left:6px solid #2b7cff; padding:12px; margin:12px 0;">
(let [{:keys [name age]} {:name "Alice" :age 25}]
(java.util.Date.)
* Офіційна документація Clojure.; Поширені помилки:
'''Практична роль:''' Pedestal підходить для складніших backend-сервісів, де потрібен interceptor-based pipeline.; '''HoneySQL''' надає можливість будувати SQL-запити як Clojure data structures.; '''Record''' створює іменований тип, схожий на map, але з додатковими можливостями.; Це дає:
Lazy sequences корисні для:
* dependencies;
* aliases;
* paths;
* tools;
* test конфігурації;
* REPL startup;
* build tasks.;== Futures, delays і promises ==
<syntaxhighlight lang="clojure">
(let [[a b c] [1 2 3]]
(+ 1 2 3) (def app-name "My App") (alter account-a - 10) Приклад: Це дає доступ до: Records(str "Hello, " name)) Clojure добре підходить для: List у Clojure записується в круглих дужках.;Приклад: core.asyncістотно: `def` не варто використовувати для локальних проміжних значень усередині логіки.; !; Clojure і Scala обидві працюють на JVM, але мають різну філософію.; Приклад: завдяки наявності JVM Clojure отримує: @result
<div style="background:#ecfdf5; border-left:6px solid #10b981; padding:12px; margin:12px 0;">
== Let ==
* clojure.tools.logging;
* Logback;
* SLF4J;
* Timbre;
* structured logging;
* JSON logs;
* tracing;
* metrics.; Clojure
'''Практична роль:''' multimethods дають гнучкий polymorphism, який не прив’язаний лише до класу об’єкта.; (+ 1 2)
(def counter (atom 0))
=== Функція для бізнес-логіки ===
</div>
'''Практична роль:''' sequence abstraction надає можливість писати універсальний код для різних типів колекцій.;</div>
<syntaxhighlight lang="clojure">
<div style="background:#ecfdf5; border-left:6px solid #10b981; padding:12px; margin:12px 0;">
</div>
<div style="background:#eef2ff; border-left:6px solid #4f46e5; padding:12px; margin:12px 0;">
Приклад:
== JVM ==
== Типові помилки початківців ==
:name
'''Практична роль:''' ці інструменти дають прості моделі для async, lazy і coordinated computation.; * передавати поведінку як аргумент;
* комбінувати логіку;
* обробляти колекції декларативно;
* уникати явних циклів;
* будувати гнучкі pipelines.; `->` передає значення як перший аргумент:
Spec(:name user)
Clojure має обмеження.;</div>
Усе інше вважається truthy, включно з `0`, порожнім рядком і порожньою колекцією.;
</syntaxhighlight> </syntaxhighlight> deps.edn і Clojure CLI
Практична роль: keywords є собою основним способом іменування полів у Clojure-даних.; `cond`: </syntaxhighlight> False-like значення:
Результат буде `"truthy"`.;=== актуалізація map === Приклад literal list: Higher-order functions</div>
<div style="background:#e7f3ff; border-left:6px solid #2b7cff; padding:12px; margin:12px 0;">
Приклад ідеї:
!;
Сучасний Clojure часто використовує Clojure CLI і файл `deps.edn`.; Java істотно: lazy evaluation має змогу бути дуже корисною, але іноді створює неочевидний час виконання або утримання ресурсів.; * composable SQL;
:user/status
Clojure не забороняє стан, але робить його явним і контрольованим.; Приклад:
{:status 200
'''Практична роль:''' `map`, `filter`, `reduce` і подібні функції є собою щоденними інструментами Clojure-розробника.; Приклад:
'''Практична роль:''' Ring робить web-розробку в Clojure data-oriented: request і response — це звичайні maps.; '''Component''' і '''Integrant''' — бібліотеки для керування lifecycle компонентів застосунку.;<div style="background:#e7f3ff; border-left:6px solid #2b7cff; padding:12px; margin:12px 0;">
(dissoc user :active)
{| class="wikitable"
<div style="background:#eafaf1; border-left:6px solid #2ecc71; padding:12px; margin:12px 0;">
Функції є собою основою Clojure.; Clojure
Приклад простого macro:
* validation;
* schema definitions;
* coercion;
* API validation;
* documentation;
* data-driven specs;
* frontend і backend shared schemas.; (ns my-app.core-test
(def roles #{:admin :user :manager})
(filter even?)
Macro у Clojure надає можливість перетворювати код до виконання.; Приклад:
<syntaxhighlight lang="clojure">
(filter even?)
'''core.async''' — бібліотека для асинхронного програмування через channels.; * Документація Reitit.; Вона не робить акцент на класичній об’єктній моделі, а пропонує будувати програми через функції, immutable data structures, namespaces, protocols, multimethods і macros.;
(GET "/" [] "Hello")) (defn hello [] істотно: синтаксис Clojure має змогу виглядати незвично через дужки, але його регулярність є собою однією з причин сили мови.; Map destructuring: (def log-state (agent [])) (+ 40 2))) (map #(* % 10))
Datomic орієнтована на:
(update :age inc)))
Оголошення функції:
!; (:require [clojure.string :as str]))
<div style="background:#eafaf1; border-left:6px solid #2ecc71; padding:12px; margin:12px 0;">
:age
|-
| Типізація
| Динамічна
| Статична
|-
| Парадигма
| Functional, Lisp, data-oriented
| FP + OOP, strong type system
|-
| Складність
| Простий синтаксис, сильні runtime-концепції
| Складніша type system
|-
| інформаційні дані
| Immutable maps, vectors, sets
| Case classes, ADTs, collections
|-
| JVM interop
| Сильний
| Сильний
|}
<syntaxhighlight lang="clojure">
Типовий backend stack має змогу включати:
(str "Order: " (:id x)))
<syntaxhighlight lang="clojure">
'''next.jdbc''' — сучасна бібліотека для роботи з SQL-базами в Clojure.;<syntaxhighlight lang="clojure">
== Datomic ==
== Clojure і Kotlin ==
[?e :user/name ?name]]
"Alice"
<syntaxhighlight lang="clojure">
!;<syntaxhighlight lang="clojure">
Головна перевага immutability: інформаційні дані не змінюються неочікувано, з цієї причини простіше думати про стан, concurrency і тестування.; Суть Clojure-коду: програми будуються як композиція функцій, які приймають інформаційні дані й повертають нові інформаційні дані.;</syntaxhighlight> |
; Reagent надає можливість писати UI як ClojureScript-функції й data structures.;<syntaxhighlight lang="clojure"> cd my-app
Lazy sequences |
|---|