Некоторое время назад я выступил на внутреннем мероприятии в Zenika Singapore. Мы были свободны в выборе темы, поэтому я выбрал что-то, о чем, как мне казалось, я недостаточно знал — каково это — создавать веб-приложение в Clojure. Этот пост является стенограммой выступления. Я подробно расскажу о Clojure, о том, какие библиотеки вы можете использовать для создания веб-приложений, и как все это чувствовало ко мне.
Clojure
Clojure — это диалект LISP, предназначенный для JVM, Microsoft CLR и JavaScript с помощью ClojureScript. Это функциональный и динамичный язык. Одна из его особенностей — неизменные структуры данных, которые полагаются на структурное совместное использование при добавлении или удалении элементов. Это обеспечивает хорошую производительность даже при сохранении неизменности.
Я в основном заинтересовался Clojure, потому что
- это очень отличается от всех языков на основе C вокруг
- все еще будучи языком общего назначения
Благодаря некоторым своим функциям, таким как программная транзакционная память (STM) и атомы, она особенно хорошо подходит для создания правильных параллельных приложений.
Один аспект, который я считаю важным: это, кажется, довольно дружелюбное сообщество, и мне понравились обе группы пользователей, в которых я принимал участие, Clojure Berlin и Clojure Meetup Singapore .
Если вы хотите начать работу с Clojure, лучше всего начать с очень распространенного инструмента сборки Leinigen . Среди прочего, он предлагает простой способ создания и запуска проектов, автономный или в REPL, функция, которая обычно используется с диалектами LISP.
Одного использования REPL и Leiningen вам будет недостаточно, по крайней мере, вам нужно что-то для редактирования файлов. Естественно, многие люди, похоже, используют emacs, кроме того, что есть также Cursive (построенный на IntelliJ), Lighttable (экспериментальная IDE) и Nightcode (очень простой редактор со встроенным REPL).
Чтобы начать работу с проектом, вы можете просто установить Leiningen и начать, запустив REPL с помощью lein repl
.
Давайте начнем с простой операции, добавив два числа.
1
2
|
user=> (+ 2 3 ) 5 |
Это уже показывает две из более необычных особенностей Clojure. Во-первых, весь код представлен в виде списка. Вот почему даже операция заключена в скобки. Во-вторых, Clojure использует префиксную нотацию, даже когда речь идет о математических операциях. Но это также имеет то преимущество, что вы можете просто увеличить количество параметров для операции добавления.
1
2
|
user=> (+ 2 3 4 5 ) 14 |
И если подумать: это совсем не так уж необычно. Если вы видите + как имя функции (что это такое), это очень похоже на то, как вы бы вызывали функцию на языке, подобном ac.
1
|
plus( 2 , 3 , 4 , 5 ) |
Конечно, вы также можете присвоить результат вычисления переменной.
1
2
3
4
5
6
|
user=> (def result (+ 2 3 4 5 )) #'user/result user=> result 14 user=> (- result 1 ) 13 |
Помимо числовых значений существуют также другие типы данных, например, строки и логические значения, которые вы можете использовать напрямую.
Также очень легко создавать функции.
1
2
3
4
|
user=> (defn append-mod [val] (str val "-mod" )) #'user/append-mod user=> (append-mod "some-value" ) "some-value-mod" |
Более интересными структурами данных являются коллекции. Есть векторы для последовательных данных.
1
2
3
4
5
6
|
user=> (def characters [ "a" "b" "c" ]) #'user/characters user=> (characters 0 ) "a" user=> (characters 1 ) "b" |
И есть карты, часто используемые с так называемыми ключевыми словами в качестве ключей.
1
2
3
4
|
user=> (def my-map {:key "value" :foo "bar" }) #'user/my-map user=> (my-map :key) "value" |
Будучи функциональным языком, очень часто выполняется преобразование коллекций, например, с помощью операции map. Это также показывает использование функций в качестве граждан первого класса, как видно из передачи в upper-case
функции.
1
2
|
userer=> (map clojure.string/upper- case characters) ( "A" "B" "C" ) |
Важно: это не изменяет существующую коллекцию — она создает новую. Все возможно благодаря эффективной реализации структур данных.
проблемы
Это правда, что Clojure имеет простой синтаксис, который позволяет легко начать работу. Но есть еще много вещей, которые нужно изучить, и с самого начала не имеет большого значения, является ли что-то синтаксисом, макросом или вызовом библиотеки. Это может быть особенно запутанным, что иногда есть связанные, но разные понятия. Например, это разные способы создания функции, но для разных целей.
-
(defn name [] (body))
-
(def name (fn [] (body)))
-
#(body)
Одна вещь, которая все еще трудна для меня, это решить, как структурировать программы в Clojure. Кажется распространенным, чтобы в одном и том же пространстве имен было много функций. Я предполагаю, что трудно решить, какая функция отвечает за какие данные или задачу.
Наконец, по крайней мере для меня, документы могут сбивать с толку.
Создание веб-приложений
В качестве языка общего назначения Clojure, конечно, может использоваться и часто используется для создания веб-приложений. По сравнению с Java-ландшафтом выбора гораздо меньше, очень распространенной комбинацией является использование трех библиотек: Ring в качестве базовой библиотеки, Compojure для маршрутизации и Hiccup для шаблонизации.
Кольцо реализовано в виде конвейера. Сначала есть адаптер, который используется для сопоставления с внутренним представлением запроса / ответа и который адаптируется к существующей веб-среде выполнения. Существует адаптер, использующий Jetty, или другой, который использует только API сервлетов, что позволяет развертывать приложение Ring в любом контейнере сервлета.
Далее идут промежуточные программы. Это как фильтры в мире сервлетов Java и могут быть использованы для улучшения приложения. По умолчанию некоторые промежуточные программы настроены, например, для обработки параметров, сеанса или файлов cookie.
В конце запрос попадает в обработчик, который преобразует запрос в ответ.
Compojure может помочь вам реализовать маршрутизацию для этих обработчиков. Это простой пример, который создает один успешный маршрут и одну функцию для обработки путей, которые не найдены.
1
2
3
|
(defroutes app (GET "/" [] "<h1>Hello World</h1>" ) (route/not-found "<h1>Page not found</h1>" )) |
Если вы хотите начать самостоятельно, используйте шаблон leiningen-compojure, который создаст для вас скелет приложения.
1
|
lein new compojure my_project_name |
Это создаст необходимую структуру папок, файл leiningen, обработчик и тест для него.
Если вы не хотите писать все html в Strings самостоятельно, как в примере выше, пришло время для библиотеки шаблонов. Тот, который часто используется в сочетании с Ring и Compojure — это Hiccup. Это позволяет вам писать код Clojure, который переводится в HTML.
1
2
|
user=> (html [:span {: class "foo" } "bar" ]) "<span class=" \ "foo\"" >bar</span>" |
Я разработал очень простое приложение с использованием этих библиотек: инструмент для просмотра и добавления словарного запаса. После запуска вы можете увидеть список слов, добавить больше слов и посмотреть переводы. Я бы не сказал, что он готов к производству, одна из причин в том, что он хранит все данные только в памяти 🙂 Вы можете найти исходный код на Github .
Он содержит GET и POST маршрут для чтения списка и добавления слова и шаблона Hiccup.
Вывод
Работать над новым языком было весело, и после понимания основ Clojure было легко начать работу с веб-приложением, в основном благодаря шаблону Leiningen Compojure, который облегчает настройку нового проекта. В промежуточном программном обеспечении Ring доступно множество готовых функций. Hiccup все еще кажется мне немного странным, я не слишком уверен, что многие разработчики веб-интерфейсов заинтересованы в работе с ним.
Хотелось бы, чтобы у меня было больше времени, чтобы подготовить доклад и поработать над примером. Есть еще много вещей, о которых я понятия не имею, и я надеюсь, что смогу найти время, чтобы продолжить обучение. Несмотря на то, что я не планирую использовать Clojure в проекте на работе в ближайшее время, очень полезно узнать о новых подходах — ваше восприятие некоторых языковых функций может измениться.
Если вы хотите начать работать и с Clojure — я могу особенно рекомендовать серию Aphyrs по основам . В течение многих лет я видел полезную лекцию разных людей из InnoQ, которая особенно касается веб-библиотек. Запись Майкла Витца доступна на YouTube .
Смотрите оригинальную статью здесь: Учимся создавать Clojure Webapps
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |