Clojure — современный диалект Лиспа, язык программирования общего назначения с поддержкой разработки в интерактивном режиме. Сам язык с динамической системой типов поощряет функциональное программирование и упрощает поддержку многопоточности, а благодаря своей структуре может запускаться на платформах Java и JavaScript. При этом на Clojure работают уже, как правило, опытные разработчики, которые осознанно выбрали этот язык для решения своих задач. Мы попросили Clojure-разработчиков рассказать о том, как устроен этот язык программирования, какие задачи можно решать с его помощью и отличиях от других языков — функциональных, смешанных или императивных.
Clojure — это диалект Лиспа, в котором заложена похожая философия кода как данных — гомоиконичность, а также мощная макросистема. Принципы гомоиконичности позволяют использовать крайне небольшой синтаксис языка Clojure, в котором структура программы похожа на его синтаксис — поэтому для того, чтобы понять структуру программы, нужно просто прочитать текстовую разметку программы. Если прибавить к гомоиконичности и маленькому синтаксису реализацию макросов — инструкций, которые сообщают программе, какие именно действия нужно выполнять — получается достаточно мощный язык программирования.
(ns clojure.examples.hello
(:gen-class))
;; Этот код выводит на экран фразу "Hello World"
(defn example []
(println "Hello World"))
(example)
Название языка Clojure созвучно слову «closure» – «замыкание», которое в абстрактной математике обозначает множества, замкнутые на самих себя. При этом язык Clojure не полностью функциональный — в нем есть и поддержка функций с побочным эффектом, например, функции ввода и вывода. Однако они не имеют своего состояния и служат, как правило, только для взаимодействия алгоритма с внешним миром.
Вы изучали Clojure как первый язык или уже были программистом, когда решили его изучить? Есть ли смысл изучать Clojure в качестве первого языка?
Я начал программировать очень много лет назад — мой первый язык был Basic, потом были C++, C. Основные первые работы были на Java, делал backend Application. За всё это время я смотрел разные языки, в том числе даже работал с JS, потому что начал изучать системы фронтенда.
Оказалось, что многие языки имеют проблемы с координацией, когда речь начинает идти о многопоточности и мультипроцессинге — не ясно, как они должны работать, чтобы не было постоянных race condition.
Тогда меня заинтересовало, какие существуют подходы к решению проблемы многопоточности. Начал смотреть на функциональные языки — первый язык, с которым я работал, был Haskell. Я месяцев шесть его использовал — мне очень понравилось, у него совершенно другой подход к тому, как строить программы, как работает стейт-менеджмент. Но потом я понял, что найти работу хаскелистом достаточно сложно — все-таки это маленький рынок, поэтому я выбрал другой функциональный язык — Scala.
Со Scala тоже возникли сложности — я заметил, что большую часть кода писал как на Java, ведь он сочетает в себе возможности функционального и объектно-ориентированного программирования — на Scala тоже есть объекты, и там можно делать гибридный код. И, даже не осознавая этого, начинаешь делать то, к чему привык. При этом лет 12 назад в Scala все процессы были еще не налажены, поэтому я начал подбирать другой язык программирования — и выбрал Clojure.
Мне сразу понравилось, что Clojure — совершенно другой язык по сравнению с уже традиционными языками разработки, которые мы используем и к которым давно привыкли. Clojure довольно интерактивный язык — в нем есть возможность написать функцию и сразу из редактора запустить её и посмотреть, как она работает, проверить её.
Несмотря на отличия, к Clojure нужно привыкнуть — тогда можно понять, что этот язык достаточно простой и маленький. Когда я работал со Scala, приходилось что-то постоянно гуглить, искать на Stack Overflow — смотреть, как можно решить ту или иную задачу, выбирать между разными подходами. В Clojure всё работает намного проще и все подходы к решению задачи в общем похожи друг на друга — все, кто работают с Clojure, делают алгоритмы в более или менее одинаковом стиле.
Clojure очень легко читать, если ты уже выучил язык, плюс всегда можно поиграть с кодом, который пишешь — посмотреть, что он делает, поменять его. Это очень помогает изучать язык — например, в Java после написания программы постоянно приходится заниматься дебагом, это снижает мотивацию и может вообще уничтожить желание работать именно с языком. А когда можно постоянно взаимодействовать и коммуницировать с кодом во время написания — как будто бы разговаривать, как это и происходит в Clojure, — становится намного интереснее.
Какие есть особенности у Clojure? Какие очевидные плюсы и минусы у этого языка?
Плюсы Clojure
Самый большой плюс Clojure в его функциональности и неизменяемости функций. Ты точно знаешь, что функция выполняет, и что нет никаких изменений, которые она за собой тянет. Поэтому когда смотришь код большого проекта, можно просто взять его кусок и точно знать, что он делает и что выполняет. При этом не обязательно знать, что делает окружающий его код. В традиционных же языках созданный код меняет другой код, поэтому всегда нужно понимать, как части программы взаимодействуют друг с другом, за что отвечают те или иные куски кода и как все устроено внутри алгоритмов. Именно поэтому в Java постоянно используют дебагер — ведь всю программу в голове держать невозможно, но нужно всё контролировать и прогнозировать все возможные изменения в коде после того, как разработчик решит поменять какую-нибудь строчку.
В Clojure можно просто прочитать код и узнать, что он делает и за что отвечает. И в его работе не будет никаких неизвестных изменений, которые он за собой тянет. Особенно это удобно, когда работаешь в большой команде — сам язык позволяет создавать изоляцию между программистами и один участок кода никак не может испортить другой.
Ещё из плюсов — в Clojure можно использовать любые библиотеки из Java и JavaScript. Это огромный плюс языка — сам по себе он достаточно маленький и людей на нем работает не очень много. Поэтому отлично, что можно использовать сторонние системы.
Мы работали и с Java, и с Clojure, но пришли к выводу, что одни и те же проекты на Clojure создаются намного быстрее. Нужно меньше кода, чтобы создать программу, он будет быстрее работать, а разработчик только решает проблему через язык программирования. А не как у JS или Java, где приходится много работать именно со структурой языка, а не с решением проблемы.
В программах, которые сделаны на Clojure, меньше багов. Когда ты приходишь в проект, где работают с Clojure, разбираться с кодом намного проще. В этом Clojure выигрывает у многих языков — особенно в работе с большими системами данных.
Минусы Clojure
Clojure достаточно сильно отличается от популярных языков разработки, к нему нужно привыкнуть, к его подходу. Ещё Clojure в некоторых местах немного медленнее, чем другие языки. Обычно это не проблема, но если у вас мало ресурсов, то лучше использовать что-то другое.
Другой минус — Clojure компилируется только на JVM или JS. Если эти платформы подходят к вашему проекту, то всё идеально, если нет — придется выбрать другой язык.
Clojure — динамический язык. Дело вкуса, но если вам не очень близок такой подход, и вы любите, например, делать статические переменные, то тоже лучше поискать что-то ещё.
Как устроено коммьюнити вокруг Clojure?
Коммьюнити в Clojure очень активное — например, у нас в Торонто недавно была большая конференция Clojure/north, которую мы делали, и в ней принимали участие программисты из абсолютно разных частей света — из Финляндии, США, Великобритании и даже Индии. Ну и есть, конечно, российские компании, которые используют Clojure.
При этом нужно понимать, что Clojure — нишевый язык, поэтому количество людей, которые его используют, никогда не сравнится с JS или Java. Но из языков поменьше, Clojure — один из самых востребованных, особенно из функциональных языков. Поэтому его используют многие компании, даже корпорации, включая Apple или Amazon.
Этот язык привлекает очень опытных людей, что влияет и на коммьюнити, и на всю экосистему вокруг языка. JS привлекает неопытных людей, которые в итоге создают не очень качественные библиотеки — они часто ломаются, потому что собирали их программисты без большого количества опыта. На Clojure, к счастью, всё устроено иначе.
Другая важная новость — компанию Congitect создателя Clojure Ричарда Хикки, которая занималась поддержкой и развитием языка, купила большая финансовая корпорация Nubank из Бразилии — она активно использует Clojure. Поэтому теперь язык будет ещё стабильнее и быстрее развиваться.
Существует ли спрос на программистов, которые используют Clojure? В сочетании с какими языками?
Обычно ищут разработчиков, которые уже знают JS или Java — все-таки Clojure использует инструменты и системы этих языков. И если человек знает уже платформу, то ему, конечно, будет легче.
Но вообще все зависит от компании — мы периодически берем студентов из университета, которые вообще не писали коммерческого кода. То есть мы можем взять студента и научить его делать что-то полезное на Clojure за пару недель. Clojure просто учить людям, у которых абсолютно нет опыта в программировании и голова пока не забита разными концепциями.
Выучить Clojure просто для людей, которые только начали программировать — с опытом до двух лет, либо уже опытным инженерам, которые программируют много лет. А в среднем — разработчикам, которые программируют от двух до пяти лет — обычно труднее всего. Когда разработчики делают всё по одному сценарию, а потом им говорят — можно задачу совсем иным подходом, — обычно человеку бывает сложно перестроиться. И тут дело именно в опыте разработки — он уже есть, но ещё не накопился до той критической массы, когда у программиста меняется подход к изучению нового.
Какие проекты лучше всего реализовывать на Clojure?
Clojure подходит для фуллстек-разработки, как и JS. Только Clojure будет намного более функциональнее. Да, существует Node.Js, но это достаточно медленный инструмент, который в скорости работы точно уступает Clojure.
Clojure лучше всего работает для финансового рынка, дата-аналитики, машинного обучения — сфер, где основной фокус делается на данных, которые нужно быстро обрабатывать.
Однако для веб и фронтенда Clojure тоже отлично работает, даже через собственные библиотеки, построенные на React. Знаю примеры, когда разработчики даже делали игры на Clojure — точнее, на нём делалась логика игры, все остальное, конечно, писалось в Unity.
Будет ли Clojure востребован в будущем?
Не думаю, что Clojure будет быстро расти или когда-нибудь заменит Java или JS. Но язык будут точно использовать компании, которые хотят построить большие и сложные системы, которые при этом не должны ломаться.
Вы изучали Clojure как первый язык или уже были программистом, когда решили его изучить? Есть ли смысл изучать Clojure в качестве первого языка?
Для начала я хотел бы прояснить, что активно использовал Clojure несколько лет — с 2011 по 2015 года. С тех пор лишь поддерживаю с десяток своих open source библиотек в той степени, в которой позволяет время.
Clojure для меня даже не был первым Lisp-ом, первым был Emacs Lisp. Изучать Clojure как первый язык имеет смысл, только если ваша работа как-то будет связана с данными. Если вы хотите разрабатывать интерфейсы, конечно, можно начать с ClojureScript, но куда практичнее будет JavaScript или TypeScript.
Программисту, который работает с другими языками, более распространенными, полезно освоить Clojure для профессионального роста?
Это достаточно уникальный язык даже через 10 лет после релиза. За это время произошел маленький Кембрийский взрыв в количестве используемых в индустрии языков. Почти каждую главную особенность Clojure — immutability, code-as-data, подход к полиморфизму и симбиоз с другими языками теперь можно найти где-то ещё. Но мало где их можно найти именно в такой комбинации, и особенно на платформах вроде JVM, Node и .NET.
Как именно Clojure помогает прокачаться разработчику, за счёт чего это происходит?
Clojure, философия её автора и сообщества открывают глаза на то, что очень маленький набор базовых концепций полностью достаточен для решения огромного количества задач. В мире хватает языков программирования, где кардинально больше концепций, и каждые несколько лет добавляются новые, а старые редко удаляются или пересматриваются. Некоторые языки так набиты фичами и частными случаями, что даже опытные люди и авторы языка по-настоящему понимают и используют лишь какую-то его часть.
После знакомства с Clojure вы перестанете думать, что это — единственный возможный вариант, и станете искать более простые решения во всём.
Какие есть особенности у Clojure? Какие очевидные плюсы и минусы есть у этого языка?
Плюсы
Immutability (очень важная вещь для языка, ориентированного на concurrency, на мой взгляд), отличная стандартная библиотека для работы с коллекциями. «Расширяемый» полиморфизм. Метапрограммирование может быть полезно, а может быть и нет.
Именно из-за минималистичности у Clojure несколько портов под разные рантаймы, и они действительно поддерживаются и используются.
Язык невозможно оценивать без какого-то мнения о его сообществе. Мне Clojure-сообщество нравится относительной зрелостью и отсутствием гонок за модой. Моим самым старым Clojure библиотекам 9 лет и я могу вспомнить лишь один раз, когда мне приходилось тратить время из-за изменений в языке. Backwards compatibility здесь одна из лучших в индустрии, и это опять же следствие компактности языка.
Минусы
Это нишевый и необычно выглядящий язык. Из-за этого некоторые люди и команды даже не рассматривают его. Это сужает количество потенциальных пользователей.
Компилятор Clojure иногда выдает совершенно неочевидные для новичков ошибки. Иногда это раздражает и опытных пользователей.
Лично на мой взгляд, многие ключевые люди в Clojure core team совершенно не ценят качество документации, а процесс контрибуций много лет требовал отправки бумажной почты (!!!) в Durham, NC. За последние годы в этих вещах произошел сдвиг, но некоторые люди в сообществе выгорели в процессе борьбы за эти изменения и покинули его.
Компиляция в Clojure происходит при запуске приложения, что на JVM делает время старта очень печальным. Это решаемо, но делает Clojure менее конкурентноспособным для ряда задач.
Почему из всех функциональных языков вы выбрали именно Clojure, а не, например, Haskell?
У меня за плечами пять-шесть функциональных языка за последние десять лет. Где-то в 2011 году у меня за плечами было года полтора использования Scala, до этого — несколько лет Java, Ruby. Мне хотелось что-то объединяющее Java и Ruby, но экосистема Scala на тот момент была на стадии становления с жуткими growing pains. Так, например, при выходе новой версии в 2011 году надо было ждать рекомпиляции по сути всей экосистемы, потому что изменения в компиляторе были почти всегда обратно-несовместимыми (binary incompatible).
На все эти адаптации тратилось большое количество времени. Clojure, как я упоминал выше, является полной противоположностью в этом смысле. Поэтому я решил попробовать его и остался очень доволен. Справедливости ради отметим, что тех пор в Scala многое поменялось, но история с обратной совместимостью по-прежнему далека от идеала.
Haskell — это отдельная вселенная, в то время как Clojure живет на платформах, которые очень широко распространены (JVM, Node, .NET). Сообщество и кривая изучения у Haskell совсем другие. Не сомневаюсь, что Haskell способен расширить горизонты не меньше, но Clojure мне кажется более практичным вариантом.
Haskell — язык, позволяющий глубже понять программирование. Как он устроен и почему его выбирают разработчики? Подробно разобрали, как устроен чистый функциональный язык программирования и отличиях этой парадигмы разработки от других.
Последние годы я в основном работаю с Erlang и Elixir. Это тоже небольшие функциональные языки с immutable data structures и своим подходом к concurrency. Elixir многое почерпнул у Clojure. Например, первый автор Mix — в прошлом один из ключевых авторов Leiningen. Если бы не отдельный runtime и экосистема, Elixir был бы очень сильным конкурентом Clojure по всем фронтам, и с куда более открытым автором и сообществом.
Если бы .NET Core существовал в текущем виде в 2011 году, я бы, наверное, выбрал F#: в нем есть почти все, что я люблю в Clojure, плюс статическая типизация и полезные сообщения об ошибках от компилятора.
Какие инструменты или фреймворки языка вы используете? Какие проекты лучше всего реализовывать на Clojure?
Мне Clojure кажется отличным вариантом для работы с данными, (микро)сервисами, где важна concurrency, или проблему хорошо решил бы DSL. Не уверен, что для UI-приложений рассмотрел бы ClojureScript: в этой сфере очень много альтернатив с огромными сообществами.
Есть ли спрос на программистов со знанием Clojure? В сочетании с какими языками и инструментами чаще всего работодатели ищут Clojure-разработчиков?
Сразу оговорюсь: я очень плохо представляю себе реалии спроса на навыки и найма инженеров на территории бывшего СССР. Все рассуждения ниже — в контексте мирового рынка.
На любой нишевый язык спрос не так велик, но иногда предложение даже меньше. На сегодняшний день Clojure в больших компаниях уже не удивителен, но основной спрос скорее со стороны стартапов. Масштабы спроса оценить не берусь, но знаю людей, которые хотели работать в основном с Clojure и довольно быстро к этому пришли. В индустрии определенно есть спрос на людей, открытых новым идеям и владеющих разными языками, и опыт с Clojure определенно будет плюсом с этой точки зрения.
Будет ли Clojure востребован в будущем?
Здесь уместно вставить XKCD про Lisp ;) Люди каждые десятилетия открывают для себя диалект Lisp-а. Этому семейству языков более 50 лет, и Clojure является очень практичным и современным вариантом. Думаю, и язык, и нишевый спрос, останутся. Clojure — это Porsche мира языков программирования в том смысле, что это вряд ли будет вашим единственным рабочим языком. Но в правильной команде и с подходящим use case-ом он может дать отличный результат.
Вы изучали Clojure как первый язык или уже были программистом, когда решили его изучить? Есть ли смысл изучать Clojure в качестве первого языка?
Я уже был полиглотом — Visual Basic, PHP, JS, Ruby, Java, C#, когда познакомился с Clojure. Конечно, Clojure хорош как первый язык, но вместе с ним все-таки придется разобраться и с Java, и с JavaScript.
Изучение Clojure позволит разработчику выйти на новый уровень, глубже понять программирование?
По моему мнению, Clojure — это венец динамических языков. Ричард Хикки создал Clojure с третьего раза в профессионально-сознательном возрасте. Clojure отличается простым концептуальным дизайном и этому стоит поучиться.
Как именно Clojure помогает прокачаться, за счёт чего это происходит?
Clojure позволяет работать с сутью решаемой проблемы, не отвлекаясь на «ритуалы». REPL и функциональная основа языка взаимодополняют друг друга — вы интерактивно пишете и исполняете простой код, не покидая emacs — и это много стоит!
Какие есть особенности у Clojure? Какие очевидные плюсы и минусы есть у этого языка?
Clojure рассчитан на профессионалов, понимающих, что и зачем они делают. Не стоит ожидать, что вас поведут за ручку добрые фреймворки — придется думать своей головой.
Почему из всех функциональных языков вы выбрали именно Clojure, а не, например, Хаскель?
Хаскель слишком долго компилируется :) Хаскель состоит из двух парадигм — функционального программирования и программирования на типах. Причем вторая часть толще, сложнее и бесполезнее, даже порой вреднее, для большинства задач.
Какие инструменты или фреймворки языка вы используете?
В Clojure предпочитают библиотеки фреймворкам. Где-то треть библиотек мы себе разработали сами. Интересный феномен — если в Clojure библиотеку уже не коммитили около года, это не значит, что она мертва. Возможно, она просто закончена и больше нечего добавить.
Какие проекты лучше всего реализовывать на Clojure?
Clojure — прагматичный язык общего назначения, на котором прекрасно пишутся бизнесовые back и front, и даже системные вещи, типа баз данных (datomic).
Есть ли спрос на программистов со знанием Clojure? В сочетании с какими языками и инструментами чаще всего работодатели ищут Clojure-разработчиков?
Мы нанимаем на постоянной основе. Речь не идет о программисте на «X» — мы (и другие сознательные конторы) ищем инженеров с «правильным» мышлением, умеющих эффективно, просто и элегантно решать сложные проблемы. А на Clojure это делать приятно и легко.
Будет ли Clojure востребован в будущем?
В раскрутку Clojure, в отличии от многих других «корпоративных» языков, никто не вливал много денег. Это крепкое и пассионарное сообщество профессионалов, которое растет естественным образом. Те, кто пришли к нам несколько лет назад, уже внедрили Clojure в production — и это залог будущего для языка. Я не вижу пока никаких признаков заката, скорее стабильный нехайповый рост — и это хорошо для экосистемы.
По сравнению с разработчиками, которые пишут на JS или Python, спрос на Clojure-программистов намного ниже. Несмотря на это, на HH есть вакансии, где требуются именно инженеры, которые смогут писать на этом языке программирования. На HH на сегодняшний день есть 12 вакансий Clojure-разработчиков, а на «Хабр.Карьере» — 2 вакансии, обе от компании Health Samurai.
Средняя зарплата Junior Clojure Developer, которую предлагают компании, составляет от 70 тыс. до 150 тыс. рублей. При этом в Health Samurai отмечают, что первоначальные знания Clojure не являются обязательными.
Вакансии уровня Senior для программиста со знанием Clojure или желанием погрузиться в изучение Лисп-языков, начинаются от 270 тыс. рублей в месяц.
На Хекслете сейчас нет курсов изучения Clojure, однако есть отдельный курс по функциональному программированию для JavaScript, вебинар на эту тему от разработчика Никиты Соболева или программиста Александра Гранина, бесплатный курс по языку Racket и небольшой курс по функциональному языку программирования Erlang.
Документацию к Clojure вы можете посмотреть на официальном сайте языка.
Кроме того, мы используем Clojure в open source проекте Codebattle, если хотите поучаствовать и попробовать изучить Clojure, то пишите нам.