Я принес вам программируемый язык программирования!
В 2014 году группа профессиональных разработчиков на Clojure под руководством Дмитрия Бушенко провела первые и единственные онлайн-курсы по языку Clojure на русском языке.
Специально для курса мы записали 71 оригинальное видео общей продолжительностью 17 часов 25 минут и 44 секунды. Курс пользовался успехом — пришло более 200 человек, но материалы в открытом доступе не публиковались.
Этот сайт — те самые материалы.
Мы публикуем их в том виде, в каком они есть. Лекции сами по себе связные, полные и самодостаточные. Они даже почти не устарели (на июнь 2016-го), хотя, конечно, появилось и много нового. Задания тоже можете порешать — это ровно те файлы, которые выдавались на дом слушателям курса в 2014-м.
Предвидя вопрос: новых курсов, с группами, менторами, проверкой домашек в ближайшее время не будет.
Ну, поехали!
Задание: необходимо сделать простую базу данных на основе CSV-файлов. Файлы, с которыми предлагается работать в задании: student.csv
, student_subject.csv
, subject.csv
(находятся в архиве). Эти три файла реализуют связи типа «многие-ко-многим», т.е. один student может изучать множество subject-ов, один subject может принадлежать множеству student-ов.
Заготовка кода представлена в файле src/csvdb/core.clj
. Поскольку это простая база данных, мы будем реализовывать только различные виды запроса select, например, такие:
(select student
:where #(> (:id %) 1)
:order-by :year
:limit 2)
(select student-subject
:limit 2
:joins [[:student_id student :id]
[:subject_id subject :id]])
Выполнять эти запросы нужно в REPL, поэтому никакой дополнительной системы ввода-вывода для консоли писать не нужно.
Часть функций в заготовке помечены ключевым словом :ImplementMe
— эти функции вам необходимо реализовать. Перед каждой такой функцией в комментариях дан пример вызова функций, а снизу, после знака =>
— результат вызова этой функции. В комментарии, после слова Hint
, дана подсказка: список clojure-функций, которые я использовал для реализации этой функции.
После того, как вы реализуете все функции, выполните команду lein test
и убедитесь, что тесты проходят.
Также доступны слайды
Реализуйте многопоточный сервер базы данных, принимающий на вход строковые sql-запросы, и возвращающий результат в виде EDN.
Проект task02.zip содержит заготовку этого сервера. Реализуйте недостающие части кода, отмеченные в тексте маркером :implement-me
. Код должен соответствовать существующим тестам, запустите их командой lein test
.
Обратите внимание, что в project.clj
некоторые неймспейсы помечены для компиляции:
:aot [task02.Database task02.core]
core.clj
содержит класс task02.core
и функцию main
, которая загружает данные и запускает сервер.db.clj
содержит заготовку базы данных, которую мы начали реализовывать в первом ДЗ. На этот раз данные можно изменять, удалять, добавлять.query.clj
содержит функцию perform-query
, которая выполняет разбор запроса и выполняет этот запрос. Запрос можно передавать в виде текстовой строки, как обычный sql-запрос.Database.clj
используется для создания класса Database
, который можно будет импортировать из любого Java-проекта и использовать его.Для того, чтобы скомпилировать ваш проект и установить его в локальный maven-репозиторий, выполните команды lein compile && lein install
.
Дополнительно разработан клиент нашей БД — task02-java-client. Этот клиент написан на Java. Обратите внимание, как в pom.xml
импортируется наш проект task02
:
<dependency>
<groupId>by.clojurecourse</groupId>
<artifactId>task02</artifactId>
<version>0.1.0</version>
</dependency>
Обратите внимание также на библиотеку работы с EDN в Java:
<dependency>
<groupId>us.bpsm</groupId>
<artifactId>edn-java</artifactId>
<version>0.4.4</version>
</dependency>
Для того, чтобы скомпилировать java-клиент, необходимо выполнить команду mvn -q compile
.
Для того, чтобы запустить клиент:
lein run
,
mvn -q exec:java -Dexec.mainClass="task02.Client" -Dexec.args="'select student'"
Последний аргумент команды — запрос к базе данных.
Для тех, кому это задание покажется слишком простым, дополнительно предлагается реализовать следующее:
На этот раз мы рассматриваем сразу две темы: средства метапрограммирования в Clojure и доступ к данным из Clojure. Задание по макросам — обязательное, задание по базам данных — опциональное.
Разработать предметно-ориентированный язык программирования для удобной работы с датами и временем. Основа языка — макрос with-datetime
, который анализирует код внутри себя и выполняет необходимые замены. Внутри этого макроса должны работать операции сравнения двух дат как чисел, а также операции создания новой даты на основе указанной, например ((java.util.Date.) + 1 day)
.
Формат синтаксиса сравнения дат: (> date1 date2)
, поддерживаемые операторы сравнения — >
, <
, >=
, <=
Формат синтаксиса создания даты: (дата операция количество период)
, где:
дата
— переменная или вызов функци, возвращающий дату, объект java.util.Date
;
операция
— только +
или -
количество
— число, переменная или функция, возвращающая целое число;
период
— символ периода, поддерживаются следующие периоды: day days week weeks month months year years hour hours minute minutes second seconds
. Период в единственном числе (например, day
) ничем не отличается от периода во множественном числе (например, days
) и служит только для того, чтобы конструкции (today + 1 day)
и (today + 2 days)
читались «правильно» по-английски.
Пример использования языка:
;; Заготовки дат
(import '[java.util Calendar Date])
(def cal (Calendar/getInstance))
(def today (Date.))
(def yesterday
(do
(.add cal Calendar/DATE -1)
(.getTime cal)))
(def tomorrow
(do
(.add cal Calendar/DATE 2)
(.getTime cal)))
;; Использование нашего макроса
(with-datetime
(when (> today tomorrow)
(println "Time goes wrong"))
(when (<= yesterday today)
(println "Correct"))
(let [six (+ 1 2 3)
d1 (today - 2 days)
d2 (today + 1 week)
d3 (today + six months)
d4 (today + (one) year)]
(if (and (< d1 d2)
(< d2 d3)
(< d3 d4))
(println "DSL works correctly"))))
Файл с заданием, он же с подсказками
В архиве задания находится файл features.2014.edn
. Это кусочек базы данных IMDb за 2014 год. Вам нужно:
Замените в исходном файле datomic.clj
места, помеченные как :TODO
на реализацию по вашему усмотрению и выполните:
lein run -m datomic/reset
lein run -m datomic/import
lein test
Для работы потребуется запущенный Datomic. Бесплатную версию можно скачать с их сайта.
Цель последней части курсов — научить разрабатывать web-приложения на Clojure. Поэтому основные лекции для этой части — лекции по Ring, Compojure и ClojureScript. Помимо этих лекций в виде бонуса предлагаем посмотреть видео о core.async и websocket-ах. Эти технологии могут оказаться полезными при выполнении последнего задания.
Файл с исходником из лекции по Compojure
Заготовка проекта из лекции про ClojureScript
Заготовка проекта из лекции про блог на ClojureScript
Это наше последнее задание, оно является творческим. Я предлагаю вам разработать веб-приложение на Clojure. Сервер предлагаю сделать на основе Ring/Compojure, базу данных можете выбрать самостоятельно. Клиентская часть должна быть реализована по большей части на ClojureScript и работать без перезагрузки html-страницы. Разработанное приложение предлагаю задеплоить в Интернете на OpenShift или Heroku. Видео о том, как деплоить на OpenShift я выложу в ближайшие дни (увы, данное видео, похоже, утеряно, но есть запись в блоге Димы)
Многие из вас слышали гундосые причитания скептиков: «Clojure это игрушка для теоретиков», «никто не сможет это поддерживать», «это никогда не применит ни одна компания» и тому подобное. Никита Прокопов просто смеется над этим.
Он трудится в мощной международной компании Echo и эффективно применяет Clojure в работе. Он, как Прометей, несет свет истины со страниц своего блога (к слову, самого популярного личного блога про Clojure в рунете). Он выступает лично на IT мероприятиях.
На наших курсах вы сможете воспользоваться знаниями и опытом Никиты самым прямым образом — не упустите такой шанс!
В 2010 году мой коллега, которого мы считали слегка чокнутым, приволок на работу очередной выпуск журнала «Функциональное программирование», отпечатанный, что характерно, на черно-белом струйном принтере. Это был один из первых выпусков и мне запомнилась статья Алекса Отта о Clojure. Именно из нее я, как и многие другие программисты, узнал об этом языке. Название было попсовое — «Вы все еще используете Java? Тогда мы идем к вам», однако содержание статьи не подкачало и надолго въелось в мозг.
В данный момент Алекс специализируется на информационной безопасности и контентной фильтрации данных. И, хотя его основным языком сейчас является C/C++, он не забывает функциональщину, в том числе Clojure. Преодолевая рабочую загруженность, он участвует в open source проектах и переводить книги, например участвовал в переводе Practical Common Lisp и Introduction to Functional Programming.
На этом Алексей не остановился и продолжает писать статьи, записывать лекции и выступать публично, славя и продвигая эту замечательную технологию. Будет он помогать и тем, кто захочет изучить основы и тонкости Clojure в рамках нашего курса.
И еще он Emacs-ниндзя, не знаю как это поможет нашим ученикам, но уверен, что это важно :)
Увлеченный программист, интересующийся самыми модерновыми технологиями. В прошлой жизни программировал на C++, C# и Java, но после прочтения эпичнейшего холивара появилось новое хобби: маргинальные технологии, не попавшие в мейнстрим. Из наиболее любимых — Clojure и Emacs Lisp. В прошлом году провел онлайн/оффлайновые курсы по Clojure, также публикует учебные видео по Emacs и Emacs Lisp.
С гордостью представляем вам следующего лектора — Крейгтона Киркендалла. Крейг живет в Цинциннати, США и уже более 16 лет профессионально занимается программированием. Сейчас он работает системным архитектором в Systems Evolution.
Крейг увлекается функциональным программированием в общем и Lisp-ами в частности. Особенно ему нравится язык CloureScript, для которого он разработал библиотеку Enfocus, предназначенную для манипулирования DOM. Крейг является комиттером и в другие opensource-проекты.
Крейг согласился помочь нам в подготовке курсов и записал для нас лекцию про манипулирование DOM и правильное использование библиотеки Enfocus. Кто, как не автор, научит вас правильно использовать эту библиотеку? Присоединяйтесь к нам, это отличный шанс получить правильные знания о языке Clojure!
Никита — талантливый программист, призер нескольких олимпиад по программированию, первый в Беларуси, кто решился преподавать курс по Clojure в университете, один из менторов нашего прошлогоднего курса по Clojure. Сейчас живет в Лондоне, работает в Google.
Илья — один из лучших слушателей первого курса по Clojure, который мы проводили год назад. На этот раз Илья решил выступить в роли ментора и записал для нас лекцию по WebSocket-ам.
Известный во Владивостоке IT-активист, организатор различных IT-конференций, классный программист и настоящий русский богатырь. Илья помогает нам с PR-ом курсов, пишет тексты для сайта clojurecourse.by.
Коммьюнити-менеджер в компании Altoros. Ольга помогла нам с разработкой сайта, предоставив дизайнера и верстальщика. Кроме того, Ольга (от имени компании Altoros) предоставляет нам помещение для будущих встреч любителей Clojure.
Курсы закончились, но общение продолжается. Любой вопрос вы можете задать в фейсбук-группе курса, которая за это время превратилась в клуб по интересам.
Удачи в изучении Clojure!