Clojure: Объявление символов
Clojure — не является полностью функциональным языком программирования (Haskell, например, является), однако, это в большей степени продиктовано прагматичностью, которая заложена в дизайне языка. Благодаря этому, в Clojure можно оперировать как константами, так и переменными. Для начала, рассмотрим константы (создаются с помощью формы def):
(def id expr)
; id — идентификатор
; expr — выражение
; форма def 'связывает' идентификатор с выражением
(def lang "clojure")
(println lang) ; => clojureЗначением объявления может быть как нормальная форма (значение), так и составная:
(def result (+ 7 (- 4 6)))
(println result) ; => 5def связывает имя (идентификатор) и значение следующего за ним выражения в рамках пространства имен, в котором происходит объявление. Имена объявлений, состоящие из нескольких слов, соединяют с помощью дефиса. В Lisp-языках повсеместно принят так называемый "kebab-case".
(def dangerous-year 1984)
(println dangerous-year) ; => 1984Если же нужно работать с каким-либо изменяемым состоянием, тогда на помощь приходит форма atom с набором функций, благодаря которым атом можно менять:
(def lang (atom "clojure"))
(println @lang) ; => clojure
; мутируем lang
(reset! lang "Clojure!!!")
(println @lang) ; => "Clojure!!!
; объявим счетчик
(def counter (atom 0))
; поменяем его с помощью форм swap! и inc
(swap! counter inc) ; => 1
(swap! counter inc) ; => 2
; а теперь уменьшим счетчик на 1
(swap! counter dec) ; => 1В общем случае использовать атомы как переменные не рекомендуется. Clojure отлично поддерживает функциональную парадигму и всячески её поощряет. Код с переменными практически всегда легко заменяется на код с константами. Как было описано выше, тема атомов и изменяемого состояния будет рассмотрена позже в соответствующем модуле.
Заметим, что в данном случае мы тоже использовали форму def, почему так? Идея связывания (от англ. binding) является идиоматическим способом записать функцию, в которую передается аргументом то, что записано в связывании. Звучит немного запутанно, поэтому еще раз рассмотрим пример выше поподробнее:
(def ; используем форму def
lang ; lang является идентификатором, с которым происходит связывание
(atom ; атом здесь является выражением, которое возвращает ссылку
"clojure" ; данные, на которые ссылается атом
)
)Благодаря тому, что связывание является более верхоуровневой концепцией, чем ссылка, мы можем связывать идентификатор не только с данными или ссылками, но и с функциями (функции будут рассмотрены дальше, не страшно, если что-то в примере ниже не будет до конца понятно).
(def my-fn (fn [a] (inc a))) ; => свяжем идентификатор my-fn с анонимной функцией, в которой переданный аргумент увеличивается на 1
(my-fn 1) ; => 2
(my-fn 8) ; => 9Задание
Создайте объявление, обозначающее "количество участников" (имя соорудите сами), присвойте ему значение 10 и распечатайте на экран.
Полезное
Ваше упражнение проверяется по этим тестам
(ns define-test
(:require [test-helper :refer [assert-output]]))
(assert-output "10")Решение учителя откроется через:
20:00
