<?xml version="1.0"?>
<rss version="2.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007" xmlns:atom="http://www.w3.org/2005/Atom">
   <channel>
      <title>Russian Clojure Planet</title>
      <description>Pipes Output</description>
      <link>http://pipes.yahoo.com/pipes/pipe.info?_id=16a2f0518462dcc95c054226eb1c7a42</link>
      <atom:link rel="next" href="http://pipes.yahoo.com/pipes/pipe.run?_id=16a2f0518462dcc95c054226eb1c7a42&amp;_render=rss"/>
      <pubDate>Thu, 01 Oct 2015 23:22:58 +0000</pubDate>
      <generator>http://pipes.yahoo.com/pipes/</generator>
      <item>
         <title>Готовится перевод &quot;Clojure Programming&quot;</title>
         <link>http://alexott-ru.blogspot.com/2013/01/clojure-programming.html</link>
         <description>Издательство &quot;ДМК-Пресс&quot; продолжает серию переводов книг про новые языки программирования, и следующая вещь в списке - &quot;Clojure Programming&quot;. Перевод уже начался, и они ищут людей которые помогут с технической вычиткой перевода.&amp;nbsp; Если кому-то интересно, то пишите на dm at dmk-press.ru.</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-565993793918682080</guid>
         <pubDate>Fri, 11 Jan 2013 09:40:00 +0000</pubDate>
      </item>
      <item>
         <title>Выступление про Clojure на ITSea 2012</title>
         <link>http://alexott-ru.blogspot.com/2012/09/clojure-itsea-2012.html</link>
         <description>На прошлой неделе я рассказывал про Clojure на небольшой конференции ITSea (совмещенной с купанием в море и т.п. :-), и затем еще давал небольшой мастер-класс на тему практического использования Clojure. Слайды &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.slideshare.net/alexott/clojure-lisp-for-the-modern-world&quot;&gt;доступны на slideshare&lt;/a&gt; (а вот записи выступления к сожалению не было):&lt;br /&gt; Данный постинг является дополнением к этим слайдам, и содержит ссылки на разные ресурсы, упоминавшиеся в рассказе:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure.org/&quot;&gt;Сайт языка&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.net/ru/fp/books/&quot;&gt;Список доступных книг про Clojure&lt;/a&gt; (разделы про конкретные языки в обзоре литературы по ФП)&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.net/ru/clojure/clojure-intro/index.html&quot;&gt;Введение в Clojure на русском языке &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.net/ru/clojure/video.html&quot;&gt;Список видео-лекций и презентаций про Clojure&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://planet.clojure.in/&quot;&gt;Planet Clojure&lt;/a&gt; - аггрегатор блогов&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://dev.clojure.org/display/doc/Getting+Started&quot;&gt;Getting started with Clojure&lt;/a&gt; - описание первых шагов, включая установку и настройку средств разработки &lt;/li&gt;&lt;li&gt;Интерактивные ресурсы/учебники: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.4clojure.com/problems&quot;&gt;4Clojure&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://tryclj.com/&quot;&gt;TryClojure&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://himera.herokuapp.com/index.html&quot;&gt;Himera&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/relevance/labrepl&quot;&gt;labrepl&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Списки рассылки: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://groups.google.com/forum/?hl=ru&amp;amp;fromgroups#!forum/clojure&quot;&gt;clojure&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://groups.google.com/forum/?hl=ru&amp;amp;fromgroups#!forum/clojure-russian&quot;&gt;clojure-russian&lt;/a&gt; &lt;/li&gt;&lt;li&gt;IDE/редактора (остальные редактора/IDE описаны в подразделах Getting Started): &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://dev.clojure.org/display/doc/Getting+Started+with+Eclipse+and+Counterclockwise&quot;&gt;Eclipse&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://dev.clojure.org/display/doc/Getting+Started+with+La+Clojure+and+IntelliJ+IDEA&quot;&gt;IntelliJ IDEA&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Средства сборки: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.net/ru/clojure/ClojureMaven.html&quot;&gt;поддержка Clojure в Maven&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/technomancy/leiningen&quot;&gt;Leiningen &lt;/a&gt;&lt;/li&gt;&lt;li&gt;Библиотеки/фреймворки: &lt;ul&gt;&lt;li&gt;Web: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/ring-clojure/ring&quot;&gt;Ring&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/weavejester/compojure&quot;&gt;Compojure&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.webnoir.org/&quot;&gt;Noir, &lt;/a&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/weavejester/hiccup&quot;&gt;Hiccup&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/weavejester/lein-ring&quot;&gt;lein-ring&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/clojure/clojurescript&quot;&gt;ClojureScript&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojurescriptone.com/&quot;&gt;ClojureScript One&lt;/a&gt;, l&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/emezeske/lein-cljsbuild&quot;&gt;ein-cljsbuild&lt;/a&gt;&lt;/li&gt;&lt;li&gt;SQL: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://sqlkorma.com/&quot;&gt;Korma&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/clojure/java.jdbc&quot;&gt;clojure.java.jdbc&lt;/a&gt;&lt;/li&gt;&lt;li&gt;NoSQL: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojuremongodb.info/&quot;&gt;Monger&lt;/a&gt; (MongoDB), &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/clojure-clutch/clutch&quot;&gt;Clutch&lt;/a&gt; (CouchDB), &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/compasslabs/clojure-hbase-schemas&quot;&gt;clojure-hbase-schemas&lt;/a&gt; (HBase)&lt;/li&gt;&lt;li&gt;GUI: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/daveray/seesaw&quot;&gt;Seesaw&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/clojure/core.logic&quot;&gt;core.logic&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://dev.clojure.org/display/doc/Clojure+Contrib&quot;&gt;Contrib libraries&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Внутреннее устройство persistent коллекций: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/&quot;&gt;вектора&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice/&quot;&gt;отображения&lt;/a&gt; (maps)&lt;/li&gt;&lt;/ul&gt;</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-9038843391490053436</guid>
         <pubDate>Tue, 25 Sep 2012 16:24:00 +0000</pubDate>
      </item>
      <item>
         <title>Clojure 1.4!</title>
         <link>http://alexott-ru.blogspot.com/2012/04/clojure-14.html</link>
         <description>А между тем, незаметно подкрался релиз новой версии языка Clojure - 1.4.&lt;br /&gt;Rich Hickey называет этот релиз в основном maintenance, хотя есть и достаточно крупные изменения:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Расширяемая процедура чтения (reader) - разработчик может указать функцию чтения для своих типов данных. Разработчик должен указать метку для своего типа данных, и соответствующую функцию чтения, и данная функция будет вызвана после того, как следующая (после метки) форма будет считана стандартным reader. Например, можно будет писать вот так:&lt;code&gt; &lt;span style=&quot;&quot;&gt;#foo/bar [1 2 3]&lt;/span&gt; &lt;/code&gt;- в этом случае, после чтения метки, процедура чтения сначала считает форму &lt;code style=&quot;&quot;&gt;[1 2 3]&lt;/code&gt;, а затем вызовет процедуру связанную с данной меткой (если она определена) и передаст ей прочитанные данные. В состав новой версии вошла поддержка чтения двух новых типов - &lt;span style=&quot;&quot;&gt;#inst&lt;/span&gt; - для времени и даты, и &lt;span style=&quot;&quot;&gt;#uuid&lt;/span&gt; - для UUID.&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&amp;nbsp;Новый синтаксис для доступа к полям записей (унифицировано с ClojureScript) - теперь можно писать &lt;span style=&quot;&quot;&gt;(.-field_name record-instance)&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;Возможность контролировать поведение компилятора Clojure с помощью опций, указанных через переменную &lt;span style=&quot;&quot;&gt;*compiler-options*&lt;/span&gt;.&lt;/li&gt;&lt;/ul&gt;Остальные изменения включают в себя добавление новых функций в базовую библиотеку, достаточно много исправлений ошибки, оптимизации производительности. &lt;br /&gt;Полный список изменений можно &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/clojure/clojure/blob/master/changes.md&quot;&gt;найти в репозитории&lt;/a&gt;. Кроме того, может быть интересным &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.infoq.com/interviews/hickey-clojure-reader&quot;&gt;интервью Rich Hickey&lt;/a&gt; в котором он рассказывает про некоторые изменения в новой версии.</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-2846300617728437076</guid>
         <pubDate>Sun, 15 Apr 2012 18:46:00 +0000</pubDate>
      </item>
      <item>
         <title>Что нового в Clojure 1.3?</title>
         <link>http://alexott-ru.blogspot.com/2011/09/clojure-13.html</link>
         <description>&lt;p&gt;Сегодня ночью была выпущена новая версия &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure.org/&quot;&gt;языка Clojure&lt;/a&gt; &amp;mdash; 1.3.  Что нового в этой версии? Давайте рассмотрим основные изменения сделанные в этой версии (детальный список изменений можно найти &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/clojure/clojure/blob/1.3.x/changes.txt&quot;&gt;в соответствующей ветке репозитория&lt;/a&gt;).&lt;/p&gt;&lt;h3&gt;Расширенная поддержка примитивных типов&lt;/h3&gt;&lt;p class=&quot;first&quot;&gt;В предыдущих версиях, примитивные типы (long, double, etc.) поддерживались только для локальных арифметических операций и при объявлении полей &lt;code&gt;deftype&lt;/code&gt;/&lt;code&gt;defrecord&lt;/code&gt;, но не для аргументов функций и не для возвращаемых значений.  Boxing выполнялся всегда, что часто приводило к ощутимым накладным расходам.&lt;/p&gt;&lt;p&gt;В новой версии примитивные типы поддерживаются в полной мере, что приводит к значительному увеличению производительности кода (в соответствующих тестах, в среднем в 3-5 раз).  Соответственно изменилась работа с арифметическими выражениями &amp;mdash; для примитивных типов будут использоваться стандартные операторы Java.  Но при этом не будет происходит автоматического превращения в &amp;quot;Big*&amp;quot; типы при переполнении, как это происходило раньше &amp;mdash; вместо этого будет брошено исключение.  Если вам все-таки нужно автоматическая конвертация, то вы можете использовать операторы &lt;code&gt;+'&lt;/code&gt;, &lt;code&gt;*'&lt;/code&gt;, и т.д., хотя они и более медленные.  Битовые операции теперь только поддерживаются для примитивных типов, и вся их поддержка для &amp;quot;Big*&amp;quot; была убрана из языка.&lt;/p&gt;&lt;p&gt;Для использования примитивных типов вам необходимо добавить соответствующие type hints, например:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;(&lt;span style=&quot;color:#7f007f;&quot;&gt;defn&lt;/span&gt; &lt;span style=&quot;color:#0000ff;&quot;&gt;fib&lt;/span&gt; &lt;span style=&quot;color:#218a21;&quot;&gt;^long&lt;/span&gt; [&lt;span style=&quot;color:#218a21;&quot;&gt;^long&lt;/span&gt; n]&lt;br /&gt;    (&lt;span style=&quot;color:#473c8a;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color:#9f522c;&quot;&gt;&amp;lt;=&lt;/span&gt; n 1)&lt;br /&gt;        1&lt;br /&gt;        (&lt;span style=&quot;color:#9f522c;&quot;&gt;+&lt;/span&gt; (fib (&lt;span style=&quot;color:#9f522c;&quot;&gt;dec&lt;/span&gt; n)) (fib (&lt;span style=&quot;color:#9f522c;&quot;&gt;-&lt;/span&gt; n 2)))))&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Более подробно обо всем этом &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://dev.clojure.org/display/doc/Documentation+for+1.3+Numerics&quot;&gt;на соответствующей странице JIRA&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Улучшения &lt;code&gt;defrecord&lt;/code&gt; и &lt;code&gt;deftype&lt;/code&gt;&lt;/h3&gt;&lt;p class=&quot;first&quot;&gt;В версии 1.3 были сделаны различные улучшения для работы с  &lt;code&gt;defrecord&lt;/code&gt; и &lt;code&gt;deftype&lt;/code&gt;:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;новый синтаксис для чтения и записи &amp;mdash; либо с метками (&lt;code&gt;#myns.MyRecord{:a 1, :b 2}&lt;/code&gt; &amp;mdash; только для записей), либо позиционный (&lt;code&gt;#myns.MyRecord[1 2]&lt;/code&gt; &amp;mdash; для записей и типов);&lt;/li&gt;&lt;li&gt;автоматическая генерация функций для создания типов и записей: &lt;code&gt;myns/map-&amp;gt;MyRecord&lt;/code&gt; (только для записей) и &lt;code&gt;myns/-&amp;gt;MyRecord&lt;/code&gt; (для записей и типов).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Подробнее можно прочитать вот &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://dev.clojure.org/display/design/defrecord+improvements&quot;&gt;тут&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Reflection API&lt;/h3&gt;&lt;p class=&quot;first&quot;&gt;Введено новое пространство имен &lt;code&gt;clojure.reflect&lt;/code&gt;, функции которого должны обеспечить более удобную и быструю работу с классами, методами и т.д.  Подробнее об этом &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://dev.clojure.org/display/design/Reflection+API&quot;&gt;тут&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Модульный &lt;code&gt;clojure-contrib&lt;/code&gt;&lt;/h3&gt;&lt;p class=&quot;first&quot;&gt;Начиная с версии 1.3, больше не существует монолитного набора библиотек известного как &lt;code&gt;clojure-contrib&lt;/code&gt; &amp;mdash; вместо этого, были созданы отдельные проекты для каждой из библиотек, что позволяет им развиваться и выпускаться независимо друг от друга. Полный список всех старых библиотек, и соответствующих им новых, можно найти на &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go&quot;&gt;отдельной странице&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Множественные улучшения производительности&lt;/h3&gt;&lt;p class=&quot;first&quot;&gt;Кроме улучшений в части производительности, описанных выше, в новом релизе сделано множество изменений чтобы обеспечить более высокую скорость работы программ на Clojure:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Более быстрый доступ к переменным;&lt;/li&gt;&lt;li&gt;Ускорение загрузки&lt;/li&gt;&lt;li&gt;Promises не используют блокировок (locks);&lt;/li&gt;&lt;li&gt;Инлайнинг &lt;code&gt;nil?&lt;/code&gt;, битовых функций, математических операций, функций &lt;code&gt;min&lt;/code&gt; &amp;amp; &lt;code&gt;max&lt;/code&gt; с разным числом аргументов;&lt;/li&gt;&lt;li&gt;и многое другое...&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Прочее&lt;/h3&gt;&lt;p class=&quot;first&quot;&gt;Помимо новой функциональности описанной выше, а также различных исправлений ошибок, в новой версии реализованы новые вещи (перечислены не все):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Некоторые вспомогательные пространства имен (&lt;code&gt;clojure.set&lt;/code&gt;, &lt;code&gt;clojure.xml&lt;/code&gt;, &lt;code&gt;clojure.zip&lt;/code&gt;) не загружаются при запуске;&lt;/li&gt;&lt;li&gt;Объявления сделанные с помощью &lt;code&gt;def&lt;/code&gt; более не являются &amp;quot;динамическими&amp;quot; по умолчанию &amp;mdash; вы должны использовать &lt;code&gt;^:dynamic&lt;/code&gt; если хотите иметь возможность использования ее в &lt;code&gt;binding&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;Улучшенные сообщения об ошибках и исключениях;&lt;/li&gt;&lt;li&gt;Можно вызвать &lt;code&gt;deref&lt;/code&gt; с указанием таймаута;&lt;/li&gt;&lt;li&gt;Функция &lt;code&gt;comp&lt;/code&gt; возвращает &lt;code&gt;identity&lt;/code&gt; если вызвана без параметров;&lt;/li&gt;&lt;li&gt;Возможность указания разных возвращаемых типов в объявлениях одной функции с разными количествами аргументов;&lt;/li&gt;&lt;li&gt;Некоторые функции перемещены в другие пространства имен;&lt;/li&gt;&lt;/ul&gt;</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-4611071960834885318</guid>
         <pubDate>Sat, 24 Sep 2011 16:14:00 +0000</pubDate>
      </item>
      <item>
         <title>Monad tutorial для кложуры</title>
         <link>http://alexott-ru.blogspot.com/2011/04/monad-tutorial.html</link>
         <description>&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.vimeo.com/user5897815/videos&quot;&gt;Серия слайдкастов&lt;/a&gt; про монады на примере Clojure сделанный &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.exampler.com/blog/&quot;&gt;Brian Marick.&lt;/a&gt; &lt;br /&gt;Первая лекция начинается со следующей фразы &quot;Существует предсказание, что когда-то, каждый человек на земле сделает monad tutorial, и высшая цель вселенной будет достигнута, и все человечество попадет в рай...&quot; :-)</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-766601932602622688</guid>
         <pubDate>Thu, 07 Apr 2011 09:40:00 +0000</pubDate>
      </item>
      <item>
         <title>Дайджест прочитанных книг. Январь 2011</title>
         <link>http://alexott-ru.blogspot.com/2011/02/2011.html</link>
         <description>&lt;p&gt;Как вы наверное уже заметили, в прошлом месяце не было обзора литературы &amp;mdash; было слишком много дел, поэтому никакой книги я читать не закончил.  Но зато рождественские и новогодние праздники позволили прочитать больше книг.&lt;/p&gt;&lt;div class=&quot;contents&quot;&gt;&lt;dl&gt;&lt;dt&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#sec1&quot;&gt;DSLs in Action&lt;/a&gt;&lt;/dt&gt;&lt;dt&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#sec2&quot;&gt;Camel in Action&lt;/a&gt;&lt;/dt&gt;&lt;dt&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#sec3&quot;&gt;Test-driven development: By Example&lt;/a&gt;&lt;/dt&gt;&lt;/dl&gt;&lt;/div&gt;&lt;h2&gt;&lt;a rel=&quot;nofollow&quot; name=&quot;sec1&quot; id=&quot;sec1&quot;&gt;&lt;/a&gt;DSLs in Action&lt;/h2&gt;&lt;p class=&quot;first&quot;&gt;Давно собирался почитать что-то про domain specific languages (DSL) чтобы найти новые идеи, сравнить с тем что я сам делаю (у меня есть несколько DSL, которые я применяю в рабочих проектах), может быть улучшить свои решения.  Мой выбор пал на &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.com/gp/product/1935182455?ie=UTF8&amp;amp;tag=aleottshompag-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1935182455&quot;&gt;DSLs in Action&lt;/a&gt;, написанную Debasish Ghosh, который является достаточно известным разработчиком в Scala сообществе, хотя использует и другие языки, например, Haskell, Groovy, Clojure.  Когда я выбирал что почитать, я также смотрел в сторону книги &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.com/gp/product/0321712943?ie=UTF8&amp;amp;tag=aleottshompag-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0321712943&quot;&gt;Domain-Specific Languages&lt;/a&gt;, написанную Martin Fowler, но Manning прислал очередную партию скидок, и я купил книгу у них (и не пожалел).&lt;/p&gt;&lt;p&gt;Книга написана очень простым языком, но при этом дается материал очень высокого качества. Автор показывает различные приемы разработки DSL используя разные языки &amp;mdash; Ruby, Groovy, Scala, Clojure (в книге используются только языки, работающие только на JVM, и многие вещи применимы только к этой платформе).  Это позволяет показать разные подходы к проектированию и реализации DSL (есть также &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://debasishg.blogspot.com/2011/02/why-i-made-dsls-in-action-polyglotic.html&quot;&gt;статья в блоге автора&lt;/a&gt; о том, почему использовались разные языки).&lt;/p&gt;&lt;p&gt;Первая часть книги посвящена основам DSL &amp;mdash; автор начинает рассказ с описания что такое DSL, из чего они состоят, какие бывают виды DSL, как они выполняются, преимущества и недостатки использования DSL в ваших проектах.  Отдельно описывается то, как моделируются предметные области, и как они влияют на структуру DSL.&lt;/p&gt;&lt;p&gt;Вторая глава демонстрирует простой DSL, который реализован с помощью стандартной Java, и анализируются недостатки конкретного подхода.  Затем, аналогичный DSL создается с помощью Groovy, и рассматриваются его преимущества по сравнению с первой реализаций.  В остальной части главы рассматриваются паттерны реализации DSL, с учетом предыдущей информации.&lt;/p&gt;&lt;p&gt;Третья глава посвящена вопросам интеграции DSL в основной проект.  В ней обсуждаются java scripting engine, интеграция на базе Spring, и т.д.  Для каждого из возможных подходов, рассматриваются преимущества и недостатки данного подхода, то, как он может повлиять на реализацию DSL, и т.д.&lt;/p&gt;&lt;p&gt;Вторая часть (главы 4-8) посвящены реализации DSL на конкретных языках программирования. 4-я глава описывает основные приемы реализации внедряемых (internal) DSL &amp;mdash; мета-программирование, типизированные абстракции, генерацию кода во время компиляции и т.д.  И следующие две главы (5 и 6), подробно показывают как эти абстракции применяются при реализации DSL на Ruby, Groovy, Clojure и Scala.&lt;/p&gt;&lt;p&gt;Седьмая глава продолжает тему реализации DSL, но уже с точки зрения использования внешних (external) DSL.  Рассматриваются разные виды парсеров, с помощью которых можно разбирать код использующий DSL, показывается небольшой пример использования ANTLR для генерации парсеров, и приводится небольшое описание Xtext &amp;mdash; фреймворка для Eclipse, который упрощает разработку внешних DSL.&lt;/p&gt;&lt;p&gt;В восьмой главе продолжается тематика использования внешних DSL и в ней показывается применение комбинаторов парсеров для разбора исходного кода DSL.  Глава начинается с небольшого описания того, что такое комбинаторы парсеров, а затем показывается пример использования комбинаторов парсеров в Scala для работы с внешними DSL.&lt;/p&gt;&lt;p&gt;И в заключительной части книги рассматриваются текущие тенденции в части разработки и использования DSL, утилит для упрощения разработки, и сопутствующие темы.&lt;/p&gt;&lt;p&gt;Кроме основного материала, в книге имеется несколько приложений, в которых собраны краткие описания используемых языков, что позволяет ознакомиться с примерами даже тем людям, которые не программируют на конкретных языках.  Отдельно стоит упомянуть &amp;quot;философское&amp;quot; приложение A, которое посвящено обсуждению роли абстракций в моделировании предметной области, влиянию чистоты, отсутствия побочных эффектов на разработку, и сопутствующим проблемам. Кроме этого, может быть интересным приложение B, где обсуждается роль мета-программирования в разработке DSL.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Заключение:&lt;/em&gt; если вы используете и/или разрабатываете DSL, или вам просто интересна эта тема, то книгу обязательно стоит прочитать &amp;mdash; в ней много практической информации, которая будет полезна при разработке DSL.&lt;/p&gt;&lt;h2&gt;&lt;a rel=&quot;nofollow&quot; name=&quot;sec2&quot; id=&quot;sec2&quot;&gt;&lt;/a&gt;Camel in Action&lt;/h2&gt;&lt;p class=&quot;first&quot;&gt;Для очередного из &amp;quot;домашних&amp;quot; проектов понадобилось слепить систему обработки данных из разных источников, поэтому погуглив, я нашел &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://camel.apache.org/&quot;&gt;Apache Camel&lt;/a&gt;, который показался мне интересным и достаточно зрелым проектом, а на очередной маннинговской распродаже я прикупил книжку &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.com/gp/product/1935182366?ie=UTF8&amp;amp;tag=aleottshompag-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1935182366&quot;&gt;Camel in Action&lt;/a&gt; авторства Claus Ibsen и Jonathan Anstey.&lt;/p&gt;&lt;p&gt;Книга начинается (глава 1) с объяснения что такое Apache Camel, какие задачи он решает и из чего он состоит.  Во второй главе более подробно рассматриваются маршруты (routes) и показывается как можно их создавать используя код на Java или Spring.&lt;/p&gt;&lt;p&gt;Вторая часть книги полностью посвящена базовым вопросам разработки с использованием Camel, показывается как преобразовывать данные, обрабатывать ошибки, тестировать код, и использовать дополнительные компоненты, такие как JMS, базы данных и т.д.&lt;/p&gt;&lt;p&gt;А третья часть посвящена таким вопросам как использование транзакций, организация конкурентной обработки данных, а также вопросам мониторинга и деплоймента проектов.&lt;/p&gt;&lt;p&gt;Отдельная глава (11-я) описывает организацию процесса разработки с использованием Camel, включая разработку новых компонентов и адаптеров.  Кроме этого, на примере DSL для Scala, показывается как использовать Camel с другими языками (хотя на мой взгляд проект &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/krasserm/scalaz-camel&quot;&gt;scalaz-camel&lt;/a&gt; выглядит более интересным).&lt;/p&gt;&lt;p&gt;&lt;em&gt;Заключение:&lt;/em&gt; если вы заинтересованы в применении Apache Camel, то книжку стоит прочитать &amp;mdash; она может служить как хорошим введением в данную систему, так и достаточно подробным руководством по основным компонентам.&lt;/p&gt;&lt;p&gt;P.S. Для Clojure также начата работа по созданию библиотеки для интеграции с Apache Camel. Проект называется &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/dysinger/hackamore&quot;&gt;Hackamore&lt;/a&gt; и находится в начальной стадии разработки.  Если вам это интересно, то вы можете присоединиться к обсуждению в специально созданном &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://groups.google.com/group/hackamore&quot;&gt;списке рассылки&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;&lt;a rel=&quot;nofollow&quot; name=&quot;sec3&quot; id=&quot;sec3&quot;&gt;&lt;/a&gt;Test-driven development: By Example&lt;/h2&gt;&lt;p class=&quot;first&quot;&gt;Недавно я готовил презентацию для внутреннего семинара о test driven development (TDD), и решил прочитать что-то от основоположников этого движения.  Серию Extreme Programming я читал много лет назад, сразу после ее выхода, поэтому взгляд остановился на книге &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.com/gp/product/0321146530?ie=UTF8&amp;amp;tag=aleottshompag-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0321146530&quot;&gt;Test Driven Development: By Example&lt;/a&gt; Кента Бека.&lt;/p&gt;&lt;p&gt;Книжка небольшая &amp;mdash; чуть больше 200 страниц, но и этот объем является слишком большим для данной темы &amp;mdash; автор взял одну проблему, и подробно разбирает процесс ее реализации, который управляется тестами, которые создаются по мере добавления новых требований.  На протяжении первой части книги, с помощью данного примера иллюстрируются основы TDD и Unit testing.&lt;/p&gt;&lt;p&gt;Во второй части, применение TDD иллюстрируются описанием процесса реализации xUnit-подобного фреймворка для тестирования кода на Python, начиная с определения основной функциональности фреймворка, и затем, последовательной реализацией кода.&lt;/p&gt;&lt;p&gt;В третьей части рассматриваются основные приемы и паттерны использования TDD, проектирования кода для тестирования, разработки тестов и т.д.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Заключение:&lt;/em&gt; хорошее введение в TDD, но стоит прочитать только для людей кто никогда с ним не сталкивался &amp;mdash; слишком уж начального уровня. Хотя иногда попадаются полезные советы по организации кода, неплохое описание рабочего процесса и т.п.  Если вы уже хоть как-то применяли тесты в своей работе, то можно найти более короткий источник нужной информации.&lt;/p&gt;</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-7335838929614142497</guid>
         <pubDate>Wed, 09 Feb 2011 19:08:00 +0000</pubDate>
      </item>
      <item>
         <title>Типы и протоколы в Clojure</title>
         <link>http://alexott-ru.blogspot.com/2011/02/clojure.html</link>
         <description>Эта заметка также опубликована как часть &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.net/ru/clojure/clojure-intro/&quot;&gt;статьи &quot;Введение в Clojure&quot;&lt;/a&gt;...&lt;br /&gt;&lt;hr&gt;&lt;p&gt;Одно из самых больших изменений в Clojure версии 1.2 &amp;mdash; введение в язык новых артефактов: протоколов (protocols) и типов  данных (datatypes).  Данные изменения позволяют улучшить производительность программ по сравнению с мультиметодами, что в будущем даст возможность написать Clojure на Clojure (в данный момент протоколы и типы данных уже активно используются при реализации Clojure).&lt;/p&gt;&lt;div class=&quot;contents&quot;&gt;&lt;dl&gt;&lt;dt&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#sec1&quot;&gt;Что это такое и зачем нужно?&lt;/a&gt;&lt;/dt&gt;&lt;dt&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#sec2&quot;&gt;Определение протоколов&lt;/a&gt;&lt;/dt&gt;&lt;dt&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#sec3&quot;&gt;Реализация протоколов&lt;/a&gt;&lt;/dt&gt;&lt;dt&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#sec4&quot;&gt;Определение типов данных&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#sec5&quot;&gt;deftype &amp;amp; defrecord&lt;/a&gt;&lt;/dt&gt;&lt;dt&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#sec6&quot;&gt;reify&lt;/a&gt;&lt;/dt&gt;&lt;/dl&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#sec7&quot;&gt;Дополнительные функции и макросы&lt;/a&gt;&lt;/dt&gt;&lt;dt&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#sec8&quot;&gt;Дополнительная информация&lt;/a&gt;&lt;/dt&gt;&lt;/dl&gt;&lt;/div&gt;&lt;h2&gt;&lt;a rel=&quot;nofollow&quot; name=&quot;sec1&quot; id=&quot;sec1&quot;&gt;&lt;/a&gt;Что это такое и зачем нужно?&lt;/h2&gt;&lt;p class=&quot;first&quot;&gt;Протоколы и типы данных &amp;mdash; два связанных друг с другом понятия.  Протоколы используются для определения полиморфных функций, которые затем могут быть реализованы для конкретных типов данных (в том числе и из других библиотек).&lt;/p&gt;&lt;p&gt;Существует несколько причин введения протоколов и типов данных в новую версию языка:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Увеличить скорость работы полиморфных функций, при этом поддерживая большую часть функциональности мультиметодов, поскольку для протоколов диспатчеризация выполняется только по типу данных;&lt;/li&gt;&lt;li&gt;Использовать лучшие стороны интерфейсов (только спецификация функций, без реализации, реализация нескольких интерфейсов одним типом), в тоже время избегая недостатков (список реализуемых интерфейсов задан во время реализации типа данных, создание иерархии типов вида &lt;code&gt;isa/instanceof&lt;/code&gt;);&lt;/li&gt;&lt;li&gt;Избежать &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Expression_Problem&quot;&gt;Expression problem&lt;/a&gt; и дать возможность расширять набор операций над типами данных без изменениях определения типов данных (в том числе и чужих) и перекомпиляции исходного кода&lt;sup&gt;&lt;a rel=&quot;nofollow&quot; class=&quot;footref&quot; name=&quot;fnr.1&quot; href=&quot;#fn.1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;;&lt;/li&gt;&lt;li&gt;Использовать высокоуровневые абстракции для типов данных и операций над ними&lt;sup&gt;&lt;a rel=&quot;nofollow&quot; class=&quot;footref&quot; name=&quot;fnr.2&quot; href=&quot;#fn.2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;, что упрощает проектирование программ.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Также как и интерфейсы, протоколы позволяют объединить объявление нескольких полиморфных функций (или одной функции) в один объект&lt;sup&gt;&lt;a rel=&quot;nofollow&quot; class=&quot;footref&quot; name=&quot;fnr.3&quot; href=&quot;#fn.3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;.  Отличием от интерфейсов является то, что вы не можете унаследовать новый протокол от существующего протокола.&lt;/p&gt;&lt;p&gt;В отличии от имеющегося в Clojure &lt;code&gt;gen-interface&lt;/code&gt; (и соответствующих &lt;code&gt;proxy/gen-class&lt;/code&gt;) определение протоколов и типов не требует AOT (ahead-of-time) компиляции исходного кода, что упрощает распространение программ на Clojure.  Однако при определении протокола, Clojure автоматически создает соответствующий интерфейс, который будет доступен для кода, написанного на Java.&lt;/p&gt;&lt;p&gt;Типы данных, определенные с помощью &lt;code&gt;deftype&lt;/code&gt; или &lt;code&gt;defrecord&lt;/code&gt; позволяют программисту на Clojure определять свои структуры данных, вместо использования обычных отображений и структур, но об этом &lt;a rel=&quot;nofollow&quot; href=&quot;#datatypes&quot;&gt;ниже&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Важно помнить, что протоколы и типы данных с одним и тем же именем могут быть определены в разных пространствах имен, так что стоит быть осторожным и не наделать ошибок при импорте определений и последующей реализации протоколов!&lt;/em&gt;&lt;/p&gt;&lt;h2&gt;&lt;a rel=&quot;nofollow&quot; name=&quot;sec2&quot; id=&quot;sec2&quot;&gt;&lt;/a&gt;Определение протоколов&lt;/h2&gt;&lt;p class=&quot;first&quot;&gt;Протоколом называется именованный набор функций с определенными сигнатурами.  Для определения используется макрос, применение которого выглядит следующим образом:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;(&lt;span style=&quot;color:#a020f0;&quot;&gt;defprotocol&lt;/span&gt; &lt;span style=&quot;color:#0000ff;&quot;&gt;&amp;#1085;&amp;#1072;&amp;#1079;&amp;#1074;&amp;#1072;&amp;#1085;&amp;#1080;&amp;#1077;&lt;/span&gt; &lt;span style=&quot;color:#666666;&quot;&gt;&quot;&amp;#1086;&amp;#1087;&amp;#1080;&amp;#1089;&amp;#1072;&amp;#1085;&amp;#1080;&amp;#1077;&quot;&lt;/span&gt; &amp;amp; &amp;#1089;&amp;#1080;&amp;#1075;&amp;#1085;&amp;#1072;&amp;#1090;&amp;#1091;&amp;#1088;&amp;#1099;)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;название&lt;/code&gt; &amp;mdash; единственный обязательный параметр, хотя определение протокола без функций не имеет особого смысла.  В описании вы можете описать ваш протокол, и это описание будет показываться при вызове функции &lt;code&gt;doc&lt;/code&gt; для вашего протокола.  Для протокола вы можете указать одну или несколько сигнатур функций, где каждая сигнатура выглядит следующим образом:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;(&amp;#1080;&amp;#1084;&amp;#1103; [&amp;#1072;&amp;#1088;&amp;#1075;&amp;#1091;&amp;#1084;&amp;#1077;&amp;#1085;&amp;#1090;&amp;#1099;+]+ &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;&amp;#1086;&amp;#1087;&amp;#1080;&amp;#1089;&amp;#1072;&amp;#1085;&amp;#1080;&amp;#1077;&quot;&lt;/span&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Вы можете определять одну функцию, которая будет принимать различное количество параметров, но первым аргументом функции всегда является объект, на основании которого будет выполняться диспатчеризация, и к которому эта функция будет применяться.  Вы можете рассматривать его как &lt;code&gt;this&lt;/code&gt; в Java и C++.  В дополнение к сигнатурам, вы можете описать вашу функцию, но это необязательно.&lt;/p&gt;&lt;p&gt;Давайте посмотрим на стандартный пример:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;(&lt;span style=&quot;color:#a020f0;&quot;&gt;defprotocol&lt;/span&gt; &lt;span style=&quot;color:#0000ff;&quot;&gt;AProtocol&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#666666;&quot;&gt;&quot;A doc string for AProtocol abstraction&quot;&lt;/span&gt;&lt;br /&gt;  (bar [a b] &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;bar docs&quot;&lt;/span&gt;)&lt;br /&gt;  (baz [a] [a b] [a b c] &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;baz docs&quot;&lt;/span&gt;))&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Данный протокол определяет две функции: &lt;code&gt;bar&lt;/code&gt; &amp;mdash; с двумя параметрами, и &lt;code&gt;baz&lt;/code&gt; &amp;mdash; с одним, двумя или тремя параметрами.&lt;/p&gt;&lt;p&gt;&lt;code&gt;defprotocol&lt;/code&gt; также создаст соответствующий интерфейс, с тем же самым именем что и протокол. Данный интерфейс будет иметь те же самые функции, что и протокол.&lt;/p&gt;&lt;h2&gt;&lt;a rel=&quot;nofollow&quot; name=&quot;sec3&quot; id=&quot;sec3&quot;&gt;&lt;/a&gt;Реализация протоколов&lt;/h2&gt;&lt;p class=&quot;first&quot;&gt;Протокол сам по себе ни на что не влияет &amp;mdash; чтобы использовать его, мы должны добавить его специализации для типов данных или классов JVM.  Для этого может использоваться функция &lt;code&gt;extend&lt;/code&gt;, использование которой выглядит следующим образом:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;(&lt;span style=&quot;color:#006400;&quot;&gt;extend&lt;/span&gt; &amp;#1090;&amp;#1080;&amp;#1087;-&amp;#1080;&amp;#1083;&amp;#1080;-&amp;#1082;&amp;#1083;&amp;#1072;&amp;#1089;&amp;#1089;&lt;br /&gt;  &amp;#1087;&amp;#1088;&amp;#1086;&amp;#1090;&amp;#1086;&amp;#1082;&amp;#1086;&amp;#1083;-1&lt;br /&gt;   {&lt;span style=&quot;color:#006400;&quot;&gt;:&amp;#1084;&amp;#1077;&amp;#1090;&amp;#1086;&amp;#1076;-1&lt;/span&gt; &amp;#1091;&amp;#1078;&amp;#1077;-&amp;#1086;&amp;#1087;&amp;#1088;&amp;#1077;&amp;#1076;&amp;#1077;&amp;#1083;&amp;#1077;&amp;#1085;&amp;#1085;&amp;#1072;&amp;#1103;-&amp;#1092;&amp;#1091;&amp;#1085;&amp;#1082;&amp;#1094;&amp;#1080;&amp;#1103;&lt;br /&gt;    &lt;span style=&quot;color:#006400;&quot;&gt;:&amp;#1084;&amp;#1077;&amp;#1090;&amp;#1086;&amp;#1076;-2&lt;/span&gt; (&lt;span style=&quot;color:#006400;&quot;&gt;fn&lt;/span&gt; [a b] ...)&lt;br /&gt;    &lt;span style=&quot;color:#006400;&quot;&gt;:&amp;#1084;&amp;#1077;&amp;#1090;&amp;#1086;&amp;#1076;-3&lt;/span&gt; (&lt;span style=&quot;color:#006400;&quot;&gt;fn&lt;/span&gt; ([a]...) ([a b] ...)...)}&lt;br /&gt;  &amp;#1087;&amp;#1088;&amp;#1086;&amp;#1090;&amp;#1086;&amp;#1082;&amp;#1086;&amp;#1083;-2&lt;br /&gt;    {...}&lt;br /&gt;...)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Для этой функции вы указываете имя типа данных или класса (или &lt;code&gt;nil&lt;/code&gt;), и передаете список состоящий из названий протоколов (&lt;code&gt;протокол-1&lt;/code&gt; и т.д.) и отображений, которые связывают функции протокола (&lt;code&gt;метод-1&lt;/code&gt; и т.д.) с их реализациями &amp;mdash; анонимными или именованными функциями.&lt;/p&gt;&lt;p&gt;Стоит отметить, что функция &lt;code&gt;extend&lt;/code&gt; является низкоуровневым инструментом реализации протоколов.  Кроме этого, в состав языка введены макросы &lt;code&gt;extend-protocol&lt;/code&gt; &amp;amp; &lt;code&gt;extend-type&lt;/code&gt;, которые немного упрощают реализацию протоколов&lt;sup&gt;&lt;a rel=&quot;nofollow&quot; class=&quot;footref&quot; name=&quot;fnr.4&quot; href=&quot;#fn.4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;.  Протокол также может быть реализован непосредственно при &lt;a rel=&quot;nofollow&quot; href=&quot;#datatypes&quot;&gt;объявлении типа данных&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Использование &lt;code&gt;extend-type&lt;/code&gt; выглядит практически также как и использование &lt;code&gt;extend&lt;/code&gt;, но пользователь записывает реализации в более удобном виде (&lt;code&gt;extend-type&lt;/code&gt; раскрывается в соответствующий вызов &lt;code&gt;extend&lt;/code&gt;):&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;(&lt;span style=&quot;color:#006400;&quot;&gt;extend-type&lt;/span&gt; &amp;#1090;&amp;#1080;&amp;#1087;-&amp;#1080;&amp;#1083;&amp;#1080;-&amp;#1082;&amp;#1083;&amp;#1072;&amp;#1089;&amp;#1089;&lt;br /&gt;  &amp;#1087;&amp;#1088;&amp;#1086;&amp;#1090;&amp;#1086;&amp;#1082;&amp;#1086;&amp;#1083;-1&lt;br /&gt;    (&amp;#1084;&amp;#1077;&amp;#1090;&amp;#1086;&amp;#1076;-2 [a b] ...)&lt;br /&gt;    (&amp;#1084;&amp;#1077;&amp;#1090;&amp;#1086;&amp;#1076;-3 ([a]...)&lt;br /&gt;             ([a b] ...)...)&lt;br /&gt;  &amp;#1087;&amp;#1088;&amp;#1086;&amp;#1090;&amp;#1086;&amp;#1082;&amp;#1086;&amp;#1083;-2&lt;br /&gt;    (....)&lt;br /&gt;...)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Макрос &lt;code&gt;extend-protocol&lt;/code&gt; использоваться в тех случаях, если вы хотите реализовать один протокол для нескольких типов данных или классов.  В общем виде использование &lt;code&gt;extend-protocol&lt;/code&gt; выглядит следующим образом:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;(&lt;span style=&quot;color:#006400;&quot;&gt;extend-protocol&lt;/span&gt; &amp;#1085;&amp;#1072;&amp;#1079;&amp;#1074;&amp;#1072;&amp;#1085;&amp;#1080;&amp;#1077;-&amp;#1087;&amp;#1088;&amp;#1086;&amp;#1090;&amp;#1086;&amp;#1082;&amp;#1086;&amp;#1083;&amp;#1072;&lt;br /&gt;  &amp;#1058;&amp;#1080;&amp;#1087;-&amp;#1080;&amp;#1083;&amp;#1080;-&amp;#1050;&amp;#1083;&amp;#1072;&amp;#1089;&amp;#1089;-1&lt;br /&gt;   (&amp;#1084;&amp;#1077;&amp;#1090;&amp;#1086;&amp;#1076;-1 ...)&lt;br /&gt;   (&amp;#1084;&amp;#1077;&amp;#1090;&amp;#1086;&amp;#1076;-2 ...)&lt;br /&gt;  &amp;#1058;&amp;#1080;&amp;#1087;-&amp;#1080;&amp;#1083;&amp;#1080;-&amp;#1050;&amp;#1083;&amp;#1072;&amp;#1089;&amp;#1089;-2&lt;br /&gt;   (&amp;#1084;&amp;#1077;&amp;#1090;&amp;#1086;&amp;#1076;-1 ...)&lt;br /&gt;   (&amp;#1084;&amp;#1077;&amp;#1090;&amp;#1086;&amp;#1076;-2 ...)&lt;br /&gt;...)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;При использовании, &lt;code&gt;extend-protocol&lt;/code&gt; раскрывается в серию вызовов &lt;code&gt;extend-type&lt;/code&gt; для каждого из используемых типов.&lt;/p&gt;&lt;p&gt;Давайте рассмотрим небольшой пример.  Пусть мы объявим следующий простой протокол:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;(&lt;span style=&quot;color:#a020f0;&quot;&gt;defprotocol&lt;/span&gt; &lt;span style=&quot;color:#0000ff;&quot;&gt;Hello&lt;/span&gt; &lt;span style=&quot;color:#666666;&quot;&gt;&quot;Test of protocol&quot;&lt;/span&gt;&lt;br /&gt;  (hello [this] &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;hello function&quot;&lt;/span&gt;))&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Мы можем использовать &lt;code&gt;extend&lt;/code&gt;, &lt;code&gt;extend-protocol&lt;/code&gt;, или &lt;code&gt;extend-type&lt;/code&gt; для его специализации для класса &lt;code&gt;String&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;(&lt;span style=&quot;color:#006400;&quot;&gt;extend&lt;/span&gt; &lt;span style=&quot;color:#006400;&quot;&gt;String&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#006400;&quot;&gt;Hello&lt;/span&gt;&lt;br /&gt;  {&lt;span style=&quot;color:#006400;&quot;&gt;:hello&lt;/span&gt; (&lt;span style=&quot;color:#006400;&quot;&gt;fn&lt;/span&gt; [this] (&lt;span style=&quot;color:#006400;&quot;&gt;str&lt;/span&gt; &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;Hello &quot;&lt;/span&gt; this &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;!&quot;&lt;/span&gt;))})&lt;br /&gt;&lt;br /&gt;(&lt;span style=&quot;color:#006400;&quot;&gt;extend-protocol&lt;/span&gt; &lt;span style=&quot;color:#006400;&quot;&gt;Hello&lt;/span&gt; &lt;span style=&quot;color:#006400;&quot;&gt;String&lt;/span&gt;&lt;br /&gt;  (hello [this] (&lt;span style=&quot;color:#006400;&quot;&gt;str&lt;/span&gt; &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;Hello &quot;&lt;/span&gt; this &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;!&quot;&lt;/span&gt;)))&lt;br /&gt;&lt;br /&gt;(&lt;span style=&quot;color:#006400;&quot;&gt;extend-type&lt;/span&gt; &lt;span style=&quot;color:#006400;&quot;&gt;String&lt;/span&gt; &lt;span style=&quot;color:#006400;&quot;&gt;Hello&lt;/span&gt;&lt;br /&gt;  (hello [this] (&lt;span style=&quot;color:#006400;&quot;&gt;str&lt;/span&gt; &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;Hello &quot;&lt;/span&gt; this &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;!&quot;&lt;/span&gt;)))&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;При использовании любой из этих реализаций для объекта класса &lt;code&gt;String&lt;/code&gt; мы получим один и тот же ответ:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;user&amp;gt; (hello &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;world&quot;&lt;/span&gt;)&lt;br /&gt;&lt;span style=&quot;color:#008b00;&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Стоит отметить, что если вы не реализовали протокол для определенного типа данных, то при вызове функции будет сгенерировано исключение.  В том случае, если вам необходима &amp;quot;реализация по умолчанию&amp;quot;, то вы можете специализировать протокол для класса &lt;code&gt;Object&lt;/code&gt;.&lt;/p&gt;&lt;h2&gt;&lt;a rel=&quot;nofollow&quot; name=&quot;sec4&quot; id=&quot;sec4&quot;&gt;&lt;/a&gt;&lt;a rel=&quot;nofollow&quot; name=&quot;datatypes&quot; id=&quot;datatypes&quot;&gt;&lt;/a&gt;Определение типов данных&lt;/h2&gt;&lt;p class=&quot;first&quot;&gt;В Clojure 1.2 введены два метода определения новых именованных типов данных (&lt;code&gt;deftype&lt;/code&gt; и &lt;code&gt;defrecord&lt;/code&gt;), которые реализуют абстракции, определенные протоколами и/или интерфейсами (к типам данных относится также &lt;code&gt;reify&lt;/code&gt;, который описан ниже).&lt;/p&gt;&lt;p&gt;&lt;code&gt;deftype&lt;/code&gt; и &lt;code&gt;defrecord&lt;/code&gt; динамически создают именованный класс, который имеет набор заданных полей и (необязательно) методов для одного или нескольких протоколов и/или интерфейсов. Поскольку они не требуют явной компиляции, то это дает возможность их использования в интерактивной разработке.  С точки зрения разработчика &lt;code&gt;deftype&lt;/code&gt; и &lt;code&gt;defrecord&lt;/code&gt; похожи на &lt;code&gt;defstruct&lt;/code&gt;, но во многом они отличаются:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;они создают уникальный класс с соответствующими полями;&lt;/li&gt;&lt;li&gt;созданный класс имеет конкретный тип;&lt;/li&gt;&lt;li&gt;имеется конструктор;&lt;/li&gt;&lt;li&gt;для полей можно указывать типы (это будет использоваться для оптимизации и ограничения типов в конструкторе).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;code&gt;deftype&lt;/code&gt; является &amp;quot;базовым&amp;quot; инструментом для определения типов данных &amp;mdash; созданный тип имеет только конструктор, и ничего больше &amp;mdash; все остальное должен реализовывать разработчик.  Но при этом, &lt;code&gt;deftype&lt;/code&gt; может иметь изменяемые поля, чего не имеет &lt;code&gt;defrecord&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;В отличии от &lt;code&gt;deftype&lt;/code&gt;, &lt;code&gt;defrecord&lt;/code&gt; более прост в использовании, поскольку создаваемый тип данных имеет большую функциональность (по большей части за счет реализации интерфейсов &lt;code&gt;IKeywordLookup&lt;/code&gt;, &lt;code&gt;IPersistentMap&lt;/code&gt;, &lt;code&gt;Serializable&lt;/code&gt; и т.д.):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;автоматически генерируемые функции &lt;code&gt;hashCode&lt;/code&gt; и &lt;code&gt;equals&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;возможность указания мета-информации;&lt;/li&gt;&lt;li&gt;доступ к полям с помощью ключевых символов;&lt;/li&gt;&lt;li&gt;вы можете добавлять поля, не указанные в определении.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;code&gt;deftype&lt;/code&gt; и &lt;code&gt;defrecord&lt;/code&gt; обычно имеют разные области применения: &lt;code&gt;deftype&lt;/code&gt; в основном используется для &amp;quot;системных&amp;quot; вещей &amp;mdash; коллекций, и т.п., тогда как &lt;code&gt;defrecord&lt;/code&gt; в основном используется для хранения информации из &amp;quot;проблемной области&amp;quot; &amp;mdash; данных о заказчиках, записях в БД и т.п. &amp;mdash; то, для чего использовались отображения в версиях 1.0 и 1.1.&lt;/p&gt;&lt;p&gt;Давайте рассмотрим как использовать конкретные средства для создания типов данных.&lt;/p&gt;&lt;h3&gt;&lt;a rel=&quot;nofollow&quot; name=&quot;sec5&quot; id=&quot;sec5&quot;&gt;&lt;/a&gt;deftype &amp;amp; defrecord&lt;/h3&gt;&lt;p class=&quot;first&quot;&gt;В общей форме использование макросов &lt;code&gt;deftype&lt;/code&gt; и &lt;code&gt;defrecord&lt;/code&gt; выглядит следующим образом:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;(deftype &amp;#1080;&amp;#1084;&amp;#1103; [&amp;amp; &amp;#1087;&amp;#1086;&amp;#1083;&amp;#1103;] &amp;amp; &amp;#1089;&amp;#1087;&amp;#1077;&amp;#1094;&amp;#1080;&amp;#1092;&amp;#1080;&amp;#1082;&amp;#1072;&amp;#1094;&amp;#1080;&amp;#1080;)&lt;br /&gt;(defrecord &amp;#1080;&amp;#1084;&amp;#1103; [&amp;amp; &amp;#1087;&amp;#1086;&amp;#1083;&amp;#1103;] &amp;amp; &amp;#1089;&amp;#1087;&amp;#1077;&amp;#1094;&amp;#1080;&amp;#1092;&amp;#1080;&amp;#1082;&amp;#1072;&amp;#1094;&amp;#1080;&amp;#1080;)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Для обоих макросов обязательным параметром является лишь имя, которое становится именем класса.  Поля, которые станут членами класса, перечисляются в векторе, следующем за именем, и могут содержать объявления типов.  После этого вектора, можно указать список реализуемых интерфейсов и протоколов, вместе с реализацией (это не обязательно, поскольку для этого вы позже можете использовать &lt;code&gt;extend-protocol&lt;/code&gt; &amp;amp; &lt;code&gt;extend-type&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;Спецификации протоколов/интерфейсов выглядят следующим образом:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;&amp;#1087;&amp;#1088;&amp;#1086;&amp;#1090;&amp;#1086;&amp;#1082;&amp;#1086;&amp;#1083;/&amp;#1080;&amp;#1085;&amp;#1090;&amp;#1077;&amp;#1088;&amp;#1092;&amp;#1077;&amp;#1081;&amp;#1089;&lt;br /&gt;(&amp;#1085;&amp;#1072;&amp;#1079;&amp;#1074;&amp;#1072;&amp;#1085;&amp;#1080;&amp;#1077;-&amp;#1084;&amp;#1077;&amp;#1090;&amp;#1086;&amp;#1076;&amp;#1072; [&amp;#1072;&amp;#1088;&amp;#1075;&amp;#1091;&amp;#1084;&amp;#1077;&amp;#1085;&amp;#1090;&amp;#1099;*] &amp;#1088;&amp;#1077;&amp;#1072;&amp;#1083;&amp;#1080;&amp;#1079;&amp;#1072;&amp;#1094;&amp;#1080;&amp;#1103;)*&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Вы можете указать любое количество протоколов/интерфейсов, которые будут реализованы данным типом данных.  Давайте посмотрим на простейший тип данных, который реализует протокол &lt;code&gt;Hello&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;(&lt;span style=&quot;color:#a020f0;&quot;&gt;deftype&lt;/span&gt; &lt;span style=&quot;color:#0000ff;&quot;&gt;A&lt;/span&gt; []&lt;br /&gt;  &lt;span style=&quot;color:#006400;&quot;&gt;Hello&lt;/span&gt;&lt;br /&gt;  (hello [this] (&lt;span style=&quot;color:#006400;&quot;&gt;str&lt;/span&gt; &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;Hello A!&quot;&lt;/span&gt;)))&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Мы можем вызвать функцию &lt;code&gt;hello&lt;/code&gt; для нашего объекта, и получим следующий вывод:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;user&amp;gt; (hello (&lt;span style=&quot;color:#006400;&quot;&gt;A.&lt;/span&gt;))&lt;br /&gt;&lt;span style=&quot;color:#008b00;&quot;&gt;&quot;Hello A!&quot;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Мы можем также создать тип с помощью &lt;code&gt;defrecord&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;(&lt;span style=&quot;color:#a020f0;&quot;&gt;defrecord&lt;/span&gt; &lt;span style=&quot;color:#0000ff;&quot;&gt;B&lt;/span&gt; [name]&lt;br /&gt;  &lt;span style=&quot;color:#006400;&quot;&gt;Hello&lt;/span&gt;&lt;br /&gt;  (hello [this] (&lt;span style=&quot;color:#006400;&quot;&gt;str&lt;/span&gt; &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;Hello &quot;&lt;/span&gt; name &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;!&quot;&lt;/span&gt;)))&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;и вызвать метод &lt;code&gt;hello&lt;/code&gt; для этого типа:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;user&amp;gt; (hello (&lt;span style=&quot;color:#006400;&quot;&gt;B.&lt;/span&gt; &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;world&quot;&lt;/span&gt;))&lt;br /&gt;&lt;span style=&quot;color:#008b00;&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Как уже отмечалось выше, создаваемые поля по умолчанию являются неизменяемыми, но если вы создаете тип с помощью &lt;code&gt;deftype&lt;/code&gt;, то вы можете пометить некоторые поля как изменяемые, используя метаданные (с помощью ключевого символа &lt;code&gt;:volatile-mutable&lt;/code&gt; или &lt;code&gt;:unsynchronized-mutable&lt;/code&gt;).  Для таких полей вы сможете использовать оператор &lt;code&gt;(set! afield aval)&lt;/code&gt; для изменения данных.  Давайте посмотрим как это делается на примере &amp;mdash; если мы создадим следующий протокол и тип данных:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;(&lt;span style=&quot;color:#a020f0;&quot;&gt;defprotocol&lt;/span&gt; &lt;span style=&quot;color:#0000ff;&quot;&gt;Setter&lt;/span&gt;&lt;br /&gt;  (set-name [this new-name]))&lt;br /&gt;(&lt;span style=&quot;color:#a020f0;&quot;&gt;deftype&lt;/span&gt; &lt;span style=&quot;color:#0000ff;&quot;&gt;AM&lt;/span&gt; [^{&lt;span style=&quot;color:#006400;&quot;&gt;:volatile-mutable&lt;/span&gt; true} mfield]&lt;br /&gt;  &lt;span style=&quot;color:#006400;&quot;&gt;Hello&lt;/span&gt;&lt;br /&gt;  (hello [this] (&lt;span style=&quot;color:#006400;&quot;&gt;str&lt;/span&gt; &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;Hello &quot;&lt;/span&gt; mfield &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;!&quot;&lt;/span&gt;))&lt;br /&gt;  &lt;span style=&quot;color:#006400;&quot;&gt;Setter&lt;/span&gt;&lt;br /&gt;  (set-name [this new-name] &lt;br /&gt;     (set! mfield new-name)))&lt;br /&gt;&lt;/pre&gt;то мы сможем изменять значение поля:&lt;br /&gt;&lt;pre class=&quot;src&quot;&gt;user&amp;gt; (def am (AM. &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;world&quot;&lt;/span&gt;))&lt;br /&gt;#'user/am&lt;br /&gt;user&amp;gt; (hello am)&lt;br /&gt;&lt;span style=&quot;color:#008b00;&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt;&lt;br /&gt;user&amp;gt; (set-name am &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;peace&quot;&lt;/span&gt;)&lt;br /&gt;&lt;span style=&quot;color:#008b00;&quot;&gt;&quot;peace&quot;&lt;/span&gt;&lt;br /&gt;user&amp;gt; (hello am)&lt;br /&gt;&lt;span style=&quot;color:#008b00;&quot;&gt;&quot;Hello peace!&quot;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;&lt;a rel=&quot;nofollow&quot; name=&quot;sec6&quot; id=&quot;sec6&quot;&gt;&lt;/a&gt;reify&lt;/h3&gt;&lt;p&gt;&lt;code&gt;reify&lt;/code&gt; используется тогда, когда вам нужно реализовать протокол или интерфейс только в одном месте &amp;mdash; когда вы используете &lt;code&gt;reify&lt;/code&gt; вы одновременно объявляете тип, и сразу создаете объект этого типа. Функция &lt;code&gt;reify&lt;/code&gt; по своему использованию очень похожа на &lt;code&gt;proxy&lt;/code&gt;, но с некоторыми исключениями:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;можно использовать только для интерфейсов и протоколов;&lt;/li&gt;&lt;li&gt;реализуемые методы являются методами результирующего класса, и они вызываются напрямую,&lt;br /&gt;без поиска в отображении, но при этом не поддерживается подмена методов в отображении.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Эти отличия позволяют получить более высокую производительность по сравнению с &lt;code&gt;proxy&lt;/code&gt;, и при создании и при выполнении.&lt;/p&gt;&lt;p&gt;Вот небольшой пример реализации протокола &lt;code&gt;Hello&lt;/code&gt; для конкретного объекта:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;(&lt;span style=&quot;color:#a020f0;&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color:#0000ff;&quot;&gt;int-reify&lt;/span&gt; (&lt;span style=&quot;color:#006400;&quot;&gt;reify&lt;/span&gt; &lt;span style=&quot;color:#006400;&quot;&gt;Hello&lt;/span&gt;&lt;br /&gt;                 (hello [this] &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;Hello integer!&quot;&lt;/span&gt;)))&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;И при вызове &lt;code&gt;hello&lt;/code&gt; для этого объекта, мы получим соответствующий результат:&lt;/p&gt;&lt;pre class=&quot;src&quot;&gt;user&amp;gt; (hello int-reify)&lt;br /&gt;&lt;span style=&quot;color:#008b00;&quot;&gt;&quot;Hello integer!&quot;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;h2&gt;&lt;a rel=&quot;nofollow&quot; name=&quot;sec7&quot; id=&quot;sec7&quot;&gt;&lt;/a&gt;Дополнительные функции и макросы&lt;/h2&gt;&lt;p class=&quot;first&quot;&gt;Для работы с протоколами и типами данных определено некоторое количество вспомогательных функций, которые могут вам понадобиться:&lt;/p&gt;&lt;dl&gt;&lt;dt&gt;&lt;strong&gt;&lt;code&gt;extends?&lt;/code&gt;&lt;/strong&gt;&lt;/dt&gt;&lt;dd&gt;возвращает &lt;code&gt;true&lt;/code&gt; если данный тип данных (2-й аргумент) реализует интерфейс, заданный первым аргументом;&lt;/dd&gt;&lt;dt&gt;&lt;strong&gt;&lt;code&gt;extenders&lt;/code&gt;&lt;/strong&gt;&lt;/dt&gt;&lt;dd&gt;возвращает коллекцию типов, реализующих заданный протокол;&lt;/dd&gt;&lt;dt&gt;&lt;strong&gt;&lt;code&gt;satisfies?&lt;/code&gt;&lt;/strong&gt;&lt;/dt&gt;&lt;dd&gt;возвращает &lt;code&gt;true&lt;/code&gt; если данный протокол (1-й аргумент) применим к данному объекту (2-й аргумент);&lt;/dd&gt; &lt;/dl&gt;&lt;h2&gt;&lt;a rel=&quot;nofollow&quot; name=&quot;sec8&quot; id=&quot;sec8&quot;&gt;&lt;/a&gt;Дополнительная информация&lt;/h2&gt;&lt;p class=&quot;first&quot;&gt;Как всегда, основной источник информации &amp;mdash; сайт языка: ознакомьтесь с разделами &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure.org/protocols&quot;&gt;protocols&lt;/a&gt; и &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure.org/datatypes&quot;&gt;datatypes&lt;/a&gt;.  Хорошее описание протоколов и типов данных можно найти в 13-й главе недавно вышедшей книги &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.com/gp/product/1430272317?ie=UTF8&amp;amp;tag=aleottshompag-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1430272317&quot;&gt;Practical Clojure. The Definitive Guide&lt;/a&gt;, а также в &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.com/gp/product/1935182595?ie=UTF8&amp;amp;tag=aleottshompag-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1935182595&quot;&gt;Clojure in Action&lt;/a&gt; и &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.com/gp/product/1935182641?ie=UTF8&amp;amp;tag=aleottshompag-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1935182641&quot;&gt;The Joy of Clojure. Thinking the Clojure Way&lt;/a&gt;, которые будут выпущены в ближайшее время.&lt;/p&gt;&lt;p&gt;Stuart Halloway создал очень &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://vimeo.com/11236603&quot;&gt;интересный скринкаст&lt;/a&gt; в котором он рассказывает о том, зачем были созданы протоколы и data types, и демонстрирует их применение на небольших примерах.&lt;/p&gt;&lt;p&gt;Введение новых возможностей в язык не обходится без статей в блогах.  Вот ссылки на некоторые интересные статьи на эту тему:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.ibm.com/developerworks/java/library/j-clojure-protocols/index.html&quot;&gt;Статья Stuart Sierra&lt;/a&gt; на IBM developerWorks;&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.infoq.com/presentations/Clojure-Expression-Problem&quot;&gt;Clojure's Solutions to the Expression Problem&lt;/a&gt; &amp;mdash; выступление Chris Houser на конференции Strange Loop 2010;&lt;/li&gt;&lt;li&gt;Серия из 3-х статей (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.objectcommando.com/blog/2010/03/26/clojure-protocols-part-1/&quot;&gt;1&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.objectcommando.com/blog/2010/03/29/clojure-protocols-part-2/&quot;&gt;2&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.objectcommando.com/blog/2010/04/12/clojure-protocols-part-3/&quot;&gt;3&lt;/a&gt;) о протоколах в блоге Object Commando;&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://freegeek.in/blog/2010/05/clojure-protocols-datatypes-a-sneak-peek/&quot;&gt;Краткое введение&lt;/a&gt; в протоколы, написанное Baishampayan Ghose;&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://formpluslogic.blogspot.com/2010/08/clojure-protocols-and-expression.html&quot;&gt;Clojure Protocols and Expression Problem&lt;/a&gt;;&lt;/li&gt;&lt;li&gt;Два постинга от Sean Devlin &amp;mdash; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://fulldisclojure.blogspot.com/2010/08/thoughts-on-protocols.html&quot;&gt;Protocol Implementation Awesomeness&lt;/a&gt; и &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://fulldisclojure.blogspot.com/2010/08/partially-implemented-protocols.html&quot;&gt;Partially Implemented Protocols&lt;/a&gt;;&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://blog.higher-order.net/2010/05/05/circuitbreaker-clojure-1-2/&quot;&gt;Пример реализации паттерна &amp;quot;Circuit Breaker&amp;quot;&lt;/a&gt; с помощью протоколов;&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://kotka.de/blog/2010/03/memoize_done_right.html#protocols&quot;&gt;Пример использования протоколов&lt;/a&gt; для мемоизации;&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://bestinclass.dk/index.clj/2010/04/prototurtle-the-tale-of-the-bleeding-turtle.html&quot;&gt;Еще пример&lt;/a&gt; использования протоколов для реализации turtle graphics;&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://kirindave.tumblr.com/post/658770511/monkey-patching-gorilla-engineering-protocols-in&quot;&gt;Небольшое сравнение&lt;/a&gt; Monkey Patching в Ruby с протоколами в Clojure;&lt;/li&gt;&lt;li&gt;Пример реализации стека с помощью протоколов (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.viksit.com/content/stack-implementation-clojure-using-protocols-and-records&quot;&gt;1&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.viksit.com/content/stack-implementation-clojure-ii-functional-approach&quot;&gt;2&lt;/a&gt;), написанный Viksit Gaur;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;hr&gt;&lt;p class=&quot;footnote&quot;&gt;&lt;a rel=&quot;nofollow&quot; class=&quot;footnum&quot; name=&quot;fn.1&quot; href=&quot;#fnr.1&quot;&gt;1.&lt;/a&gt; Стоит однако отметить, что протоколы не реализуют monkey patching и внедрение методов&lt;br /&gt;(injection) в существующие типы данных.&lt;/p&gt;&lt;br /&gt;&lt;p class=&quot;footnote&quot;&gt;&lt;a rel=&quot;nofollow&quot; class=&quot;footnum&quot; name=&quot;fn.2&quot; href=&quot;#fnr.2&quot;&gt;2.&lt;/a&gt; Возможность реализации абстракций на Clojure и высокая скорость работы протоколов&lt;br /&gt;позволит в будущем написать Clojure на самой Clojure, без использования исходного кода&lt;br /&gt;на Java.&lt;/p&gt;&lt;br /&gt;&lt;p class=&quot;footnote&quot;&gt;&lt;a rel=&quot;nofollow&quot; class=&quot;footnum&quot; name=&quot;fn.3&quot; href=&quot;#fnr.3&quot;&gt;3.&lt;/a&gt; Люди знакомые с Haskell могут рассматривать протоколы как некоторое подобие типов&lt;br /&gt;классов (typeclasses) в этом языке, правда при этом нельзя определять реализации по&lt;br /&gt;умолчанию для методов.&lt;/p&gt;&lt;br /&gt;&lt;p class=&quot;footnote&quot;&gt;&lt;a rel=&quot;nofollow&quot; class=&quot;footnum&quot; name=&quot;fn.4&quot; href=&quot;#fnr.4&quot;&gt;4.&lt;/a&gt; Но &lt;code&gt;extend&lt;/code&gt; может использоваться в тех случаях, когда вы хотите использовать одни и те&lt;br /&gt;же реализации для разных типов данных &amp;mdash; в этом случае, вы можете создать отображение&lt;br /&gt;с нужными функциями, и использовать его для разных типов, например, как описано в&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://fulldisclojure.blogspot.com/2010/08/thoughts-on-protocols.html&quot;&gt;следующем блог-постинге&lt;/a&gt;.&lt;/p&gt;</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-2175626746263785720</guid>
         <pubDate>Fri, 04 Feb 2011 15:19:00 +0000</pubDate>
      </item>
      <item>
         <title>Дайджест прочитанных книг. Сентябрь 2010</title>
         <link>http://alexott-ru.blogspot.com/2010/10/2010.html</link>
         <description>&lt;p&gt;Мне пришла в голову идея, что было бы полезно делиться достаточно подробными впечатлениями о прочитанных книгах.  Хотя я и пользуюсь &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.goodreads.com/user/show/635213&quot;&gt;GoodReads&lt;/a&gt; и &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.shelfari.com/alexott&quot;&gt;Shelfari&lt;/a&gt;, но обзоры там делаю на английском и достаточно краткие.  В качестве периода между обзорами выбран месяц, что дает мне возможность прочитать 2-4 книги, про которые стоило бы рассказать :-)&lt;/p&gt;&lt;hr&gt;&lt;h4&gt;The Joy of Clojure: Thinking the Clojure Way&lt;/h4&gt;&lt;p class=&quot;first&quot;&gt;Я купил &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.com/gp/product/1935182641?ie=UTF8&amp;amp;tag=aleottshompag-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1935182641&quot;&gt;The Joy of Clojure: Thinking the Clojure Way&lt;/a&gt; (авторы Michael Fogus и Chris Houser) почти сразу после того, как она появилась на сайте Manning, и регулярно получал обновления для него.  Но примерно месяц назад пришла полная версия книги (но без окончательной вычитки редактором и красивой верстки), и я сел за ее чтение в полном объеме.  У этой книги имеется &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://joyofclojure.com/&quot;&gt;отдельный сайт&lt;/a&gt; на котором можно найти дополнительную информацию о книге, включая информацию о существующих скидках на предварительную версию (MEAP).&lt;/p&gt;&lt;p&gt;Хочется сразу отметить, что это не учебник по языку Clojure, и хотя в книге имеется отдельная глава с кратким (около 30 страниц) описанием основ языка, но все равно, для начала стоит прочитать одну из существующих книг: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.com/gp/product/1430272317?ie=UTF8&amp;amp;tag=aleottshompag-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1430272317&quot;&gt;Practical Clojure&lt;/a&gt; или&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.com/gp/product/1934356336?ie=UTF8&amp;amp;tag=aleottshompag-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1934356336&quot;&gt;Programming Clojure&lt;/a&gt;, или еще не выпущенную, но уже доступную через MEAP,&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.manning.com/rathore/&quot;&gt;Clojure in Action&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Книга пытается рассказать о том, как &amp;quot;более правильно&amp;quot; программировать на Clojure с точки зрения стиля языка и функционального программирования, как лучше организовывать программы на Clojure.  Сюда относятся использование &amp;quot;ленивых&amp;quot; структур данных, когда нужно и можно использовать макросы, как организовывать рекурсивное выполнение, как организованы различные структуры данных, когда их нужно и можно использовать, и т.п.&lt;/p&gt;&lt;p&gt;Также достаточно много места уделено вопросам производительности программ на Clojure &amp;mdash; какие структуры данных лучше использовать в различных ситуациях, как можно улучшить производительность с помощью type hinting, использования &amp;quot;переходных&amp;quot; структур данных, &amp;quot;блочных&amp;quot; последовательностей и мемоизации.&lt;/p&gt;&lt;p&gt;Не обойден стороной и вопрос конкуррентного программирования на Clojure, и использование изменяемых данных в программах.  Обсуждению этих вопросов посвящена 11-я глава книги, в которой обсуждается устройство изменяемых структур (refs/atoms/agents), когда их можно и нужно использовать, а также рассказывается про параллельное программирование на Clojure (futures, promises, локи и т.п.).&lt;/p&gt;&lt;p&gt;Кроме того, книга касается вопросов использования мультиметодов, протоколов и типов данных, введенных в Clojure 1.2, а также вопросов интеграции с JVM и Java.  Но эти темы рассматриваются не настолько подробно, как остальные.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Вердикт&lt;/em&gt;: эту книжку рекомендуется прочитать всем, кто уже познакомился с языком, но хочет изучить некоторые темы более подробно и/или хочет научиться &amp;quot;более правильно&amp;quot; программировать на этом языке.  Я лично нашел достаточно много интересного материала, который начал применять в своих проектах.&lt;/p&gt;&lt;h4&gt;Lucene in Action, 2-е издание&lt;/h4&gt;&lt;p class=&quot;first&quot;&gt;Я давно собирался посмотреть на &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://lucene.apache.org/&quot;&gt;Lucene&lt;/a&gt; для своих проектов, слышал про книгу Lucene in Action, но было много жалоб на то, что эта книга уже устарела и неприменима для свежих версий Lucene.  Недавно вышедшее второе издание &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.com/gp/product/1933988177?ie=UTF8&amp;amp;tag=aleottshompag-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1933988177&quot;&gt;Lucene in Action&lt;/a&gt; исправляет эту проблему.&lt;/p&gt;&lt;p&gt;Начинается книга (глава 1) с небольшого обзора Lucene и из чего она состоит, описываются основные этапы в жизненном цикле поиска &amp;mdash; сбор документов, выделение информации, индексация, и сам поиск.  Кроме того, в 1-й главе приведены небольшие, но законченные примеры того, как можно выполнять индексацию документов и затем использовать полученный индекс для поиска.&lt;/p&gt;&lt;p&gt;Первая часть книги (главы 2-6) посвящены подробному описанию того, как Lucene устроена, и как можно использовать ее возможности в приложениях.  Глава 2 полностью посвящена вопросам индексации с описанием того, какие есть опции индексации, как они влияют на работу Lucene, включая производительность, как можно производить индексацию численных и временных (temporal) данных, как можно оптимизовывать и отлаживать процесс индексации.&lt;/p&gt;&lt;p&gt;Глава 3 описывает использование основных поисковых возможностей Lucene.  Глава начинается с простого приложения, которое используется в качестве основы для остальных примеров. Сначала рассматривается использование &lt;code&gt;IndexSearch&lt;/code&gt;, который используется для выполнения поиска, а затем уже рассматриваются основные виды запросов, реализованных в Lucene, и &lt;code&gt;QueryParser&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Главы с 4-й по 6-ю посвящены &amp;quot;расширенным&amp;quot; темам, их можно пропустить при первом прочтении, если вам нужны только стандартные возможности Lucene.  В 4-й главе описываются различные анализаторы текста, реализованные в Lucene и Nutch, а также показывается как можно реализовать новые анализаторы и/или расширять существующие.  5-я глава посвящена дополнительным возможностям поиска &amp;mdash; запросам по нескольким полям и/или индексам, использовании векторов терминов (term vectors), сортировке результатов и т.п.  А в 6-й главе рассказывается о том, как можно расширить возможности поиска путем реализации собственных методов сортировки, фильтров и &amp;quot;сборщиков&amp;quot; (collectors) документов.&lt;/p&gt;&lt;p&gt;Вторая часть книги (главы 7-11) рассказывает о том, как можно выделять текст с помощью библиотеки &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://tika.apache.org/&quot;&gt;Tika&lt;/a&gt; (глава 7), какие существуют расширения для Lucene (главы 8-9), как можно использовать Lucene с языками, отличными от Java (глава 10), а 11-я глава рассматривает вопросы администрирования Lucene, и настройки производительности.&lt;/p&gt;&lt;p&gt;Третья часть книги полностью посвящена рассмотрению того, как Lucene применяется в реальных проектах (Kruge, SIREn, LinkedIn) и рассказывается про то, какие возможности Lucene они используют, как организован процесс индексации и поиска, какие расширения были добавлены для работы, и т.д.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Вердикт&lt;/em&gt;: Большое количество примеров и подробное описание как делают эту книгу очень привлекательной для людей, которые начинают использовать Lucene.  После ее прочтения, можно возвращаться к ней для получения ответов на вопросы, которые не описываются в официальной документации.&lt;/p&gt;&lt;h4&gt;Introduction to Algorithms&lt;/h4&gt;&lt;p class=&quot;first&quot;&gt;Эту книгу я уже читал много лет назад, в русском переводе (на русском она называется &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.ozon.ru/context/detail/id/2429691/?partner=alexott&quot;&gt;Алгоритмы. Построение и анализ&lt;/a&gt;), но некоторое время назад мне захотелось обновить теоретические основы, и поэтому я решил перечитать эту книгу.  В руки мне попало 2-е издание, а спустя буквально месяц вышло уже третье издание &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.com/gp/product/0262033844?ie=UTF8&amp;amp;tag=aleottshompag-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0262033844&quot;&gt;Introduction to Algorithms&lt;/a&gt;, и я немного жалею, что не дождался его, поскольку там есть некоторые полезные темы.&lt;/p&gt;&lt;p&gt;Я не могу много написать об этой книге, иначе это будет ее пересказ :-) Лучше всего о ней говорит &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://mitpress.mit.edu/catalog/item/default.asp?ttype=2&amp;amp;tid=11866&amp;amp;mode=toc&quot;&gt;оглавление этой книги&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Это классический учебник по алгоритмам и подходам к их анализу.  Книга начинается с основ анализа алгоритмов, и затем переходит к рассмотрению различных алгоритмов и структур данных (списки, деревья, хеш-таблицы, кучи и т.д.).  Для каждой из рассматриваемых тем приводится анализ сложности алгоритма, рассматриваются возможные варианты реализации структур данных и т.п.  Достаточно много места посвящено алгоритмам над графами.  Кроме базовых структур данных и алгоритмов, в книге рассматриваются некоторые &amp;quot;сложные&amp;quot; темы &amp;mdash; биноминальные кучи, b-trees и т.п.  Почти сотню страниц книги занимают приложения, в которых описывается весь математический аппарат, необходимый для чтения этой книги &amp;mdash;&lt;br /&gt;теория множеств, основы теории вероятностей, и т.п.&lt;/p&gt;&lt;p&gt;Стоит также отметить, что на английском языке доступны &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://videolectures.net/mit6046jf05_introduction_algorithms/&quot;&gt;видео-записи лекций&lt;/a&gt; по данному курсу которые читались в MIT (они также доступны через iTunesU).&lt;/p&gt;&lt;p&gt;&lt;em&gt;Вердикт&lt;/em&gt;: всем программистам читать обязательно, можно использовать как справочник, но первые главы нужно прочитать обязательно.&lt;/p&gt;</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-8275299012298254251</guid>
         <pubDate>Thu, 07 Oct 2010 14:52:00 +0000</pubDate>
      </item>
      <item>
         <title>Вторая часть марлезонского балета</title>
         <link>http://alexott-ru.blogspot.com/2010/09/blog-post.html</link>
         <description>Почти через месяц после первой части, Антон (ака golodnyj) &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://taop.rpod.ru/172639.html&quot;&gt;выложил вторую часть подкаста&lt;/a&gt; со мной, в которой рассказывается про язык Clojure.</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-5776417227635027810</guid>
         <pubDate>Wed, 15 Sep 2010 08:09:00 +0000</pubDate>
      </item>
      <item>
         <title>Вышла Clojure 1.2</title>
         <link>http://alexott-ru.blogspot.com/2010/08/clojure-12.html</link>
         <description>После 8 месяцев напряженной работы, вышла новая версия языка Clojure - 1.2.&lt;br /&gt;В этой версии очень много изменений, из которых особо стоит отметить следующие:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;добавлены протоколы (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure.org/protocols&quot;&gt;protocols&lt;/a&gt;) и типы данных (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure.org/datatypes&quot;&gt;datatypes&lt;/a&gt;), позволяющие создавать новые абстракции и полиморфные функции. При этом производительность гораздо выше чем при использовании мультиметодов;&lt;/li&gt;&lt;li&gt;расширена деструктуризация структур данных, о которой я &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott-ru.blogspot.com/2010/08/clojure.html&quot;&gt;уже писал&lt;/a&gt;;&lt;/li&gt;&lt;li&gt;в составе языка введено несколько новых пространств имен, функции которых были перенесены из clojure-contrib. Сюда относятся функции для работы со строками, repl, pretty printer, ввод/вывод Java, и т.д.;&lt;/li&gt;&lt;li&gt;расширен набор функций для работы с последовательностями; &lt;/li&gt;&lt;li&gt;добавлена поддержка аннотаций Java, что позволяет использовать соответствующий функционал различных фреймворков;&lt;/li&gt;&lt;li&gt;много изменений, связанных с улучшением производительности кода;&lt;/li&gt;&lt;li&gt;для указания метаданных теперь вместо &lt;span style=&quot;&quot;&gt;#^&lt;/span&gt; используется просто &lt;span style=&quot;&quot;&gt;^&lt;/span&gt;. &lt;/li&gt;&lt;/ul&gt;Полный список изменений &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/clojure/clojure/blob/1.2.x/changes.txt&quot;&gt;можно найти в репозитории языка&lt;/a&gt;. Также полезной может быть &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://fogus.me/static/preso/clj1.2+/&quot;&gt;презентация Michael Fogus&lt;/a&gt; о новых возможностях.&lt;br /&gt;&lt;br /&gt;P.S. я успел только частично обновить &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.net/ru/clojure/clojure-intro/&quot;&gt;Введение в Clojure&lt;/a&gt; (это обновленная версия статьи из 4-го номера &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://fprog.ru/&quot;&gt;ПФП&lt;/a&gt;) описанием функциональности из версии 1.2. Сейчас не хватает описания протоколов и типов данных. Я надеюсь, что допишу этот кусок за выходные, о чем сделаю отдельный анонс</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-4661464594298741607</guid>
         <pubDate>Thu, 19 Aug 2010 16:52:00 +0000</pubDate>
      </item>
      <item>
         <title>Подкастовое</title>
         <link>http://alexott-ru.blogspot.com/2010/08/blog-post.html</link>
         <description>Дебютировал в &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://taop.rpod.ru/168440.html&quot;&gt;подкасте у golodnyj&lt;/a&gt;. Это первая часть в которой мы общаемся на тему функционального программирования и лиспа. Вторая часть (через несколько дней) будет про язык Clojure...</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-793992068002145843</guid>
         <pubDate>Tue, 17 Aug 2010 12:35:00 +0000</pubDate>
      </item>
      <item>
         <title>Русская планета Clojure</title>
         <link>http://alexott-ru.blogspot.com/2010/08/clojure_11.html</link>
         <description>Я сделал (пока с помощью Yahoo! Pipes) &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/RussianClojurePlanet&quot;&gt;агрегатор русскоязычных блогов, посвященных Clojure&lt;/a&gt;.&amp;nbsp; Все заведено через feedburner, так что будущие изменения в хостинге не будут влиять на подписчиков. &lt;br /&gt;Если кто пишет про Clojure на русском - пишите мне, с ссылками на блог - я сразу добавлю.&lt;br /&gt;Update 1: Что-то Yahoo! Pipes выставляет неправильные ссылки на оригинальные посты - разбираюсь с ним&lt;br /&gt;Update 2: Починил</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-2667495911949908666</guid>
         <pubDate>Wed, 11 Aug 2010 15:28:00 +0000</pubDate>
      </item>
      <item>
         <title>Деструктуризация параметров в Clojure</title>
         <link>http://alexott-ru.blogspot.com/2010/08/clojure.html</link>
         <description>&lt;div class=&quot;first&quot;&gt;&lt;i&gt;Это небольшое дополнение к статье про Clojure, которое я решил опубликовать отдельно. Эта часть будет добавлена в оригинальную статью, которая сейчас обновляется в предверии выхода Clojure версии 1.2.&lt;/i&gt;&lt;/div&gt;&lt;hr /&gt;&lt;div class=&quot;first&quot;&gt;Если вы передаете сложные структуры данных в функции (&lt;code&gt;defn&lt;/code&gt; или &lt;code&gt;fn&lt;/code&gt;), или связываете значения с символами в &lt;code&gt;let&lt;/code&gt;, то вы можете использовать встроенную в Clojure &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure.org/special_forms#Special%20Forms--%28let%20%5bbindings*%20%5d%20exprs*%29&quot;&gt;деструктуризацию параметров&lt;/a&gt;, что позволяет связывать части структур данных с символами. Это значительно упрощает (и сокращает) код, поскольку вам не нужно писать явный код для получения значения значений из массивов или отображений.&lt;/div&gt;Существует две формы деструктуризации параметров — деструктуризация отображений, и деструктуризация векторов, строк и массивов.  Деструктуризация векторов/массивов/строк имеет простую форму — вы помещаете список символов внутри вектора, и значения, стоящие на соответствующих местах в деструктурируемом объекте, будут связаны с этими символами.  В том случае, если вы укажете меньше аргументов, чем указано символов, то отсутствующие значения будут рассматриваться как имеющие значение &lt;code&gt;nil&lt;/code&gt;, если укажете больше, то они будут отброшены.  Вы можете собрать &quot;лишние&quot; значения в отдельный список, используя запись &lt;code&gt;&amp;amp; символ&lt;/code&gt;, и все &quot;лишние&quot; значения будут помещены в список, связанный с указанным символом. Вот примеры использования деструктуризации векторов и строк:&lt;br /&gt;&lt;pre class=&quot;src&quot;&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [ [a b] [1 2]]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b))&lt;br /&gt;(1 2)&lt;br /&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [ [a b] [1]]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b))&lt;br /&gt;(1 nil)&lt;br /&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [ [a b] [1 2 3 4]]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b))&lt;br /&gt;(1 2)&lt;br /&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [ [a b &amp;amp; c] [1 2 3 4]]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b c))&lt;br /&gt;(1 2 (3 4))&lt;br /&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [ [a b &amp;amp; c] &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;abcde&quot;&lt;/span&gt;]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b c))&lt;br /&gt;(&amp;#92;a &amp;#92;b (&amp;#92;c &amp;#92;d &amp;#92;e))&lt;br /&gt;user&amp;gt; ((&lt;span style=&quot;color:darkgreen;&quot;&gt;fn&lt;/span&gt; [ [a b] ] (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b)) [1 2])&lt;br /&gt;(1 2)&lt;br /&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;defn&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;dfunc1&lt;/span&gt; [ [a b] ]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b))&lt;br /&gt;user&amp;gt; (dfunc1 [1 2])&lt;br /&gt;(1 2)&lt;/pre&gt;Деструктуризация отображений выглядит следующим образом — вы записываете отображение, в котором ключом является символ, с которым будет связано значение, а значением — является ключ в деструктурируемом отображении.  Например,&lt;br /&gt;&lt;pre class=&quot;src&quot;&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [{a &lt;span style=&quot;color:darkgreen;&quot;&gt;:k1&lt;/span&gt; b &lt;span style=&quot;color:darkgreen;&quot;&gt;:k2&lt;/span&gt; c &lt;span style=&quot;color:darkgreen;&quot;&gt;:k3&lt;/span&gt;} {&lt;span style=&quot;color:darkgreen;&quot;&gt;:k1&lt;/span&gt; 1 &lt;span style=&quot;color:darkgreen;&quot;&gt;:k2&lt;/span&gt; 2 &lt;span style=&quot;color:darkgreen;&quot;&gt;:k3&lt;/span&gt; 3}]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b c))&lt;br /&gt;(1 2 3)&lt;br /&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [{a &lt;span style=&quot;color:darkgreen;&quot;&gt;:k1&lt;/span&gt; b &lt;span style=&quot;color:darkgreen;&quot;&gt;:k2&lt;/span&gt; c &lt;span style=&quot;color:darkgreen;&quot;&gt;:k3&lt;/span&gt;} {&lt;span style=&quot;color:darkgreen;&quot;&gt;:k1&lt;/span&gt; 1 &lt;span style=&quot;color:darkgreen;&quot;&gt;:k3&lt;/span&gt; 3}]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b c))&lt;br /&gt;(1 nil 3)&lt;/pre&gt;Также как и в случае с деструктуризацией векторов, если конкретный ключ не был указан, то символ получает значение &lt;code&gt;nil&lt;/code&gt;, как это видно во втором примере.&lt;br /&gt;Деструктуризация отображений может иметь более сложную форму, поскольку можно указывать еще и значения по умолчанию, которые будут присвоены соответствующим символам вместо &lt;code&gt;nil&lt;/code&gt;, если нужный ключ не был указан в отображении.  Это осуществляется путем указания ключевого символа &lt;code&gt;:or&lt;/code&gt; и отображения, в котором перечисляются значения по умолчанию:&lt;br /&gt;&lt;pre class=&quot;src&quot;&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [{a &lt;span style=&quot;color:darkgreen;&quot;&gt;:a&lt;/span&gt; b &lt;span style=&quot;color:darkgreen;&quot;&gt;:b&lt;/span&gt; c &lt;span style=&quot;color:darkgreen;&quot;&gt;:c&lt;/span&gt; &lt;span style=&quot;color:darkgreen;&quot;&gt;:or&lt;/span&gt; {a 1 b 2 c 3}} {&lt;span style=&quot;color:darkgreen;&quot;&gt;:a&lt;/span&gt; 4}]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b c))&lt;br /&gt;(4 2 3)&lt;/pre&gt;Для того, чтобы не писать пары символ/ключ, имеется упрощенная форма записи, когда вы указываете ключевой символ &lt;code&gt;:keys&lt;/code&gt; и вектор, содержащий список символов, которые будут превращены в ключевые слова с теми же самыми именами, и которые будут использоваться для поиска ключей в деструктурируемом отображении.  Например, предыдущие примеры можно переписать в более компактной форме:&lt;br /&gt;&lt;pre class=&quot;src&quot;&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [{&lt;span style=&quot;color:darkgreen;&quot;&gt;:keys&lt;/span&gt; [a b c]} {&lt;span style=&quot;color:darkgreen;&quot;&gt;:a&lt;/span&gt; 1 &lt;span style=&quot;color:darkgreen;&quot;&gt;:b&lt;/span&gt; 2 &lt;span style=&quot;color:darkgreen;&quot;&gt;:c&lt;/span&gt; 3}]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b c))&lt;br /&gt;(1 2 3)&lt;br /&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [{&lt;span style=&quot;color:darkgreen;&quot;&gt;:keys&lt;/span&gt; [a b c]} {&lt;span style=&quot;color:darkgreen;&quot;&gt;:a&lt;/span&gt; 1 &lt;span style=&quot;color:darkgreen;&quot;&gt;:c&lt;/span&gt; 3}]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b c))&lt;br /&gt;(1 nil 3)&lt;/pre&gt;Кроме ключевых символов, в качестве ключей отображений вы можете использовать строки и символы.  Для этого нужно использовать ключевое слово &lt;code&gt;:strs&lt;/code&gt; — для строк и &lt;code&gt;:syms&lt;/code&gt; — для символов, как это показано в следующих примерах:&lt;br /&gt;&lt;pre class=&quot;src&quot;&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [{&lt;span style=&quot;color:darkgreen;&quot;&gt;:strs&lt;/span&gt; [a b c] &lt;span style=&quot;color:darkgreen;&quot;&gt;:as&lt;/span&gt; m &lt;span style=&quot;color:darkgreen;&quot;&gt;:or&lt;/span&gt; {a 2 b 3}} {&lt;span style=&quot;color:#008b00;&quot;&gt;&quot;a&quot;&lt;/span&gt; 5 &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;c&quot;&lt;/span&gt; 6}]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b c m))&lt;br /&gt;(5 3 6 {&lt;span style=&quot;color:#008b00;&quot;&gt;&quot;a&quot;&lt;/span&gt; 5, &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;c&quot;&lt;/span&gt; 6})&lt;br /&gt;&lt;br /&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [{&lt;span style=&quot;color:darkgreen;&quot;&gt;:syms&lt;/span&gt; [a b c] &lt;span style=&quot;color:darkgreen;&quot;&gt;:as&lt;/span&gt; m &lt;span style=&quot;color:darkgreen;&quot;&gt;:or&lt;/span&gt; {a 2 b 3}} {'a 5 'b 6}]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b c m))&lt;br /&gt;(5 3 6 {&lt;span style=&quot;color:#008b00;&quot;&gt;&quot;a&quot;&lt;/span&gt; 5, &lt;span style=&quot;color:#008b00;&quot;&gt;&quot;c&quot;&lt;/span&gt; 6})&lt;/pre&gt;Особенно полезна деструктуризация отображений для тех случаев, когда вы хотите иметь необязательные (и именованные) параметры в функциях.  В этом случае, объявление функции будет иметь вид&lt;br /&gt;&lt;pre class=&quot;src&quot;&gt;(&lt;span style=&quot;color:#7f007f;&quot;&gt;defn&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;имя-функции&lt;/span&gt; [обязательные параметры&lt;br /&gt;         &amp;amp; {&lt;span style=&quot;color:#79378a;&quot;&gt;:keys&lt;/span&gt; [необязательные параметры]&lt;br /&gt;            &lt;span style=&quot;color:#79378a;&quot;&gt;:or&lt;/span&gt; {значения по умолчанию}}]&lt;br /&gt;тело функции)&lt;/pre&gt;например,&lt;br /&gt;&lt;pre class=&quot;src&quot;&gt;user&amp;gt; (&lt;span style=&quot;color:#7f007f;&quot;&gt;defn&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;dfunc2&lt;/span&gt; [a b &amp;amp; {&lt;span style=&quot;color:#79378a;&quot;&gt;:keys&lt;/span&gt; [c d] &lt;span style=&quot;color:#79378a;&quot;&gt;:or&lt;/span&gt; {c &lt;span style=&quot;color:#8a2152;&quot;&gt;&quot;c&quot;&lt;/span&gt; d &lt;span style=&quot;color:#8a2152;&quot;&gt;&quot;d&quot;&lt;/span&gt;}}]&lt;br /&gt;  (&lt;span style=&quot;color:#79378a;&quot;&gt;list&lt;/span&gt; a b c d))&lt;br /&gt;user&amp;gt; (dfunc2 1 2 &lt;span style=&quot;color:#79378a;&quot;&gt;:c&lt;/span&gt; 3)&lt;br /&gt;(1 2 3 &lt;span style=&quot;color:#8a2152;&quot;&gt;&quot;d&quot;&lt;/span&gt;)&lt;/pre&gt;Здесь мы определяем функцию, принимающую два обязательных параметра, и два необязательных, значения которых можно указывать после соответствующих ключевых символов. &lt;br /&gt;Деструктуризация — это полезный инструмент, но иногда необходимо получить все переданные параметры в неизменном виде.  Для этого можно использовать ключевой символ &lt;code&gt;:as символ&lt;/code&gt;, которая связывает указанный символ с оригинальными параметрами.  Например:&lt;br /&gt;&lt;pre class=&quot;src&quot;&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [[a b &lt;span style=&quot;color:darkgreen;&quot;&gt;:as&lt;/span&gt; c] [1 2 3]]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b c))&lt;br /&gt;(1 2 [1 2 3])&lt;br /&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [{a &lt;span style=&quot;color:darkgreen;&quot;&gt;:a&lt;/span&gt; b &lt;span style=&quot;color:darkgreen;&quot;&gt;:b&lt;/span&gt; &lt;span style=&quot;color:darkgreen;&quot;&gt;:as&lt;/span&gt; c} {&lt;span style=&quot;color:darkgreen;&quot;&gt;:a&lt;/span&gt; 1 &lt;span style=&quot;color:darkgreen;&quot;&gt;:b&lt;/span&gt; 2 &lt;span style=&quot;color:darkgreen;&quot;&gt;:c&lt;/span&gt; 3}]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b c))&lt;br /&gt;(1 2 {&lt;span style=&quot;color:darkgreen;&quot;&gt;:a&lt;/span&gt; 1, &lt;span style=&quot;color:darkgreen;&quot;&gt;:b&lt;/span&gt; 2, &lt;span style=&quot;color:darkgreen;&quot;&gt;:c&lt;/span&gt; 3})&lt;/pre&gt;Также хочется отметить, деструктуризация может применяться и к вложенным структурам, например, если у вас есть вектор векторов, или вложенные отображения.  Например,&lt;br /&gt;&lt;pre class=&quot;src&quot;&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [ [a [b c]] [1 [2 3]]]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b c))&lt;br /&gt;(1 2 3)&lt;br /&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [ [a [b c]] [1 2]]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a b c))&lt;br /&gt;Error....&lt;br /&gt;user&amp;gt; (&lt;span style=&quot;color:#a020f0;&quot;&gt;let&lt;/span&gt; [{a &lt;span style=&quot;color:darkgreen;&quot;&gt;:a&lt;/span&gt; {c &lt;span style=&quot;color:darkgreen;&quot;&gt;:c&lt;/span&gt; d &lt;span style=&quot;color:darkgreen;&quot;&gt;:d&lt;/span&gt;} &lt;span style=&quot;color:darkgreen;&quot;&gt;:b&lt;/span&gt;} {&lt;span style=&quot;color:darkgreen;&quot;&gt;:a&lt;/span&gt; 1 &lt;span style=&quot;color:darkgreen;&quot;&gt;:b&lt;/span&gt; {&lt;span style=&quot;color:darkgreen;&quot;&gt;:c&lt;/span&gt; 3 &lt;span style=&quot;color:darkgreen;&quot;&gt;:d&lt;/span&gt; 4}}]&lt;br /&gt;  (&lt;span style=&quot;color:darkgreen;&quot;&gt;list&lt;/span&gt; a c d))&lt;br /&gt;(1 3 4)&lt;/pre&gt;Но тут стоит быть осторожным, поскольку если вместо вектора вы передадите объект несовместимого типа, то вы получите ошибку, как во втором примере.&lt;br /&gt;Дополнительные примеры вы можете найти &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://paste.lisp.org/display/97057&quot;&gt;на данной странице&lt;/a&gt;.  Также хорошее описание деструктуризации параметров можно найти в книге &quot;Clojure in Action&quot;.</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-5837699222427427270</guid>
         <pubDate>Fri, 06 Aug 2010 15:14:00 +0000</pubDate>
      </item>
      <item>
         <title>Статья про Clojure &amp; Hadoop</title>
         <link>http://alexott-ru.blogspot.com/2010/07/clojure-hadoop.html</link>
         <description>Наконец-то закончил давно начатую и откладываемую с&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.net/ru/clojure/ClojureHadoop.html&quot;&gt;татью про использование Clojure для программирования Hadoop&lt;/a&gt;.&amp;nbsp; В статье описывается пакет &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://groups.google.ru/group/clojure-russian?hl=ru&quot;&gt;clojure-hadoop&lt;/a&gt;, который позволяет сильно упростить программирование заданий для Hadoop. &lt;br /&gt;&lt;br /&gt;P.S. English version will follow after short time, that I need to make translation ;-)</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-5910535155681413362</guid>
         <pubDate>Fri, 23 Jul 2010 09:58:00 +0000</pubDate>
      </item>
      <item>
         <title>Список рассылки про Clojure на русском</title>
         <link>http://alexott-ru.blogspot.com/2010/07/clojure.html</link>
         <description>Вчера был создан список рассылки для обсуждения вопросов о Clojure на русском языке. Кто заинтересован - &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://groups.google.ru/group/clojure-russian&quot;&gt;присоединяйтесь&lt;/a&gt;!</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-6053367119597289087</guid>
         <pubDate>Wed, 21 Jul 2010 07:53:00 +0000</pubDate>
      </item>
      <item>
         <title>Презентация про Clojure с MarginCon 2010</title>
         <link>http://alexott-ru.blogspot.com/2010/07/clojure-margincon-2010.html</link>
         <description>В конце июня я делал доклад про Clojure на &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://margincon.ru/&quot;&gt;конференции MarginCon&lt;/a&gt; (через Skype), а сегодня я выложил &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.slideshare.net/alexott/clojure-margincon-2010&quot;&gt;презентацию синхронизированную со звуком&lt;/a&gt;. Огромное спасибо &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://pyobject.ru/&quot;&gt;Юре Юревичу&lt;/a&gt; за предоставленную запись и за возможность выступления на этой конференции...&lt;br /&gt;P.S. звук немного гуляет, в нескольких местах опущено по несколько секунд выступления, но в целом не должно быть проблемы с остальным текстом</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-6279936530034978478</guid>
         <pubDate>Sun, 11 Jul 2010 19:52:00 +0000</pubDate>
      </item>
      <item>
         <title>Впечатления о Practical Clojure</title>
         <link>http://alexott-ru.blogspot.com/2010/07/practical-clojure.html</link>
         <description>Вчера, практически в один заход прочитал &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.com/gp/product/1430272317?ie=UTF8&amp;amp;tag=aleottshompag-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1430272317&quot;&gt;Practical Clojure&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;1&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=aleottshompag-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1430272317&quot; style=&quot;border:medium none important;margin:0px;&quot; width=&quot;1&quot;/&gt; - хотелось ознакомиться с новой книгой, чтобы составить свое мнение.&lt;br /&gt;Что я могу сказать о ней после прочтения? Это краткое и очень хорошее введение в язык Clojure - в книге есть вся необходимая информация для того, чтобы начать работу с языком, включая описание таких эксперементальных вещей, как протоколы и типы данных.&lt;br /&gt;Кроме того, в книге достаточно много диаграм и схем, которые облегчают понимание структур и потоков данных в Clojure.&amp;nbsp; Также, в книге достаточно много места посвящено объяснению концепций state/identity и тому, как они применяются внутри Clojure.&lt;br /&gt;Среди недостатков можно отметить отсутствие больших примеров, таких как Lancet в &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.com/gp/product/1934356336?ie=UTF8&amp;amp;tag=aleottshompag-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1934356336&quot;&gt;Programming Clojure&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;1&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=aleottshompag-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1934356336&quot; style=&quot;border:medium none important;margin:0px;&quot; width=&quot;1&quot;/&gt;, а также нет никакой информации средам разработки и т.п. вещам, так что эту информацию надо искать в других источниках.</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-969326177306035957</guid>
         <pubDate>Fri, 09 Jul 2010 10:19:00 +0000</pubDate>
      </item>
      <item>
         <title>Небольшой опрос</title>
         <link>http://alexott-ru.blogspot.com/2010/06/blog-post.html</link>
         <description>Решил сделать небольшой опрос на тему книг про Clojure.  Это не значит, что я собираюсь писать книгу, но я думаю в этом направлении... &lt;br /&gt;&lt;em&gt;Update:&lt;/em&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://spreadsheets.google.com/viewform?hl=en_GB&amp;formkey=dFdKNml2ZE9naVVJVUNubFFyN0RtSmc6MQ#gid=0&quot;&gt;Ссылка на опросник&lt;/a&gt;, если вам неудобно заполнять его на blogspot...&lt;br /&gt;&lt;br /&gt; Loading...&lt;br /&gt;&lt;br /&gt;P.S. просьба попиарить этот опросник, особенно среди ява-программистов...</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-8768735891787737109</guid>
         <pubDate>Wed, 09 Jun 2010 09:45:00 +0000</pubDate>
      </item>
      <item>
         <title>Видео-материалы про Clojure (продолжение)</title>
         <link>http://alexott-ru.blogspot.com/2010/04/clojure.html</link>
         <description>Собрал ссылки на видео-материалы о кложуре на &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.net/ru/clojure/video.html&quot;&gt;отдельной странице&lt;/a&gt; на своем сайте - собираюсь регулярно обновлять этот список по мере появления новых материалов.</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-3850606772910010872</guid>
         <pubDate>Tue, 27 Apr 2010 14:39:00 +0000</pubDate>
      </item>
      <item>
         <title>Leiningen + Clojure</title>
         <link>http://alexott-ru.blogspot.com/2010/04/leiningen-clojure.html</link>
         <description>Написал &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.net/ru/clojure/ClojureLein.html&quot;&gt;еще одну заметку&lt;/a&gt; про сборку кода написанного на Clojure. В ней рассматривается использование утилиты Leiningen, написанной на Clojure, и которая намного проще Maven для небольших проектов.</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-3484075133239646446</guid>
         <pubDate>Wed, 14 Apr 2010 12:46:00 +0000</pubDate>
      </item>
      <item>
         <title>Использование Maven для сборки кода на Clojure</title>
         <link>http://alexott-ru.blogspot.com/2010/04/maven-clojure.html</link>
         <description>Написал и выложил на свой сайт &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.net/ru/clojure/ClojureMaven.html&quot;&gt;небольшую заметку&lt;/a&gt; про использование Maven для сборки и тестирования кода, написанного на Clojure. Замечания просьба оставлять прямо на сайте...&lt;br /&gt;P.S. Следом планируется публикация заметки про Leiningen, может быть закончу до конца недели</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-3614600381512336375</guid>
         <pubDate>Wed, 07 Apr 2010 18:14:00 +0000</pubDate>
      </item>
      <item>
         <title>Более простое начало работы с Clojure</title>
         <link>http://alexott-ru.blogspot.com/2010/03/clojure.html</link>
         <description>Stuart Halloway (автор книги Programming Clojure) разрабатывает проект &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/relevance/labrepl&quot;&gt;labrepl&lt;/a&gt;, который предназначен для упрощения начала работы с Clojure.  Проект содержит различные примеры использования Clojure и позволяет достаточно просто установить среду в которой можно эксперементировать с этим языком, используя разные библиотеки - clojure-contrib, incanter, compojure и используя разные среды разработки и средства сборки проектов.</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-4685638890941903879</guid>
         <pubDate>Tue, 23 Mar 2010 21:28:00 +0000</pubDate>
      </item>
      <item>
         <title>Новый номер журнала &quot;Практика функционального программирования&quot;</title>
         <link>http://alexott-ru.blogspot.com/2010/02/blog-post_25.html</link>
         <description>Выпущен новый, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://fprog.ru/2010/issue4/&quot;&gt;4-й номер&lt;/a&gt; журнала &quot;Практика функционального программирования&quot;. В новом номере вы можете почитать о производительности Lisp'а, о свертках, мономорфизме и бесточечном стиле программирования на Haskell, а также моя &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://fprog.ru/2010/issue4/alex-ott-clojure/&quot;&gt;статья о языке Clojure&lt;/a&gt;.&lt;br /&gt;Статья получилась не особо короткая (больше 30 страниц), но она должна содержать все необходимые материалы для начала работы с этим языком - я надеюсь, что их будет достаточно и для людей не знакомых с Lisp.&lt;br /&gt;Я также хотел бы поблагодарить людей, помогавших мне в написании этой статьи за их комментарии и советы</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-4794716393634896350</guid>
         <pubDate>Thu, 25 Feb 2010 17:06:00 +0000</pubDate>
      </item>
      <item>
         <title>Презентация про Incanter</title>
         <link>http://alexott-ru.blogspot.com/2010/02/incanter.html</link>
         <description>В &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://data-sorcery.org/2010/02/11/data-sorcery-pt1/&quot;&gt;блоге проекта Incanter&lt;/a&gt; выложена презентация о работе с наборами данных и графиками.&amp;nbsp; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://incanter.org/&quot;&gt;Incanter&lt;/a&gt; - R-подобная среда и набор библиотек для Clojure для статистической обработки данных.&amp;nbsp; Кроме того, существует проект &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/jolby/rincanter&quot;&gt;RIncanter&lt;/a&gt;, который реализует взаимодействие между R и Clojure/Incanter.</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-1336398498389614174</guid>
         <pubDate>Fri, 12 Feb 2010 08:29:00 +0000</pubDate>
      </item>
      <item>
         <title>Видеоматериалы про Clojure</title>
         <link>http://alexott-ru.blogspot.com/2010/01/clojure.html</link>
         <description>Поскольку не вся информация помещается в статью, то решил публиковать в блог излишки информации :-)&lt;br /&gt;Существует несколько хороших наборов видеоматериалов, посвященных Clojure:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure.blip.tv/&quot;&gt;http://clojure.blip.tv/&lt;/a&gt; - содержит видео с рассказами о Clojure, записанные на выступлениях как автора языка - Rich Hickey, так и других разработчиков.&amp;nbsp; Лекции самые разные по содержанию, и содержат интересные выступления. Есть отдельные лекции &quot;Clojure для программистов на Lisp&quot; и &quot;Clojure для программистов на Java&quot;, которые могут служить очень хорошими введениями в язык;&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://vimeo.com/channels/fulldisclojure&quot;&gt;набор скринкастов от Sean Devlin&lt;/a&gt;, в которых рассказывается как про возможности новой версии Clojure - 1.1, так и про другие темы - управление проектами, и т.д.&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Rich-Hickey-and-Brian-Beckman-Inside-Clojure/&quot;&gt;Inside Clojure&lt;/a&gt; - лекция Rich Hickey для Channel 9, в котором рассказывается про внутреннее устройство языка&lt;/li&gt;&lt;/ul&gt;Update: Спасибо комментаторам за дополнительные ссылки, я про них совсем забыл:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey&quot;&gt;Persistent Data Structures and Managed References&lt;/a&gt; - еще одна презентация Rich Hickey о внутреннем устройстве Clojure&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.youtube.com/watch?v=Aoeav_T1ARU&quot;&gt;Intro to Clojure&lt;/a&gt; - серия презентация о Clojure;&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://peepcode.com/products/functional-programming-with-clojure&quot;&gt;Functional Programming with Clojure&lt;/a&gt; - платный скринкаст, показывающий возможности Clojure на примере разработки игры (я сам не смотрел его, в отличии от предыдущих материалов)...&lt;/li&gt;&lt;/ul&gt;</description>
         <author>Alex Ott</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-2145365503775784580.post-3531859702256244936</guid>
         <pubDate>Tue, 26 Jan 2010 14:52:00 +0000</pubDate>
      </item>
      <item>
         <title>Applicative-order evaluation vs Normal-order evaluation</title>
         <link>http://dolzhenko.blogspot.com/2010/10/applicative-order-evaluation-vs-normal.html</link>
         <description>&lt;span class=&quot;i&quot;&gt;Нормальным порядком вычисления&lt;/span&gt; (normal-order evaluation), если кратко, можно назвать такой порядок вычисления, что сперва происходит &amp;laquo;полная подстановка, затем редукция&amp;raquo;.&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;i&quot;&gt;Аппликативный порядок вычисления&lt;/span&gt; (applicative-order evaluation), напротив, сперва происходит &amp;laquo;вычисление аргументов, затем вызов процедуры&amp;raquo;.&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; name='more'&gt;&lt;/a&gt;&lt;br /&gt;В качестве наглядного примера - попробуем реализовать свою собственную функцию &lt;span class=&quot;b i&quot;&gt;and&lt;/span&gt; для &lt;span class=&quot;i&quot;&gt;clojure&lt;/span&gt;.&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;clojure&quot;&gt;(defn&lt;br /&gt;  #^{:test (fn []&lt;br /&gt; (assert (true? (my-and true)))&lt;br /&gt; (assert (false? (my-and true false)))&lt;br /&gt; (assert (true? (my-and true true)))&lt;br /&gt; (assert (false? (my-and true true false)))&lt;br /&gt; (assert (true? (my-and true true true)))&lt;br /&gt;)}&lt;br /&gt;  my-and &lt;br /&gt;  ([x] x)&lt;br /&gt;  ([x &amp;amp; more] (if (false? x) x (reduce my-and more)))&lt;br /&gt;)&lt;/code&gt;&lt;/pre&gt;Отлично. &lt;br /&gt;&lt;br /&gt;Почему же тогда автор &lt;span class=&quot;b i&quot;&gt;clojure&lt;/span&gt; решил использовать макросы в реализации функции &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/clojure/clojure/blob/b578c69d7480f621841ebcafdfa98e33fcb765f6/src/clj/clojure/core.clj#L693&quot;&gt;and&lt;/a&gt; ?&lt;br /&gt;&lt;br /&gt;В группе языков lisp, как впрочем и во многих других языках, используется &lt;span class=&quot;i&quot;&gt;аппликативный порядок вычисления&lt;/span&gt; (в общем случае, если не используются мощности &amp;laquo;синтаксического сахара&amp;raquo;). &lt;br /&gt;&lt;br /&gt;Разница между &lt;span class=&quot;i b&quot;&gt;my-and&lt;/span&gt; и &lt;span class=&quot;b i&quot;&gt;and&lt;/span&gt; в том, что &lt;span class=&quot;i b&quot;&gt;my-and&lt;/span&gt; использует аппликативный порядок (т.е все аргументы будут вычислены до вызова функции), в то время как &lt;span class=&quot;b i&quot;&gt;and&lt;/span&gt; использует несколько иной порядок. &lt;br /&gt;И, поэтому, один из легальных способов изменить порядок вычисления - применение &lt;span class=&quot;i&quot;&gt;макросов&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;В качестве примера используем функцию &lt;span class=&quot;b i&quot;&gt;foo&lt;/span&gt;:&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;clojure&quot;&gt;user=&amp;gt; (defn foo[x] (do (println &quot;foo&quot;) x))&lt;br /&gt;user=&amp;gt; (my-and (foo false) (foo false) (foo true))&lt;br /&gt;foo&lt;br /&gt;foo&lt;br /&gt;foo&lt;br /&gt;false&lt;br /&gt;user=&amp;gt; (and (foo false) (foo false) (foo true))&lt;br /&gt;foo&lt;br /&gt;false&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;i&quot;&gt;P.S.&lt;/span&gt; Строго говоря, &lt;span class=&quot;b i&quot;&gt;and&lt;/span&gt; не использует нормальный порядок вычисления, а &amp;laquo;псевдонормальный порядок&amp;raquo; на один шаг.</description>
         <author>Vladimir Dolzhenko</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-2278643709621197709</guid>
         <pubDate>Sun, 31 Oct 2010 18:03:00 +0000</pubDate>
      </item>
      <item>
         <title>FP-approach in Java via Goolge Collections</title>
         <link>http://dolzhenko.blogspot.com/2010/03/fp-approach-in-java-via-goolge.html</link>
         <description>I'm going to demonstrate some elements of functional programming (&lt;span class=&quot;b i&quot;&gt;fp&lt;/span&gt;) approach in java.&lt;br /&gt;&lt;br /&gt;For this purpose I use &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://code.google.com/p/google-collections/&quot;&gt;Google Collections Library&lt;/a&gt; - provides new and elegant collection types as well as some &lt;span class=&quot;b i&quot;&gt;fp&lt;/span&gt; elements and techniques.&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; name='more'&gt;&lt;/a&gt;&lt;br /&gt;A bit more about Google Collections Library:&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://code.google.com/p/google-collections/wiki/Faq&quot;&gt;Google Collections Library FAQ&lt;/a&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.javalobby.org/articles/google-collections/&quot;&gt;What is the Google Collections Library?&lt;/a&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://bwinterberg.blogspot.com/2009/09/introduction-to-google-collections.html&quot;&gt;Introduction to Google Collections by Benjamin Winterberg&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For obvious cases I put examples in &lt;span class=&quot;b&quot;&gt;clojure&lt;/span&gt; and in &lt;span class=&quot;b&quot;&gt;java&lt;/span&gt; using fp-approach techniques.&lt;br /&gt;&lt;br /&gt;Took short and nice example from &quot;Programming clojure&quot; book - StringUtils.isBlank() is the method (from the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://commons.apache.org/&quot;&gt;Apache Commons&lt;/a&gt;) checks to see whether a string is blank: either empty or consisting of only whitespace :&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;java&quot;&gt;public static boolean isBlank(String str) {&lt;br /&gt;  int strLen;&lt;br /&gt;  if (str == null || (strLen = str.length()) == 0) {&lt;br /&gt;    return true;&lt;br /&gt;  }&lt;br /&gt;  for (int i = 0; i &amp;lt; strLen; i++) {&lt;br /&gt;    if ((Character.isWhitespace(str.charAt(i)) == false)) {&lt;br /&gt;      return false;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  return true;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;Here is a similar implementation in Clojure:&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;lisp&quot;&gt;(defn blank? [s] (every? #(Character/isWhitespace %) s))&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Java-fp-approach implementation of isBlank method powered by google collections,  string is a sequence of chars - that's why I had introduce &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gist.github.com/346279&quot;&gt;stringIterator&lt;/a&gt;:&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;java&quot;&gt;import static ru.dolzhenko.lambda.iterators.StringIterator.*;&lt;br /&gt;&lt;br /&gt;import static com.google.common.collect.Iterators.*;&lt;br /&gt;&lt;br /&gt;public static boolean isBlank(String str) {&lt;br /&gt;return all(&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gist.github.com/346279&quot;&gt;stringIterator&lt;/a&gt;(str),&lt;br /&gt;  new Predicate&amp;lt;Character&amp;gt;() {&lt;br /&gt;    @Override&lt;br /&gt;    public boolean apply(Character ch) {&lt;br /&gt;      return Character.isWhitespace(ch);&lt;br /&gt;    }&lt;br /&gt;  });&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;quote&quot;&gt;&lt;span class=&quot;b i&quot;&gt;map&lt;/span&gt; is function mapping, a classic primitive in functional programming - apply a function to all elements of a list, and return the resulting list.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;e.g. parse string values to numbers:&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;lisp&quot;&gt;(map #(Integer/valueOf %) [&quot;1&quot; &quot;2&quot; &quot;3&quot;])&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;on java: &lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;java&quot;&gt;Collections2.transform(&lt;br /&gt;  ImmutableList.of(&quot;1&quot;, &quot;2&quot;, &quot;3&quot;), &lt;br /&gt;  new Function&amp;lt;String, Integer&amp;gt;() {&lt;br /&gt;    @Override&lt;br /&gt;    public Integer apply(String from) {&lt;br /&gt;      return Integer.valueOf(from);&lt;br /&gt;    }&lt;br /&gt;  });&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Transform is also available for &lt;span class=&quot;i&quot;&gt;Iterables.transform(Iterable, Function)&lt;/span&gt;, &lt;span class=&quot;i&quot;&gt;Iterators.transform(Iterator, Function)&lt;/span&gt; etc.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;quote&quot;&gt;The &lt;span class=&quot;b i&quot;&gt;reduce&lt;/span&gt; function is a little less obvious in its intent. This function reduces a list to a single value by combining elements via a supplied function.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;quote&quot;&gt;The &lt;span class=&quot;b i&quot;&gt;filter&lt;/span&gt; function returns elements of collection that satisfy predicate.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;For instance, Let's solve &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://projecteuler.net/index.php?section=problems&amp;id=1&quot;&gt;ProjectEuler - Problem #1&lt;/a&gt; - find the sum of all the multiples of 3 or 5 below 1000:&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;lisp&quot;&gt;(reduce + (filter #(or (zero? (mod % 3)) (zero? (mod % 5))) (range 1000)))&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;... and the same on java: &lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;java&quot;&gt;// import static import static com.google.common.base.Predicates.*;&lt;br /&gt;// import static com.google.common.collect.Iterators.*;&lt;br /&gt;&lt;br /&gt;// import static ru.dolzhenko.lambda.iterators.&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gist.github.com/346755#file_lambda_iterators.java&quot;&gt;LambdaIterators&lt;/a&gt;.*;&lt;br /&gt;// import static ru.dolzhenko.lambda.functions.&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gist.github.com/346755#file_lambda_functions.java&quot;&gt;LambdaFunctions&lt;/a&gt;.*;&lt;br /&gt;// import static ru.dolzhenko.lambda.functions.&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gist.github.com/346755#file_lambda_predicates.java&quot;&gt;LambdaPredicates&lt;/a&gt;.*;&lt;br /&gt;&lt;br /&gt;final BigDecimal value = reduce(sum(), filter(range(1000),&lt;br /&gt;  or(&lt;br /&gt;    zero(mod(new BigDecimal(3))),&lt;br /&gt;    zero(mod(new BigDecimal(5)))&lt;br /&gt;  )));&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Yeah, there are no &lt;span class=&quot;b i&quot;&gt;reduce&lt;/span&gt; and &lt;span class=&quot;b i&quot;&gt;range&lt;/span&gt; functions in google collections too, so I had to &lt;strike&gt;build my own theme park, with blackjack&lt;/strike&gt; make my own collection of functions &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gist.github.com/346755&quot;&gt;LambdaIterators &amp; Co.&lt;/a&gt; that supplement google collections with such useful functions as &lt;span class=&quot;b i&quot;&gt;reduce&lt;/span&gt;, &lt;span class=&quot;b i&quot;&gt;range&lt;/span&gt;, &lt;span class=&quot;b i&quot;&gt;take&lt;/span&gt;, &lt;span class=&quot;b i&quot;&gt;takeWhile&lt;/span&gt;, &lt;span class=&quot;b i&quot;&gt;iterate&lt;/span&gt;, &lt;span class=&quot;b i&quot;&gt;first&lt;/span&gt;, &lt;span class=&quot;b i&quot;&gt;rest&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Definitely, &lt;span class=&quot;b i&quot;&gt;Predicate&lt;/span&gt; is a function, so it can be described as &lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;java&quot;&gt;public interface Predicate&amp;lt;T&amp;gt; extends Function&amp;lt;T, Boolean&amp;gt;{ &lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;To avoid autoboxing overhead authors of google collections prefer to introduce new interface.&lt;br /&gt;&lt;br /&gt;After that we able to construct expressions like &lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;lisp&quot;&gt;(take 5 (filter even? (iterate inc 1)))&lt;/code&gt;&lt;/pre&gt;on java:&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;java&quot;&gt;take(5, filter(iterate(inc(), BigDecimal.ONE), even()))&lt;/code&gt;&lt;/pre&gt; as well as for finite collection as well as for infinite collection - functions &lt;br /&gt;&lt;span class=&quot;b i&quot;&gt;filter&lt;/span&gt;, &lt;span class=&quot;b i&quot;&gt;transform&lt;/span&gt;, &lt;span class=&quot;b i&quot;&gt;take&lt;/span&gt;, &lt;span class=&quot;b i&quot;&gt;takeWhile&lt;/span&gt;, &lt;span class=&quot;b i&quot;&gt;iterate&lt;/span&gt;, &lt;span class=&quot;b i&quot;&gt;first&lt;/span&gt;, &lt;span class=&quot;b i&quot;&gt;rest&lt;/span&gt; are lazy - in other words, elements are not calculated until they are needed.&lt;br /&gt;&lt;br /&gt;btw. &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://code.google.com/p/lambdaj&quot;&gt;lambdaj&lt;/a&gt; is useful framework that provides pseudo fp approach in java.</description>
         <author>Vladimir Dolzhenko</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-4133876200664541646</guid>
         <pubDate>Sun, 28 Mar 2010 23:50:00 +0000</pubDate>
      </item>
      <item>
         <title>Задачка: A(4,3)</title>
         <link>http://dolzhenko.blogspot.com/2010/02/a43.html</link>
         <description>&lt;div class=&quot;quote&quot;&gt;функция A(x,y) определена как&lt;br /&gt; A(0,y) = 1, y &amp;ge; 0 &lt;br /&gt; A(1,0) = 2 &lt;br /&gt; A(x,0) = x + 2, x &amp;ge; 2 &lt;br /&gt; A(x + 1, y + 1) = A( A(x, y + 1), y), x &amp;ge; 0, y &amp;ge; 0 &lt;br /&gt; &lt;br /&gt; A(4,3) = ?&lt;/div&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; name='more'&gt;&lt;/a&gt;&lt;br /&gt;Данная функция есть &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Ackermann_function&quot;&gt;функция Аккермана&lt;/a&gt; - простой пример вычислимой функции, которая не является примитивно рекурсивной.&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;border:1px solid #000;padding:10px;text-align:center;height:180px;background-color:white;text-align:center;&quot;&gt;&lt;img src=&quot;http://lh4.ggpht.com/_0W-IrdaBLsY/S4elbMAcywI/AAAAAAAAE3U/9pcjJgu6V8c/Ackermann-complex.png&quot; border=&quot;0&quot; width=&quot;500&quot; height=&quot;148&quot;/&gt;&lt;br /&gt;F(z) = A(4, z)&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Попытки вычислить &lt;span class=&quot;b&quot;&gt;A(4, 3)&lt;/span&gt; &lt;span class=&quot;i&quot;&gt;в лоб&lt;/span&gt; обречены на провал (код на clojure):&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;lisp&quot;&gt;(defn A([x y]&lt;br /&gt; (cond &lt;br /&gt;  (zero? x) 1&lt;br /&gt;  (and (= x 1) (zero? y)) 2&lt;br /&gt;  (and (&amp;gt;= x 2) (zero? y)) (+ x 2)&lt;br /&gt;  :else (recur (A (dec x) y) (dec y))&lt;br /&gt; )&lt;br /&gt;))&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Однако, на &lt;span class=&quot;i&quot;&gt;erlang&lt;/span&gt; прямо в лоб решается запросто:&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;erlang&quot;&gt;-module(ack).&lt;br /&gt;-export([a/2]).&lt;br /&gt;&lt;br /&gt;a(0,_) -&amp;gt; 1;&lt;br /&gt;a(1,0) -&amp;gt; 2; &lt;br /&gt;a(X,0) -&amp;gt; X+2;&lt;br /&gt;a(X,Y) -&amp;gt; a( a(X-1,Y), Y-1).&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;запускаем...&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;erlang&quot;&gt;$ erl&lt;br /&gt;1&amp;gt; c(ack.erl).&lt;br /&gt;{ok,ack}&lt;br /&gt;2&amp;gt; ack:a(4,3).&lt;br /&gt;&lt;span class=&quot;i b&quot;&gt;ответ скрыт&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Решить данную задачу на &lt;span class=&quot;i&quot;&gt;clojure&lt;/span&gt; вполне реально - дерзайте!&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;float:left;border:1px solid #444;margin-right:10px;background-color:white;padding:10px;text-align:center;&quot;&gt;&lt;img title=&quot;Tetrahedron&quot; alt=&quot;Tetrahedron&quot; src=&quot;http://projecteuler.net/images/levels/tetrahedron.gif&quot;&gt;&lt;br /&gt;&lt;span class=&quot;b&quot;&gt;Level 1&lt;/span&gt;&lt;/div&gt; &lt;span class=&quot;b&quot;&gt;ps.&lt;/span&gt; Я тем временем заработал &lt;span class=&quot;b&quot;&gt;Level 1&lt;/span&gt; на &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://projecteuler.net/index.php?section=problems&quot;&gt;Project Euler&lt;/a&gt; - на мой взгляд, отличный способ прокачать навыки в функциональном программировании.&lt;div class='clear'&gt;&lt;/div&gt;</description>
         <author>Vladimir Dolzhenko</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-8876539221358949363</guid>
         <pubDate>Fri, 26 Feb 2010 12:56:00 +0000</pubDate>
         <media:thumbnail height="72" url="http://lh4.ggpht.com/_0W-IrdaBLsY/S4elbMAcywI/AAAAAAAAE3U/9pcjJgu6V8c/s72-c/Ackermann-complex.png" width="72" xmlns:media="http://search.yahoo.com/mrss/"/>
      </item>
      <item>
         <title>Задачка: Робот на бесконечной лестнице</title>
         <link>http://dolzhenko.blogspot.com/2010/02/blog-post.html</link>
         <description>&lt;img style=&quot;display:block;margin:10px;width:101px;height:95px;float:left;&quot; src=&quot;http://lh5.ggpht.com/_0W-IrdaBLsY/TQ5VboGYlyI/AAAAAAAAFvE/U_Hj1E7gC50/loderunner.gif&quot; width=&quot;101&quot; height=&quot;95&quot; border=&quot;0&quot;/&gt;&lt;div class=&quot;quote&quot;&gt;На бесконечной лестнице находится робот у которого есть API - подняться вверх. Однако не всякая попытка поднятся вверх заканчивается успехом - робот может как поднятся на верх на 1 ступеньку - функция API вернёт &lt;span class=&quot;b&quot;&gt;1&lt;/span&gt; - или съехать ниже на 1 ступеньку - возвращаемое значение &lt;span class=&quot;b&quot;&gt;-1&lt;/span&gt;. &lt;br /&gt;&lt;br /&gt;Не используя локальных переменных, циклов и формальных параметров функции написать алгоритм, поднимающий &lt;span class=&quot;b&quot;&gt;гарантированно&lt;/span&gt; робота на &lt;span class=&quot;b&quot;&gt;10&lt;/span&gt; ступеней вверх&lt;/div&gt;&lt;a rel=&quot;nofollow&quot; name='more'&gt;&lt;/a&gt;&lt;br /&gt;Задачка скорее разминка для хвоста в целях попрактиковаться на &lt;span class=&quot;i&quot;&gt;clojure&lt;/span&gt;</description>
         <author>Vladimir Dolzhenko</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-9146421003254039251</guid>
         <pubDate>Thu, 04 Feb 2010 08:34:00 +0000</pubDate>
         <media:thumbnail height="72" url="http://lh5.ggpht.com/_0W-IrdaBLsY/TQ5VboGYlyI/AAAAAAAAFvE/U_Hj1E7gC50/s72-c/loderunner.gif" width="72" xmlns:media="http://search.yahoo.com/mrss/"/>
      </item>
      <item>
         <title>Clojure - Hello world!</title>
         <link>http://dolzhenko.blogspot.com/2010/01/clojure-hello-world.html</link>
         <description>&lt;img src=&quot;http://clojure.org/file/view/clojure-icon.gif&quot; style=&quot;float:left;margin:15px;&quot;&gt;Подсадил меня один &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://andrewbass.blogspot.com/&quot;&gt;хороший человек&lt;/a&gt; на &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure.org/&quot;&gt;Clojure&lt;/a&gt; - диалект &lt;span class=&quot;i&quot;&gt;Lisp&lt;/span&gt;, работающий в JVM.&lt;br /&gt;&lt;br /&gt;Язык очень интересный, функциональный, особенно интересен после многолетнего использования объекто-ориентированной парадигмы.&lt;br /&gt;&lt;br /&gt;Как же выглядит традицоинный &lt;strike&gt;Hello, world !&lt;/strike&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Fibonacci_number&quot;&gt;ряд Фибоначчи&lt;/a&gt; на &lt;span class=&quot;i&quot;&gt;clojure&lt;/span&gt; ?&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;lisp&quot;&gt;(defn fib [n]&lt;br /&gt;&quot;Calculate n-th item of Fibonacci sequence&quot;&lt;br /&gt;(if (= n 0) 1&lt;br /&gt;    (if (= n 1) 2&lt;br /&gt;      (+ (fib (- n 2)) (fib (- n 1))))))&lt;/code&gt;&lt;/pre&gt;&lt;a rel=&quot;nofollow&quot; name='more'&gt;&lt;/a&gt; пробуем:&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;lisp&quot;&gt;user=&amp;gt; (map fib (range 10))&lt;br /&gt;(1 2 3 5 8 13 21 34 55 89)&lt;/code&gt;&lt;/pre&gt; Однако, если мы попробуем найти хотя бы 50ый элемент, то... наша попытка обречена на провал - мы впадём в оооочень глубокую рекурсию.&lt;br /&gt;&lt;br /&gt;Выход конечно же использовать не обычную рекурсию, а &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Tail_recursion&quot;&gt;хвостовую&lt;/a&gt;.&lt;br /&gt;Итак, моя версия &lt;span class=&quot;i&quot;&gt;Hello, World&lt;/span&gt;:&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;lisp&quot;&gt;(defn fib&lt;br /&gt;&quot;Calculate n-th item of Fibonacci sequence&quot;&lt;br /&gt;([n]&lt;br /&gt;  (if (zero? n) 1&lt;br /&gt;    (if (= n 1) 2&lt;br /&gt;      ((fn&lt;br /&gt;        [n v2 v1] ; v2 = fib(n-2), v1 = fib(n-1) &lt;br /&gt;        (if (zero? n) (+ v2 v1)&lt;br /&gt;          (recur (dec n) v1 (+ v2 v1))))&lt;br /&gt;       (- n 2) 1 2)))))&lt;/code&gt;&lt;/pre&gt; вуаля:&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;lisp&quot;&gt;user=&amp;gt; (map fib (range 20))&lt;br /&gt;(1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946)&lt;br /&gt;user=&amp;gt; (fib 100)&lt;br /&gt;354224848179261915075&lt;br /&gt;user=&amp;gt; (fib 500)&lt;br /&gt;139423224561697880139724382870407283950070256587697307264108962948325571622863290691557658876222521294125&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;i&quot;&gt;updated.&lt;/span&gt; наиболее красивое решение, определяющее рекурсивно последовательность:&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;lisp&quot;&gt;(def fibs (lazy-cat [1 2] (map + fibs (rest fibs))))&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;&lt;code class=&quot;lisp&quot;&gt;&lt;br /&gt;; элементы ряда, которые меньше, чем 100&lt;br /&gt;user=&amp;gt; (take-while #(&amp;lt; % 100) fibs) &lt;br /&gt;(1 2 3 5 8 13 21 34 55 89)&lt;br /&gt;; первые 10 элементов ряда&lt;br /&gt;user=&amp;gt; (take 10 fibs)&lt;br /&gt;(1 2 3 5 8 13 21 34 55 89)&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Матчасть: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.shelfari.com/books/5121921/Programming-Clojure&quot;&gt;Programming Clojure by Stuart Halloway&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;В качестве практического применения можно попробовать решать задачи из &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://projecteuler.net/&quot;&gt;Проекта &amp;laquo;Эйлер&amp;raquo;&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;b&quot;&gt;ps.&lt;/span&gt; После того как сам решил несколько задач нашёл &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://grok-code.com/367/learning-clojure-with-project-euler/&quot;&gt;решение первых трёх задач на clojure&lt;/a&gt;.</description>
         <author>Vladimir Dolzhenko</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-2692203373784415391</guid>
         <pubDate>Thu, 28 Jan 2010 13:22:00 +0000</pubDate>
      </item>
      <item>
         <title>Devclub 2011 # 02. Про лисп.</title>
         <link>http://lafy.livejournal.com/152330.html</link>
         <description>&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://vimeo.com/20403696&quot;&gt;Mir Lisp'a by Jevgeni Holodkov&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.devclub.eu/2011/02/27/video-holodkov-lisp/&quot;&gt;оценить можно здесь&lt;/a&gt;</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:152330</guid>
         <pubDate>Sun, 27 Feb 2011 11:35:52 +0000</pubDate>
      </item>
      <item>
         <title>Волшебство и Магия Clojure</title>
         <link>http://lafy.livejournal.com/146378.html</link>
         <description>Сделал перевод lisperati: Casting SPELs in Lisp, адаптированный под Clojure.&lt;br /&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://lisperati.planvita.com/&quot;&gt;&lt;img src=&quot;http://lisperati.planvita.com/images/casting_spels.png&quot;/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Перевод: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href='http://lisperati.planvita.com/'&gt;http://lisperati.planvita.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Очень жду комментариев в стиле &quot;ты написал вот так, а пишется вот так&quot; или &quot;написано вот так, но лучше было бы вот так&quot;, оставляйте их в комментариях к посту или на github &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href='http://github.com/jevgeni/spels-ru/issues'&gt;http://github.com/jevgeni/spels-ru/issues&lt;/a&gt;. Спасибо!</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:146378</guid>
         <pubDate>Mon, 28 Jun 2010 05:25:44 +0000</pubDate>
      </item>
      <item>
         <title>devclub.eu quiz</title>
         <link>http://lafy.livejournal.com/146122.html</link>
         <description>На &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.devclub.eu&quot;&gt;devclub.eu&lt;/a&gt; куча решений к &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.devclub.eu/2010/05/31/homework-june-2010/&quot;&gt;quiz-у, который предложил Андрей Солнцев&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Задание: Напечатать на экране следующее:&lt;br /&gt;1&lt;br /&gt;2-1&lt;br /&gt;1-2-3&lt;br /&gt;4-3-2-1&lt;br /&gt;1-2-3-4-5&lt;br /&gt;6-5-4-3-2-1&lt;br /&gt;(Естественно, вместо 6 может быть любое число).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Большинство решений вообщем-то похожи, разница лишь в синтаксисе (и функциях, которые доступны в языке). Все решения стремятся к &quot;one-line solution&quot; ну и благодаря своей динамичности и хорошей библиотеке пока большинством признано решение на Groovy (Сергей Кирьянов):&lt;br /&gt;&lt;pre style=&quot;color:#000000;background:#ffffff;&quot;&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt; i &lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#008000;&quot;&gt;.10&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; println&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt; i%&lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt; ? &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;i : i&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#008000;&quot;&gt;.1&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;join&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#0000e6;&quot;&gt;'-'&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;С моей же точки зрения, если взять за основу, что мы выводим текст на консоль и N не может быть слишком большим, то совершенно гениальным решением является код от Ильи Хямяляйнена (который он кстати сам считает WTF-кодом):&lt;br /&gt;&lt;pre style=&quot;color:#000000;background:#ffffff;&quot;&gt;System.out.print(&quot;1&quot;)&lt;span style=&quot;color:#808030;&quot;&gt;;&lt;/span&gt;
System.out.print(&quot;2-1&quot;)&lt;span style=&quot;color:#808030;&quot;&gt;;&lt;/span&gt;
System.out.print(&quot;1-2-3&quot;)&lt;span style=&quot;color:#808030;&quot;&gt;;&lt;/span&gt;
System.out.print(&quot;4-3-2-1&quot;)&lt;span style=&quot;color:#808030;&quot;&gt;;&lt;/span&gt;
System.out.print(&quot;1-2-3-4-5&quot;)&lt;span style=&quot;color:#808030;&quot;&gt;;&lt;/span&gt;
System.out.print(&quot;6-5-4-3-2-1&quot;)&lt;span style=&quot;color:#808030;&quot;&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Впрочем, на джаве это действительно выглядит ужастно, хоть и читаемо лучше всех решений :) К счастью, у нас есть Clojure, который умеет генерить такого рода штуковины.&lt;br /&gt;&lt;br /&gt;Итак, задача сведется к тому, чтобы выводить на экран ряды из цифр, перевернутные через раз. Цифры печатаются через знак &quot;-&quot;. Т.е. код может выглядеть так:&lt;br /&gt;&lt;pre style=&quot;color:#000000;background:#ffffff;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;do&lt;/span&gt; 
    &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;println&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;str-join&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;-&quot;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;range&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; 
    &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;println&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;str-join&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;-&quot;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;reverse-range&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;println&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;str-join&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;-&quot;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;range&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;println&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;str-join&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;-&quot;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;reverse-range&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; 
    &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;println&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;str-join&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;-&quot;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;range&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; 
    &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;println&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;str-join&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;-&quot;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;reverse-range&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;7&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;	&lt;br /&gt;Сделаем это через макросы:&lt;br /&gt;&lt;pre style=&quot;color:#000000;background:#ffffff;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;ns&lt;/span&gt; foo
  &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;:use&lt;/span&gt; clojure&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;contrib&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;str-utils&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;
  
&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;defn&lt;/span&gt; reverse-range 
    &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;start end&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;
    &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;reverse&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;range&lt;/span&gt; start end&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;

&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;defmacro&lt;/span&gt; ranger
&lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;size&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;
&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;func &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;cycle&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;`range `reverse-range&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt; 
    &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;cons&lt;/span&gt; &lt;span style=&quot;color:#800080;&quot;&gt;'do&lt;/span&gt; 
        &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;step &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;range&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt; size&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt; 
            `&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;println&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;str-join&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;-&quot;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;~&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;nth&lt;/span&gt; func step&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;~&lt;/span&gt;step&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Выглядит страшнее, чем код на груви, но читабельность, как ни странно, сохранена - любой программист сможет всегда вызывать macroexpand и понять, как работает тот или иной макрос:&lt;br /&gt;&lt;pre style=&quot;color:#000000;background:#ffffff;&quot;&gt;foo&lt;span style=&quot;color:#808030;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;macroexpand&lt;/span&gt;
      &lt;span style=&quot;color:#800080;&quot;&gt;'&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;ranger&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;do&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;clojure.core/println&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;clojure.contrib.str-utils/str-join&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;-&quot;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;clojure.core/range&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; 
    &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;clojure.core/println&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;clojure.contrib.str-utils/str-join&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;-&quot;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;foo/reverse-range&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; 
    &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;clojure.core/println&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;clojure.contrib.str-utils/str-join&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;-&quot;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;clojure.core/range&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;	&lt;br /&gt;Ну и, собственно, демка (все работает:) ):&lt;br /&gt;&lt;pre style=&quot;color:#000000;background:#ffffff;&quot;&gt;foo&lt;span style=&quot;color:#808030;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#800000;font-weight:bold;&quot;&gt;ranger&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;
&lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;-&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;
&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;-&lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;-&lt;span style=&quot;color:#008c00;&quot;&gt;3&lt;/span&gt;
&lt;span style=&quot;color:#008c00;&quot;&gt;4&lt;/span&gt;-&lt;span style=&quot;color:#008c00;&quot;&gt;3&lt;/span&gt;-&lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;-&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;
&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;-&lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;-&lt;span style=&quot;color:#008c00;&quot;&gt;3&lt;/span&gt;-&lt;span style=&quot;color:#008c00;&quot;&gt;4&lt;/span&gt;-&lt;span style=&quot;color:#008c00;&quot;&gt;5&lt;/span&gt;
&lt;span style=&quot;color:#008c00;&quot;&gt;6&lt;/span&gt;-&lt;span style=&quot;color:#008c00;&quot;&gt;5&lt;/span&gt;-&lt;span style=&quot;color:#008c00;&quot;&gt;4&lt;/span&gt;-&lt;span style=&quot;color:#008c00;&quot;&gt;3&lt;/span&gt;-&lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;-&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; name='cutid1-end'&gt;&lt;/a&gt;</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:146122</guid>
         <pubDate>Sat, 05 Jun 2010 17:46:19 +0000</pubDate>
      </item>
      <item>
         <title>Clojure video [devclub.eu #04-10]</title>
         <link>http://lafy.livejournal.com/145246.html</link>
         <description>Обработал первое (оно же свое) видео с &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.devclub.eu&quot;&gt;devclub.eu&lt;/a&gt;. Изначально тема называлась &quot;(Clojure (как практический лисп) или (как полюбить скобочки))&quot;, в процессе подготовки я потерял к ней интерес и стал готовить связку out of tar pit (по управлению сложностью) и clojure в сравнении с другими языками. Добавил в него все, что я когда-то видел, слышал или читал про кложуру. Много примеров взял с блогов авторов книг, которые перечислил в конце. В результате народ ожидал одно, получил другое и был сбит с толку. Вообще - собирал отзывы - очень противоречивые. Было несколько тех, кто знаком с лиспом и сказали, что не понял доклада, были те, кто вообще не в теме - но им понравилось. Вообщем, видимо, получилось что-то явно не простое и сумбурное :) В добавок я путался с терминологией (называл то метод, то функция, то оператор, чем еще больше запутывал). Зато много холиворил и ходил по лезвию - в видео очень много спорных моментов :)) &lt;br /&gt;&lt;br /&gt;Аккуратно, в этот раз HD - так что трафик и лаги на нетбуках (отключайте HD в плейере). &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://vimeo.com/11413473&quot;&gt;(Link)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:145246</guid>
         <pubDate>Mon, 03 May 2010 17:55:07 +0000</pubDate>
      </item>
      <item>
         <title>Clojure тренинг!</title>
         <link>http://lafy.livejournal.com/141568.html</link>
         <description>Rubyonline запускает онлайн курс по изучению Clojure. Начинается 24 апреля сего года. Регистрация бесплатна. Для этого нужно зарегистрироваться на сайте &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://rubylearning.org&quot;&gt;RubyLearning.org&lt;/a&gt; и потом зарегистрироваться по ссылке &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://rubylearning.org/class/course/view.php?id=53&quot;&gt;Clojure 101 1st Batch&lt;/a&gt; с ключом &lt;b&gt;Clojure101&lt;/b&gt;. Затем обновить свой профиль и описать себя в нескольких предложениях на форуме. &lt;br /&gt;&lt;br /&gt;Больше информации &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://rubylearning.com/blog/2010/03/09/clojure-101-a-new-course/&quot;&gt;можно найти здесь&lt;/a&gt;.</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:141568</guid>
         <pubDate>Sun, 14 Mar 2010 18:56:20 +0000</pubDate>
      </item>
      <item>
         <title>А в это время в рунете про Clojure (06 февраля -&amp;gt; 13 марта 2010)</title>
         <link>http://lafy.livejournal.com/141432.html</link>
         <description>Ах, лучше поздно, чем..  Повыдергивал самое интересное, что произошло :)&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://data-sorcery.org/2009/12/20/getting-started/&quot;&gt;Как установить Clojure/slime&lt;/a&gt; с помощью крутой штуки EPLA? &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/holmic/statuses/8722239976&quot;&gt;(via Holmic)&lt;/a&gt;. Еще одна статья &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://zahardzhan.posterous.com/-emacs-clojure&quot;&gt;на русском здесь.&lt;/a&gt;. И еще &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://mkazarian.blogspot.com/2010/02/clojure-emacs-java.html&quot;&gt;одна здесь&lt;/a&gt; (by mkazarian) &lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://tinyurl.com/yfbwcmc&quot;&gt;Сравнение F#, Clojure и другие функциональные языки&lt;/a&gt;. Автор считает первые вполне прагматичными и имеющие потенциал, в отличии от академических поделок &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/alexott/status/8716964527&quot;&gt;(via alexott)&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://techposters.net/blog/languages/497.html&quot;&gt;Clojure cheat sheets&lt;/a&gt; via &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/msugvnua&quot;&gt;MSUGVNUA&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; Андрей Власовских &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/vlasovskikh/status/8786066702&quot;&gt;померял скорость запуска кложуры&lt;/a&gt; в скриптовом режиме и &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/vlasovskikh/status/8806022581&quot;&gt;скорость компиляции&lt;/a&gt;. Выводы - режим скриптов бесполезен - мееедленннный.&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.parleys.com/#st=5&amp;amp;id=1518&amp;amp;sl=1&quot;&gt;Отличное видео про Clojure: Functional Concurrency on JVM от Howard Lewis&lt;/a&gt; (тот, который tapestry делает) &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://anton-arhipov.livejournal.com/116383.html&quot;&gt;(via anton arhipov)&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gist.github.com/303426&quot;&gt;Машинка Тьюринга&lt;/a&gt; на Clojure от &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/zahardzhan/statuses/9053768380&quot;&gt;Романа zahardzhan Захарова &lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://java.ociweb.com/mark/stm/article.html&quot;&gt;Хорошая статья по реализации одного из кирпичика&lt;/a&gt; Clojure - STM. (via alexott)&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/technomancy/leiningen/blob/1.1.0/NEWS#L3&quot;&gt;Вышла свежая (ну, уже не такая свежая) версия Leiningen&lt;/a&gt;, нативный инструмент для сборки кложурных проектов &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/zahardzhan/statuses/9224078758&quot;&gt;(via zahardzhan)&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &quot;It's ok to hate Java, but love JVM&quot; (c) Rich Hickey &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://juick.com/mirocumo/551084#2&quot;&gt;(via mirocumo)&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;span class=&quot;ljuser  i-ljuser  i-ljuser-type-P     &quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://sorhed.livejournal.com/profile&quot; class=&quot;i-ljuser-profile&quot;&gt;&lt;img class=&quot;i-ljuser-userhead&quot; src=&quot;http://l-stat.livejournal.net/img/userinfo.gif?v=17080?v=131.4&quot;/&gt;&lt;/a&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://sorhed.livejournal.com/&quot; class=&quot;i-ljuser-username&quot;&gt;&lt;b&gt;sorhed&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;  &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://sorhed.livejournal.com/531497.html?thread=3351849&quot;&gt;рассказал про хаскель, сделав выпад в сторону lisp-а&lt;/a&gt;, что было парировано &lt;span class=&quot;ljuser  i-ljuser  i-ljuser-type-P     &quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://satmech.livejournal.com/profile&quot; class=&quot;i-ljuser-profile&quot;&gt;&lt;img class=&quot;i-ljuser-userhead&quot; src=&quot;http://l-stat.livejournal.net/img/userinfo.gif?v=17080?v=131.4&quot;/&gt;&lt;/a&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://satmech.livejournal.com/&quot; class=&quot;i-ljuser-username&quot;&gt;&lt;b&gt;satmech&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; , который привел в сравнение код написанный на Clojure. В суть не вникал, но на Clojure действительно выглядит понятнее :))&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Clojure и проект Euler, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://habrahabr.ru/blogs/lisp/84204/&quot;&gt;часть 1&lt;/a&gt; и &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://habrahabr.ru/blogs/lisp/84791/&quot;&gt;часть 2&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Нашумевшая в отдельных комьюнити статья от Алекса Отта &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://fprog.ru/2010/issue4/alex-ott-clojure/&quot;&gt;Clojure, или «Вы все еще используете Java? Тогда мы идем к вам!»&lt;/a&gt;. Алекс систематизировал довольно много информации. Ответа на вопрос &quot;как идиоматически верно программировать на Clojure&quot; там нет, но зато хорошо описываются возможности языка. Есть с чего начать. Ну и переодически есть сравнения с Common Lisp-ом, который, по моему мнению, выглядит грустно на фоне Clojure :)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://dolzhenko.blogspot.com/2010/02/a43.html&quot;&gt;Математическая задачка от Dolzenko&lt;/a&gt;. Легко решается на эрланге, но плохо на Clojure. Можете потренироваться :) &lt;/li&gt;&lt;br /&gt;&lt;li&gt;А не создать ли ru_clojure? (via &lt;span class=&quot;ljuser  i-ljuser  i-ljuser-type-P     &quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.livejournal.com/profile&quot; class=&quot;i-ljuser-profile&quot;&gt;&lt;img class=&quot;i-ljuser-userhead&quot; src=&quot;http://l-stat.livejournal.net/img/userinfo.gif?v=17080?v=131.4&quot;/&gt;&lt;/a&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.livejournal.com/&quot; class=&quot;i-ljuser-username&quot;&gt;&lt;b&gt;alexott&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; , &lt;span class=&quot;ljuser  i-ljuser  i-ljuser-type-P     &quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://astoon.livejournal.com/profile&quot; class=&quot;i-ljuser-profile&quot;&gt;&lt;img class=&quot;i-ljuser-userhead&quot; src=&quot;http://l-stat.livejournal.net/img/userinfo.gif?v=17080?v=131.4&quot;/&gt;&lt;/a&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://astoon.livejournal.com/&quot; class=&quot;i-ljuser-username&quot;&gt;&lt;b&gt;astoon&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;  &amp; &lt;span class=&quot;ljuser  i-ljuser  i-ljuser-type-P     &quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://san-a.livejournal.com/profile&quot; class=&quot;i-ljuser-profile&quot;&gt;&lt;img class=&quot;i-ljuser-userhead&quot; src=&quot;http://l-stat.livejournal.net/img/userinfo.gif?v=17080?v=131.4&quot;/&gt;&lt;/a&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://san-a.livejournal.com/&quot; class=&quot;i-ljuser-username&quot;&gt;&lt;b&gt;san_a&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; ).. и Х днями позже &lt;span class=&quot;ljuser  i-ljuser  i-ljuser-type-P     &quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://san-a.livejournal.com/profile&quot; class=&quot;i-ljuser-profile&quot;&gt;&lt;img class=&quot;i-ljuser-userhead&quot; src=&quot;http://l-stat.livejournal.net/img/userinfo.gif?v=17080?v=131.4&quot;/&gt;&lt;/a&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://san-a.livejournal.com/&quot; class=&quot;i-ljuser-username&quot;&gt;&lt;b&gt;san_a&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;  &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://community.livejournal.com/ru_clojure/&quot;&gt;создает его :)&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://invis87.livejournal.com/4423.html&quot;&gt;Пример ленивых коллекций&lt;/a&gt; на Clojure от &lt;span class=&quot;ljuser  i-ljuser  i-ljuser-deleted  i-ljuser-type-P     &quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://invis87.livejournal.com/profile&quot; class=&quot;i-ljuser-profile&quot;&gt;&lt;img class=&quot;i-ljuser-userhead&quot; src=&quot;http://l-stat.livejournal.net/img/userinfo.gif?v=17080?v=131.4&quot;/&gt;&lt;/a&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://invis87.livejournal.com/&quot; class=&quot;i-ljuser-username&quot;&gt;&lt;b&gt;invis87&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://zahardzhan.posterous.com/-fnand-fnor-fnnot&quot;&gt;Функциональные комбинаторы fn/and, fn/or и fn/not&lt;/a&gt; by zahardzhan.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/webusnix/statuses/10086954871&quot;&gt;Похоже эра функциональных языков пошла) Куда ни глянь, везде #clojure,#scala,#f#,#haskell,#lisp... Почему только сейчас ?&lt;/a&gt; (ура, товарищи, значит все наши усилия не напрасны!)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:141432</guid>
         <pubDate>Sat, 13 Mar 2010 20:58:06 +0000</pubDate>
      </item>
      <item>
         <title>А в это время в рунете про Clojure (24 января -&amp;gt; 05 февраля 2010)</title>
         <link>http://lafy.livejournal.com/138545.html</link>
         <description>&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;span class=&quot;ljuser  i-ljuser  i-ljuser-type-P     &quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://ivan-gandhi.livejournal.com/profile&quot; class=&quot;i-ljuser-profile&quot;&gt;&lt;img class=&quot;i-ljuser-userhead&quot; src=&quot;http://l-stat.livejournal.net/img/userinfo.gif?v=17080?v=131.4&quot;/&gt; &lt;/a&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://ivan-gandhi.livejournal.com/&quot; class=&quot;i-ljuser-username&quot;&gt;&lt;b&gt;ivan_gandhi&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;  &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://community.livejournal.com/ru_declarative/93793.html&quot;&gt;спрашивает&lt;/a&gt; &quot;В чём цимес-то? В том, что это лисп на jvm? С таким же успехом можно форт поставить. Я что хочу сказать - разве техника не ушла уже вперёд? Меня всё подташнивало, пока я читал эту книжечку - как окунулся в атмосферу 20-летней давности, когда торжественно открывались новые способы хитрым образом устроить то, что на самом деле можно одной строчкой выразительно написать на, извините, Хаскеле.&quot;&lt;br /&gt;&lt;br /&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://juick.com/Deepwalker/516841&quot;&gt;Deepwalker&lt;/a&gt; в другом месте пишет &lt;i&gt;&quot;что так все с этим clojure носятся? Ну он же страшен, у него же скобок больше чем осмысленных символов. Я понимаю, TM там, но неужели в 21-ом веке нельзя синтаксис причесать?&quot;&lt;/i&gt; .&lt;br /&gt;&lt;br /&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/riffm/statuses/8677558922&quot;&gt;Riffm: &lt;/a&gt; &quot;ты видел код на clojure? я один раз посмотрел, больше не хочу&quot; &lt;br /&gt;&lt;br /&gt;У кого что есть добавить? Возразить? :) &lt;br /&gt;&lt;/li&gt;&lt;li&gt; Еще один холиварный топик: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/zahardzhan/statuses/8220642684&quot;&gt;Zahardzhan утверждает, что&lt;/a&gt; &quot;Clojure-комунити сделало за два года в разы больше, чем Common Lisp-комунити за двадцать лет&quot;. Он же советует &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://tomfaulhaber.github.com/autodoc/&quot;&gt;хороший leiningen плагин для автодокументации&lt;/a&gt; clojure-проектов (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/zahardzhan/statuses/8220329857&quot;&gt;via twitter&lt;/a&gt;). Примерно тоже самое &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/holmic/statuses/8674922764&quot;&gt;говорит holmic&lt;/a&gt;: &quot;Clojure движется вперед, как локомотив на полных парах. За 2 года он набрал коммунити и библиотек не меньше чем CL за 25&quot;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott-ru.blogspot.com/2010/01/clojure.html&quot;&gt;Отличная подборка видео-материалов по Clojure&lt;/a&gt; от Alexott.&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &quot;скала гнетет, а кложура рулит&quot;! &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://juick.com/mirocumo/505492#6&quot;&gt;Обсуждение на juick&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &quot;Лол, в библиотеке кложуры есть бесконечная последовательность простых чисел. Интересно, оно действительно кому-то надо, или она там потому-что это просто прикольно?&quot; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://juick.com/civil696/508191&quot;&gt;via juick&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://dolzhenko.blogspot.com/2010/01/clojure-hello-world.html&quot;&gt;Clojure hello fibonacci&lt;/a&gt;, хвостовая рекурсия (by Владимир Долженко).&lt;br /&gt;&lt;/li&gt;&lt;li&gt; На lisper.ru открылся &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://lisper.ru/forum/thread/158&quot;&gt;подфорум о Clojure&lt;/a&gt; (via &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://zw0rk.blogspot.com/2010/02/clojure.html&quot;&gt;zw0rk&lt;/a&gt;)&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &quot;Каково дебажить многопоточное приложение в питоне? В clojure в куда проще - в эмакс слиме есть инспектор всего подряд.&quot; (via &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/zahardzhan/statuses/8542580714&quot;&gt;zahardzhan&lt;/a&gt;)&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://codemonkeyism.com/clojure-scala-part-2/&quot;&gt;Scala VS Clojure&lt;/a&gt;. Энглиш, если в кратце, то автор советует Scala :) (via &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/cybem/statuses/8509234116&quot;&gt;cybem&lt;/a&gt;)&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/alexott/statuses/8631033463&quot;&gt;Alexott играется с clojure-hadoop&lt;/a&gt;. Ждем результатов :)&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Задачка для разминки ума и тренировки в Clojure. &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://dolzhenko.blogspot.com/2010/02/blog-post.html&quot;&gt;Робот на бесконечной лестнице&lt;/a&gt;. (by Владимир Долженко)&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:138545</guid>
         <pubDate>Fri, 05 Feb 2010 17:01:20 +0000</pubDate>
      </item>
      <item>
         <title>clojure in action</title>
         <link>http://lafy.livejournal.com/137434.html</link>
         <description>Пишу статью по функциональному дизайну (точнее, как я это понимаю...:) ) с примерами на Clojure для вполне реальной задачи, с которой столкнулся на работе, которую раньше я бы решил с применением ООП техник. Накатал пока 3 страницы и задумался - выложить постом в ЖЖ как и планировал, организовать локальный &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://codingdojo.org/cgi-bin/wiki.pl?WhatIsCodingDojo&quot;&gt;Coding Dojo&lt;/a&gt; по этой проблеме и отточить решение, или выступить сначала с этой темой на &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.devclub.eu&quot;&gt;девклабе&lt;/a&gt;?</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:137434</guid>
         <pubDate>Fri, 29 Jan 2010 10:07:24 +0000</pubDate>
      </item>
      <item>
         <title>3 HelloWorld на Clojure</title>
         <link>http://lafy.livejournal.com/136390.html</link>
         <description>Сначала написал об этом у &lt;span class=&quot;ljuser  i-ljuser  i-ljuser-type-P     &quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://astoon.livejournal.com/profile&quot; class=&quot;i-ljuser-profile&quot;&gt;&lt;img class=&quot;i-ljuser-userhead&quot; src=&quot;http://l-stat.livejournal.net/img/userinfo.gif?v=17080?v=131.4&quot;/&gt;&lt;/a&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://astoon.livejournal.com/&quot; class=&quot;i-ljuser-username&quot;&gt;&lt;b&gt;astoon&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;  в комментариях, а потом решил и себе сохранить. Вдруг я соберусь перевести &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure.org/compilation&quot;&gt;http://clojure.org/compilation&lt;/a&gt; и захочу добавить немного примеров? :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Clojure файлы можно запускать как прямо с помощью Clojure скрипта (1), так и компилировать в .class файлы. Это можно делать с помощью двух способов: как используя command line (2), так и внутри скрипта Clojure/REPL (3).&lt;br /&gt;&lt;br /&gt;Соответственно, варианты следующие:&lt;br /&gt;1) &lt;br /&gt;есть hello.clj где есть одна строка: (println &quot;hello world&quot;).&lt;br /&gt;&lt;pre&gt;
C:&amp;#92;&amp;gt;java -cp c:&amp;#92;java&amp;#92;clojure-1.1.0&amp;#92;clojure.jar clojure.main c:&amp;#92;hw&amp;#92;hello.clj
-&amp;gt; hello, world!
&lt;/pre&gt;&lt;br /&gt;2) &lt;br /&gt;есть hello_main.clj, который выглядит так:&lt;br /&gt;&lt;pre&gt;
(ns hello_main
	(:gen-class))

(defn -main []
	(println &quot;hello, world!&quot;))


C:&amp;#92;&amp;gt;java -classpath c:&amp;#92;java&amp;#92;clojure-1.1.0&amp;#92;clojure.jar;c:&amp;#92;hw;c:&amp;#92;hw&amp;#92;classes 
-Dclojure.compile.path=c:&amp;#92;hw&amp;#92;classes clojure.lang.Compile hello_main
Compiling hello_main to c:&amp;#92;hw&amp;#92;classes

C:&amp;#92;&amp;gt;java -classpath c:&amp;#92;java&amp;#92;clojure-1.1.0&amp;#92;clojure.jar;c:&amp;#92;hw;c:&amp;#92;hw&amp;#92;classes hello_main
hello, world!
&lt;/pre&gt;&lt;br /&gt;3)&lt;br /&gt;Есть hello_compile.clj, который выглядит так:&lt;br /&gt;&lt;pre&gt;
(ns hello_compile
	(:gen-class))

(defn -main []
	(println &quot;hello, world from hello_compile!&quot;))


C:&amp;#92;&amp;gt;java -classpath c:&amp;#92;java&amp;#92;clojure-1.1.0&amp;#92;clojure.jar;c:&amp;#92;hw;c:&amp;#92;hw&amp;#92;classes clojure.main
Clojure 1.1.0
user=&amp;gt; (set! *compile-path* &quot;c:/hw/classes&quot;)
&quot;c:/hw/classes&quot;
user=&amp;gt; (compile 'hello_compile)
hello_compile

C:&amp;#92;&amp;gt;java -classpath c:&amp;#92;java&amp;#92;clojure-1.1.0&amp;#92;clojure.jar;c:&amp;#92;hw;c:&amp;#92;hw&amp;#92;classes hello_compile
hello, world from hello_compile!
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Кстати, встретился с двумя интересными неудобствами. Во первых - при компиляции нужно указывать не файл, а namespace. Если сделать так:&lt;br /&gt;&lt;pre&gt;
java -classpath c:&amp;#92;java&amp;#92;clojure-1.1.0&amp;#92;clojure.jar;c:&amp;#92;hw;c:&amp;#92;hw&amp;#92;classes 
-Dclojure.compile.path=c:&amp;#92;hw&amp;#92;classes clojure.lang.Compile c:&amp;#92;hw&amp;#92;hello_main
&lt;/pre&gt;&lt;br /&gt;то получишь очень непонятный exception:&lt;br /&gt;&lt;pre&gt;
Compiling c:&amp;#92;hw&amp;#92;hello_main to c:&amp;#92;hw&amp;#92;classes
Exception in thread &quot;main&quot; java.io.FileNotFoundException: Could not locate c:&amp;#92;hw&amp;#92;hello_main__init.class 
or c:&amp;#92;hw&amp;#92;hello_main.clj on classpath:
        at clojure.lang.RT.load(RT.java:402)
        at clojure.lang.RT.load(RT.java:371)
        at clojure.core$load__6449$fn__6458.invoke(core.clj:4171)
        at clojure.core$load__6449.doInvoke(core.clj:4170)
        at clojure.lang.RestFn.invoke(RestFn.java:413)
        at clojure.core$load_one__6379.invoke(core.clj:4007)
        at clojure.core$compile__6464$fn__6466.invoke(core.clj:4181)
        at clojure.core$compile__6464.invoke(core.clj:4180)
        at clojure.lang.Var.invoke(Var.java:359)
        at clojure.lang.Compile.main(Compile.java:56)
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Другое неудобство - нельзя использовать дефис в имени: дефис заменяется на подчеркивание и файл больше не находится.&lt;br /&gt;&lt;pre&gt;
c:&amp;#92;tools&amp;#92;jad&amp;gt;java -classpath c:&amp;#92;java&amp;#92;clojure-1.1.0&amp;#92;clojure.jar;c:&amp;#92;hw;c:&amp;#92;hw&amp;#92;classes 
-Dclojure.compile.path=c:&amp;#92;hw&amp;#92;classes clojure.lang.Compile hello-main
Compiling hello-main to c:&amp;#92;hw&amp;#92;classes
Exception in thread &quot;main&quot; java.lang.Exception: namespace 'hello-main' not found after loading '/hello_main'
        at clojure.core$load_one__6379.invoke(core.clj:4010)
        at clojure.core$compile__6464$fn__6466.invoke(core.clj:4181)
        at clojure.core$compile__6464.invoke(core.clj:4180)
        at clojure.lang.Var.invoke(Var.java:359)
        at clojure.lang.Compile.main(Compile.java:56)
&lt;/pre&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; name='cutid1-end'&gt;&lt;/a&gt;</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:136390</guid>
         <pubDate>Sat, 23 Jan 2010 23:47:17 +0000</pubDate>
      </item>
      <item>
         <title>Clojure в рунете (18 -&amp;gt; 23 января 2009)</title>
         <link>http://lafy.livejournal.com/135790.html</link>
         <description>&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Пример рабочей конфигурации Maven для компиляции исходников clojure в jar. (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/liebke/incanter/blob/master/modules/incanter-core/pom.xml&quot;&gt;здесь&lt;/a&gt;, via &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://astoon.livejournal.com/71654.html?thread=71654#t71654&quot;&gt;alexott&lt;/a&gt;)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Почему Clojure набирает популярность, в то время когда про другие Lisp-ы не слышно? (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://blog.braintrace.ru/blog/clojure-popularity&quot;&gt;здесь&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/andreypopp/statuses/8087601302&quot;&gt;@andreypopp&lt;/a&gt;) &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/_semenov_/statuses/8087742630&quot;&gt;@_semenov_ считает&lt;/a&gt;, что ФП просто модно в Java мире, а andreypopp предполагает, что пользователи Clojure в &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/andreypopp/statuses/8087835239&quot;&gt;основном не-java программисты&lt;/a&gt; и причина в другом.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Clojure in Action за 10$ с купоном dotd0121. (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.manning.com/rathore/&quot;&gt;здесь&lt;/a&gt;, via &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/alexott&quot;&gt;alexott&lt;/a&gt;)&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Постепенно становится все больше и больше восторженных комментариев java (и не только) программистов в адрес Clojure. (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/kuryachy_s/statuses/8024980714&quot;&gt;здесь&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://rmihael.livejournal.com/212149.html?thread=979637&quot;&gt;здесь&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://community.livejournal.com/ru_java/897066.html?thread=11910698&quot;&gt;здесь&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/vorushin/statuses/7979738786&quot;&gt;здесь&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://astoon.livejournal.com/71654.html&quot;&gt;здесь&lt;/a&gt;)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Вакансия в Москве. Разработчик на Clojure (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://moikrug.ru/vacancies/637933049/&quot;&gt;здесь&lt;/a&gt;, via &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://friendfeed.com/clojure-programming/ac8a0f9d/clojure-russia-startup#guid=f1c29da8cd0f7d4a8de9f3f6431c50f2&quot;&gt;dulanov&lt;/a&gt;)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:135790</guid>
         <pubDate>Sat, 23 Jan 2010 13:12:01 +0000</pubDate>
      </item>
      <item>
         <title>Clojure in Action for 10$</title>
         <link>http://lafy.livejournal.com/135380.html</link>
         <description>Кстати, сейчас есть еще одна MEAP книга по Clojure: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.manning.com/rathore/&quot;&gt;Clojure in Action&lt;/a&gt;. С купоном dotd0121 всего 10$. Темы, которые там раскрываются: clojure itself; real-world application; web-scale systems design; DSLs. ух! :)</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:135380</guid>
         <pubDate>Fri, 22 Jan 2010 09:54:12 +0000</pubDate>
      </item>
      <item>
         <title>clojure epic fail</title>
         <link>http://lafy.livejournal.com/134237.html</link>
         <description>Как мы выяснили с &lt;span class=&quot;ljuser  i-ljuser  i-ljuser-type-P     &quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://anton-arhipov.livejournal.com/profile&quot; class=&quot;i-ljuser-profile&quot;&gt;&lt;img class=&quot;i-ljuser-userhead&quot; src=&quot;http://l-stat.livejournal.net/img/userinfo.gif?v=17080?v=131.4&quot;/&gt;&lt;/a&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://anton-arhipov.livejournal.com/&quot; class=&quot;i-ljuser-username&quot;&gt;&lt;b&gt;anton_arhipov&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; : Clojure, в отличии от Groovy, стоит аккуратно использовать для работы с плавающей точкой.&lt;br /&gt;&lt;br /&gt;Groovy выглядит так:&lt;br /&gt;&lt;code&gt;0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 = 1&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;0.1 в груви это BigDecimal, поэтому создается 10 объектов, складываются и получается еще один со значением 1.&lt;br /&gt;&lt;br /&gt;В Clojure ситуация плачевная.&lt;br /&gt;&lt;code&gt;(+ 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1) возвращает 0.9999999999999999.&lt;/code&gt;&lt;br /&gt;В принципе, можно решить проблему, если использовать не double, а вариант с BigDecimal тоже. Или использовать рациональные числа:&lt;br /&gt;&lt;code&gt;(+ 0.1M 0.1M 0.1M 0.1M 0.1M 0.1M 0.1M 0.1M 0.1M 0.1M) = 1M&lt;/code&gt;&lt;br /&gt;и&lt;br /&gt;&lt;code&gt;(+ 1/10 1/10 1/10 1/10 1/10 1/10 1/10 1/10 1/10 1/10) = 1&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Но, как правильно возразили - в базе хранят в виде 0.1, поэтому нужно все равно что-то делать. Например, конвертировать 0.1 в BigDecimal или Ratio:&lt;br /&gt;&lt;code&gt;(bigdec 0.1) = 0.1M&lt;/code&gt;&lt;br /&gt;и&lt;br /&gt;&lt;code&gt;(rationalize 0.1) = 1/10&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Все бы было хорошо, но предположим в базе хранят цены, а функция хочет увеличить цену на 10%. Clojure, как очень гибкий язык, вполне может использоваться не-специалистами, которые обязательно напишут:&lt;br /&gt;&lt;code&gt;(* 100M 1.1)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Лично я ожидал увидеть здесь конвертацию 0.1 в BigDecimal, но ни тут то было:&lt;br /&gt;&lt;code&gt;(* 100M 1.1) = 110.00000000000001&lt;/code&gt;&lt;br /&gt;&lt;code&gt;(class (* 100M 1.1)) = java.lang.Double&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;К слову, Scala тоже не конвертирует 0.1 в BigDecimal, но по крайней мере у нее с арифметикой все ок:&lt;br /&gt;&lt;code&gt;scala.BigDecimal(1.5) * 1.5&lt;br /&gt;res9: BigDecimal = 2.25&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Вот такая вот фигня.</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:134237</guid>
         <pubDate>Sat, 16 Jan 2010 21:54:59 +0000</pubDate>
      </item>
      <item>
         <title>Clojure ratio</title>
         <link>http://lafy.livejournal.com/134012.html</link>
         <description>Где-то на просторах твиттернета пробегал вопрос &quot;А почему Clojure лучше, чем Scala или Groovy?&quot;. В Clojure можно так:&lt;br /&gt;user=&amp;gt; (+ 3/4 1/6)&lt;br /&gt;11/12&lt;br /&gt;&lt;br /&gt;Groovy, Scala и прочие - так не умеют :)</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:134012</guid>
         <pubDate>Sat, 16 Jan 2010 20:30:18 +0000</pubDate>
      </item>
      <item>
         <title>DSLs in Action</title>
         <link>http://lafy.livejournal.com/133048.html</link>
         <description>&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.manning.com/ghosh/&quot;&gt;&lt;img src=&quot;http://www.manning.com/ghosh/ghosh_cover150.jpg&quot;/&gt;&lt;/a&gt;&lt;br /&gt;Ох-эх-ух! Где бы найти все время чтобы все это прочитать!</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:133048</guid>
         <pubDate>Thu, 14 Jan 2010 21:24:31 +0000</pubDate>
      </item>
      <item>
         <title>FUD Scala vs Clojure!</title>
         <link>http://lafy.livejournal.com/132652.html</link>
         <description>&lt;br /&gt;Вот для примера два варианта программы, которые делают одно и то же:&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Вариант на Scala&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;font-family:Andale Mono, Lucida Console, Monaco, fixed, monospace;color:#000000;background-color:#eee;font-size:12px;border:1px dashed #999999;line-height:14px;padding:5px;overflow:auto;width:100%;&quot;&gt;&lt;code&gt;type Supercalifragilisticexpialidocious = java.lang.Integer

implicit def Supercalifragilisticexpialidocious2Int(tehThingToConvert:Supercalifragilisticexpialidocious) = {
  tehThingToConvert.asInstanceOf[Int]
}

trait ClosureTestMixin {
  def makeAdder(tehAdditionValue:Supercalifragilisticexpialidocious):Function1[Int,Int]
}

class AdderMaker extends ClosureTestMixin {
  def apply(tehAdditionValue:Supercalifragilisticexpialidocious):Function1[Int,Int] = {
    new Function1[Int,Int] {
      def apply(tehOtherAdditionValue:Int):Int = {
        return tehAdditionValue.$plus(tehOtherAdditionValue.asInstanceOf[Supercalifragilisticexpialidocious])
      }
    }
  }

  def makeAdder(tehAdditionValue:Supercalifragilisticexpialidocious):Function1[Int,Int] = {
    return this.apply(tehAdditionValue)
  }
}

val tehAdderMakerInstance = new AdderMaker()

val tehAdderPlus10 = tehAdderMakerInstance.makeAdder(10)

tehAdderPlus10.apply(9)
//=&amp;gt; 19
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Вариант на Clojure&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;font-family:Andale Mono, Lucida Console, Monaco, fixed, monospace;color:#000000;background-color:#eee;font-size:12px;border:1px dashed #999999;line-height:14px;padding:5px;overflow:auto;width:100%;&quot;&gt;&lt;code&gt;(((fn mk-adder [x] #(+ % x)) 10) 9)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Разница очевидна! 29 строк и почти тысяча символов на Scala и всего 35 символов на Clojure!&lt;br /&gt;&lt;br /&gt;p.s. если есть идеи, как сделать вариант со Scala больше, длиннее и страшнее - не стесняйтесь, говорите. Или напишите fogus-у в комменты ;)&lt;br /&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; name='cutid1-end'&gt;&lt;/a&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://blog.fogus.me/2010/01/04/comparing-lines-of-code-scala-and-clojure-fud-version/&quot;&gt;by fogus&lt;/a&gt;</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:132652</guid>
         <pubDate>Thu, 14 Jan 2010 21:06:56 +0000</pubDate>
      </item>
      <item>
         <title>кинул бы в твиттер, но вышел за пределы :)</title>
         <link>http://lafy.livejournal.com/131699.html</link>
         <description>Тыкаюсь с clojure. Настроение идет по синусоиде. После scheme кажется, что связали одну руку. И рекурсия не настоящая, и дебажить как непонятно и еще в книжках везде понапихивали println в функции. Правда возможности со списками радуют, да и я еще до тредов не добрался, там обещает быть веселее :)</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:131699</guid>
         <pubDate>Tue, 12 Jan 2010 21:35:36 +0000</pubDate>
      </item>
      <item>
         <title>Мысли вслух. Как рассматривать Clojure в контексте хотя бы лет 5?</title>
         <link>http://lafy.livejournal.com/131454.html</link>
         <description>&lt;br /&gt;Clojure придется постараться, чтобы захватить этот мир :) Нет, это очень классный язык и все такое. Больше того - он местами прагматичный и не пытается переделать все сразу. Проблема в том, что для эффективного использования Clojure - все равно нужно уметь программировать на Java. Для использования преимуществ функционального подхода - все равно прийдется в некоторой мере владеть императивным стилем. Плюс еще небольшая, но смесь синтаксисов для упрощения взаимодействия с Java аля:&lt;br /&gt;&lt;br /&gt;(.. obj getController getAuthenticator authorize)&lt;br /&gt;vs&lt;br /&gt;(authorize (authenticator (controller obj)))&lt;br /&gt;&lt;br /&gt;Clojure пошел по пути &quot;что не сломано в Java, то и не чиним&quot; (в отличии от groovy? По ощущениям там обернуто в собственные классы больше классов). В результате - стабильное, быстрое, production-ready ядро и хорошее взаимодействие с Java. Clojure классная вещь и настоящие джавамены оценят ее. Но я не понимаю, как позиционировать ее перед теми, кто еще только начинает программировать? С одной стороны, может это быть тем самым, откуда стоит начинать знакомство с платформой, постепенно переходя к Java? Или, наоборот, может стоит рассматривать Clojure лишь как еще одну Java библиотеку? Или же, как просто мостик в функциональное программирование?&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; name='cutid1-end'&gt;&lt;/a&gt;</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:lafy:131454</guid>
         <pubDate>Sun, 10 Jan 2010 16:21:15 +0000</pubDate>
      </item>
      <item>
         <title>требуется Clojure Middle back-end developer в Москву</title>
         <link>http://ru-clojure.livejournal.com/3339.html</link>
         <description>В наш проект &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://&amp;#x000412; &amp;#x00043d;&amp;#x000430;&amp;#x000448; &amp;#x00043f;&amp;#x000440;&amp;#x00043e;&amp;#x000435;&amp;#x00043a;&amp;#x000442; https://www.getshopapp.com &amp;#x000442;&amp;#x000440;&amp;#x000435;&amp;#x000431;&amp;#x000443;&amp;#x000435;&amp;#x000442;&amp;#x000441;&amp;#x00044f; Clojure Middle back-end developer&quot;&gt;https://www.getshopapp.com&lt;/a&gt; требуется Clojure Middle back-end developer.&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;margin:1.5em 0px 0px;padding:0px;border:0px;font:inherit;font-size:16px;vertical-align:baseline;color:rgb(77, 86, 89);line-height:24px;background-color:rgb(255, 255, 255);&quot;&gt;&lt;div style=&quot;margin:0px;padding:0px;border:0px;font:inherit;font-size:0.875em;vertical-align:baseline;overflow:hidden;&quot;&gt;&lt;p style=&quot;margin:0px 0px 1em;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;&lt;strong style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Обязательно&lt;/strong&gt;&lt;/p&gt;&lt;ul style=&quot;margin:0px 0px 1em;padding:0px 0px 0px 1.5em;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Системное мышление&lt;/li&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Умение писать параллельный код&lt;/li&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Уверенное понимание концепций RDBMS&lt;/li&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Опыт командой работы&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;&lt;p style=&quot;margin:0px 0px 1em;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;&lt;strong style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Технологии&lt;/strong&gt;&lt;/p&gt;&lt;ul style=&quot;margin:0px 0px 1em;padding:0px 0px 0px 1.5em;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Clojure (уверенное знание)&lt;/li&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;MySQL (уверенно знание)&lt;/li&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Java (желательно)&lt;/li&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Python (желательно)&lt;/li&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Git (+ Git Flow)&lt;/li&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Apache/JBoss&lt;/li&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;JSON/XML&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;p style=&quot;margin:0px 0px 1em;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;&lt;strong style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Желательно&lt;/strong&gt;&lt;/p&gt;&lt;ul style=&quot;margin:0px 0px 1em;padding:0px 0px 0px 1.5em;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Опыт разработки высоконагруженных сервисов&lt;/li&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Опыт оптимизации/тюнинга JVM&lt;/li&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Опыт оптимизации запросов к БД&lt;/li&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Опыт работы с AWS&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;p style=&quot;margin:0px 0px 1em;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;&lt;strong style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;С нас:&lt;/strong&gt;&lt;/p&gt;&lt;ul style=&quot;margin:0px 0px 1em;padding:0px 0px 0px 1.5em;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Зарплата от 80 до 110 тысяч рублей (по результатам собеседования)&lt;/li&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Офис в бизнес-центре в пределах 5ти минут от метро Автозаводская&lt;/li&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Сильная команда, в которой можно быстро расти&lt;/li&gt;&lt;br /&gt;&lt;li style=&quot;margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;&quot;&gt;Интересные задачи&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;margin:1.5em 0px 0px;padding:0px;border:0px;font:inherit;font-size:16px;vertical-align:baseline;color:rgb(77, 86, 89);line-height:24px;background-color:rgb(255, 255, 255);&quot;&gt;&lt;h4 style=&quot;margin:0px 0px 5px;padding:0px;border:0px;font:inherit;font-size:0.875em;vertical-align:baseline;line-height:1em;overflow:hidden;&quot;&gt;Бонусы&lt;/h4&gt;&lt;div style=&quot;margin:0px;padding:0px;border:0px;font:inherit;font-size:0.875em;vertical-align:baseline;overflow:hidden;&quot;&gt;интересные задачи на несколько лет вперед, динамично развивающийся проект со скорым выходом на международный рынок, мудрый и добрый начальник&lt;br /&gt;&lt;br /&gt;Присылайте резюме на почту andrey(собачка)getshopapp.com &lt;/div&gt;&lt;/div&gt;</description>
         <author>andrey_promo</author>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:ru_clojure:3339</guid>
         <pubDate>Thu, 17 Oct 2013 10:01:11 +0000</pubDate>
      </item>
      <item>
         <title>Вакансия: Новосибирск, Java/Scala/Clojure-разработчик (платформа Eclipse), в офис, 110 000 р.</title>
         <link>http://ru-clojure.livejournal.com/3150.html</link>
         <description>&lt;span style=&quot;font-size:14px;line-height:19px;color:rgb(0, 0, 0);font-family:Helvetica, Arial, sans-serif;text-align:left;background-color:rgb(255, 255, 255);&quot;&gt;Одной хорошей компании (не российской) в офис в Новосибирск требуются Java/Scala/Clojure-разработчики, знающие и любящие платформу Eclipse. &lt;b&gt;Кандидаты из других городов/стран горячо приветствуются.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Собеседование по скайпу, приезд на очную ставку оплачивается компанией, &lt;b&gt;помощь при релокации&lt;/b&gt;. Множество плюшек.&lt;/div&gt;&lt;div&gt;Нам не важно, знаете ли вы Java, С#, и т.д. Дело в том, что скорее всего вы не знаете Fantom, а на нем вам тоже, возможно, придется программировать. Кроме того, если вы знакомы со Scala или Clojure на достойном уровне - мы готовы с вами работать минуя всякие собеседования.&lt;br /&gt;&lt;br /&gt;Название компании - в личку.&lt;/div&gt;&lt;div&gt;Резюме присылайте на&amp;nbsp;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;mailto:russianvarg@gmail.com?subject=%D0%92%D0%B0%D0%BA%D0%B0%D0%BD%D1%81%D0%B8%D1%8F%20Java-%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%87%D0%B8%D0%BA&quot; style=&quot;color:rgb(153, 0, 153);background-color:transparent;border:0px;&quot;&gt;russianvarg@gmail.com&lt;/a&gt;.&lt;/div&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; name='cutid1-end'&gt;&lt;/a&gt;&lt;br /&gt;</description>
         <author>varg242</author>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:ru_clojure:3150</guid>
         <pubDate>Thu, 31 May 2012 10:18:41 +0000</pubDate>
      </item>
      <item>
         <title>j2me и ClassLoader в clojure</title>
         <link>http://ru-clojure.livejournal.com/3049.html</link>
         <description>Кто-нибудь скрещивал clojure и j2me?&lt;br /&gt;У меня при попытке скомпилировать переписанный на clojure просой пример программы для j2me возникает ошибка:&lt;br /&gt;&lt;pre&gt;Caused by: java.lang.UnsatisfiedLinkError: javax.microedition.lcdui.DeviceCaps.init()V
	at javax.microedition.lcdui.DeviceCaps.init(Native Method)
	at javax.microedition.lcdui.DeviceCaps.&amp;lt;init&amp;gt;(Display.java:3223)
	at javax.microedition.lcdui.Display.&amp;lt;clinit&amp;gt;(Display.java:489)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:247)
	at clojure.lang.RT.classForName(RT.java:1566)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Несмотря на то, что к классу javax.microedition.lcdui.Display обращение идет только из defn, компилятор пытается вызывать какие-то его методы, которые приводят к вызову нативного метода javax.microedition.lcdui.DeviceCaps.init. Даже загрузка нужной библиотеки командой &lt;pre&gt;(System/load &quot;/opt/sun-j2me-bin-2.5.2.01/bin/libzayit.so&quot;)&lt;/pre&gt; не помогает.&lt;br /&gt;Можно ли побороть загрузку классов от j2me?</description>
         <author>Mike Potanin</author>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:ru_clojure:3049</guid>
         <pubDate>Thu, 13 Jan 2011 08:10:13 +0000</pubDate>
      </item>
      <item>
         <title>seq в vector</title>
         <link>http://ru-clojure.livejournal.com/2790.html</link>
         <description>Можно ли преобразовать seq в vector (или что-нибудь с чем работает assoc) дешевле, чем apply vector?&lt;br /&gt;Или аналог map, который бы порождал vector, если его применяют к весторам?&lt;br /&gt;&lt;br /&gt;Конструкции вида (apply vector (map (partial apply vector) c) меня несколько пугают, а как без них нормально работать с векторами я не понимаю...</description>
         <author>Mike Potanin</author>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:ru_clojure:2790</guid>
         <pubDate>Fri, 10 Sep 2010 15:30:28 +0000</pubDate>
      </item>
      <item>
         <title>letrec</title>
         <link>http://ru-clojure.livejournal.com/2319.html</link>
         <description>Есть ли макрос, аналогичный letrec их scheme или аналог declare, но работающий внутри let?&lt;br /&gt;Через def рекурсивное определение работает нормально:&lt;br /&gt;&lt;pre&gt;
(declare z)
(def x (cons 1 (lazy-seq (map + x z))))
(def z (cons 1 x))
&lt;/pre&gt;&lt;br /&gt;А через let не компилируется: (let [a (cons 1 (lazy-seq (map + a (cons 0 a))))] (take 17 a))</description>
         <author>Mike Potanin</author>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:ru_clojure:2319</guid>
         <pubDate>Wed, 25 Aug 2010 16:13:29 +0000</pubDate>
      </item>
      <item>
         <title>Волшебство и Магия Clojure</title>
         <link>http://ru-clojure.livejournal.com/1680.html</link>
         <description>Сделал перевод lisperati: Casting SPELs in Lisp, адаптированный под Clojure.&lt;br /&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://lisperati.planvita.com/&quot;&gt;&lt;img src=&quot;http://lisperati.planvita.com/images/casting_spels.png&quot;/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Перевод: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href='http://lisperati.planvita.com/'&gt;http://lisperati.planvita.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Очень жду комментариев в стиле &quot;ты написал вот так, а пишется вот так&quot; или &quot;написано вот так, но лучше было бы вот так&quot;, оставляйте их в комментариях к посту или на github &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href='http://github.com/jevgeni/spels-ru/issues'&gt;http://github.com/jevgeni/spels-ru/issues&lt;/a&gt;. Спасибо!</description>
         <author>Я :-)</author>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:ru_clojure:1680</guid>
         <pubDate>Mon, 28 Jun 2010 05:28:15 +0000</pubDate>
      </item>
      <item>
         <title>clojure conference</title>
         <link>http://ru-clojure.livejournal.com/1322.html</link>
         <description>Так как на jabber.ru существуют lisp-, ocaml-, haskell-, erlang-конференции, решил создать оную и по clojure.&lt;br /&gt;&lt;br /&gt;Добро пожаловать на clojure@conference.jabber.ru.&lt;br /&gt;&lt;br /&gt;UPD: по такому случаю любителями IRC также был создан #clojure-ru на freenode.</description>
         <author>dream.designer</author>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:ru_clojure:1322</guid>
         <pubDate>Fri, 14 May 2010 18:31:58 +0000</pubDate>
      </item>
      <item>
         <title>lafy: Clojure video [devclub.eu #04-10]</title>
         <link>http://ru-clojure.livejournal.com/1071.html</link>
         <description>Не могу пройти мимо видео, сделанное Евгением Холодковым  &lt;br /&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://lafy.livejournal.com/145246.html&quot;&gt;lafy: Clojure video [devclub.eu #04-10]&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;слайды здесь &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href='http://www.planvita.com/devclub/clojure-devclub-30-04-2010.pdf'&gt;http://www.planvita.com/devclub/clojure-devclub-30-04-2010.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Очень полезная работа, несмотря на самокритику автора.&lt;br /&gt;Всем рекомендую к просмотру.</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:ru_clojure:1071</guid>
         <pubDate>Fri, 07 May 2010 09:01:42 +0000</pubDate>
      </item>
      <item>
         <title>mock и stub в clojure</title>
         <link>http://ru-clojure.livejournal.com/963.html</link>
         <description>Подскажите как создавать mock'и в clojure?&lt;br /&gt;Интересует нечто вроде fakeweb &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href='http://fakeweb.rubyforge.org/'&gt;http://fakeweb.rubyforge.org/&lt;/a&gt;</description>
         <author>edbond</author>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:ru_clojure:963</guid>
         <pubDate>Mon, 22 Mar 2010 11:32:51 +0000</pubDate>
      </item>
      <item>
         <title>Google Trends: clojure</title>
         <link>http://ru-clojure.livejournal.com/643.html</link>
         <description>Кто-нибудь может объяснить - почему clojure по регионам (Russian Federation) на втором месте, а по языкам на четвертом? Как они там считают?  &lt;br /&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.google.com/trends?q=clojure&amp;amp;ctab=0&amp;amp;geo=all&amp;amp;date=all&amp;amp;sort=0&quot;&gt;Google Trends: clojure&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Да, кстати, никого не удивляет несколько повышенный интерес России (как региона) к clojure? Кто все эти люди?</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:ru_clojure:643</guid>
         <pubDate>Mon, 15 Mar 2010 07:26:31 +0000</pubDate>
      </item>
      <item>
         <title>ru_clojure @ 2010-03-09T13:44:00</title>
         <link>http://ru-clojure.livejournal.com/289.html</link>
         <description>&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://community.livejournal.com/ru_clojure/&quot;&gt;clojure по-русски&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Замечательная статья alex-ott (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href='http://fprog.ru/2010/issue4/alex-ott-clojure/'&gt;http://fprog.ru/2010/issue4/alex-ott-clojure/&lt;/a&gt;) сподвигла на создание данного сообщества.&lt;br /&gt;Надеюсь на просторах русского инета найдется несколько человек, заинтересованных в освоении и практическом применении очень перспективного и нового языка clojure.&lt;br /&gt;&lt;br /&gt;Лично мне clojure интересен в контексте создания DSL и интеграции с JVM. Признаюсь честно, что в ФП практически не имею опыта, но надеюсь что данное сообщество поможет привлечет в мир функционального программирования не только меня :)      &lt;br /&gt;&lt;br /&gt;А вопросов очень много... Давайте не замыкаться в собственных экспериментах!&lt;br /&gt;Пишем, предлагаем, комментируем.&lt;br /&gt;&lt;br /&gt;ЗЫ. Хочу быть просто читателем этого сообщества. С радостью уступлю место &quot;смотрителя&quot; любому желающему.</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:ru_clojure:289</guid>
         <pubDate>Tue, 09 Mar 2010 11:44:53 +0000</pubDate>
      </item>
      <item>
         <title>Clojure - пишем программу с базовым интерфейсом и собираем ее в .jar</title>
         <link>http://stalker401.blogspot.com/2010/12/clojure-jar.html</link>
         <description>&lt;div&gt;Переписал пример из &quot;Core Java. Fundamentals&quot; на clojure, чтобы разобраться с тем, как на ней пишется GUI.&lt;/div&gt;&lt;div&gt;Код и комментарии - под катом.&lt;/div&gt;&lt;div&gt;&lt;a rel=&quot;nofollow&quot; name='more'&gt;&lt;/a&gt;Вот код:&lt;/div&gt;&lt;div style=&quot;background-color:darkslategrey;color:wheat;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!--.builtin {color:#98fb98;font-weight:bold;}.function-name {color:#7b68ee;font-weight:bold;}.keyword {color:#fa8072;}.string {color:#ffa07a;font-style:italic;}.type {color:#9acd32;font-weight:bold;}a {color:inherit;background-color:inherit;font:inherit;text-decoration:inherit;}a:hover {text-decoration:underline;}--&gt;&lt;/style&gt;&lt;br /&gt;&lt;pre&gt;(&lt;span class=&quot;keyword&quot;&gt;ns&lt;/span&gt; interfacetest.core&lt;br /&gt;  (&lt;span class=&quot;builtin&quot;&gt;:import&lt;/span&gt; [javax.swing&lt;br /&gt;            JFrame&lt;br /&gt;            JLabel&lt;br /&gt;            JFileChooser&lt;br /&gt;            JMenuBar&lt;br /&gt;            JMenuItem&lt;br /&gt;            JMenu&lt;br /&gt;            ImageIcon]&lt;br /&gt;           [java.io&lt;br /&gt;            File]&lt;br /&gt;           [java.awt.event &lt;br /&gt;            ActionListener])&lt;br /&gt;  (&lt;span class=&quot;builtin&quot;&gt;:gen-class&lt;/span&gt;))&lt;br /&gt;&lt;br /&gt;(&lt;span class=&quot;keyword&quot;&gt;defn&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;create-listener&lt;/span&gt; [lmbd]&lt;br /&gt;  (&lt;span class=&quot;builtin&quot;&gt;proxy&lt;/span&gt; [ActionListener]&lt;br /&gt;      []&lt;br /&gt;    (actionPerformed [e] (lmbd e))))&lt;br /&gt;&lt;br /&gt;(&lt;span class=&quot;keyword&quot;&gt;defn&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;initframe&lt;/span&gt; [&lt;span class=&quot;type&quot;&gt;#^JFrame&lt;/span&gt; frame]&lt;br /&gt;  (&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; [lbl (JLabel.)&lt;br /&gt;        chooser (JFileChooser.)&lt;br /&gt;        menubar (JMenuBar.)&lt;br /&gt;        menu (JMenu. &lt;span class=&quot;string&quot;&gt;&quot;File&quot;&lt;/span&gt;)&lt;br /&gt;        openItem (JMenuItem. &lt;span class=&quot;string&quot;&gt;&quot;Open&quot;&lt;/span&gt;)&lt;br /&gt;        exitItem (JMenuItem. &lt;span class=&quot;string&quot;&gt;&quot;Exit&quot;&lt;/span&gt;)]&lt;br /&gt;    (&lt;span class=&quot;keyword&quot;&gt;doto&lt;/span&gt; openItem&lt;br /&gt;      (.addActionListener&lt;br /&gt;       (create-listener&lt;br /&gt;        (&lt;span class=&quot;builtin&quot;&gt;fn&lt;/span&gt; [e] (&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; [result (.showOpenDialog chooser nil)&lt;br /&gt;                      getname (&lt;span class=&quot;builtin&quot;&gt;fn&lt;/span&gt; [] (&lt;span class=&quot;keyword&quot;&gt;..&lt;/span&gt; chooser getSelectedFile getPath))]&lt;br /&gt;                  (&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;builtin&quot;&gt;=&lt;/span&gt; result JFileChooser/APPROVE_OPTION)&lt;br /&gt;                      (.setIcon lbl (ImageIcon. (getname)))))))))&lt;br /&gt;    (&lt;span class=&quot;keyword&quot;&gt;doto&lt;/span&gt; exitItem&lt;br /&gt;      (.addActionListener&lt;br /&gt;       (create-listener&lt;br /&gt;        (&lt;span class=&quot;builtin&quot;&gt;fn&lt;/span&gt; [e] (System/exit 0)))))&lt;br /&gt;    (.setCurrentDirectory chooser (File. &lt;span class=&quot;string&quot;&gt;&quot;.&quot;&lt;/span&gt;))&lt;br /&gt;    (&lt;span class=&quot;keyword&quot;&gt;doto&lt;/span&gt; menu&lt;br /&gt;      (.add openItem)&lt;br /&gt;      (.add exitItem))&lt;br /&gt;    (.add menubar menu)&lt;br /&gt;    (&lt;span class=&quot;keyword&quot;&gt;doto&lt;/span&gt; frame&lt;br /&gt;      (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)&lt;br /&gt;      (.setSize 300 300)&lt;br /&gt;      (.setVisible true)&lt;br /&gt;      (.add lbl)&lt;br /&gt;      (.setJMenuBar menubar))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(&lt;span class=&quot;keyword&quot;&gt;defn&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;-main&lt;/span&gt; []&lt;br /&gt;  (&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; [fr (JFrame. &lt;span class=&quot;string&quot;&gt;&quot;Hello world&quot;&lt;/span&gt;)]&lt;br /&gt;    (initframe fr)))&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Результатом работы программы будет небольшая формочка с двумя пунктами меню - &quot;Open&quot; и &quot;Exit&quot;. Open предложит выбрать изображение, которое и будет помещено на формочку (изображение не ресайзится, от очень большой картинки будет показана только часть.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Разберем код по порядку.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Инструкция (ns) задает пространство имен под названием interfacetest.core. В ней же указано, что необходимо сгенерировать Java-класс для этого пространства имен (что и будет сделано при компиляции) - :gen-class. В директиве :import подключаются классы из стандартной библиотеки Java (написанные не на Clojure).&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Функция create-listener превращает функцию clojure в объект, реализующий интерфейс ActionListener. Эти объекты понадобятся нам позже, для меню.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Далее следует функция initframe, принимающая объект класса JFrame (инструкция #^JFrame заставляет делать проверку типов при компиляции, если я ничего не путаю). В let-биндинге создаются объекты JMenuBar, JFileChooser, JMenuItem и так далее, а затем, при помощи инструкций doto производятся действия над этими объектами и собирается интерфейс. &lt;pre&gt;(doto object ...)&lt;/pre&gt;позволяет производить несколько действий подряд над одним и тем же объектом. Обычно вызов методов объектов производится так: &lt;pre&gt;(.method object args)&lt;/pre&gt;, в случае с doto можно делать так: &lt;pre&gt;(doto object (.method args) ... )&lt;/pre&gt;, чем мы и пользуемся.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Затем определяется метод -main, который будет вызываться java'ой. В нем мы создаем фрейм и вызываем для него initframe.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Да, еще момент - я использовал в let-биндинге лямбда-функцию, чтобы отложить получение имени выбранного файла, потому что не был уверен, что на момент биндинга оно будет существовать. Такая вот ленивость.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Вроде все. Теперь про компиляцию.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Пространство имен называется interfacetest.core, значит, создаем на диске директорию interfacetest и кладем туда файл core.clj с указанным выше содержимым. Затем переходим в командной строке в директорию уровнем выше interfacetest, и запускаем REPL Clojure. В интерпретаторе пишем:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre&gt;(compile 'interfacetest.core)&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Файл откомпилирован, и на диске создана директория classes, в которой лежат interfacetest/*.class. Проверить, что все получилось, можно следующим образом - из командной строки переходим в директорию classes (желательно положить туда же clojure.jar) и пишем:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre&gt;java -cp .;clojure.jar interfacetest.core&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Обратите внимание - здесь указана версия для Windows - разделитель &quot;;&quot; в classpath. Для линукса нужно будет заменить &quot;;&quot; на &quot;:&quot;.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Осталось только собрать наш jar. Распаковываем clojure.jar как обычный .zip-архив, копируем директорию clojure (ту, которая лежит в директории распаковки), кладем ее рядом с interfacetest и пишем:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre&gt;jar cvfe jarfilename.jar interfacetest.core clojure&amp;#92;* interfacetest&amp;#92;*&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Опять же, это версия для Windows - для линукса заменяем обратные слеши на прямые. Получаем исполняемый файл, который запускается без лишних библиотек.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Вроде все. За кадром остался вопрос, как определить только используемые классы из clojure.jar и не включать из в итоговый jar, тем самым уменьшая его размер (думаю, это можно сделать).&lt;br /&gt;&lt;/div&gt;</description>
         <author>Crazy_Owl</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-7280809786242057910.post-8570978877280286897</guid>
         <pubDate>Thu, 09 Dec 2010 19:46:00 +0000</pubDate>
      </item>
      <item>
         <title>Clojure-вакансия</title>
         <link>http://my-clojure.blogspot.com/2013/06/clojure.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;&lt;h5 class=&quot;uiStreamMessage userContentWrapper&quot;&gt;&lt;span style=&quot;font-size:small;font-weight:normal;&quot;&gt;&lt;span class=&quot;messageBody&quot;&gt;&lt;span class=&quot;userContent&quot;&gt;Друзья, нам на проект нужен Сlojure-программист. Мы делаем американскую копию сайта youdo.ru. Часть исходника я уже написал, но мне подкинули  еще один проект параллельно, и теперь мне нужен помошник.&lt;br /&gt; &lt;br /&gt;  Используемые технологии: Clojure  в бэкенде, ClojureScript на фронтенде.  Архитектура в стиле Single-Page Application. Интеграция с Google+,  Facebook, Google Maps и платежными системами.&lt;br /&gt;&lt;span class=&quot;text_exposed_show&quot;&gt; &lt;br /&gt; Варианты сотрудничества обсуждаемые, но очень желательно, чтобы хотя бы полдня вы были в офисе.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt;&lt;h5 class=&quot;uiStreamMessage userContentWrapper&quot;&gt;&lt;span style=&quot;font-size:small;font-weight:normal;&quot;&gt;&lt;span class=&quot;messageBody&quot;&gt;&lt;span class=&quot;userContent&quot;&gt;&lt;span class=&quot;text_exposed_show&quot;&gt;Если кого заинтересовал -- пишите d.bushenko@gmail.com &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt;&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-3687067286490315840</guid>
         <pubDate>Thu, 20 Jun 2013 11:34:00 +0000</pubDate>
      </item>
      <item>
         <title>Курсы по Clojure закончились</title>
         <link>http://my-clojure.blogspot.com/2013/05/clojure.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;В марте я начал курсы по языку Clojure. Все участники были поделены на три группы: А -- очники, B -- дистанционщики с преподавателем, С -- дистанционщики без преподавателя. Из примерно сотни стартовавших до конца обучения дошли всего 18 человек.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://fbcdn-sphotos-f-a.akamaihd.net/hphotos-ak-ash3/524781_464026087006855_150418915_n.jpg&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;585&quot; src=&quot;https://fbcdn-sphotos-f-a.akamaihd.net/hphotos-ak-ash3/524781_464026087006855_150418915_n.jpg&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;text-align:center;&quot;&gt;На фото -- мы с Никитой Белоглазовым толкаем речь.&lt;/div&gt;&lt;div style=&quot;text-align:center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;Поскольку слушателей курсов было много, я попросил помочь мне вести группы Никиту Белоглазова, Алекса Отта, Никиту Прокопова и Виталия Монастырева. Благодаря их помощи, курсы получились довольно масштабными, если бы я был один, то смог бы взять максимум человек 30.&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://fbcdn-sphotos-b-a.akamaihd.net/hphotos-ak-ash3/601758_464026177006846_523319292_n.jpg&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;Параллельно я провел три занятия по Clojure и функциональному программированию в БГУ у третьекурсников ФПМ. Двум студентам, выполнившим ДЗ, я тоже вручил сертификаты.&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://fbcdn-sphotos-b-a.akamaihd.net/hphotos-ak-ash3/601758_464026177006846_523319292_n.jpg&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;406&quot; src=&quot;https://fbcdn-sphotos-b-a.akamaihd.net/hphotos-ak-ash3/601758_464026177006846_523319292_n.jpg&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;br /&gt;На фото я вручаю сертификат, а Никита награждает значком с символом Сlojure&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;На курсах мы разобрали следующие основные темы:&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;1. Основы ФП&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;2. Параллельное программирование&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;3. Макросы и предметно-ориентированные языки&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;4. Веб-разработка&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;По итогам курсов те, кто дошли до конца, разработали свое небольшое веб-приложение в стиле Single-Page Application. Самое забавное, на мой взгляд, сделал Виталий Монастырев (http://www.komoku.org:3000/index.html).&lt;br /&gt;&lt;br /&gt;После вручения сертификатов как-то сама собой случилась посиделка с чаем и тортиком. На заседании было высказано несколько очень здравых идей и предложений. Вот краткие итоги:&lt;br /&gt;&lt;br /&gt;1. Разработаем сайт минского коммьюнити clojure.by&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;2. Задачи комьюнити: &lt;br /&gt;а) пропаганда clojure, культурная экспансия в умы ООП-инфицированных;&lt;br /&gt;б) обзоры интересных clojure-технологий в виде докладов на митапах;&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;в) совместная разработка best practices по использованию clojure в различных областях. На данный момент следующие темы требуют выработки общих best practices: веб-разработка, разработка параллельных алгоритмов средствами clojure, разработка предметно-ориентированных языков.&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;г) организация clojure-хакатонов.&lt;br /&gt;&lt;br /&gt;Цели комьюнити всего две: повысить собстенный уровень образования в использовании Clojure, а также создать условия, при которых на коммерческих фирмах будут разрешать выполнять проекты на Clojure.&lt;br /&gt;&lt;br /&gt;3. Создать чисто технарьскую конференцию thestrangeloop.by по примеру thestrangeloop.com. С этим пунктом пока много неясного, предлагаю его обсудить. Но в целом, на этой конфе должны быть исключительно программерские доклады от классных докладчиков (возможно даже дистанционно). Языки и технологии в основном маргинальные, вроде Clojure, Haskell, CL, Scheme, Emaсs Lisp, Scala, ML, Erlang и т.д. Задачи конфы -- дать возможность обсудить проблемы использования маргинальных технологий &quot;вживую&quot;, познакомиться с грамотными специалистами. Причем я думаю, тезисы докладов стоит публиковать заранее, чтобы слушатели ознакомились и могли заготовить вопросы для обсуждения. Возможно даже такую конфу стоило бы проводить в онлайне -- дешево и сердито. &lt;br /&gt;&lt;br /&gt;По поводу сlojure.by и thestrangeloop.by прошу высказаться всех заинтересованных.&lt;/div&gt;&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-6497821792973293484</guid>
         <pubDate>Thu, 02 May 2013 11:58:00 +0000</pubDate>
      </item>
      <item>
         <title>Настройка окружения Clojure и IntelliJ IDEA на MS Windows</title>
         <link>http://my-clojure.blogspot.com/2013/04/clojure-intellij-idea-ms-windows.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Во-первых, необходимо установить leiningen2. Заходим на leiningen.org, читаем инструкции.&lt;br /&gt;&lt;br /&gt;Качаем &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://raw.github.com/technomancy/leiningen/stable/bin/lein.bat&quot;&gt;lein.bat&lt;/a&gt; куда-нибудь, например, в q:&amp;#92;programs&amp;#92;lein. Затем необходимо прописать этот путь в переменную %PATH% таким образом, чтобы lein.bat был доступен отовсюду.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://1.bp.blogspot.com/-hzFnzS9A4o8/UWrE7RkYJEI/AAAAAAAAAT4/aOcbOE3lJZI/s1600/path.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;386&quot; src=&quot;http://1.bp.blogspot.com/-hzFnzS9A4o8/UWrE7RkYJEI/AAAAAAAAAT4/aOcbOE3lJZI/s640/path.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Откройте cmd.exe и выполните команду lein self-install. Leiningen скачает и самостоятельно установит свою последнюю версию.&lt;br /&gt;&lt;br /&gt;Домашний каталог утилиты lein -- C:&amp;#92;users&amp;#92;&lt;i&gt;&amp;lt;user&amp;gt;&lt;/i&gt;&amp;#92;.lein, где &lt;i&gt;&amp;lt;user&amp;gt; -- &lt;/i&gt;имя вашего пользователя. В домашнем каталоге lein находятся файлы настройки. Создайте там файл profiles.clj с таким содержимым:&lt;br /&gt;&lt;br /&gt;{:user {:plugins [[lein-pprint &quot;1.1.1&quot;] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [lein2-eclipse &quot;2.0.0&quot;] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [lein-idea &quot;1.0.1&quot;]] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :dependencies [[slamhound &quot;1.3.1&quot;]]}}&lt;br /&gt;&lt;br /&gt;Здесь перечислино несколько плагинов для интеграции с IDE Eclipse и IntelliJ IDEA.&lt;br /&gt;&lt;br /&gt;Мы в любом случае будем использовать lein для того, чтобы создавать проекты и управлять зависимостями. На данный момент lein делает это гораздо лучше IDE.&lt;br /&gt;&lt;br /&gt;Чтобы создать новый проект, выполните команду lein new myclojure1, где myclojure1 -- имя нового проекта.&lt;br /&gt;&lt;br /&gt;Зайдите в каталог myclojure1 и выполните там команду lein deps. Leiningen&amp;nbsp; подятянет все зависимости (в том числе и саму Clojure).&lt;br /&gt;&lt;br /&gt;Сконвертируйте полученный проект в IDEA-project командой lein idea.&lt;br /&gt;&lt;br /&gt;Далее, необходимо импортировать этот проект в IntelliJ IDEA. Чтобы IDEA могла работать с Clojure -- установите плагин LaClojure. Затем импортните проект myclojure1 (не забудьте настроить JDK для этого проеката, если не настроили для всей IDEA).&lt;br /&gt;&lt;br /&gt;Запустить REPL можно выбрав пункт меню Tool -&amp;gt; Start Clojure Console.&lt;br /&gt;&lt;br /&gt;Скомпилировать исходник на Clojure можно выбрав его в дереве проекта (src&amp;#92;myclojure1&amp;#92;core.clj), и выбрав пункт меню Tools -&amp;gt; Clojure REPL -&amp;gt; Load file in REPL.&lt;br /&gt;&lt;br /&gt;Для того, чтобы перейти в неймспейс этого файла, обратите внимание на первую строчку core.clj:&lt;br /&gt;&lt;br /&gt;(ns myclojure1.core)&lt;br /&gt;&lt;br /&gt;Введите в REPL следующий текст:&lt;br /&gt;&lt;br /&gt;(in-ns 'myclojure1.core)&lt;br /&gt;&lt;br /&gt;После выполнения этой команды, все определения, доступные в core.clj станут доступны и в REPL.&lt;br /&gt;&lt;br /&gt;Успехов! &lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-1271033274168064537</guid>
         <pubDate>Sun, 14 Apr 2013 18:02:00 +0000</pubDate>
         <media:thumbnail height="72" url="http://1.bp.blogspot.com/-hzFnzS9A4o8/UWrE7RkYJEI/AAAAAAAAAT4/aOcbOE3lJZI/s72-c/path.png" width="72" xmlns:media="http://search.yahoo.com/mrss/"/>
      </item>
      <item>
         <title>Как деплоить Clojure на OpenShift</title>
         <link>http://my-clojure.blogspot.com/2013/04/clojure-openshift.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;P {margin-bottom:0.21cm;}A:link {}         &lt;/style&gt;&lt;br /&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;Прежде всего вам необходимо зарегистрироваться на OpenShift и залогиниться. Второй этап — настроить ssh-доступ. Да, y OpenShift есть специальные консольные утилиты для работы без ssh, но это не наш случай.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;1. Генерим открытый ssh-ключ:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;$ ssh-keygen -t rsa &lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;В каталоге .ssh вы получите два файла: id_rsa и id_rsa.pub.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;2. Зайдите в настройки своего аккаунта.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://2.bp.blogspot.com/-w6YbRsJD1c4/UV1lsy2hitI/AAAAAAAAAQI/aVZVDK3Swwc/s1600/01.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;376&quot; src=&quot;http://2.bp.blogspot.com/-w6YbRsJD1c4/UV1lsy2hitI/AAAAAAAAAQI/aVZVDK3Swwc/s640/01.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;3. Выберите «Change settings», попадете на экран Personal Information.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&amp;nbsp; &lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://3.bp.blogspot.com/-bRlqrJ-I3Y0/UV1l1MkJPWI/AAAAAAAAAQQ/6kQKlBaedIs/s1600/02.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;460&quot; src=&quot;http://3.bp.blogspot.com/-bRlqrJ-I3Y0/UV1l1MkJPWI/AAAAAAAAAQQ/6kQKlBaedIs/s640/02.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;4. Нажмите кнопку «Add a new key...», попадете на экран Add a public key. Скопируйте туда содержимое файла id_rsa.pub.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://3.bp.blogspot.com/-4v4567DfoKs/UV1l_0laqYI/AAAAAAAAAQY/tL4GAZmd6fE/s1600/03.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;388&quot; src=&quot;http://3.bp.blogspot.com/-4v4567DfoKs/UV1l_0laqYI/AAAAAAAAAQY/tL4GAZmd6fE/s640/03.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;Далее необходимо создать приложение.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;5. Выберите вкладку «My Applications» и нажмите кнопку «Add application». OpenShift покажет вам экран выбора типа приложения. Выберите приложение Tomcat7.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://2.bp.blogspot.com/-6MZQob90yGg/UV1mGX1M6ZI/AAAAAAAAAQg/KQz3W3m4rwI/s1600/04.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;444&quot; src=&quot;http://2.bp.blogspot.com/-6MZQob90yGg/UV1mGX1M6ZI/AAAAAAAAAQg/KQz3W3m4rwI/s640/04.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;6. На экране конфигурации нового приложения введите его имя и нажмите кнопку «Create application.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://3.bp.blogspot.com/-i4Ooyo9yQCE/UV1mOECyZTI/AAAAAAAAAQo/I8zYuOweuQM/s1600/05.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;640&quot; src=&quot;http://3.bp.blogspot.com/-i4Ooyo9yQCE/UV1mOECyZTI/AAAAAAAAAQo/I8zYuOweuQM/s640/05.png&quot; width=&quot;632&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;7. Откроется экран с подробностями о созданном приложении. Нажмите на ссылку «Add cartridge».&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://4.bp.blogspot.com/-uk2PkWHRUY0/UV1mVgIHo5I/AAAAAAAAAQw/nYOXlp6EbvE/s1600/06.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;640&quot; src=&quot;http://4.bp.blogspot.com/-uk2PkWHRUY0/UV1mVgIHo5I/AAAAAAAAAQw/nYOXlp6EbvE/s640/06.png&quot; width=&quot;602&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;8. В открывшемся экране выберите нужную вам базу данных. В этом примере мы рассматриваем MySQL 5.1. Добавьте этот картридж.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://4.bp.blogspot.com/-mDz0o15VQNs/UV1mhrC-JyI/AAAAAAAAAQ4/7GkKtJaXtps/s1600/07.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;538&quot; src=&quot;http://4.bp.blogspot.com/-mDz0o15VQNs/UV1mhrC-JyI/AAAAAAAAAQ4/7GkKtJaXtps/s640/07.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;9. OpenShift покажет вам экран с информацией о вашей БД. Важный момент: хост и порт для коннекта из приложения хранятся в переменных окружения среды OPENSHIFT_MYSQL_DB_HOST и OPENSHIFT_MYSQL_DB_PORT.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://2.bp.blogspot.com/-ZOdq1iRt0qU/UV1mpB0ahgI/AAAAAAAAARA/3e-FdjtaKpc/s1600/08.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;408&quot; src=&quot;http://2.bp.blogspot.com/-ZOdq1iRt0qU/UV1mpB0ahgI/AAAAAAAAARA/3e-FdjtaKpc/s640/08.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;10. Зайдите на вкладку My applications, выберите ваше приложение и нажмите на ссылку «Want to login to your application?». OpenShift покажет вам ssh-команду для логина на сервер.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://2.bp.blogspot.com/-TiGeQ4WTPeA/UV1myiZfAYI/AAAAAAAAARI/2bXZqmS66D8/s1600/09.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;358&quot; src=&quot;http://2.bp.blogspot.com/-TiGeQ4WTPeA/UV1myiZfAYI/AAAAAAAAARI/2bXZqmS66D8/s640/09.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;11. Введите показанную команду&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;$ ssh 515c...00401@helloworld-writing.rhcloud.com  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;Если до этого вы правильно зарегистрировали ваш id_rsa.pub, то ssh тихо залогинит вас на сервер и не спросит пароля.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;Выполните команду  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;$ ctl_all restart&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;Эта команда необходима для того, чтобы OpenShift рестартанул приложение и подтянул картридж с MySQL. После перезагрузки в окружении среды перезапущенного Tomcat появятся переменные OPENSHIFT_MYSQL_DB_HOST и OPENSHIFT_MYSQL_DB_PORT.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;12. Выйдите из ssh-сессии командой exit. Сконфигурируйте строку соединения к MySQL следующим образом.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;(def env (into {} (System/getenv))) &lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;(def dbhost (get env &quot;OPENSHIFT_MYSQL_DB_HOST&quot;)) &lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;(def dbport (get env &quot;OPENSHIFT_MYSQL_DB_PORT&quot;)) &lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;(def default-conn {:classname &quot;com.mysql.jdbc.Driver&quot; &lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;                   :subprotocol &quot;mysql&quot; &lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :user &quot;myuser&quot; &lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;                   :password &quot;mypassword&quot; &lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;                   :subname (str &quot;//&quot; dbhost &quot;:&quot; dbport &quot;/helloworld?useUnicode=true&amp;amp;characterEncoding=utf8&quot;) &lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;                   :delimiters &quot;`&quot;})&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;В поля :user и :password необходимо подставить значения, которые OpenShift выдал вам на шаге 9. В поле :subname слово helloworld — это имя БД (также получено на шаге 9).&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;13. Соберите ваше веб-приложение командой lein ring uberwar. Переименуйте её в ROOT.war.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;14. Скопируйте war-ку на сервер:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;$ scp ROOT.war 515....01@helloworld-writing.rhcloud.com:app-root/data  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;15. Залогиньтесь на сервер&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;$ ssh 515...401@helloworld-writing.rhcloud.com  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;16. Переместите скопированную war-ку в каталог с веб-приложениями:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;$ mv app-root/data/ROOT.war app-root/runtime/repo/webapps/&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;17. Через некоторое время ваше новое приложение будет доступно. В моем случае — по адресу &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://helloworld-writing.rhcloud.com/&quot;&gt;http://helloworld-writing.rhcloud.com&lt;/a&gt;.&amp;nbsp;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0cm;&quot;&gt;&amp;nbsp; &lt;/div&gt;&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-4250308880840250285</guid>
         <pubDate>Thu, 04 Apr 2013 14:42:00 +0000</pubDate>
         <media:thumbnail height="72" url="http://2.bp.blogspot.com/-w6YbRsJD1c4/UV1lsy2hitI/AAAAAAAAAQI/aVZVDK3Swwc/s72-c/01.png" width="72" xmlns:media="http://search.yahoo.com/mrss/"/>
      </item>
      <item>
         <title>Clojure в БГУ</title>
         <link>http://my-clojure.blogspot.com/2013/03/clojure.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Сегодня договорились с деканом ФПМ БГУ о том, что я проведу три занятия по Clojure на ФПМ (занятия парные, лекция + ПЗ) в рамках спецкурса по функциональному программированию.&lt;br /&gt;&lt;br /&gt;Главная печаль в том, что до крайности не хочется заниматься настройкой окружения в лаборатории, т.к. у них там компы c Windows XP и дохлым интернетом. Вот как студентам установить lein?&lt;br /&gt;&lt;br /&gt;Одно из решений, которое я придумал: предложу студентам залогиниться на мой ноутбук по SSH и работать там в консольном Emacs-е. Заодно и ктулхуугодный редактор пропиарю :-)&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-5039230514777843710</guid>
         <pubDate>Wed, 27 Mar 2013 17:57:00 +0000</pubDate>
      </item>
      <item>
         <title>Почему Emacs?</title>
         <link>http://my-clojure.blogspot.com/2013/03/emacs.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://3.bp.blogspot.com/-1LCNj7P6Mos/UTuziWVax9I/AAAAAAAAAP4/LGGB2SoVmNI/s1600/emacs_vi_power_drill_cartoon.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;203&quot; src=&quot;http://3.bp.blogspot.com/-1LCNj7P6Mos/UTuziWVax9I/AAAAAAAAAP4/LGGB2SoVmNI/s640/emacs_vi_power_drill_cartoon.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://2.bp.blogspot.com/-VVUj2V-flr0/UTuzXCQ2MvI/AAAAAAAAAPw/OlZcfKFhXn8/s1600/editor.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp; На сегодняшний день основным инструментом программистов являются супер-технологичные IDE, помогающие выполнять процентов 80 ежедневной работы. Они умеют очень многое: автоматически дополнять код, отлаживать приложение, проводить сложный рефакторинг. Поэтому люди, пользующиеся такими старыми, с виду, инструментами, как Emacs, кажутся совсем уж чудаками. Но чудачество ли это в самом деле? И почему этот текстовый редактор до сих пор жив и все еще пользуется уважением?&lt;br /&gt;&lt;br /&gt;&amp;nbsp; На моей предыдущей работе я программировал в основном J2EE-приложения. Мне очень нравились Eclipse и Jetbrains Idea, с их помощью мне удавалось за очень короткое время разрабатывать формочки, веб-сервисы и даже архитектуру приложения. Да я, в общем, не особо и задумывался о том, на чем писать. Все пишут в Eclipse -- ну и я тоже.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; А потом все резко изменилось. Мне предложили написать для платформы Android виртуальное казино. В приложении была всего одна формочка, зато масса логики, которую нужно было алгоритмизировать. Самым неприятным занятием было объявить в xml-файле 130 полей разметки на столе для ставок, затем их же проинициализировать в коде на java. Ни Eclipse, ни Idea уже ничем не могли мне в этом помочь, а выполнять эту работу вручную совсем не хотелось. Мои коллеги относились к этому проще. Они полагали, что раз платят, то нужно выполнять задание, даже если оно такое бездумное и скучное. Также полагал и мой менеджер. А как считаете вы?&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Еще во время учебы в школе я решил, что стану программистом. Я обажал каверзные задачки, участвовал в олимпиадах, мне очень нравилось составлять алгоритмы. Профессия программиста меня привлекала своей загадочностью. В то время мне казалось, что программисты занимаются невероятно сложной и очень интеллектуальной работой. Сейчас уже прошло примерно пятнадцать лет с тех пор, и я уже думаю несколько иначе.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Чем же сегодня занимаются программисты на крупных фирмах, особенно на тех, которые практикуют &quot;промышленное программирование&quot;? Разве программированием? Большая часть времени уходит на всякую конфигурацию Spring или других фреймворков, генерацию заготовок кода при помощи IDE, добавление всяческих аннотаций для связи различных частей кода, написание и прогон тестов и т.д. Изредка код писать все-таки приходится. Но это, как правило, очень простой код: взять что-то из базы, привести объект к другому типу, в цикле пройтись по коллекции. Давайте спросим себя: неужели именно такое программирование нам нравится?&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Когда я взялся писать виртуальное казино для Android, было ощущение, что меня разбудили после долгого сна. Я почуствовал, что передо мной задача очень отличающаяся от тех, что мне приходилось делать раньше. Мне не нужно было писать никаких конфигураций, да и IDE ничем не могло мне помочь. Мне нужно было писать алгоритмы и думать, много думать и много писать.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Первое, что я обнаружил, так это то, что текстовый редактор в Eclipse никуда не годится. Я набираю код всеми десятью пальцами сразу, и мне не надо смотреть на клавиатуру, когда мои пальцы находятся над клавишами алфавита. А для перемещения по тексту необходимо сдвигать правую руку на клавиши со стрелочками или даже еще дальше -- к PgDown/PgUp. Но даже это не идет ни в какое сравнение с тем, как отвлекает необходимость хвататься за мышку! Это здорово выбивает из состояния потока!&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Во-вторых, конечно же, я не стал писать эти 130 полей вручную. Нужно было разработать какой-то генератор кода, и здесь Eclipse опять ничем не смог мне помочь. Писать плагины для Eclipse невероятно затратное дело. Следовало выбрать один из скриптовых языков вроде Perl, Python или Ruby. Но я все равно не понимал, почему не сделать возможность в Eclipse для написания простых плагинов как раз для таких случаев. В редакторе Eclipse есть курсор, и им можно было бы выделять фрагменты текста для обработки. А когда пишешь скрипт для обработки текста, например, на Perl, курсора нет, и необходимо как-то парсить структуру текста регулярными выражениями или помечать места для упрощения анализа текста.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; В-третьих, когда огромный xml-файл был уже готов, время от времени приходилось подправлять сгенерированные координаты ячеек. Например, поднять весь ряд немного вверх, или сдвинуть часть ячеек чуть-чуть правее. Теоретически, можно было переделать генератор, сгенерировать новый код, вставить его на замену старому и решить задачу. Но в моем случае первоначально сгенерированный код уже был обработан вручную, и повторная генерация кода потребовала бы повторной его ручной обработки. Мне дико не хватало возможности написать макрос, чтобы текстовый редактор выполнял всю обработку за меня.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Мне не понравилось программировать казино на Android в Eclipse. Оказалось, что Eclipse прекрасно подходит для задач code monkeys, ежедневно клепающих формочки для очередной CRM на Java. Но этот же Eclipse совсем плохо показывает себя в задачах, для которых у него нет заготовок вроде генераторов кода.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Давайте спросим себя, что же это за задачи, для которых IDE подходят не очень хорошо?&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Это самые нестандартные задачи, это проекты, содержащие элемент изобретательности, технического творчества. Это задачи, для которых в индустрии до сих пор не выработаны типовые решения. Это задачи, где вам приходится много алгоритмизировать и много думать.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Вернемся к самому первому тезису статьи. В самом ли деле, те, кто используют Emacs, безнадежно устаревшие чудаки? Или все-таки действительно есть причины для применения этого древнего текстового редактора?&lt;br /&gt;&lt;br /&gt;&amp;nbsp; А вы знаете, что, например, в Emacs можно настроить сочетания клавиш таким образом, чтобы всю работу с текстом, в том числе и перемещение, можно было выполнять, не убирая пальцы с алфавитно-цифровой клавиатуры? И тем более не хватаясь за мышку? Когда концентрация на коде максимальна, очень важно не отвлекаться на посторонние вещи!&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Редактору Emacs легко придать абсолютно аскетичный вид. Казалось бы, зачем убирать панели инструментов, строку меню, боковые навигаторы кода и прочие элементы управления, если у нас итак достаточно вместительные экраны мониторов? Ответ очень простой: пространства на экране никогда не бывает достаточно! Когда-нибудь в будущем, когда картинка будет проецироваться пользователю напрямую в мозг и не будет ограничена размерами монитора, все равно будут те, кому и такое изображение покажется недостаточно вместительным. Эти будущие гики, также, как и сегодняшние, будут стараться убрать с изображения все отвлекающие детали и максимально освободить себе рабочее пространство, чтобы заполнить его действительно полезной информацией.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Таким образом, Emacs идеально подходит для тех, кому требуется полная концентрация внимания на редактируемом тексте.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Текстовый редактор Emacs -- это, по сути, небольшое ядро, включающее в себя интерпретатор языка Emacs Lisp, и громадное количество скриптов, написанных на этом Lisp-е. Весь интерфейс, все функции, вообще всё-всё-всё в Emacs -- это программы на Emacs Lisp. Все эти скрипты хорошо документируемы и доступны в исходных кодах. Поэтому, если вас что-то не устраивает в Emacs, то вы вольны изменить это так, как вам нравится. Писать плагины для Emacs невероятно просто.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://2.bp.blogspot.com/-7UZSp0vW77E/UTur3cx9LQI/AAAAAAAAAPY/DyBaT_-PfmI/s1600/geek_vs_non_geek_repetitive_tasks.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;419&quot; src=&quot;http://2.bp.blogspot.com/-7UZSp0vW77E/UTur3cx9LQI/AAAAAAAAAPY/DyBaT_-PfmI/s640/geek_vs_non_geek_repetitive_tasks.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp; Я специально хочу остановиться на этой мысли: писать плагины для Emacs так просто, что я, не задумываясь, пишу их чуть ли не для каждой сложной задачи. Посмотрите, как выглядит &quot;Hello World&quot; в стиле Emacs Lisp:&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; (defun my-test-message ()&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; (interactive)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (message &quot;Hello, World!&quot;))&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; Обратите внимание, сколько xml-конфигураций мы здесь не правим, сколько интерфейсов не реализовываем, сколько классов не наследуем! Всего одна простая функция, и если её скомпилировать (C-x C-e за последней скобкой функции), она тут же становится частью редактора Emacs!&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Именно эта простота написания плагинов так сильно подкупает в Emacs. Когда я программирую на Java, я пишу расширения Emacs для генерации всего того boilerplate-кода, который не умеет генерировать Eclipse. Emacs автоматизирует мне много по-настоящему скучной рутинной работы!&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Есть и еще одна проблема, с которой плохо справляются IDE -- это нестандартные и предметно-ориентированные языки программирования. Для них нет и никогда не будет поддержки в Eclipse, Idea, Netbeans и т.д. Но зато вы с лёгкостью можете добавить поддержку любого нужного вам языка в Emacs!&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; У Emacs есть еще один существенный плюс: превосходная интеграция с Clojure. Исторически сложилось так, что программисты на Lisp-подобных языках предпочитают разрабатывать программы в Emacs, потому что в этом редакторе есть все, что нужно лисперу. Это и правильная подсветка кода и скобочек, и автодополнение кода, и REPL для интерактивной разработки, и просмотр документации, и многое другое. Если вы планируете посвятить много времени Lisp-подобным языкам, то вам однозначно стоит попробовать Emacs. Тем более, что освоив Clojure вам будет уже довольно просто разобраться с Emacs Lisp и разрабатывать плагины для этого текстового редактора. Если у вас действительно возникнет желание изучить также и Emacs Lisp, могу порекомендовать вам &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://docs.google.com/file/d/0BzmL7xzGeOtOOWE1ZTc3NzAtZjkyNy00ZDU5LTg2Y2UtZDc4MmNkNTI1ZmJl/edit?usp=sharing&quot;&gt;пособие&lt;/a&gt;.&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; Откровенно говоря, нужно признать, что у Emacs есть одна проблема: довольно высокий порог вхождения. Далеко не с первого раза можно понять, как там что устроено и почему именно так, а еще как переделать, чтобы было удобнее. В Emacs множество комбинаций клавиш начинаются с Ctrl, от чего сильно устает левый мизинец; комбинации для перемещения курсора придумали как будто специально, чтобы ими было неудобно пользоваться: Ctrl-f, Ctrl-b, Ctrl-n, Ctrl-p. Это связано с тем, что Emacs создали очень давно, когда у клавиатур не только не было клавиши &quot;Win&quot;, но даже и само расположение клавиш было другим. Например, Клавиша Ctrl находилась на том месте, где сейчас традиционно расположена Alt, и Ctrl в то время нажимали большим пальцем левой руки, а вовсе не мизинцем.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://2.bp.blogspot.com/-XEQGa4gP8XY/UTuwwLs5-SI/AAAAAAAAAPo/0YW4qkVbAck/s1600/kb.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://2.bp.blogspot.com/-XEQGa4gP8XY/UTuwwLs5-SI/AAAAAAAAAPo/0YW4qkVbAck/s1600/kb.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp; Но, как уже было сказано, ничто не мешает вам изменить управляющие клавиши. Например, известный Emacs-ер Xah Lee создал проект &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://ergoemacs.org/emacs/ergonomic_emacs_keybinding.html&quot;&gt;ergoemacs&lt;/a&gt;, в котором он предлагает совершенно иную раскладку, намного более эргономичную.&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; Для слушателей Clojure Course, которые хотели бы попробовать Emacs, я создал немного &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/dbushenko/emacs-config&quot;&gt;модифицированную версию&lt;/a&gt; Ergo Emacs. Этот конфиг, конечно, не заменит начального ознакомления с документацией, но зато поможет сделать работу с Emacs несколько удобнее.&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; Ниже несколько основных клавиатурных сочетаний, которые я использую в своем конфиге. Здесь используются следующие традиционные для Emacs обозначения клавиш: C -- Ctrl, M -- Alt, S -- Shift.&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; Перемещение курсора:&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; M-i -- up&lt;br /&gt;&amp;nbsp; M-k -- down&lt;br /&gt;&amp;nbsp; M-j -- left&lt;br /&gt;&amp;nbsp; M-l -- right&lt;br /&gt;&amp;nbsp; M-u -- word left&lt;br /&gt;&amp;nbsp; M-o -- word right&lt;br /&gt;&amp;nbsp; M-S-i -- page up&lt;br /&gt;&amp;nbsp; M-S-k -- page down&lt;br /&gt;&amp;nbsp; M-S-j -- beginning of document&lt;br /&gt;&amp;nbsp; M-S-l -- end of document&lt;br /&gt;&amp;nbsp; M-h -- end of line&lt;br /&gt;&amp;nbsp; M-S-h -- beginning of line&lt;br /&gt;&amp;nbsp; C-l -- go to line&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; Редактирование текста:&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; M-m -- new line&lt;br /&gt;&amp;nbsp; M-d -- backspace&lt;br /&gt;&amp;nbsp; M-f -- delete&lt;br /&gt;&amp;nbsp; M-Space -- start/end selection&lt;br /&gt;&amp;nbsp; M-c -- copy&lt;br /&gt;&amp;nbsp; M-x -- cut&lt;br /&gt;&amp;nbsp; M-v -- paste&lt;br /&gt;&amp;nbsp; M-s -- save document&lt;br /&gt;&amp;nbsp; C-o -- open file&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Работа с окнами:&lt;br /&gt;&lt;br /&gt;&amp;nbsp; C-x 2 -- split window horizontally&lt;br /&gt;&amp;nbsp; C-x 3 -- split window vertically&lt;br /&gt;&amp;nbsp; C-x 0 -- close current window&lt;br /&gt;&amp;nbsp; C-x 1 -- leave only current window&lt;br /&gt;&amp;nbsp; M-q -- next window&lt;br /&gt;&amp;nbsp; M-S-9 -- shrink horizontal window&lt;br /&gt;&amp;nbsp; M-S-0 -- enlarge horizontal window&lt;br /&gt;&amp;nbsp; M-9 -- shrink vertical window&lt;br /&gt;&amp;nbsp; M-0 -- enlarge vertical window&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; Закладки:&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; C-b -- set bookmark&lt;br /&gt;&amp;nbsp; M-b -- jump to bookmark&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; Системные операции:&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; F5 -- run Emacs command&lt;br /&gt;&amp;nbsp; C-x C-c -- close Emacs&lt;br /&gt;&amp;nbsp; C-x b -- select buffer&lt;br /&gt;&amp;nbsp; C-x k -- kill buffer&lt;br /&gt;&amp;nbsp; C-c l -- truncate long lines on/off&lt;br /&gt;&amp;nbsp; C-g -- сancel&lt;br /&gt;&amp;nbsp; F11 -- show help for my keybindings&lt;br /&gt;&lt;br /&gt;&amp;nbsp;Для того, чтобы воспользоваться моим конфигом, просто скопируйте его себе в домашнюю дирректорию.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;А вообще, конечно, очень рекомендую прочесть &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.net/ru/emacs/TUTORIAL.ru&quot;&gt;учебник&lt;/a&gt; по Emacs в переводе Алекса Отта.&lt;br /&gt;&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-4287106447846914009</guid>
         <pubDate>Sun, 10 Mar 2013 01:19:00 +0000</pubDate>
         <media:thumbnail height="72" url="http://3.bp.blogspot.com/-1LCNj7P6Mos/UTuziWVax9I/AAAAAAAAAP4/LGGB2SoVmNI/s72-c/emacs_vi_power_drill_cartoon.png" width="72" xmlns:media="http://search.yahoo.com/mrss/"/>
      </item>
      <item>
         <title>14 марта стартуют курсы Clojure</title>
         <link>http://my-clojure.blogspot.com/2013/03/14-clojure.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;P {margin-bottom:0.21cm;direction:ltr;color:rgb(0, 0, 0);}P.western {font-family:&quot;Liberation Serif&quot;, serif;font-size:12pt;}P.cjk {font-family:&quot;WenQuanYi Zen Hei Sharp&quot;;font-size:12pt;}P.ctl {font-family:&quot;DejaVu Sans&quot;;font-size:12pt;}A:link {color:rgb(0, 0, 255);}&lt;/style&gt;&lt;br /&gt;&lt;div class=&quot;western&quot; style=&quot;margin-bottom:0.35cm;text-indent:1.25cm;&quot;&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;Вам надоела многословность Java или C#? Вы хотите, чтобы писать программы было проще и быстрее? Вас достало писать вручную одни и те же паттерны проектирования?&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;western&quot; style=&quot;margin-bottom:0.35cm;text-indent:1.25cm;&quot;&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;Решение есть! Приходите на курсы Clojure, мы научим вас самым современным методам программирования! Вы будете использовать преимущества &lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;b&gt;функционального подхода&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;b&gt;интерактивной разработки и метапрограммирования&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;. Мы покажем вам, как автоматизировать программерскую рутину!&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;western&quot; style=&quot;margin-bottom:0.35cm;text-indent:1.25cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;western&quot; style=&quot;margin-bottom:0.35cm;text-indent:1.25cm;&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;С &lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;b&gt;14 марта по 18 апреля 2013г. &lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;в офисе компании &lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;b&gt;ITA&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;(г.Минск, проспект Независимости, 58) будут проходить курсы программирования на Clojure. Программа курсов включает в себя изучение основ &lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;i&gt;функционального&lt;/i&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;и &lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;i&gt;мета-программирования&lt;/i&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;средствами языка Clojure, а также применение Clojure для разработки современных веб-приложений.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;western&quot; style=&quot;margin-bottom:0.35cm;text-indent:1.25cm;&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;Примерный план занятий:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;western&quot; style=&quot;margin-bottom:0.35cm;text-indent:1.25cm;&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;i&gt;14.03.2013 &lt;/i&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;— Установка и настройка необходимых инструментов, введение в Clojure и функциональное программирование.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;western&quot; style=&quot;margin-bottom:0.35cm;text-indent:1.25cm;&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;i&gt;21.03.2013&lt;/i&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;— Функции высшего порядка, ленивые вычисления, полиморфизм, STM, взаимодействие с Java.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;western&quot; style=&quot;margin-bottom:0.35cm;text-indent:1.25cm;&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;i&gt;28.03.2013 &lt;/i&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;— Макросы, предметно-ориентированные языки, генерация кода.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;western&quot; style=&quot;margin-bottom:0.35cm;text-indent:1.25cm;&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;i&gt;04.04.2013&lt;/i&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;— Введение в веб-стек Clojure. Ring, Compojure, lib-noir, развертывание приложений.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;western&quot; style=&quot;margin-bottom:0.35cm;text-indent:1.25cm;&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;i&gt;11.04.2013 &lt;/i&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;— Генерация html (Clostache, Hiccup, Enlive), Взаимодействие с БД (Korma).&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;western&quot; style=&quot;margin-bottom:0.35cm;text-indent:1.25cm;&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;i&gt;18.04.2013 &lt;/i&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;— ClojureScript вместо JavaScript.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;western&quot; style=&quot;margin-bottom:0.35cm;text-indent:1.25cm;&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;Для успешного прохождения курсов необходимо иметь представление о Java, SQL, HTML, CSS и JavaScript.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;western&quot; style=&quot;margin-bottom:0.35cm;text-indent:1.25cm;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.blogger.com/blogger.g?blogID=4007342736133040943&quot; name=&quot;__DdeLink__1_504709992&quot;&gt;&lt;/a&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;Количество мест на очную форму обучения ограничено. Поэтому те, кто хочет посетить курсы лично, должны будут выполнить тестовое задание на алгоритмизацию. Задание будет объявлено в группе «&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.facebook.com/groups/clojure.course/&quot;&gt;Clojure Course&lt;/a&gt;»&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color:red;&quot;&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;в facebook 7 марта 2013г. Если у Вас есть желание получить задание предварительно, присылайте Ваши заявки на &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;span lang=&quot;en-US&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;email&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;: &lt;/span&gt;&lt;/span&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;mailto:dmitry.bushenko@ita.by&quot;&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;span lang=&quot;en-US&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;d.bushenko@gmail.com&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;span lang=&quot;en-US&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;. После успешного прохождения очной формы курсов, слушатели получат сертификаты.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;western&quot; style=&quot;margin-bottom:0.35cm;text-indent:1.25cm;&quot;&gt;&lt;span style=&quot;background:transparent;&quot;&gt;&lt;span style=&quot;font-family:Calibri, serif;&quot;&gt;Для тех, кто не сможет попасть на очную форму обучения, мы предложим вам дистанционную. Информацию о том, как попасть на дистанционную форму обучения мы объявим в группе «&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.facebook.com/groups/clojure.course/&quot;&gt;Clojure Course&lt;/a&gt;» в facebook 7 марта 2013г.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-2469163314764720726</guid>
         <pubDate>Fri, 01 Mar 2013 13:26:00 +0000</pubDate>
      </item>
      <item>
         <title>Обзор Clojure на тусовке Software Craftmanship</title>
         <link>http://my-clojure.blogspot.com/2013/02/clojure-software-craftmanship.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;На днях делал презентацию языка Clojure на тусовке Software Craftmanship.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://4.bp.blogspot.com/-eKFboapDSps/USpfGM-SDYI/AAAAAAAAAPI/cvUOksUxxJc/s1600/me.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;238&quot; src=&quot;http://4.bp.blogspot.com/-eKFboapDSps/USpfGM-SDYI/AAAAAAAAAPI/cvUOksUxxJc/s320/me.png&quot; width=&quot;320&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Саму презентацию можно взять &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://docs.google.com/file/d/0BzmL7xzGeOtOVFJlMk5zdmhRX2c/edit?usp=sharing&quot;&gt;здесь&lt;/a&gt;. Видео доклада -- &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://video.yandex.by/users/d-bushenko/view/4/&quot;&gt;здесь&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Были разобраны следующие темы:&lt;br /&gt;1. Какие причины заставляют программистов искать замену языкам промышленного программирования (Java, C#, C++, etc.).&lt;br /&gt;2. Что такое Clojure.&lt;br /&gt;3. Синтаксис Clojure.&lt;br /&gt;4. Макросы -- самое мощное средство метапрограммирования.&lt;br /&gt;5. Зачем нужны eDSL и как их пишут на Clojure.&lt;br /&gt;6. Когда стоит, а когда не стоит применять Clojure.&lt;br /&gt;7. Как продавать Clojure менеджеру и заказчику.&lt;br /&gt;8. Как пользоваться Clojure, если от вас все-таки требуют код на языке промышленного уровня (например, Java).&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-6371360247338098441</guid>
         <pubDate>Sun, 24 Feb 2013 21:50:00 +0000</pubDate>
         <media:thumbnail height="72" url="http://4.bp.blogspot.com/-eKFboapDSps/USpfGM-SDYI/AAAAAAAAAPI/cvUOksUxxJc/s72-c/me.png" width="72" xmlns:media="http://search.yahoo.com/mrss/"/>
      </item>
      <item>
         <title>Курсы Clojure -- продолжение</title>
         <link>http://my-clojure.blogspot.com/2013/01/clojure_28.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Спасибо всем, кто высказался за проведение курсов. Ваше мнение имело важное значение для того, чтобы мы решились их провести.&lt;br /&gt;&lt;br /&gt;Скорее всего курсы начнутся через месяц, в последних числах февраля (это пока не точно). Еще мы планируем выдавать сертификаты о прохождении курсов тем, кто выполнит все домашние задания.&lt;br /&gt;&lt;br /&gt;С помощью Алекса Отта я составил предварительную &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://docs.google.com/document/d/1qzMgbTOXEAZYYPz1zLqAFDK885pfwxeQOvw5CL1Wvx0/edit&quot;&gt;программу курсов&lt;/a&gt;. Опять же, это пока не официально, возможны изменения.&lt;br /&gt;&lt;br /&gt;Вообще я предлагаю всем заинтересованным обсудить программу, что-то подкорректировать, добавить-убрать. Буду очень благодарен за feedback.&lt;br /&gt;&lt;br /&gt;Побеседовав с Алексом, решил вынести из основной части программы почти всю &quot;эзотерику&quot; и включить её в виде бонуса (бонусы буду записывать по мере сил и возможностей). Вначале предполагалось, что&amp;nbsp; метацикилческий интерпретатор мы будем тоже писать на курсах. Но раз уж я вынес его в бонус, то мою реализацию можно посмотреть &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/dbushenko/clj-lisp&quot;&gt;здесь&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Всем, кто хочет и может помочь мне с материалами курсов, предлагаю выбрать тему/подтему или даже какой-то совсем уж ограниченный фрагмент занятия. Пожалуйста, связывайтесь по этому поводу со мной через email: d.bushenko-at-gmail.com Имена всех, кто будет помогать мне с материалами, тоже каким-нибудь образом увековечим.&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-4566385971544652024</guid>
         <pubDate>Mon, 28 Jan 2013 14:44:00 +0000</pubDate>
      </item>
      <item>
         <title>Курсы Clojure онлайн</title>
         <link>http://my-clojure.blogspot.com/2013/01/clojure.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Мне удалось в какой-то мере заинтересовать руководство нашей фирмы языком Clojure. Если все будет хорошо, то в ближайшее время начну курс по Clojure для сотрудников. Лекции буду записывать и выкладывать по мере возможности.&lt;br /&gt;&lt;br /&gt;Скорее всего, для всех желающих мы организуем этот же самый курс онлайн. Т.е. те же лекции (только в записи), те же задания (их я планирую проверять вручную).&lt;br /&gt;&lt;br /&gt;Если есть желающие поучаствовать (либо помочь с подбором материала, либо пройти курс) -- пишите.&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-6704773094342019088</guid>
         <pubDate>Fri, 25 Jan 2013 19:33:00 +0000</pubDate>
      </item>
      <item>
         <title>Web-разработка на Clojure</title>
         <link>http://my-clojure.blogspot.com/2013/01/web-clojure.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}A:link {}--&gt;         &lt;/style&gt;&lt;br /&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Как я уже писал в своей прошлой статье, мне удалось заинтересовать начальство разработкой на Clojure. Поскольку еще на предыдущей работе мне удалось выбить разрешение на использование Clojure в одном из проектов, можно сделать определенные выводы.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Легче всего убедить начальство в случае, если предстоит небольшой fixed-price проект, на который, предположительно, ресурсов выделено или впритык, или меньше, чем нужно. Ваш главный аргумент здесь – время (оно же – деньги). Вы берете предложенную вам оценку сроков и поясняете начальству, что вот на этом, этом и этом этапах (итерациях, модулях, системах и т.д.) можно сократить сроки разработки на 30-40%, если отказаться от Java в пользу Clojure. Любой умный начальник (ну а зачем вам работать у глупого?) как минимум выслушает ваше предложение о том, как сократить сроки.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Будьте готовы ответить на вопрос, за счет чего уменьшатся сроки. Это самый шаткий момент, здесь нужна максимальная предметность. Не стоит рассказывать о вредности мутабельного состояния или славном прошлом лиспа. Идеальный вариант – на примерах показать насколько меньше в Clojure различных церемоний, а также насколько проще в Clojure автоматизировать всю ручную работу, привычную Java-программистам.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;В этот раз мне повезло сыграть на контрасте. Во-первых, я показал, насколько проще в Clojure работать с REST-сервисами, по сравнению с “правильным” способом на Java – библиотекой JAX-RS. Во-вторых, я немного рассказал о применении макросов для автоматизации, а также о том, насколько просто получить доступ к данным из БД (на примере библиотеки Korma).&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Следующий вопрос, который необходимо будет решить – кто будет поддерживать ваш исходник, ведь Clojure кроме вас никто и не знает. Я предложил провести небольшой мастер-класс по Clojure, чтобы научить людей хотя бы читать и немного понимать Clojure-код. Главное здесь – избавить коллектив от страха перед скобочками. Кроме того, я раздумываю над тем, чтобы написать небольшую методичку, максимально приближенную к практике, о применении Clojure в web-разработке. Алекс Отт написал введение в сам язык (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.net/ru/clojure/clojure-intro/&quot;&gt;http://alexott.net/ru/clojure/clojure-intro/&lt;/a&gt;), но я думаю, есть смысл добавить описание популярных библиотек, а также рассказать о распространенных приемах разработки на Clojure.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Само собой, не рекомендую ввязываться во всю эту авантюру, если не опробовали Clojure раньше в хобби-проектах. Крах будет фатальным как для вас, так и для репутации Clojure на вашей фирме.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Помимо текущего, у меня уже есть один коммерческий проект на Clojure в продакшене и два хобби-проекта, поработавшие в продакшене какое-то время. Но последний из них я писал в сентябре 2012, с тех пор кое-что поменялось. Ниже я расскажу, что, с моей точки зрения, изменилось, а также о том, какие грабли бывают с Clojure.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Самое заметное изменение – смерть микро-фреймворка Noir. Как известно, Крис Гранжер собрал на Kistsarter-е нужную сумму для своего стартапа и сейчас во всю пилит экспериментальную супер-модерновую IDE LightTable. Поэтому на веб-фреймворк Noir и ORM Korma времени у него не осталось. Общими усилиями выпустили версию Noir 1.3, и на этом развитие фреймворка прекратилось.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;К счастью, теперешний мейнтейнер Noir  – Raynes (Энтони Гримс) – исхитрился разделить этот фреймворк на две части: сам Noir и библиотеку lib-noir. Так вот, библиотека lib-noir, которая содержит полюбившиеся всем “батарейки”, жива и развивается. Теперь её используют в связке с Compojure.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://secure.gravatar.com/avatar/54222b6321f0504e0a312c24e97adfc1?s=420&amp;amp;d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://secure.gravatar.com/avatar/54222b6321f0504e0a312c24e97adfc1?s=420&amp;amp;d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png&quot; width=&quot;200&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;text-align:center;&quot;&gt;&amp;nbsp;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}A:link {}--&gt;&lt;/style&gt;Энтони Гримс&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;text-align:center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&amp;nbsp;Библиотеку Korma постигла более счастливая судьба. Пару недель назад в чате #clojure на irc.freenode.net Алекс Барановский предложил взять развитие Korma в свои руки. Ему дали права мейнтейнера, и теперь он по-стахановски постит в гитхаб коммит за коммитом. Пару дней назад Алекс опубликовал новую версию Korma – 13-ю бету, которая вышла вслед за 11-й спустя несколько месяцев.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://secure.gravatar.com/avatar/7d2cc799db6f5916a1ca4df1259d7d32?s=420&amp;amp;d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://secure.gravatar.com/avatar/7d2cc799db6f5916a1ca4df1259d7d32?s=420&amp;amp;d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png&quot; width=&quot;200&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;text-align:center;&quot;&gt;Алекс Барановский&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Compojure и Enlive ничем особенным не отметились за последние месяцы. Зато вышло несколько бет библиотеки Enfocus (ClojureScript-версии Enlive). Автор Enfocus Крейг Киркендалл  полностью переработал архитектуру библиотеки. И теперь, в 1.0 версиях, в отличие от 0.9, для доступа к элементам DOM используется библиотека Domina. В целом, 1.0-версия Enfocus лучше и стабильнее 0.9 несмотря на значительные архитектурные изменения.&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://secure.gravatar.com/avatar/c29cd3a5f182e6de85cbd172fb9b5ab8?s=420&amp;amp;d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://secure.gravatar.com/avatar/c29cd3a5f182e6de85cbd172fb9b5ab8?s=420&amp;amp;d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png&quot; width=&quot;200&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;text-align:center;&quot;&gt;&amp;nbsp;Крейг Киркендалл&lt;/div&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}A:link {}--&gt;&lt;/style&gt;  &lt;br /&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Ну и пара слов о личных впечатлениях. Когда разрабатываешь Single-Page Application на Clojure, наиважнейшее значение приобретают unit-тесты. В jvm-версии Clojure все не так печально. Худо-бедно, стектрейс вам подскажет где и что отвалилось, хотя и здесь функциональное тестирование лишним не будет (статической типизации-то нету). Но в ClojureScript типизация настолько слабая, что на определенном этапе это может даже быть неудобным. Сизифов труд вам покажется лёгким и осмысленным по сравнению с рефакторингом работающего ClojureScript-приложения. Компилятор почти ни в чем вам не поможет, и основной способ докопаться до сути – как-то запустить засбоивший фрагмент, найти поломанную функцию и долго медитировать над её исходником.  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Чтобы рефакторинг ClojureScript-кода был менее болезненным, необходимо писать юнит-тесты. Причем, юнит-тестами нужно проверять не столько логику, сколько количество полученных параметров и даже наличие вызываемой функции впринципе (возможно вы все переименовали, но до сих пор где-то сохранился код, вызывающий старые, несуществующие функции).&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Юнит-тесты на ClojureScript – это, пока что, пичалька. ClojureScript – инструмент молодой, развивающийся. На сегодняшнем этапе нет устоявшейся практики правильного написания юнит-тестов. Местами можно наткнуться на использование библиотеки PhantomJS. Но, признаюсь честно, мне не удалось найти толкового руководство по тому, как её завести. Да и у самого ничего не получилось. Поэтому, в моих проектах юнит-тесты ClojureScript достаточно кустарные.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Завершить обзор хотелось бы на приятной ноте. В 2012-м году вышли еще две очень классные книжки по Clojure.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Очень полезная и практическая книжка Clojure Programming. Помимо самого языка, в ней есть обзор основных популярных библиотек и практик разработки на Clojure.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://akamaicovers.oreilly.com/images/0636920013754/cat.gif&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://akamaicovers.oreilly.com/images/0636920013754/cat.gif&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}A:link {}--&gt;&lt;/style&gt;  &lt;div style=&quot;margin-bottom:0in;&quot;&gt;И вторая, но единственная в своем роде, – ClojureScript: up and running. В ней всего 116 страницы, тянет на крупный туториал. Зато все по делу, без воды. Подробно рассказано, как завести ClojureScript и как разрабатывать на нем приложения.&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://akamaicovers.oreilly.com/images/0636920025139/cat.gif&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://akamaicovers.oreilly.com/images/0636920025139/cat.gif&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-168173281595501220</guid>
         <pubDate>Sun, 06 Jan 2013 17:14:00 +0000</pubDate>
      </item>
      <item>
         <title>Clojure пропаганда</title>
         <link>http://my-clojure.blogspot.com/2012/12/clojure.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Недавно предложил директору фирмы, где с недавних пор работаю, использовать Clojure для новых проектов. Не целиком, конечно, писать весь проект на Clojure (у нас на такой радикальный шаг еще не готовы). Но хотя бы часть функционала, например -- бизнес-логику.&lt;br /&gt;А для того, чтобы убедить директора, что Clojure кое-в-чем лучше Java, я написал небольшой &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://docs.google.com/document/d/1WWiUEhIfumv_RQfBFZBvIDriUY1hd1NREh698oq-7hY/edit&quot;&gt;документ&lt;/a&gt; для сравнения плюсов и минусов от применения кложуры. Возможно, пригодится и вам.&lt;br /&gt;Если есть идеи, что можно добавить или исправить, -- прошу в комменты.&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-9082448238405269360</guid>
         <pubDate>Thu, 27 Dec 2012 23:00:00 +0000</pubDate>
      </item>
      <item>
         <title>Emacs Lisp Tutorial</title>
         <link>http://my-clojure.blogspot.com/2012/09/emacs-lisp-tutorial.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Недавно один товарищ опубликовал &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://cjohansen.no/an-introduction-to-elisp&quot;&gt;учебник&lt;/a&gt; по Emacs Lisp-у. Неплохой, надо сказать, туториал, жаль что на английском. Что-то похожее мы написали с Алексом Оттом почти год назад. Наш учебник по Emacs Lisp-у можно найти &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://docs.google.com/open?id=0BzmL7xzGeOtOOWE1ZTc3NzAtZjkyNy00ZDU5LTg2Y2UtZDc4MmNkNTI1ZmJl&quot;&gt;здесь&lt;/a&gt;.&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-4813197144774186737</guid>
         <pubDate>Mon, 17 Sep 2012 11:33:00 +0000</pubDate>
      </item>
      <item>
         <title>Swank Clojure заброшен, да здравствует nrepl.el!</title>
         <link>http://my-clojure.blogspot.com/2012/08/swank-clojure-nreplel.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;На днях главный мейнтейнер swank-clojure Фил Хагельберг &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://groups.google.com/forum/?fromgroups=&amp;amp;hl=ru#%21topic/clojure/xzvI_kCaeNI&quot;&gt;объявил&lt;/a&gt; о прекращении этого проекта. Вместо поддержки этого устаревшего проекта он объединяется с разработчиками &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/kingtim/nrepl.el&quot;&gt;nrepl.el&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Обычно такие новости не приносят ничего хорошего, т.к. нужно обновлять зависимости, пытаться запустить новую библиотеку, пройтись по полю с граблями. Но не в этот раз. Просто установив nrepl.el через пакетный менеджер емакса и запустив команду nrepl-jack-in (вместо ставшей уже привычной clojure-jack-in), оказалось, что я получил практически такой же REPL с теми же самыми keybinding-ами.&lt;br /&gt;&lt;br /&gt;Вообще, на мой взгляд, в последний год в развитии Clojure наметился очень позитивный тренд: заявленные возможности, библиотеки и инструменты работают с полпинка, безо всякой магии. Интересно, встанет ли Clojure в один ряд с таким мейнстримными языками, как ruby или python? Все-таки, инфраструктура Clojure уже довольно хороша и даже относительно user-friendly.&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-1573717508276700310</guid>
         <pubDate>Fri, 24 Aug 2012 13:14:00 +0000</pubDate>
      </item>
      <item>
         <title>Как я провел лето</title>
         <link>http://my-clojure.blogspot.com/2012/08/blog-post.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Ну, не все лето, конечно, а отпуск. В отпуске мне удалось посвятить много времени любимым занятиям: изучению новых технологий и программированию. Наибольшее количество времени я посвятил ClojureScript, а результатом его изучения стало небольшое приложение учета посещений в танцевальном клубе (или фитнесс-клубе).&lt;br /&gt;&lt;br /&gt;Вот как выглядит интерфейс этого приложения:&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://4.bp.blogspot.com/-yTU2sui1cGo/UCT4ZXAM7tI/AAAAAAAAANU/1uIoHOM5Fng/s1600/01.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;464&quot; src=&quot;http://4.bp.blogspot.com/-yTU2sui1cGo/UCT4ZXAM7tI/AAAAAAAAANU/1uIoHOM5Fng/s640/01.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;text-align:center;&quot;&gt;Рис.1 Список абонементов&lt;/div&gt;&lt;div style=&quot;text-align:center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://1.bp.blogspot.com/-O3ch_Shi_Gc/UCT4moUQI_I/AAAAAAAAANc/rScxCgybuX0/s1600/02.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;464&quot; src=&quot;http://1.bp.blogspot.com/-O3ch_Shi_Gc/UCT4moUQI_I/AAAAAAAAANc/rScxCgybuX0/s640/02.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;text-align:center;&quot;&gt;Рис. 2 Детали абонемента&lt;/div&gt;&lt;div style=&quot;text-align:center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://1.bp.blogspot.com/-Zhy1NPBzuX8/UCT4v2OXDxI/AAAAAAAAANk/oN10dLpkMEM/s1600/03.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;464&quot; src=&quot;http://1.bp.blogspot.com/-Zhy1NPBzuX8/UCT4v2OXDxI/AAAAAAAAANk/oN10dLpkMEM/s640/03.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;text-align:center;&quot;&gt;Рис. 3 Выбран абонемент Чебурашки&lt;/div&gt;&lt;div style=&quot;text-align:center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://3.bp.blogspot.com/-_MHcOe6atYA/UCT47lVSwdI/AAAAAAAAANs/IkHwBETKdLE/s1600/04.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;464&quot; src=&quot;http://3.bp.blogspot.com/-_MHcOe6atYA/UCT47lVSwdI/AAAAAAAAANs/IkHwBETKdLE/s640/04.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;text-align:center;&quot;&gt;Рис. 4 Отчет по оплатам за месяц&lt;/div&gt;&lt;div style=&quot;text-align:center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;На данный момент приложение задеплоено по адресу: http://clubmanager1.com:8080/login . Логин и пароль такие: demo, demo123. (Оперу и IE ниже 9 не подериживаю)&lt;/div&gt;&lt;div style=&quot;text-align:center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;Как видите, приложение -- достаточно простое, чтобы его можно было не сильно напрягаясь написать за отпуск. Но и достаточно большое, чтобы опробовать ClojureScript на деле.&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;Я использовал следующие библиотеки:&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;[org.clojure/clojure &quot;1.4.0&quot;]&lt;br /&gt;[noir &quot;1.3.0-beta10&quot;]&lt;br /&gt;[com.mysql/connectorj &quot;5.1.12&quot;]&lt;br /&gt;[korma &quot;0.3.0-beta11&quot;]&lt;br /&gt;[cheshire &quot;4.0.1&quot;]&lt;br /&gt;[enlive &quot;1.0.1&quot;]&lt;br /&gt;[enfocus &quot;0.9.1-SNAPSHOT&quot;]&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;Изначально, для передачи данных из броузера на сервер я использовал JSON, вот почему здесь есть cheshire. Но через некоторое время (и после мощнейшего фейс-палма) обнаружил работающий ридер в ClojureScript, так что оставшиеся данные я передавал уже безо всякого json-а, прямо в виде списков, векторов и мапов Clojure.&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;Для отрисовки шаблонов изначально использовал Enlive. На клиентской стороне -- порт Enlive-а на ClojureScript, который называется Enfocus.&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align:left;&quot;&gt;В общем и целом -- впечатления очень положительные. Серьезных технологических затыков или багов нигде не обнаружил. Правда Enfocus сейчас активно обновляется до версии 1.0.0-SNAPSHOT, но этот снапшот глючный. Автор enfocus-а срочно правит баги, так что скоро увидим и стабильную версию. Версия Enfocus 0.9.1 -- достаточно стабильна и очень похожа на Enlive.&lt;/div&gt;&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-7138156286495413829</guid>
         <pubDate>Fri, 10 Aug 2012 15:17:00 +0000</pubDate>
         <media:thumbnail height="72" url="http://4.bp.blogspot.com/-yTU2sui1cGo/UCT4ZXAM7tI/AAAAAAAAANU/1uIoHOM5Fng/s72-c/01.png" width="72" xmlns:media="http://search.yahoo.com/mrss/"/>
      </item>
      <item>
         <title>MIT 6.001 читали не тем студентам...</title>
         <link>http://my-clojure.blogspot.com/2012/07/mit-6001.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Интереснейшее &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.quora.com/What-is-the-difference-between-MITs-new-6-01-course-based-on-Python-and-the-previous-6-001-course-based-on-Scheme&quot;&gt;обсуждение&lt;/a&gt; нашел по поводу замены 6.001 на 6.01 в MIT, связанный с отказом от Scheme и переходом на Python. Оказывается, дело не в устаревании курса, такое устареть не может. И не в запредельной хардкороности материала. Все банально и обидно: курс читали электронщикам, которые интересовались больше как построить роботов, нежели красивое и надежное ПО. В новом курсе 6.01, где уже используется Python, материал во многом излагается через применение программирования в робототехнике, что, конечно же, больше подходит для электронщиков.&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-1340780053595238923</guid>
         <pubDate>Fri, 13 Jul 2012 11:57:00 +0000</pubDate>
      </item>
      <item>
         <title>emacs-template.el</title>
         <link>http://my-clojure.blogspot.com/2012/06/emacs-templateel.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;На днях запилил для себя &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/dbushenko/emacs-template&quot;&gt;движок темплейтов&lt;/a&gt; для emacs lisp-а в стиле &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://mustache.github.com/&quot;&gt;Mustache&lt;/a&gt;. Использую его для генерации java-кода. Может кому еще пригодится, так что опубликовал его на GitHub.&lt;br /&gt;&lt;br /&gt;Велосипед решил пилить потому что CEDET/SRecode оказался для меня слишком сложным в освоении и использовании.&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-4777700927593861040</guid>
         <pubDate>Wed, 20 Jun 2012 14:21:00 +0000</pubDate>
      </item>
      <item>
         <title>Мой DSL для проектов на Android</title>
         <link>http://my-clojure.blogspot.com/2012/06/dsl-android.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;          &lt;/style&gt;&lt;br /&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Пару месяцев назад перепала мне задачка пилить в одиночку довольно объемный проект на Android. Сам по себе проект был несложный, но количество повторяющегося кода зашкаливало. При том самое обидное, что стандартными средствами как-то избавиться от повторений не представляется возможным. Тогда я и наваял первоначальную версию небольшой &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/dbushenko/adsl&quot;&gt;генерилки андроид-кода&lt;/a&gt;.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Больше всего, конечно, в андроиде меня раздражает xml. Логично, что формочки лучше описывать в декларативном стиле; понятно, что java для этого не годится; разумеется, xml  здесь уместен. Но, блин, как же отстойно все это выглядит! Элементарного цикла в нем не сделать, а уж про реюзабельность вообще молчу. Она там, конечно, есть в виде подключаемых пользовательских компонентов. Но все эти механизмы страшно сосут даже по сравнению с инструментами разработки под iPhone!&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Самое главное, чего я хотел добиться созданием своего DSL, – это избавиться от богомерзкого xml. Я &lt;span lang=&quot;ru-RU&quot;&gt;хотел&lt;/span&gt; описывать UI в декларативном стиле на языке общего назначения. Оказалось, что на Clojure – это очень даже просто, достаточно воспользоваться библиотекой hiccup.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Например, вместо этого &lt;/div&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;&amp;lt;&lt;/span&gt;Button android&lt;span style=&quot;color:purple;&quot;&gt;:&lt;/span&gt;id&lt;span style=&quot;color:#808030;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#0000e6;&quot;&gt;@+id/helloWorldBtn&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt; &lt;br /&gt;&lt;span style=&quot;color:#e34adc;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:&lt;/span&gt;background&lt;span style=&quot;color:#808030;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#0000e6;&quot;&gt;@drawable/blue_button_slt&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt;    &lt;br /&gt;&lt;span style=&quot;color:#e34adc;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:&lt;/span&gt;layout_height&lt;span style=&quot;color:#808030;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#0000e6;&quot;&gt;wrap_content&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#e34adc;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:&lt;/span&gt;layout_width&lt;span style=&quot;color:#808030;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#0000e6;&quot;&gt;wrap_content&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#e34adc;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:&lt;/span&gt;text&lt;span style=&quot;color:#808030;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#0000e6;&quot;&gt;Push me!&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#e34adc;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:&lt;/span&gt;textColor&lt;span style=&quot;color:#808030;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#0000e6;&quot;&gt;#fff&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#e34adc;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:&lt;/span&gt;textSize&lt;span style=&quot;color:#808030;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#0000e6;&quot;&gt;10dp&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#e34adc;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:&lt;/span&gt;textStyle&lt;span style=&quot;color:#808030;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#0000e6;&quot;&gt;bold&lt;/span&gt;&lt;span style=&quot;color:maroon;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;          &lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;писать такой код: &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;          &lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;/div&gt;&lt;br /&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;Button&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;helloWorldBtn&quot;&lt;/span&gt; wc wc&lt;br /&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:text&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;Push me!&quot;&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#400000;&quot;&gt;:textColor&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;#fff&quot;&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#400000;&quot;&gt;:textSize&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;10dp&quot;&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#400000;&quot;&gt;:textStyle&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;bold&quot;&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#400000;&quot;&gt;:background&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;drawable&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;blue_button_slt&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;На данном этапе выигрыша в коде почти никакого нет. Зато уже можно сделать, например, так:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;defn&lt;/span&gt; large-button &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;id attributes image &lt;span style=&quot;color:#808030;&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt; txt&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;VLayout&lt;/span&gt; &lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt; wc wc &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;conj&lt;/span&gt; attributes &lt;span style=&quot;color:#400000;&quot;&gt;:gravity&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;center&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;           &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;ImageButton&lt;/span&gt; id &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;60dp&quot;&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;70dp&quot;&lt;/span&gt;&lt;br /&gt;                        &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:background&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;drawable&lt;/span&gt; image&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;           &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;if-not&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;empty?&lt;/span&gt; txt&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;             &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;TextView&lt;/span&gt; &lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;125dp&quot;&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;18dp&quot;&lt;/span&gt; &lt;br /&gt;                        &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:text&lt;/span&gt; txt&lt;br /&gt;                         &lt;span style=&quot;color:#400000;&quot;&gt;:textSize&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;16dp&quot;&lt;/span&gt;&lt;br /&gt;                         &lt;span style=&quot;color:#400000;&quot;&gt;:gravity&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;center&quot;&lt;/span&gt;&lt;br /&gt;                         &lt;span style=&quot;color:#400000;&quot;&gt;:textColor&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;#0096c1&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;          &lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Как видите, введение языка общего назначения вместо xml позволяет легко создавать функции. Напротив, создание реюзабельного компонента под андроид – процедура более долгая и трудоемкая. Еще очень удобно использовать if-ы, loop-ы и прочие возможности языка. Кроме того, код на Clojure писать проще, ведь можно заранее задать для компонентов сокращенные варианты атрибутов либо рациональные настройки. Например, в приведенном выше исходнике wc означает &quot;wrap_content&quot;.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Кроме генерации xml на основе приведенного выше примере, можно сгенерировать и код на java. Это позволит автоматизировать многие, часто повторяемые операции.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Рассмотрим пример формы с текстовой строкой и двумя кнопками.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;defn&lt;/span&gt; layout &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;html&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;VLayoutFP&lt;/span&gt; &lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:background&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;drawable&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;home_bgr&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;HLayoutFP&lt;/span&gt; &lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;     &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;VLayoutFP&lt;/span&gt; &lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;      &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;TextView&lt;/span&gt; &lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt; wc wc &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:text&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;Demo text&quot;&lt;/span&gt;&lt;br /&gt;                 &lt;span style=&quot;color:#400000;&quot;&gt;:textColor&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;#09bbaa&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;Button&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;helloWorldBtn&quot;&lt;/span&gt; wc wc &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:text&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;Push me!&quot;&lt;/span&gt;&lt;br /&gt;                       &lt;span style=&quot;color:#400000;&quot;&gt;:textColor&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;#fff&quot;&lt;/span&gt;&lt;br /&gt;                       &lt;span style=&quot;color:#400000;&quot;&gt;:textSize&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;10dp&quot;&lt;/span&gt;&lt;br /&gt;                       &lt;span style=&quot;color:#400000;&quot;&gt;:textStyle&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;bold&quot;&lt;/span&gt;&lt;br /&gt;                       &lt;span style=&quot;color:#400000;&quot;&gt;:background&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;drawable&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;blue_button_slt&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;                       &lt;span style=&quot;color:#400000;&quot;&gt;:code&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;-&amp;gt;java&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;                             &lt;span style=&quot;color:#808030;&quot;&gt;   (&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:String&lt;/span&gt; hello &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;                                &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;def&lt;/span&gt; world &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;world&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;                                &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;System.out.println&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;+&lt;/span&gt; hello &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot; &quot;&lt;/span&gt; world&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;Button&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;demoBtn&quot;&lt;/span&gt; wc wc &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:text&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;Push me!&quot;&lt;/span&gt;&lt;br /&gt;                     &lt;span style=&quot;color:#400000;&quot;&gt;:textColor&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;#fff&quot;&lt;/span&gt;&lt;br /&gt;                     &lt;span style=&quot;color:#400000;&quot;&gt;:textSize&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;10dp&quot;&lt;/span&gt;&lt;br /&gt;                     &lt;span style=&quot;color:#400000;&quot;&gt;:textStyle&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;bold&quot;&lt;/span&gt;&lt;br /&gt;                     &lt;span style=&quot;color:#400000;&quot;&gt;:background&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;drawable&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;blue_button_slt&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;                     &lt;span style=&quot;color:#400000;&quot;&gt;:code&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;-&amp;gt;java&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;background:none repeat scroll 0% 0% rgb(255, 255, 255);color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;                              (&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;startActivity&lt;/span&gt;&lt;br /&gt;                                &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;new&lt;/span&gt; android&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;content&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;Intent this OrderScreen&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;class&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;generate-activity&lt;/span&gt; layout &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;com.adsl.demo&quot;&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;MyDemoActivity&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&amp;nbsp;          &lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Будет создана связка файлов MVC. Генерятся классы MyDemoActivityModel, MyDemoActivityView, MyDemoActivityController и связываются таким образом, что они сразу готовы к использованию как единая сущность. Будет создана заготовка метода, который вызывается во вьюхе при изменении модели.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;public&lt;/span&gt; void update(Observable modelObj, Object arg) &lt;span style=&quot;color:purple;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    initialize&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:purple;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    MyDemoActivityModel model &lt;span style=&quot;color:#808030;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;MyDemoActivityModel&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;modelObj&lt;span style=&quot;color:purple;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:purple;&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&amp;nbsp;          &lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;В классе MyDemoActivityView будут созданы атрибуты:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;private&lt;/span&gt; Button _helloWorldBtn&lt;span style=&quot;color:#808030;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;private&lt;/span&gt; Button _demoBtn&lt;span style=&quot;color:#808030;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt; &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;          &lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Позже они инициализируются таким образом:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;_helloWorldBtn = (Button) findViewById(R.id.helloWorldBtn)&lt;span style=&quot;color:#808030;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;_demoBtn = (Button) findViewById(R.id.demoBtn)&lt;span style=&quot;color:#808030;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;          &lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;br /&gt;Кнопкам назначается листенер, который вызывает соответствующий метод контроллера:&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;View.OnClickListener listener = new View.OnClickListener() &lt;span style=&quot;color:purple;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style=&quot;color:#808030;&quot;&gt;@&lt;/span&gt;Override&lt;br /&gt;        &lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#bb7977;&quot;&gt;void&lt;/span&gt; onClick&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;View v&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:purple;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;v&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;equals&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;_helloWorldBtn&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:purple;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;            controller&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;helloWorldBtnActionPerformed&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;MyDemoActivityView&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:purple;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:purple;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:purple;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;v&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;equals&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;_demoBtn&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:purple;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;            controller&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;demoBtnActionPerformed&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;MyDemoActivityView&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:purple;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:purple;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:purple;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span style=&quot;color:purple;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span style=&quot;color:purple;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;_helloWorldBtn.setOnClickListener(listener)&lt;span style=&quot;color:#808030;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;_demoBtn.setOnClickListener(listener)&lt;span style=&quot;color:#808030;&quot;&gt;;&lt;/span&gt; &lt;/pre&gt;&amp;nbsp;          &lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;br /&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Еще одна забавная штука, которую я добавил скорее по приколу, – это компиляция из моего псевдо-лиспа в java. Кнопке можно задать атрибут :code и прописать туда такое выражение:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;-&amp;gt;java&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;         &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:String&lt;/span&gt; hello &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;                  &lt;span style=&quot;color:dimgrey;&quot;&gt;; Объявить стринговую переменную&lt;/span&gt;&lt;br /&gt;         &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;def&lt;/span&gt; world &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;world&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;                           &lt;span style=&quot;color:dimgrey;&quot;&gt;; Объявить нетипизированную переменную&lt;/span&gt;&lt;br /&gt;         &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;System.out.println&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;+&lt;/span&gt; hello &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot; &quot;&lt;/span&gt; world&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;   &lt;span style=&quot;color:dimgrey;&quot;&gt;; Вызвать функцию с параметрами&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt; &lt;/div&gt;&lt;br /&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;          &lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Генератор преобразует эти выражения в java-код и вставит его в тело метода:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;public&lt;/span&gt; void helloWorldBtnActionPerformed(MyDemoActivityView view) &lt;span style=&quot;color:purple;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#bb7977;font-weight:bold;&quot;&gt;String&lt;/span&gt; hello &lt;span style=&quot;color:#808030;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;span style=&quot;color:purple;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#bb7977;font-weight:bold;&quot;&gt;Object&lt;/span&gt; world &lt;span style=&quot;color:#808030;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;world&quot;&lt;/span&gt;&lt;span style=&quot;color:purple;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#bb7977;font-weight:bold;&quot;&gt;System&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;out&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;println&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;hello &lt;span style=&quot;color:#808030;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;+&lt;/span&gt; world&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:purple;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:purple;&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;background:none repeat scroll 0% 0% rgb(255, 255, 255);color:black;&quot;&gt;&lt;span style=&quot;color:purple;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt; &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;          &lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Вообще, такой транслятор с псевдо-лиспа в java мне понадобился в основном затем, чтобы можно было по нажатию кнопки сделать простую инициализацию объекта либо показать другой активити.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Например:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;-&amp;gt;java&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;startActivity&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;new&lt;/span&gt; android&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;content&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;Intent this OrderScreen&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;class&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;background:none repeat scroll 0% 0% rgb(255, 255, 255);color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;          &lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;На выходе будет:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;public&lt;/span&gt; void demoBtnActionPerformed(MyDemoActivityView view) &lt;span style=&quot;color:purple;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;       startActivity&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;new&lt;/span&gt; android&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;content&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;Intent&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;,&lt;/span&gt; OrderScreen&lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt;class&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:purple;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:purple;&quot;&gt;}&lt;/span&gt; &lt;/pre&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;br /&gt;Сам транслятор содержится в файле clj2java.clj, а главная функция выглядит так: &lt;br /&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;defn&lt;/span&gt; process&lt;br /&gt;  &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;[data&lt;/span&gt; raw-code&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;     &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;code &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;enrich-with-data&lt;/span&gt; data raw-code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;list?&lt;/span&gt; code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;         &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;elem1 &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;first&lt;/span&gt; code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;           &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;cond&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;=&lt;/span&gt; elem1 &lt;span style=&quot;color:purple;&quot;&gt;'def&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;process-definition&lt;/span&gt; code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;=&lt;/span&gt; elem1 &lt;span style=&quot;color:purple;&quot;&gt;'defn&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;process-func-definition&lt;/span&gt; code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;=&lt;/span&gt; elem1 &lt;span style=&quot;color:purple;&quot;&gt;'do&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;process-command-sequence&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;next&lt;/span&gt; code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;=&lt;/span&gt; elem1 &lt;span style=&quot;color:purple;&quot;&gt;'set&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;process-assignment&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;next&lt;/span&gt; code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;=&lt;/span&gt; elem1 &lt;span style=&quot;color:purple;&quot;&gt;'if&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;process-if&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;next&lt;/span&gt; code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;=&lt;/span&gt; elem1 &lt;span style=&quot;color:purple;&quot;&gt;'return&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;process-return&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;next&lt;/span&gt; code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;=&lt;/span&gt; elem1 &lt;span style=&quot;color:purple;&quot;&gt;'-&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;process-method-call&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;next&lt;/span&gt; code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;=&lt;/span&gt; elem1 &lt;span style=&quot;color:purple;&quot;&gt;'lambda-interface&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;process-lambda-interface&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;=&lt;/span&gt; elem1 &lt;span style=&quot;color:purple;&quot;&gt;'lambda&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;process-lambda&lt;/span&gt; code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;=&lt;/span&gt; elem1 &lt;span style=&quot;color:purple;&quot;&gt;'call&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;process-call&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;next&lt;/span&gt; code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;=&lt;/span&gt; elem1 &lt;span style=&quot;color:purple;&quot;&gt;'loop&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;process-loop&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;next&lt;/span&gt; code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;=&lt;/span&gt; elem1 &lt;span style=&quot;color:purple;&quot;&gt;'new&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;process-new&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;next&lt;/span&gt; code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#400000;&quot;&gt;:else&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;process-function-call&lt;/span&gt; code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;         &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;process-single-value&lt;/span&gt; code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;[raw-code]&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;process&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;}&lt;/span&gt; raw-code&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;background:none repeat scroll 0% 0% rgb(255, 255, 255);color:black;&quot;&gt;&lt;/pre&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Как видите, транслятор умеет не так уж и мало и позволяет писать более краткий, по сравнению с java, код.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Сам же язык описания интерфейсов построен с применением барьеров абстракции, как об этом рассказывается в SICP и On Lisp. Весь код содержится в файле util.clj.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;На нижнем уровне абстракции находятся различные служебные функции и ядро всех будущих компонентов – функция виджет: &lt;/div&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;&lt;pre style=&quot;background:none repeat scroll 0% 0% rgb(255, 255, 255);color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;defn&lt;/span&gt; widget &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;type id width height params-raw &lt;span style=&quot;color:#808030;&quot;&gt;&amp;amp;&lt;/span&gt; more&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;br /&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Все прочие виджеты создаются на основе этой функции, например, так:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;defn&lt;/span&gt; Button &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;id width height &lt;span style=&quot;color:#808030;&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;params&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;widget&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;Button&quot;&lt;/span&gt; id width height &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;apply&lt;/span&gt; android params&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;defn&lt;/span&gt; HLayoutWC &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;id &lt;span style=&quot;color:#808030;&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;params &lt;span style=&quot;color:#808030;&quot;&gt;&amp;amp;&lt;/span&gt; more&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;widget&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;LinearLayout&quot;&lt;/span&gt; id &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;wrap_content&quot;&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;wrap_content&quot;&lt;/span&gt; &lt;br /&gt;          &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;merge&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;xmlns:android&quot;&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;http://schemas.android.com/apk/res/android&quot;&lt;/span&gt;&lt;br /&gt;                  &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;andr-attr&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;orientation&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;horizontal&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;                 &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;apply&lt;/span&gt; android params&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;          more&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;background:none repeat scroll 0% 0% rgb(255, 255, 255);color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Верхний уровень абстракции – кастомные виджеты и хелперы, которые создаются на основе стандартных виджетов. Например, синяя кнопка выглядит так:&lt;span style=&quot;color:#808030;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt; &lt;/div&gt;&lt;pre style=&quot;background:none repeat scroll 0% 0% rgb(255, 255, 255);color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;defn&lt;/span&gt; BlueButton &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;id width height &lt;span style=&quot;color:#808030;&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;params&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;Button&lt;/span&gt; id width height &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;flatten&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;conj&lt;/span&gt; params &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:background&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;drawable&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;blue_button_slt&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;                                                   &lt;span style=&quot;color:#400000;&quot;&gt;:textColor&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;#fff&quot;&lt;/span&gt;&lt;br /&gt;                                                   &lt;span style=&quot;color:#400000;&quot;&gt;:textSize&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;10dp&quot;&lt;/span&gt;&lt;br /&gt;                                                   &lt;span style=&quot;color:#400000;&quot;&gt;:textStyle&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;bold&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;br /&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;А хелперы для отступа выглядят так:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;defn&lt;/span&gt; padding-top &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;top &lt;span style=&quot;color:#808030;&quot;&gt;&amp;amp;&lt;/span&gt; more&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;HLayout&lt;/span&gt; &lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt; wc wc &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:paddingTop&lt;/span&gt; top&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;           more&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;defn&lt;/span&gt; padding-left &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;left &lt;span style=&quot;color:#808030;&quot;&gt;&amp;amp;&lt;/span&gt; more&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;HLayout&lt;/span&gt; &lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt; wc wc &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:paddingLeft&lt;/span&gt; left&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;           more&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt; &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&amp;nbsp;&amp;nbsp;          &lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Саму генерилку описывать особо нет смысла, т.к. она достаточно простая.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Плюсы подхода:&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Сокращение кода  описания активити в три-четыре раза.  Чем больше и сложнее  описываемая форма  – тем больше выигрыш.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Гораздо более простой  способ создания абстракций при помощи  обыкновенных функций. В результате  значительно повышается реюзабельность  кода.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Значительно облегчается  чтение и модификация кода UI по сравнению  с использованием xml.&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Минусы:&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Сгенеренный код  выглядит, порой, написанным copy-paste-ом.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;При перегенерации  кода теряется код, написанный вручную  в сгенеренных ранее файлах.&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Вообще, я с минусами придумал бороться следующим образом. Во-первых, не лазить в сгенеренные файлы вообще. Если нужно добавить тело метода или еще какую функциональность, то нужно наследоваться от сгенеренных классов. Это избавляет от необходимости переносить вручную набитый код в новую версию нагенеренных классов. Кроме того, раз не нужно больше лазить в сгенеренные классы, то отпадает требование о красоте их кода, и автоматический copy-paste становится допустимым. Главное, чтобы его не было на уровне самого DSL.&lt;/div&gt;&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-4968201549989302511</guid>
         <pubDate>Tue, 12 Jun 2012 15:05:00 +0000</pubDate>
      </item>
      <item>
         <title>Впечатления о ClojureScript</title>
         <link>http://my-clojure.blogspot.com/2012/05/clojurescript.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;На прошлой неделе решил наконец ознакомиться с ClojureScript по-подробнее. До этого я смотрел презентацию Рича Хикки и некоторые другие скринкасты, успел &quot;пощупать&quot; ClojureScriptOne и почитать пару статей о том, как он (ClojureScript) крут. В общем, никаких особых сложностей с ним я не ожидал, поэтому начавшиеся приключения стали для меня откровенным сюрпризом.&lt;br /&gt;&lt;br /&gt;Во-первых, мне не удалось создать browser-connected repl, соединенный со своей html-иной. Я выполнял простые туториалы шаг за шагом, и на этапе соединения у меня ничего не получалось. Тогда я запустил проект samples/repl, входящий в поставку ClojureScript. И все было хорошо до тех пор, пока я не попытался соединиться с веб-страницей. В результате, при помощи Дэвида Нолена и еще нескольких разработчиков ClojureScript выяснилось, что документация чуть-чуть не соответствует. После моих гневных отзывов её (документацию) наконец поправили, а я напишу здесь русский вариант туториала о том, как начать работать с ClojureScript.&lt;br /&gt;&lt;br /&gt;1. Качаем с &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/clojure/clojurescript&quot;&gt;гитхаба&lt;/a&gt; последнюю версию ClojureScript.&lt;br /&gt;2. Настраиваем emacs:&lt;br /&gt;&amp;nbsp; a) Создаем файл browser-repl.sh с правами на выполнение:&lt;br /&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;if [ &quot;$CLOJURESCRIPT_HOME&quot; = &quot;&quot; ]; then&lt;br /&gt;&amp;nbsp; CLOJURESCRIPT_HOME=&quot;`dirname $0`/..&quot;&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;CLJSC_CP=''&lt;br /&gt;for next in lib/: lib/*: src/clj: src/cljs: test/cljs; do&lt;br /&gt;&amp;nbsp; CLJSC_CP=$CLJSC_CP$CLOJURESCRIPT_HOME'/'$next&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;java -server -cp $CLJSC_CP clojure.main -e &amp;#92;&lt;br /&gt;&quot;(require '[cljs.repl :as repl])&lt;br /&gt;(require '[cljs.repl.browser :as browser])&lt;br /&gt;(def env (browser/repl-env))&lt;br /&gt;(repl/repl env)&quot;&lt;br /&gt;&lt;br /&gt;б) Прописываем в .emacs настройки для inferior-lisp'a:&lt;br /&gt;(setq inferior-lisp-program &quot;~/clojure/clojurescript/browser-repl.sh&quot;)&lt;br /&gt;&lt;br /&gt;Здесь &quot;~/clojure/clojurescript/browser-repl.sh&quot; -- естственно, путь к созданному на шаге 2а файлу browser-repl.sh.&lt;br /&gt;&lt;br /&gt;3. Добавляем clojurescript/bin в $PATH. &lt;br /&gt;&lt;br /&gt;4. Заходим в каталог clojurescript/samples/repl, компилируем исходники: cljsc src/ &amp;gt; main.js&lt;br /&gt;&lt;br /&gt;Файл main.js будет позднее использоваться в index.html&lt;br /&gt;&lt;br /&gt;Обратите внимание на содержимое файла test.cljs. Он содержит такую строчку:&lt;br /&gt;(repl/connect &quot;http://localhost:9000/repl&quot;)&lt;br /&gt;Именно она позволяет затем соединиться с Emacs-ом.&lt;br /&gt;&lt;br /&gt;5. Файлы index.html, main.js и каталог out необходимо захостить на каком-нибудь веб-сервере. Я, например, просто создал каталог Tomcat7/webapps/my и сложил туда все это барахло. В моем случае страница index.html стала доступна по адресу localhost:8080/my/index.html.&lt;br /&gt;&lt;br /&gt;Внимание! Хостить страницу обяхательно, просто открыв её как файл с диска вы&amp;nbsp; не сможете к ней подконнектиться из Emacs-а!&lt;br /&gt;&lt;br /&gt;6. Запускаем Emacs, выполняем команду M-x inferior-lisp.&lt;br /&gt;&lt;br /&gt;7. Вводим следующие команды:&lt;br /&gt;(require '[cljs.repl :as repl])&lt;br /&gt;(require '[cljs.repl.browser :as browser])&lt;br /&gt;(def env (browser/repl-env))&lt;br /&gt;(repl/repl env)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;8. Загружаем/обновляем index.html в броузере. После этого repl в Emacs-е должен заработать. Например, вычисление (+ 1 1) должно выдать ответ 2. Если это произошло -- вуаля! у вас веб-консоль прямо в Emacs-е!&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://3.bp.blogspot.com/-qQT9BLeDkDM/T8CYs2ii6HI/AAAAAAAAAM4/PAm5KuBpA7I/s1600/clojurescript.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;473&quot; src=&quot;http://3.bp.blogspot.com/-qQT9BLeDkDM/T8CYs2ii6HI/AAAAAAAAAM4/PAm5KuBpA7I/s640/clojurescript.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;В моем примере index.html содержит следующий фрагмент:&lt;br /&gt;&lt;br /&gt;&lt;pre id=&quot;line1&quot;&gt;      &amp;lt;&lt;span class=&quot;start-tag&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;attribute-name&quot;&gt;id&lt;/span&gt;=&quot;&lt;a rel=&quot;nofollow&quot; class=&quot;attribute-value&quot; target=&quot;_blank&quot; href=&quot;http://www.blogger.com/blogger.g?blogID=4007342736133040943&quot;&gt;dates&lt;/a&gt;&quot;&amp;gt;&lt;br /&gt; &amp;lt;&lt;span class=&quot;start-tag&quot;&gt;div&lt;/span&gt;&amp;gt;23.05.2012&amp;lt;/&lt;span class=&quot;end-tag&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;br /&gt; &amp;lt;&lt;span class=&quot;start-tag&quot;&gt;div&lt;/span&gt;&amp;gt;25.05.2012&amp;lt;/&lt;span class=&quot;end-tag&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;br /&gt; &amp;lt;&lt;span class=&quot;start-tag&quot;&gt;div&lt;/span&gt;&amp;gt;27.05.2012&amp;lt;/&lt;span class=&quot;end-tag&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;br /&gt; &amp;lt;&lt;span class=&quot;start-tag&quot;&gt;div&lt;/span&gt;&amp;gt;28.05.2012&amp;lt;/&lt;span class=&quot;end-tag&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;br /&gt; &amp;lt;&lt;span class=&quot;start-tag&quot;&gt;div&lt;/span&gt;&amp;gt;29.05.2012&amp;lt;/&lt;span class=&quot;end-tag&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;/&lt;span class=&quot;end-tag&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre id=&quot;line1&quot;&gt;&amp;nbsp;&lt;/pre&gt;Таким образом, команды на скриншоте изменяют размер шрифта и цвет текста первой даты.&lt;br /&gt;&lt;br /&gt;Вообще, документация на ClojureScript достаточно бедная. Поэтому, вместо того, чтобы искать блог-посты и туториалы по использованию ClojureScript, я просто стал читать его исходники. Рекомендую для этого воспользоваться инструментом &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/fogus/marginalia&quot;&gt;Marginalia&lt;/a&gt;. С Leiningen 2 это вообще просто.&lt;br /&gt;&lt;br /&gt;1. В .lein/profiles.clj добавьте плагин lein-marginalia&lt;br /&gt;&lt;br /&gt;{:user {:plugins [ [lein-marginalia &quot;0.7.0&quot;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [lein-pprint &quot;1.1.1&quot;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [lein-swank &quot;1.4.4&quot;]]}}&lt;br /&gt;&lt;br /&gt;2. Создайте новый проект: lein new clj-docs&lt;br /&gt;3. Скопируйте в катлог cljs-docs/src содержимое каталогоа cljorescript/src.&lt;br /&gt;4. Выполните команду lein marg, и в каталоге docs будет создан файл uberdoc.html, который слева содержит комментарии к исходнику,&amp;nbsp; а справа -- сам исходник.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://2.bp.blogspot.com/-IDqzazd0N6c/T8Ca7GoMboI/AAAAAAAAANA/t7lCEJIzf2Y/s1600/doc.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;412&quot; src=&quot;http://2.bp.blogspot.com/-IDqzazd0N6c/T8Ca7GoMboI/AAAAAAAAANA/t7lCEJIzf2Y/s640/doc.png&quot; width=&quot;640&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Еще стоит ознакомиться с &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://closure-library.googlecode.com/svn/docs/index.html&quot;&gt;Google Closure API&lt;/a&gt; -- тоже полезное подспорье в работе с ClojureScript.&lt;br /&gt;&lt;br /&gt;Ну а в целом, ClojureScript мне очень понравился, и я надеюсь использовать его дальше в своих проектах.&lt;br /&gt;&lt;br /&gt;&lt;pre id=&quot;line1&quot;&gt;&lt;/pre&gt;&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-7910071235775186798</guid>
         <pubDate>Sat, 26 May 2012 11:59:00 +0000</pubDate>
         <media:thumbnail height="72" url="http://3.bp.blogspot.com/-qQT9BLeDkDM/T8CYs2ii6HI/AAAAAAAAAM4/PAm5KuBpA7I/s72-c/clojurescript.png" width="72" xmlns:media="http://search.yahoo.com/mrss/"/>
      </item>
      <item>
         <title>Гусеничный Lisp-трактор</title>
         <link>http://my-clojure.blogspot.com/2012/05/lisp.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Просматривая записи Казимира Майорника, нашел у него очень любопытную &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://kazimirmajorinc.blogspot.com/2009/04/crawler-tractor.html&quot;&gt;статью&lt;/a&gt;. Это всего лишь забавный эксперимент, показывающий, как при помощи лисповой парадигмы &quot;код-как-данные&quot; можно реализовать циклическое выполнение кода без циклов и рекурсий. Никакой практической ценности в этом нет, просто красиво смотрится. Я написал что-то похожее на Clojure, но несколько усовершенствованное. В моей версии алгоритм выглядит так.&lt;br /&gt;&lt;br /&gt;1) Список f содержит всего одну функцию. Её и запускаем первой.&lt;br /&gt;2) Первая функция передает свой код в update.&lt;br /&gt;3) Update &quot;препарирует&quot; код, находит номер текущей итерации, инкрементирует его и собирает такую же функцию, как ей передали, но с новым значением итерации.&lt;br /&gt;4) Первая функция получает вторую функцию и добавляет её в конец списка f. Если список f содержит более трех элементов, то первый элемент списка f удаляется. Таким образом, в списке f содержится не более четырех элементов.&lt;br /&gt;5) Первая функция запускает вторую функцию и завершается.&lt;br /&gt;&lt;br /&gt;Выглядит и впрямь, как гусеничный трак :-)&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;overflow:auto;&quot;&gt;&lt;pre style=&quot;background:#ffffff;color:black;&quot;&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;defn&lt;/span&gt; update &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;func&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;p &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;nth&lt;/span&gt; func &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;        &lt;span style=&quot;color:dimgrey;&quot;&gt;;; Получить список (println (str &quot;Hi for the &quot; 1 &quot; time!&quot;))&lt;/span&gt;&lt;br /&gt;        n &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;nth&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;second&lt;/span&gt; p&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;  &lt;span style=&quot;color:dimgrey;&quot;&gt;;; Получить 1 из списка&lt;/span&gt;&lt;br /&gt;        &lt;span style=&quot;color:dimgrey;&quot;&gt;;; Создать список (println (str &quot;Hi for the &quot; 2 &quot; time!&quot;))&lt;/span&gt;&lt;br /&gt;        new-p &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;cons&lt;/span&gt; &lt;span style=&quot;color:purple;&quot;&gt;'println&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;list&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;map&lt;/span&gt; #&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;=&lt;/span&gt; n &lt;span style=&quot;color:#808030;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;inc&lt;/span&gt; n&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;identity&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;second&lt;/span&gt; p&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color:dimgrey;&quot;&gt;;; Заменить в теле функции (println (str &quot;Hi for the &quot; 1 &quot; time!&quot;))&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color:dimgrey;&quot;&gt;;; на (println (str &quot;Hi for the &quot; 2 &quot; time!&quot;))&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;map&lt;/span&gt; #&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;and&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;seq?&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;first&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:purple;&quot;&gt;'println&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; new-p &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;identity&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; func&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;def&lt;/span&gt; f &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;ref&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:purple;&quot;&gt;'&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;fn&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;                &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;println&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;str&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot;Hi for the &quot;&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#0000e6;&quot;&gt;&quot; time!&quot;&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;                &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;[&lt;/span&gt;func &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;last&lt;/span&gt; @f&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;                      &lt;span style=&quot;color:dimgrey;&quot;&gt;;; Обновить список функций f&lt;/span&gt;&lt;br /&gt;                      &lt;span style=&quot;color:dimgrey;&quot;&gt;;; Удалить первую функцию, если список f содержит больше трех элементов&lt;/span&gt;&lt;br /&gt;                      new-f &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;count&lt;/span&gt; @f&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;                              &lt;span style=&quot;color:dimgrey;&quot;&gt;;; Добавить обновленную функцию в конец списка&lt;/span&gt;&lt;br /&gt;                              &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;conj&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;vec&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;drop&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; @f&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;update&lt;/span&gt; func&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt; &lt;br /&gt;                              &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;conj&lt;/span&gt; @f &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;update&lt;/span&gt; func&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;                  &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;dosync&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;ref-set&lt;/span&gt; f new-f&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;                  &lt;span style=&quot;color:dimgrey;&quot;&gt;;; Выполнить последнюю функцию списка&lt;/span&gt;&lt;br /&gt;                  &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;eval&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;last&lt;/span&gt; @f&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;eval&lt;/span&gt; &lt;span style=&quot;color:#808030;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:maroon;font-weight:bold;&quot;&gt;last&lt;/span&gt; @f&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#808030;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-5460356322053006814</guid>
         <pubDate>Tue, 08 May 2012 16:55:00 +0000</pubDate>
      </item>
      <item>
         <title>CEDET 1.1, Emacs и Java</title>
         <link>http://my-clojure.blogspot.com/2012/05/cedet-11-emacs-java.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;&lt;br /&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Недавно вышедший Cedet 1.1 добавляет долгожданную поддержку импорта символов из jar-ок. Теперь Emacs предоставляет поддержку автодополнения кода java примерно на том же уровне, что и современные IDE.  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Например, у нас есть класс My1:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://3.bp.blogspot.com/-m9Mdc8sb6F4/T6e48hCSKvI/AAAAAAAAAME/AiG7XTvUAag/s1600/0.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://3.bp.blogspot.com/-m9Mdc8sb6F4/T6e48hCSKvI/AAAAAAAAAME/AiG7XTvUAag/s1600/0.png&quot;/&gt;&amp;nbsp;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Он используется в My2:&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://2.bp.blogspot.com/-J5nWvEQFs-Y/T6e5DJpHbPI/AAAAAAAAAMM/7c7joWq7dz0/s1600/1.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://2.bp.blogspot.com/-J5nWvEQFs-Y/T6e5DJpHbPI/AAAAAAAAAMM/7c7joWq7dz0/s1600/1.png&quot;/&gt;&amp;nbsp;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Обратите внимание, как flymake параллельно скомпилировал файл и подсветил ошибки. Если набрать “my.” и выполнить функцию semantic-ia-complete-symbol-menu (у меня она замаплена на Ctrl-Space), то Emacs выдаст такую подсказку:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://4.bp.blogspot.com/-N3FZltjj6s0/T6e5KQjC8oI/AAAAAAAAAMU/40aSSsboFCE/s1600/2.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/-N3FZltjj6s0/T6e5KQjC8oI/AAAAAAAAAMU/40aSSsboFCE/s1600/2.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Аналогично можно запрашивать подсказку по членам системных классов. Например, для StringBuilder:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://2.bp.blogspot.com/-eOZw9DGvgrI/T6e5TUCA41I/AAAAAAAAAMc/3SFjnqY4OWc/s1600/3.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://2.bp.blogspot.com/-eOZw9DGvgrI/T6e5TUCA41I/AAAAAAAAAMc/3SFjnqY4OWc/s1600/3.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:0.79in;}P {margin-bottom:0.08in;}--&gt;&lt;/style&gt;  &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Правда надо учитывать, что, во-первых, импорты “звёздочкой” не срабатывают, системных классов semanticdb-javap тоже не знает. Поэтому, если необходимы подсказки, то импорт классов из неймспейса java.lang нужно делать явно, как в моем примере.&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Для того, чтобы заработали показанные выше механизмы, необходимо следующее:&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;установленный пакет  flymake;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;установленный пакет  auto-complete;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;скачанный CEDET 1.1;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Ну и конечно же,  последний Emacs и java.&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Конфигурация CEDET в .emacs :&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;(load-file &quot;~/cedet/common/cedet.el&quot;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;           ;; Подгрузить cedet&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;(global-semanticdb-minor-mode 1) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;   ;; Инициализировать semanticdb&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;;; Загрузить поддержку авто-дополнения &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;(semantic-load-enable-gaudy-code-helpers) &lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;(custom-set-variables &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ;; Инициализация переменных, указывающих, где&amp;nbsp;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;; установлена java&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;. . .&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;'(cedet-java-jdk-root &quot;/opt/jdk&quot;)&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&amp;nbsp;;; Сюда нужно добавить все jar-ки, из&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&amp;nbsp;;; которых необходимо импортировать символы&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;'(semanticdb-javap-classpath '(&quot;/opt/jdk/jre/lib/rt.jar&quot;))&lt;/div&gt;. . . &lt;br /&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;)&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Конфигурация flymake:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;(require 'flymake)&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;(add-hook 'java-mode-hook 'flymake-mode-on)&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;(defun my-java-flymake-init ()&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;(list &quot;javac&quot; (list (flymake-init-create-temp-buffer-copy&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;'flymake-create-temp-with-folder-structure))))&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;(add-to-list 'flymake-allowed-file-name-masks '(&quot;&amp;#92;&amp;#92;.java$&quot; my-java-flymake-init flymake-simple-cleanup))&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;Конфигурация auto-complete:&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;(require 'auto-complete-config)&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;(add-to-list 'ac-dictionary-directories &quot;~/.emacs.d/ac-dict&quot;)&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;(ac-config-default)&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom:0in;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-2686848577588213909</guid>
         <pubDate>Mon, 07 May 2012 15:03:00 +0000</pubDate>
         <media:thumbnail height="72" url="http://3.bp.blogspot.com/-m9Mdc8sb6F4/T6e48hCSKvI/AAAAAAAAAME/AiG7XTvUAag/s72-c/0.png" width="72" xmlns:media="http://search.yahoo.com/mrss/"/>
      </item>
      <item>
         <title>Итоги за месяц</title>
         <link>http://my-clojure.blogspot.com/2012/03/blog-post.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Давно не писал сюда из-за нехватки времени. Но вот, наконец, я достаточно освободился, чтобы набросать пару строк в блог.&lt;br /&gt;&lt;br /&gt;Со времени последней записи у меня произошло много интересных событий, и многое можно было бы описать здесь, т.к. почти все так или иначе связано с Clojure. Наиболее интересное, на мой взгляд, -- это первое в моей практике применение Clojure на коммерческом проекте. О нем вкратце и расскажу.&lt;br /&gt;&lt;br /&gt;Проект, который я делал с начала февраля по середину марта, -- андроид-приложение для планшетов. Оно предназначалось для дистанционного обучения какой-то фигне сотрудников какой-то компании. Технических сложностей там никаких нету, писать здесь не о чем, за исключением достаточного большого объема работы: необходимо было реализовать 22 формы со всякими разными украшениями. Дополнительная сложность -- необходимо написать еще и JSON веб-сервис, который может отдавать запрашиваемые данные и сохранять у себя ответы пользователей на опросы и тесты.&lt;br /&gt;&lt;br /&gt;Дедлайн был очень жесткий: 12 марта. На мой взгляд, при таких объемах и сроках проект должен делать не один человек, а как минимум трое.&lt;br /&gt;&lt;br /&gt;Во-первых, мне удалось уговорить заказчика разрешить писать веб-сервис на Clojure вместо java. По моим прикидкам, это сэкономило бы мне неделю работы. Для заказчика были крайне важны сроки, и он позитивно воспринял мое предложение, но поинтересовался: какие минусы у clojure? Я честно сказал, что этот язык просто менее распространен, чем java. Все остальное -- то же, что и у java. Например, готовый сервис мы захостим под Tomcat в виде war-файла. Заказчик согласился с этим риском, заметив, что если вдальнейшем будет необходимость, то тогда вебсервис можно будет переделать на java. Забегая вперед скажу, что необходимость не возникла :-)&lt;br /&gt;&lt;br /&gt;Я воспользовался библиотеками noir1.3-alpha10, cheshire, sqlkorma, lobos и очень быстро показал работающий сервак. Функциональность в сервак я добавлял в процессе работы над клиентской частью по мере необходимости. Поскольку я пользовался связкой Emacs+Slime, рабочий код я получал очень быстро. А время, которое я тратил на разработку очередной функции сервака, в среднем равнялось нескольким минутам. &lt;br /&gt;&lt;br /&gt;Основное время, конечно же, занимала Android-часть, причем в основном -- настройка внешнего вида формочек. Android -- неплохая платформа для пользователя, но очень сырая и недоделанная для разработчика. В отличие от ябловодов, нам, андроидам, нет возможности пользоваться WYSIWYG-редактором для построения GUI. А редактировать гигантские простыни xml-кода вручную -- сомнительное удовольствие...&lt;br /&gt;&lt;br /&gt;Решение нашлось довольно быстро. Я разработал небольшой DSL на основе Clojure и Hiccup. С применением этого DSL формочку я целиком описывал на Clojure, а потом генерил из неё связку xml и java-кода (при этом генерился весь MVC на форму). В среднем, количество кода в DSL и количесство сгенеренного xml+java кода соотносились как 1:3 или 1:4, что уже очень неплохо. Еще один важный бонус, который я получил от этого DSL -- возможность использования нормального вменяемого языка для описания UI вместо XML. Появилась возможность выносить общую функциональность в функции, делать циклы и т.д. Понятно, что большинство повторно используемых компонент оформлялись как отдельные виджеты; но там, где для этого не было необходимости -- я просто объявлял функцию на Clojure. Еще важное замечание: код в стиле Hiccup читается гораздо проще, чем xml.&lt;br /&gt;&lt;br /&gt;Дальше развивать свой DSL у меня уже не было времени, а повторяющийся код, который я не мог обобщить, все равно встречался. Например, код для работы с БД и вебсервисом состоял по большей части из извлечения-записи в хеш-таблицы по ключам, соответствующим именам полей в БД. Здесь мне на помощь пришел Emacs. Буквально пара десятков строк кода на elisp-е, и весь оставшийся boilerplate-код на java генерил Emacs.&lt;br /&gt;&lt;br /&gt;Надо сказать, что в сроки я уложился, но с учетом, что в конце проекта на 2 недели мне дали в помощь товарища. Думаю, получилось очень даже хорошо.&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-5041398139791653503</guid>
         <pubDate>Thu, 29 Mar 2012 11:59:00 +0000</pubDate>
      </item>
      <item>
         <title>Деплоймент Clojure под Tomcat</title>
         <link>http://my-clojure.blogspot.com/2012/02/clojure-tomcat.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Не так давно я взялся за небольшой проект с клиент-серверной архитектурой. JSON веб-сервис мне позволили реализовать на clojure, что я очень быстро и сделал при помощи библиотек: Noir, Lobos, Korma и Cheshire. Но зато была масса непоняток с деплойментом этого готового сервиса на хостинг. Во-первых, по непонятной причине, оригинальный сервер, поработав какое-то время, попросту отваливается. Я до сих теряюсь в догадках, что заставляет его так капризничать. Понятное дело, что я решил задеплоить всё на Tomcat. &lt;br /&gt;&lt;br /&gt;Мне не удалось нигде найти нормальной инструкции о том, как деплоить noir-приложение под томкат, так что я решил восполнить этот пробел.&lt;br /&gt;&lt;br /&gt;Данная инструкция рассчитана на веб-сайт, разработанный на clojure при помощи фреймворка Noir (опробовано на noir 1.3.0-alpha10).&lt;br /&gt;&lt;br /&gt;1) Добавьте [lein-ring &quot;0.5.4&quot;] в :dev-dependencies вашего файла project.clj.&lt;br /&gt;Внимание! [uk.org.alienscience/leiningen-war &quot;0.0.13&quot;] – это не то же самое, что lein-ring. Плагин lein-ring умеет создавать ring-handler для noir-приложения и запаковать все в war-ку. А плагин leiningen-war только создает war-ку, а ring-handler-а не создает.&lt;br /&gt;&lt;br /&gt;2) В файле project.clj укажите ваш ring-handler и пространство имен для ahead-of-time компиляции.&lt;br /&gt;:ring {:handler MyProject.server/handler} &lt;br /&gt;:aot [MyProject.server]&lt;br /&gt;&lt;br /&gt;3) Создайте ring-handler в server.clj:&lt;br /&gt;(:require [noir.server :as server])&lt;br /&gt;. . .&lt;br /&gt;(def handler (server/gen-handler {:base-url &quot;/myproject&quot;}))&lt;br /&gt;Внимание! Обязательно нужно указать :base-url, иначе редиректы и линки задеплоенного в томкат приложения будут указывать не на localhost:8080/myproject/, а на localhost:8080/ . Эпик фейл будет фееричный!&lt;br /&gt;&lt;br /&gt;4) Уберите такую загрузку вьюх: (server/load-views &quot;src/MyProject/views/&quot;) из файла server.clj. Вьюхи нужно загружать явно:&amp;nbsp;&amp;nbsp; &lt;br /&gt;(:require [noir.server :as server]&lt;br /&gt;. . .&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [MyProject.views.pages])&lt;br /&gt;Если этого не сделать, то после упаковки в war-ку и даже jar-ку, ни один ваш маршрут работать не будет.&lt;br /&gt;&lt;br /&gt;5) Все линки и формы, если вы их генерите из hiccup, нужно создавать функциями:&lt;br /&gt;(hiccup.form-helpers/form-to [:post &quot;/myurl&quot;] ...) &lt;br /&gt;(hiccup.page-helpers/link-to &quot;/myurl&quot; …)&lt;br /&gt;Если этого не сделать, то они будут вести на localhost:8080/ вместо localhost:8080/myproject.&lt;br /&gt;&lt;br /&gt;6) Создайте war-ку командой lein ring uberwar. &lt;br /&gt;Внимание! Команда lein ring uberwar поставляется с lein-ring-плагином, и в нашем случае она работает. Команда lein uberwar поставляется с плагином&amp;nbsp; leiningen-war, и здесь она не работает. Так что этот плагин вообще лучше не использовать с noir.&lt;br /&gt;&lt;br /&gt;7) Скопируйте war-ку в webapps томката и переименуйте её в myproject.war. &lt;br /&gt;&lt;br /&gt;Теперь, после запуска томката, по адреусу localhost:8080/myproject будет ваше приложение. &lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-5189313045610543915</guid>
         <pubDate>Sun, 19 Feb 2012 11:35:00 +0000</pubDate>
      </item>
      <item>
         <title>Noir benchmark</title>
         <link>http://my-clojure.blogspot.com/2012/01/noir-benchmark.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Решил немного потестить простое веб-приложение, описанное в предыдущей статье. Тесты проводились на ноутбуке Acer Aspire 5745G (Intel Core i5 2.26Ghz, 4Gb). Обнаружил следующее.&lt;br /&gt;&lt;br /&gt;Во-первых, при запуске сайта командой lein run запускаются два java-процесса. Первый, занимающий 28.8Mb -- видимо служебный, т.к. никакие его характерстики за время работы приложения не менялись. Второй, сходу запросивший 76.7Mb, -- само веб-приложение. Я создал два типа сущностей: mypage и mypage2 с CRUD-действиями для них, не используя БД. Т.е. скорость обработки запроса целиком зависила от скорости работы java-машины и не зависела от скорости ввода-вывода или поиска данных в таблицах. При обращении к различным действиям сущности mypage объем потребляемой памяти возрос до 90.3Mb. При обращении к mypage2 -- до 93.5Mb. При повторном обращении к этим же сущностям потребление памяти никак не поменялось. При перезапуске приложения цифры изменились до 96Mb и 99Mb.&lt;br /&gt;&lt;br /&gt;Интересно взглянуть на производительность веб-приложения под нагрузкой. Я создал скрипт, делающий 70000 таких запросов:&lt;br /&gt;wget http://localhost:8080/mypage&lt;br /&gt;wget http://localhost:8080/mypage/848867&lt;br /&gt;wget http://localhost:8080/mypage/edit/996283&lt;br /&gt;wget http://localhost:8080/mypage/527997&lt;br /&gt;wget http://localhost:8080/mypage/edit/410389&lt;br /&gt;&lt;br /&gt;Сущности с указанными айдишниками, естественно, существовали в приложении. Эти 70тыс. запросов jetty обработал за полчаса, отдавая, таким образом, примерно 2333 динамических страницы в минуту или примерно 39 в секунду.&lt;br /&gt;&lt;br /&gt;Самым интересным для меня в этом эксперименте стало потребление памяти и процессорного времени.&lt;br /&gt;&lt;br /&gt;Сначала jetty затребовал 92% процессорного времени, но его запросы довольно быстро сократились до 40%. Затем, довольно медленно, и они стали снижаться. К концу эксперимента jetty потреблял всего 4% процессорного времени.&lt;br /&gt;&lt;br /&gt;Аналогично, запросы памяти сначала были немалыми. Довольно быстро jetty &quot;откушал&quot; 232.8Mb, после чего потребляемая память стала уверенно снижаться, остановившись на отметке 84.6Mb.&lt;br /&gt;&lt;br /&gt;Надо еще учитывать, что нагрузка на сервер была ограничена возможностями консоли, в которой работал wget, ведь его вывод на экран тоже занимает какое-то время. Но, по крайней мере, верхнюю границу запросов процессора и памяти мы получили. Нижняя, естественно, достоверной не является.&lt;br /&gt;&lt;br /&gt;Такое снижение потребляемой памяти и процессора стало возможно благодаря run-time оптимизациям java-машины (в Sun некогда здорово над этим поработали). Вот и скажи теперь, что java -- медленная...&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-1703369417605451593</guid>
         <pubDate>Sun, 22 Jan 2012 18:01:00 +0000</pubDate>
      </item>
      <item>
         <title>CRUD на Clojure средствами Noir</title>
         <link>http://my-clojure.blogspot.com/2012/01/crud-clojure-noir.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:2cm;}P {margin-bottom:0.21cm;}A:link {color:#000080;text-decoration:underline;}--&gt;&lt;/style&gt;&lt;br /&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Давно собирался рассказать немного о Noir – классном веб-фреймворке для Clojure. Наконец, у меня появилась возможность написать большой туториал по применению Noir, что я с удовольствием и сделаю :-)&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Есть ли вообще необходимость в самоучителе по Noir? Не очень существенная, если честно. На сайте фреймворка (webnoir.org) более чем приличная документация: раздел для быстрого старта, несколько обучалок по использованию Noir и даже индекс API. Мой туториал, возможно, будет вам полезен, если вы, зная Clojure и разобравшись более-менее с Noir, все еще не очень представляете себе архитектуру своего будущего приложения.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;А задуматься над архитектурой придется. Noir очень сильно отличается от всех известных мне фреймворков. При своем минимализме он оставляет выбор конкретных библиотек за пользователем – такая свобода может привести к неверному их использованию. Насколько этот выбор широк можете судить хотя бы по &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://brehaut.net/blog/2011/ring_introduction&quot;&gt;статье&lt;/a&gt; с обзором разных компонентов для каждого из уровней веб-стека на clojure. &lt;br /&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Давайте посмотрим, на что похоже приложение Noir. Если вы проследовали инструкциям из Getting Started на сайте webnoir.org, то у вас уже установлен leiningen-плагин для Noir. Создадим новый проект командой  lein noir new optimalist. У него очень простая структура.  &lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;b&gt;resources&lt;/b&gt; – содержит каталог public со статическим контентом (css, javasript, images);&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;b&gt;src&lt;/b&gt; – каталог с исходниками;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;b&gt;test&lt;/b&gt; – тесты;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;b&gt;project&lt;/b&gt;.clj – описание проекта и версий подключаемых библиотек.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Исходники содержаться в двух каталогах &lt;b&gt;src/optimalist/views &lt;/b&gt;и&lt;b&gt; src/optimalist/models&lt;/b&gt;. Никаких вопросов не вызывает? А как насчет &lt;b&gt;src/optimalist/controllers&lt;/b&gt;? Такого каталога нету, т.&amp;nbsp;к.  самописных контроллеров здесь не предусмотрено. Это, конечно, у многих может вызвать разрыв шаблона: как вообще программировать MVC без C!  &lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Автор Noir Крис Гранжер очень подробно &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://groups.google.com/group/clj-noir/browse_thread/thread/1718a9b1312156d3/502c3c7e24f7319c?hl=ru&amp;amp;lnk=gst&amp;amp;q=controller#502c3c7e24f7319c&quot;&gt;обосновал&lt;/a&gt; свое представление архитектуры. Исторически сложилось, что бизнес-логику обычно помещали в контроллер. Но со временем её все больше и больше выносили в отдельные компоненты, контроллер стал совсем тоненьким и, откровенно говоря, ненужным. Функции маршрутизации берет на себя фреймворк, так что в Noir (да и в других современных веб-фреймворках) строгой необходимости в отдельных контроллерах попросту нету. Единственное, что всё еще делает контроллер – это указывает, какую страницу рендерить в ответ на запрос пользователя. Раз уж код контроллера такой маленький, то Крис Гранжер попросту решил перенести функции контроллера на уровень View.  &lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Если сравнивать такой подход с другими фреймворками, то, пожалуй, Крис – один из первых, кто открыто решился заявить о ненужности контроллеров. Например, в практике программирования Ruby on Rails всё еще считается правильным всю бизнес логику вынести на уровень модели, а контроллеры сделать маленькими и легковесными. Это очень упрощает тестирование. Но это половинчатый подход: выбросили бы контроллеры да и дело с концом! Скажем, в JSF2.0 примерно так и обстоят дела. Вся бизнес-логика находится в Java-бинах, вызываются они с уровня View напрямую, минуя слой контроллера. Маршруты привязываются к страницам обычно централизованно в специальном файле конфигурации.  &lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Поскольку каталог models пустой, давайте взглянем повнимательнее на содержимое каталога views.  &lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;В файле common.clj создается специальная функция layout. Она задает общий шаблон страницы, заголовки и структуру html-файла.  &lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;В файле welcome.clj при помощи defpage задается маршрут «/welcome» и функция, которая сгенерирует ответ на запрос пользователя по этому маршруту. Как видно из кода, функция вернет строку приветствия. Шаблон html-страницы создается при помощи библиотеки Hiccup. Она позволяет писать html-код прямо на языке clojure при помощи родных для clojure структур данных: векторов и мапов.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Hiccup очень удобен тем, что позволяет производить любые манипуляции с шаблоном прямо при помощи Clojure. Заметьте, такой подход вообще не встречается среди мейнстримных фреймворков. Что в ASP.NET, что в J2EE для разметки страницы применяется свой собственный DSL, построенный на базе XHTML. Как, например, сделать повторяющийся фрагмент страницы на JSF2.0, на которой еще есть экшены? Правильно, с применением ломика и какой-то матери. В ASP.NET с этим, вроде, несколько проще, но подход такой же: xml-теги. Ну и скажите мне, как программисту Java, почему я не могу использовать Java для изменения шаблона веб-страницы? Как ни крути, но даже Java... хотя нет, уж лучше этот долбаный XML, чем веб-страницы на Java...&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Короче, в Noir используется hiccup, а hiccup позволяет писать html-страницы на clojure в декларативном стиле.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Вручную hiccup-код имеет смысл писать только для страниц очень небольшого размера. Если вам досталась от дизайнера монстрозная страница в десятки килобайт кода – конечно, такое поделие переписывать на hiccup не стоит. В этом вам поможет &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/nathell/clj-tagsoup&quot;&gt;clj-tagsoup&lt;/a&gt;. Просто вызовите его функцию parse с указанием html-страницы и сохраните полученный hiccup-код.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Почти все руководства о веб-фреймворках в виде первого учебного приложения предлагают свой вариант блога. Давайте и мы сделаем свой простой блог при помощи Noir. Переименуем welcome.clj в article_pages.clj (а также namespace) и напишем код первой страницы блога – списка записей. Еще я немного изменил список импортируемых библиотек.&lt;/div&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;ns&lt;/span&gt; optimalist&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;views&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;article_pages&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:require&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;optimalist&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;views&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;common &lt;span style=&quot;color:#400000;&quot;&gt;:as&lt;/span&gt; common&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;noir&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;response &lt;span style=&quot;color:#400000;&quot;&gt;:as&lt;/span&gt; resp&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:use&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;noir&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;        &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;hiccup&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defpage&lt;/span&gt; articles &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/articles&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;         &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;common/layout&lt;/span&gt;&lt;br /&gt;           &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:p&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;List of articles&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:2cm;}P {margin-bottom:0.21cm;}--&gt;&lt;/style&gt;   &lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Обратите внимание, что маршрут «/articles» – именованный. В будущем я смогу получить его при помощи (url-for articles).  &lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Запустите веб-приложение командой lein run и откройте его по ссылке localhost:8080/articles. Разумеется, вы увидите текст «List of articles». Но пока что еще не работает корневой маршрут: localhost:8080/. Давайте добавим для него определение маршрута. &lt;/div&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defpage&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;resp/redirect&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;url-for&lt;/span&gt; articles&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:2cm;}P {margin-bottom:0.21cm;}--&gt;&lt;/style&gt; Как видите, здесь объявляется неименованный маршрут «/», и вместо ответа на него сервер редиректит на страницу articles.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Следующая проблема: как вывести список каких-либо элементов? Поскольку код шаблона мы пишем на clojure, то воспользуемся функцией for:&lt;/div&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defpage&lt;/span&gt; articles &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/articles&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;data &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:title&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;First title&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:body&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;First body&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;              &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:title&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Second title&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:body&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Second body&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;              &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:title&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Third title&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:body&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Third body&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;         &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;common/layout&lt;/span&gt;&lt;br /&gt;          &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:p&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;List of articles&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;           &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;item data&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;             &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:div&lt;/span&gt;&lt;br /&gt;              &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:title&lt;/span&gt; item&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;              &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;              &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:body&lt;/span&gt; item&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;              &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:2cm;}P {margin-bottom:0.21cm;}--&gt;&lt;/style&gt; Пока что все достаточно просто, не так ли? Страница articles покажет нам следующий текст:&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-style:normal;font-weight:normal;&quot;&gt;&lt;span style=&quot;color:black;&quot;&gt;&lt;span style=&quot;font-family:Times New Roman;&quot;&gt;&lt;span style=&quot;font-size:small;&quot;&gt;List of articles&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;border:none;font-style:normal;font-weight:normal;line-height:0.64cm;margin-bottom:0cm;orphans:2;padding:0cm;widows:2;&quot;&gt;&lt;span style=&quot;color:black;&quot;&gt;&lt;span style=&quot;font-family:Times New Roman;&quot;&gt;&lt;span style=&quot;font-size:small;&quot;&gt;First title&lt;br /&gt;First body&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;border:none;font-style:normal;font-weight:normal;line-height:0.64cm;margin-bottom:0cm;orphans:2;padding:0cm;widows:2;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;border:none;font-style:normal;font-weight:normal;line-height:0.64cm;margin-bottom:0cm;orphans:2;padding:0cm;widows:2;&quot;&gt;&lt;span style=&quot;color:black;&quot;&gt;&lt;span style=&quot;font-family:Times New Roman;&quot;&gt;&lt;span style=&quot;font-size:small;&quot;&gt;Second title&lt;br /&gt;Second body&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;border:none;font-style:normal;font-weight:normal;line-height:0.64cm;margin-bottom:0cm;orphans:2;padding:0cm;widows:2;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;border:none;font-style:normal;font-weight:normal;line-height:0.64cm;margin-bottom:0cm;orphans:2;padding:0cm;widows:2;&quot;&gt;&lt;span style=&quot;color:black;&quot;&gt;&lt;span style=&quot;font-family:Times New Roman;&quot;&gt;&lt;span style=&quot;font-size:small;&quot;&gt;Third title&lt;br /&gt;Third body&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;Теперь данные нужно перенести в отдельный файл. Создадим в каталоге models файл article_model.clj, добавим туда код:&lt;br /&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;ns&lt;/span&gt; optimalist&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;models&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;article_model&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;def&lt;/span&gt; *data*&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;ref&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:title&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;First article&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:body&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Lorem ipsum dolor sit amet.&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;2&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:title&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Second article&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:body&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Lorem ipsum dolor sit amet.&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;3&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:title&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Third article&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:body&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Lorem ipsum dolor sit amet. &quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;4&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:title&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Fourth article&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:body&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Lorem ipsum dolor sit amet.&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defn&lt;/span&gt; fetch-list &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  @*data*&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:2cm;}P {margin-bottom:0.21cm;}--&gt;&lt;/style&gt; Воспользуемся этой моделью. Чтобы импортировать модель, добавим в секцию require такую строку: [optimalist.models.article_model :as article-model]; а код функции articles перепишем таким образом: &lt;/div&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defpage&lt;/span&gt; articles &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/articles&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;common/layout&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:p&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;List of articles&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;item &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;article-model/fetch-list&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;      &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:div&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:title&lt;/span&gt; item&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:body&lt;/span&gt; item&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:2cm;}P {margin-bottom:0.21cm;}--&gt;&lt;/style&gt; Вообще такая организация кода всё еще не очень удобная. Что если будет несколько страниц с похожим функционалом? Нам придется выносить hiccup-код в отдельные модули чтобы сделать его reusable. Давайте сделаем это сразу. Создатим файл view/article_templates.clj и вынесем туда генерацию httml.&lt;/div&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;ns&lt;/span&gt; optimalist&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;views&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;article_templates&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:use&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;noir&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;        &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;hiccup&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defn&lt;/span&gt; show-list &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;articles-list&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:p&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;List of articles&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;item articles-list&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;      &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:div&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:title&lt;/span&gt; item&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:body&lt;/span&gt; item&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:2cm;}P {margin-bottom:0.21cm;}--&gt;&lt;/style&gt;   &lt;/div&gt;В модуле article_pages.clj необходимо добавить строку [optimalist.views.article_templates :as article-view] в секцию :require. А страница articles тогда будет выглядеть так: &lt;br /&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defpage&lt;/span&gt; articles &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/articles&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;common/layout&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;article-view/show-list&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;article-model/fetch-list&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Следующая наша задача – добавить к элементам списка ссылки на действия. Лично я – большой любитель технологии REST, о которой узнал из Ruby on Rails. Наши четыре действия над сущностью create, read, update, delete подразумевают наличие семи маршрутов:&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;table cellpadding=&quot;4&quot; cellspacing=&quot;0&quot; style=&quot;width:642px;&quot;&gt;&lt;colgroup&gt;&lt;col width=&quot;152&quot;&gt;  &lt;col width=&quot;138&quot;&gt;  &lt;col width=&quot;326&quot;&gt;  &lt;/colgroup&gt;&lt;tbody&gt;&lt;tr valign=&quot;TOP&quot;&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:1px solid #000000;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0.1cm;&quot; width=&quot;152&quot;&gt;&lt;b&gt;Маршрут&lt;/b&gt;&lt;/td&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:1px solid #000000;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0.1cm;&quot; width=&quot;138&quot;&gt;&lt;b&gt;Метод&lt;/b&gt;&lt;/td&gt;   &lt;td style=&quot;border:1px solid #000000;padding:0.1cm;&quot; width=&quot;326&quot;&gt;&lt;b&gt;Описание&lt;/b&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr valign=&quot;TOP&quot;&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0cm;&quot; width=&quot;152&quot;&gt;/articles&lt;/td&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0cm;&quot; width=&quot;138&quot;&gt;GET&lt;/td&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:1px solid #000000;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0.1cm;padding-top:0cm;&quot; width=&quot;326&quot;&gt;Список записей&lt;/td&gt;  &lt;/tr&gt;&lt;tr valign=&quot;TOP&quot;&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0cm;&quot; width=&quot;152&quot;&gt;/article/:id&lt;/td&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0cm;&quot; width=&quot;138&quot;&gt;GET&lt;/td&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:1px solid #000000;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0.1cm;padding-top:0cm;&quot; width=&quot;326&quot;&gt;Просмотреть одну запись&lt;/td&gt;  &lt;/tr&gt;&lt;tr valign=&quot;TOP&quot;&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0cm;&quot; width=&quot;152&quot;&gt;/article/edit/:id&lt;/td&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0cm;&quot; width=&quot;138&quot;&gt;GET&lt;/td&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:1px solid #000000;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0.1cm;padding-top:0cm;&quot; width=&quot;326&quot;&gt;Показать форму редактирования &lt;span style=&quot;font-weight:normal;&quot;&gt;записи&lt;/span&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr valign=&quot;TOP&quot;&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0cm;&quot; width=&quot;152&quot;&gt;/article/update/:id&lt;/td&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0cm;&quot; width=&quot;138&quot;&gt;POST&lt;/td&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:1px solid #000000;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0.1cm;padding-top:0cm;&quot; width=&quot;326&quot;&gt;Изменить запись в соответствии с    указанными данными&lt;/td&gt;  &lt;/tr&gt;&lt;tr valign=&quot;TOP&quot;&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0cm;&quot; width=&quot;152&quot;&gt;/article/delete/:id&lt;/td&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0cm;&quot; width=&quot;138&quot;&gt;POST&lt;/td&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:1px solid #000000;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0.1cm;padding-top:0cm;&quot; width=&quot;326&quot;&gt;Удалить запись&lt;/td&gt;  &lt;/tr&gt;&lt;tr valign=&quot;TOP&quot;&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0cm;&quot; width=&quot;152&quot;&gt;/article/new&lt;/td&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0cm;&quot; width=&quot;138&quot;&gt;GET&lt;/td&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:1px solid #000000;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0.1cm;padding-top:0cm;&quot; width=&quot;326&quot;&gt;Показать пустую форму для создания    записи&lt;/td&gt;  &lt;/tr&gt;&lt;tr valign=&quot;TOP&quot;&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0cm;&quot; width=&quot;152&quot;&gt;/article/create&lt;/td&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:none;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0cm;padding-top:0cm;&quot; width=&quot;138&quot;&gt;&lt;div style=&quot;font-weight:normal;&quot;&gt;POST&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-bottom:1px solid #000000;border-left:1px solid #000000;border-right:1px solid #000000;border-top:none;padding-bottom:0.1cm;padding-left:0.1cm;padding-right:0.1cm;padding-top:0cm;&quot; width=&quot;326&quot;&gt;Создать запись в соответствии с    указанными данными&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Вообще в REST должны использоваться методы не только GET и POST, а также PUT (для создания новой записи) и DELETE (для удаления). Но то ли браузеры не понимают этих методов, то ли веб сервера, но факт остается фактом: использовать мы можем только GET и POST.  В Ruby on Rails для обхода этого ограничения создается скрытое поле. И если указывается метод PUT или DELETE, то на самом деле используется POST с пометкой в скрытом поле, что это все-таки PUT/DELETE.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Разные методы отправки запроса нужно использовать не только для красоты. По сети ползают роботы-индексаторы, которые пытаются перейти по ссылкам на другие страницы. Представьте, например, что на вашем сайте кнопка DELETE сделана при помощи обыкновенной ссылки (запрос методом GET), и робот решит по ней перейти.  Робот ведь не знает, что эта ссылка приводит к какому-то разрушительному действию, правда? Вот для этого-то все запросы, как-нибудь изменяющие сущность, должны быть отправлены методом POST.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Итак, первая ссылка, которую я хотел бы добавить к списку сущностей – маршрут /article/:id для просмотра записи.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;Вначале в article_pages добавим страницу: &lt;br /&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defpage&lt;/span&gt; view-article &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/article/:id&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;id &lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;common/layout&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;View article&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:2cm;}P {margin-bottom:0.21cm;}--&gt;&lt;/style&gt;   &lt;br /&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Она пока ничего не делает, но зато её сразу же можно протестить в браузере по маршруту /article/1. Заметьте, что в определении страницы задан хеш параметров {id :id}. Это деструктуризаця параметров запроса, и делает она именно то, на что похоже: создает локальную переменную id, значение которой будет получено из части маршрута :id.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Теперь добавим ссылку на эту страницу в функции show-list&lt;/div&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defn&lt;/span&gt; show-list &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;articles-list&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:p&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;List of articles&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;item articles-list&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;      &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:div&lt;/span&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:title&lt;/span&gt; item&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:body&lt;/span&gt; item&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:href&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;url-for&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;str&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/article/&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:id&lt;/span&gt; item&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;View&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;Функция url-for умеет создавать абсолютный URL по заданным параметрам. Параметром может быть как текстовая строка с маршрутом, так и сам именованный маршрут. И хотя предложенное выше решение – вполне работоспособное, но оно все-таки не оптимальное. Что если вы решите изменить URL в странице view-article? Тогда вам придется искать все места, где вы на него ссылаетесь, и править маршруты вручную. Лучше использовать именованый маршрут следующим образом: &lt;br /&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;(url-for optimalist.views.article_pages/view-article {:id (:id item)})&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Здесь optimalist.views.article_pages/view-article  – полное имя именованного маршрута. Необходимо писать его целиком, т.&amp;nbsp;к. в файле article_templates.clj ничего не известно о aricle_pages.clj. И импортировать article_pages.clj мы тоже не можем, т.&amp;nbsp;к. там уже есть импорт article_templates.clj, и мы получим циклическую зависимость. Поэтому, все-таки, придется писать целиком.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Второй параметр – хеш значений, которые будут переданы в генератор маршрута. Поскольку наш маршрут выглядит как «/article/:id», то ему нужно передать хеш {:id &amp;lt;значение&amp;gt;}. &lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Вообще, конечно же, такая запись жутко громоздкая и неудобная. Поэтому в начало файла article_templates.clj, после объявления неймспейса, добавим алиас:&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;(alias 'article 'optimalist.views.article_pages)&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Теперь генерацию ссылки можно переписать таким образом:&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;(url-for article/view-article {:id (:id item)})&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;Это уже значительно лучше, но все еще пока не идеально. Элементов типа «ссылка» у нас будет достаточно много, особенно, если много разных сущностей. Но типов ссылок всего несколько: new, view, edit, delete, back. Мы могли бы сделать более абстрактный механизм генерации ссылок, который инкапсулирует в себе всю внутреннюю структуру вектора [:a …], в том числе и надпись на ссылке. Создадим файл views/helpers/widget.clj:&amp;nbsp; &lt;br /&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;ns&lt;/span&gt; optimalist&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;views&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;helpers&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;widget&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:require&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;noir&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defmacro&lt;/span&gt; view-link &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;page id&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#406080;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;vec&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt;&lt;br /&gt;     &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:href&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;noir.core/url-for&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;~&lt;/span&gt;page &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;~&lt;/span&gt;id&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;View&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:2cm;}P {margin-bottom:0.21cm;}--&gt;&lt;/style&gt; Теперь его можно подключить в article_templates.clj, добавив строку [optimalist.views.helpers.widget] в секцию :use. А вместо записи [:a {href … } «View»] вставим вызов макроса: (view-link article/view-article (:id item)).&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Макрос здесь нужен из-за параметра page – символа, к которому привязан именованный маршрут. Конечно, его можно было бы передавать закавыченным, но это не очень-то красиво.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Сам макрос пока-что не слишком удачный. Что если нам понадобится добавить еще несколько похожих ссылок? Copy-paste – не наш метод, поэтому немного расширим наш язык для данного конкретного случая.  &lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Это очень интересная технология, описанная Полом Грэмом в книге «On Lisp», и называется она «bottom-up programming». Идея заключается в том, что вы не только пишете свое приложение, используя Lisp, но и изменяете Lisp, чтобы легче было писать ваше предложение. Снизу, в язык вводятся новые конструкции, упрощающие реализацию приложения. Сверху, приложение описывается при помощи ваших новых конструкций, что делает код значительно короче. Отсюда и bottom-up programming.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;Новые конструкции, которые мы вводим в язык, называются утилитами. Давайте добавим  две таких: &lt;br /&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defmacro&lt;/span&gt; common-url &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;page id&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#406080;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;noir.core/url-for&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;~&lt;/span&gt;page &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;~&lt;/span&gt;id&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defmacro&lt;/span&gt; common-link &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;url text &lt;span style=&quot;color:#308080;&quot;&gt;&amp;amp;&lt;/span&gt; params&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#406080;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;vec&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;merge&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:href&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;~&lt;/span&gt;url&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;~&lt;/span&gt;@params&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;~&lt;/span&gt;text&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:2cm;}P {margin-bottom:0.21cm;}--&gt;&lt;/style&gt; Первый макрос просто инкапсулирует знание о том, как создавать URL. Теперь нам не надо заботиться о том, чтобы дописывать noir.core к url-for, а также создавать хеш для единственного занчения id.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;Второй макрос создает html-ссылку с заданным текстом на указанный URL. Необязательный параметр params – это возможные параметры самой ссылки. Например, если нам потребуется задать обработчик onclick, то мы сможем сделать это через params.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;Перепишем текст генерации ссылки с применением двух новых утилит: &lt;br /&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defmacro&lt;/span&gt; view-link &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;page id&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#406080;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;common-link&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;common-url&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;~&lt;/span&gt;page &lt;span style=&quot;color:#308080;&quot;&gt;~&lt;/span&gt;id&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;View&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defmacro&lt;/span&gt; edit-link &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;page id&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#406080;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;common-link&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;common-url&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;~&lt;/span&gt;page &lt;span style=&quot;color:#308080;&quot;&gt;~&lt;/span&gt;id&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Edit&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:2cm;}P {margin-bottom:0.21cm;}--&gt;&lt;/style&gt;   &lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&amp;nbsp;Итак, на данный момент, у нас есть список записей и ссылка на просмотр каждой записи. Давайте теперь реализуем функцию view-article: &lt;/div&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defpage&lt;/span&gt; view-article &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/article/:id&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;id &lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;common/layout&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;article-view/show&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;article-model/fetch&lt;/span&gt; id&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:2cm;}P {margin-bottom:0.21cm;}--&gt;&lt;/style&gt; Чтобы она заработала, нужно в article_templates добавить функцию show: &lt;/div&gt;&lt;pre style=&quot;background:none repeat scroll 0% 0% rgb(246, 248, 255);color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defn&lt;/span&gt; show &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;article&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:div&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:h1&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:title&lt;/span&gt; article&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:div&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:body&lt;/span&gt; article&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:href&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;url-for&lt;/span&gt; article&lt;span style=&quot;color:#308080;&quot;&gt;/&lt;/span&gt;articles&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Back&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;) &lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;В article_model необходимо добавить функцию fetch:&lt;span style=&quot;color:#308080;&quot;&gt; &lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defn&lt;/span&gt; fetch &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;id&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;first&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;filter&lt;/span&gt; #&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;=&lt;/span&gt; id &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:id&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; @*data*&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!-- _filtered {margin:2cm;}P {margin-bottom:0.21cm;}--&gt;&lt;/style&gt;   &lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;На этом, пожалуй, все сложности и закончились. Дальше, по накатанной. Проект целиком вы можете найти &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/dbushenko/Simple-Noir-blog-example&quot;&gt;здесь&lt;/a&gt;, а вот как выглядят два основных файла проекта.&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;b&gt;article_pages.clj&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;ns&lt;/span&gt; optimalist&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;views&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;article_pages&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:require&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;optimalist&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;views&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;common &lt;span style=&quot;color:#400000;&quot;&gt;:as&lt;/span&gt; common&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;noir&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;response &lt;span style=&quot;color:#400000;&quot;&gt;:as&lt;/span&gt; resp&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;optimalist&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;views&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;article_templates &lt;span style=&quot;color:#400000;&quot;&gt;:as&lt;/span&gt; article-view&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;            &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;optimalist&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;models&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;article_model &lt;span style=&quot;color:#400000;&quot;&gt;:as&lt;/span&gt; article-model&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:use&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;noir&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defpage&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;resp/redirect&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;url-for&lt;/span&gt; articles&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defpage&lt;/span&gt; articles &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/articles&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;common/layout&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;article-view/show-list&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;article-model/fetch-list&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defpage&lt;/span&gt; view-article &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/article/:id&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;id &lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;common/layout&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;article-view/show&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;article-model/fetch&lt;/span&gt; id&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defpage&lt;/span&gt; edit-article &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/article/edit/:id&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;id &lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;item &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;article-model/fetch&lt;/span&gt; id&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;common/layout&lt;/span&gt;&lt;br /&gt;     &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;article-view/form&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;url-for&lt;/span&gt; update-article &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt; id&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Update&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:title&lt;/span&gt; item&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:body&lt;/span&gt; item&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defpage&lt;/span&gt; update-article &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:post&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/article/update/:id&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:keys&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;id title body&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;article-model/update&lt;/span&gt; id title body&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;resp/redirect&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;url-for&lt;/span&gt; view-article &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt; id&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defpage&lt;/span&gt; new-article &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/article/new&quot;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;common/layout&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;article-view/form&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;url-for&lt;/span&gt; create-article&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Create&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defpage&lt;/span&gt; create-article &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:post&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/article/create&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:keys&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;title body&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;article-model/create&lt;/span&gt; title body&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;resp/redirect&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;url-for&lt;/span&gt; articles&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defpage&lt;/span&gt; delete-article &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:post&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;/delete/:id&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;id &lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;article-model/delete&lt;/span&gt; id&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;resp/redirect&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;url-for&lt;/span&gt; articles&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;b&gt;article_templates.clj&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;pre style=&quot;background:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;ns&lt;/span&gt; optimalist&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;views&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;article_templates&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:require&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;optimalist&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;views&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;helpers&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;widget &lt;span style=&quot;color:#400000;&quot;&gt;:as&lt;/span&gt; widget&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:use&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;noir&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;        &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;hiccup&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;alias&lt;/span&gt; &lt;span style=&quot;color:#406080;&quot;&gt;'article&lt;/span&gt; &lt;span style=&quot;color:#406080;&quot;&gt;'optimalist&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;views&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;article_pages&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defn&lt;/span&gt; show &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;article&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:div&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:h1&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:title&lt;/span&gt; article&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:div&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:body&lt;/span&gt; article&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:href&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;url-for&lt;/span&gt; article&lt;span style=&quot;color:#308080;&quot;&gt;/&lt;/span&gt;articles&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Back&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defn&lt;/span&gt; list-item &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;item&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;id &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:id&lt;/span&gt; item&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:div&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:div&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:title&lt;/span&gt; item&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;     &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:body&lt;/span&gt; item&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;     &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:form&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;str&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;form-&quot;&lt;/span&gt; id&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:method&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:action&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;url-for&lt;/span&gt; article&lt;span style=&quot;color:#308080;&quot;&gt;/&lt;/span&gt;delete-article &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:id&lt;/span&gt; id&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;      &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:div&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;widget/view-link&lt;/span&gt; article&lt;span style=&quot;color:#308080;&quot;&gt;/&lt;/span&gt;view-article id&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot; | &quot;&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;widget/edit-link&lt;/span&gt; article&lt;span style=&quot;color:#308080;&quot;&gt;/&lt;/span&gt;edit-article id&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot; | &quot;&lt;/span&gt;&lt;br /&gt;       &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;widget/delete-link&lt;/span&gt; id&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;     &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defn&lt;/span&gt; show-list &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;articles-list&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:div&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;item articles-list&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; &lt;br /&gt;     &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;list-item&lt;/span&gt; item&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:href&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;url-for&lt;/span&gt; article&lt;span style=&quot;color:#308080;&quot;&gt;/&lt;/span&gt;new-article&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;New&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defn&lt;/span&gt; form &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;url button-text &lt;span style=&quot;color:#308080;&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;title body &lt;span style=&quot;color:#308080;&quot;&gt;&amp;amp;&lt;/span&gt; rest&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:form&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:method&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:action&lt;/span&gt; url&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:input&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:name&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:type&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:value&lt;/span&gt; title&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:textarea&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:name&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;body&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt; body&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:input&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:type&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;submit&quot;&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:value&lt;/span&gt; button-text&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:br&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:href&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;url-for&lt;/span&gt; article&lt;span style=&quot;color:#308080;&quot;&gt;/&lt;/span&gt;articles&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Back&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;font-weight:normal;margin-bottom:0cm;&quot;&gt;&lt;/div&gt;&lt;/div&gt;</description>
         <author>Dmitry</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-4007342736133040943.post-2950385532556177667</guid>
         <pubDate>Sun, 08 Jan 2012 12:22:00 +0000</pubDate>
      </item>
      <item>
         <title>Субботний вечер пропаганды маргинальных технологий: Статистический анализ с помощью clojure и incanter</title>
         <link>http://pdrobushevich.blogspot.com/2011/03/clojureincanter.html</link>
         <description>&lt;p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://4.bp.blogspot.com/-9tBREyP_YAg/TZ1R5kx2ZXI/AAAAAAAAAcY/SSLLAEnb8WA/s1600/incanter-i-logo-holo.png&quot; style=&quot;clear:right;float:right;margin-left:1em;margin-bottom:1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;175&quot; width=&quot;173&quot; src=&quot;http://4.bp.blogspot.com/-9tBREyP_YAg/TZ1R5kx2ZXI/AAAAAAAAAcY/SSLLAEnb8WA/s320/incanter-i-logo-holo.png&quot;&gt;&lt;/a&gt;&lt;/div&gt;Начну из далека. Все прекрасно знают, что Java код компилируется в платформа независимый java bytecode. Sun&amp;#39;ики этого не планировали, но, так же как и для CLR, появились альтернативные языки, компилируемые под JVM. Зачастую это порты других известных языков: Jython (Python), JRuby (Ruby), Kawa (Scheme). Они пользуются небольшой популярностью по очевидной причине, люди предпочитают использовать не порт, а настоящий язык. Но есть языки разработанные специально для JVM. Например Groovy, солянка Ruby и Java, заполучил своё место под солнцем как скриптовый язык, часто используется, как основа более гибких конфигураций, нежели статический xml и вроде веб на нём тоже делают. Ещё есть Scala, мельтипарадигменный язык, который совмещает в себе огромную кучу фич из ООП и ФП. Мне он не очень нравится перегруженностью синтаксиса, но он набирает популярность как замена Java. Но сегодня я хотел бы поговорить о &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure.org/&quot;&gt;Clojure&lt;/a&gt; - это функциональный язык, диалект великого Lisp&amp;#39;а. Ах, нет, я хотел обмануть, про замечательный язык clojure я не стану рассказывать детально в этой статье, лучший способ с ним познакомиться это &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.net/ru/clojure/&quot;&gt;одноименный раздел на сайте Алекса Отта&lt;/a&gt;. Там же есть постоянно обновляющаяся &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.net/ru/clojure/clojure-intro/index.html&quot;&gt;вводная статья&lt;/a&gt; написанная Алексом для журнала &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://fprog.ru/&quot;&gt;fprog&lt;/a&gt;. &lt;p&gt;Я участвую в проекте по обработке данных. Предыдущая версия использовала MS Sql Server для своей работы, поэтому анализ работы системы сделать было достаточно просто, можно было обойтись и простым t-sql скриптом или, если нужно было графическое представление, то можно было использовать Reporting services. Сейчас же, для того компонента, которым я занимаюсь, никакие СУБД не используются, поэтому какие-то выводы можно делать исключительно по логам. Поэтому даже был сделан отдельный структурированный лог в csv формате обо всех важных событиях, произошедших в системе. К примеру, к нам приходит много файлов, поэтому для каждого из этих фалов, этот лог содержит упрощённо 3 записи: файл найден, файл отправлен на обработку, файл обработан. Как то у &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.facebook.com/profile.php?id=100000498221779&quot;&gt;Ярослава&lt;/a&gt; возникла идея попробовать &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.r-project.org/&quot;&gt;язык R&lt;/a&gt;, чтобы нарисовать какие-нибудь интересные аналитические графики. Меня идея заинтересовала, я скачал книгу и впал в ступор. В общем и целом, язык этот мне не понравился (можно сказать не осилил:)). Но месяц назад в очередном порыве изучения clojure, у Алекса наткнулся на упоминания о проекте &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://incanter.org/&quot;&gt;incanter&lt;/a&gt;. Лучше всего его описали сами авторы:  &lt;/p&gt;&lt;blockquote&gt;Incanter is a Clojure-based, R-like platform for statistical computing and graphics.&lt;/blockquote&gt;&lt;p&gt;В этой статье я попробую рассказать, как я, человек знакомый с clojure только по статьям/книгам/скринкастам, использовал incanter для построения интересных, на мой взгляд, графиков работы нашего приложения.  &lt;/p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://pdrobushevich.blogspot.com/2011/03/clojureincanter.html#more&quot;&gt;Дальше »&lt;/a&gt;</description>
         <author>Pavel Drobushevich</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-7555770271531199968.post-6335057064292047981</guid>
         <pubDate>Sat, 26 Mar 2011 22:39:00 +0000</pubDate>
         <media:thumbnail height="72" url="http://4.bp.blogspot.com/-9tBREyP_YAg/TZ1R5kx2ZXI/AAAAAAAAAcY/SSLLAEnb8WA/s72-c/incanter-i-logo-holo.png" width="72" xmlns:media="http://search.yahoo.com/mrss/"/>
      </item>
      <item>
         <title>Новое в clojure 1.5</title>
         <link>http://hrustyashko.blogspot.com/2013/03/clojure-15.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;1 марта был выпущен релиз clojure 1.5. Полный список изменений здесь&amp;nbsp;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://github.com/clojure/clojure/blob/master/changes.md&quot;&gt;https://github.com/clojure/clojure/blob/master/changes.md&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Теперь для версии clojure 1.5 требуется Java 7 (используется класс&amp;nbsp;java.util.concurrent.ForkJoinPool). Новая версия Java необходима для работы с новым добавленным неймспейсом clojure.core.reducers&lt;br /&gt;&lt;br /&gt;Новая библиотека core.reducers призвана увеличить скорость обработки коллекций. Основная оптимизация заключается в том, что последовательность действий над коллекцией (например (filter #() (map #() seq))) не создает промежуточную коллекцию и действия могут выполняться параллельно(при этом код остаётся без изменений)&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;clojure-&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;-&lt;span style=&quot;color:green;&quot;&gt;5.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;require&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#406080;&quot;&gt;'clojure&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;reducers &lt;span style=&quot;color:#400000;&quot;&gt;:as&lt;/span&gt; &lt;span style=&quot;color:#406080;&quot;&gt;'r&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt;&lt;br /&gt;clojure-&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;-&lt;span style=&quot;color:green;&quot;&gt;5.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;def&lt;/span&gt; numbers &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;into&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;range&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;99999&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#406080;&quot;&gt;#'clojure-1-5&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;/&lt;/span&gt;numbers&lt;br /&gt;clojure-&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;-&lt;span style=&quot;color:green;&quot;&gt;5.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;time&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;doseq&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;x &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;range&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;reduce&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;r/filter&lt;/span&gt; #&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;4&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;mod&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;r/map&lt;/span&gt; inc numbers&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Elapsed time: 729.914422 msecs&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt;&lt;br /&gt;clojure-&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;-&lt;span style=&quot;color:green;&quot;&gt;5.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;time&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;doseq&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;x &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;range&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;reduce&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;filter&lt;/span&gt; #&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;4&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;mod&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;map&lt;/span&gt; inc numbers&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;Elapsed time: 847.422309 msecs&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Для &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure.org/agents&quot;&gt;агентов&lt;/a&gt;&amp;nbsp;появилась возможность задать собственный пул тредов для выполнения модифицирующих операций над агентами(с помощью send, send-of, send-via)&lt;br /&gt;Например можно выполнять операции над агентами в один поток(по умолчанию число потоков равно числу ядер + 2)&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;&lt;pre&gt;clojure-&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;-&lt;span style=&quot;color:green;&quot;&gt;5.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;def&lt;/span&gt; a &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;agent&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#406080;&quot;&gt;#'clojure-1-5&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;/&lt;/span&gt;a&lt;br /&gt;clojure-&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;-&lt;span style=&quot;color:green;&quot;&gt;5.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; @a&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;clojure-&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;-&lt;span style=&quot;color:green;&quot;&gt;5.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;send&lt;/span&gt; a assoc &lt;span style=&quot;color:#400000;&quot;&gt;:b&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;#&lt;span style=&quot;color:#308080;&quot;&gt;&amp;lt;&lt;/span&gt;Agent@17d577c&lt;span style=&quot;color:#400000;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:b&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;clojure-&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;-&lt;span style=&quot;color:green;&quot;&gt;5.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; @a&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:b&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;clojure-&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;-&lt;span style=&quot;color:green;&quot;&gt;5.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;set-agent-send-executor!&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;java.util.concurrent.Executors/newSingleThreadExecutor&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;#&lt;span style=&quot;color:#308080;&quot;&gt;&amp;lt;&lt;/span&gt;FinalizableDelegatedExecutorService java&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;util&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;concurrent&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;Executors$FinalizableDelegatedExecutorService@108fbd4&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;clojure-&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;-&lt;span style=&quot;color:green;&quot;&gt;5.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;send&lt;/span&gt; a assoc &lt;span style=&quot;color:#400000;&quot;&gt;:c&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;#&lt;span style=&quot;color:#308080;&quot;&gt;&amp;lt;&lt;/span&gt;Agent@17d577c&lt;span style=&quot;color:#400000;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:c&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:b&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;clojure-&lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;-&lt;span style=&quot;color:green;&quot;&gt;5.&lt;/span&gt;core&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; @a&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:c&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:b&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;Для кастомизации функции send используется&amp;nbsp;set-agent-send-executor! для send-off используется &amp;nbsp;set-agent-send-off-executor!. Если нужно выполнить действие над агентом с произвольным исполнителем, можно использовать send-via. &amp;nbsp;В общем случае функцию send следует использовать когда операция занимает фиксированное количество времени, а send-off когда операция может быть заблокирована по I/O или другому внешнему ресурсу.&lt;br /&gt;&lt;br /&gt;Начиная с версии 1.5 функции-конструкторы (&lt;span style=&quot;font-family:inherit;&quot;&gt;hash-map, array-map&lt;/span&gt;) принимают дублирующие значения ключей и не выкидывают исключения&lt;br /&gt;&lt;br /&gt;в версии 1.4&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;hash-map&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:b&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;IllegalArgumentException Duplicate key&lt;span style=&quot;color:#400000;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt;  clojure&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;lang&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;PersistentHashMap&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;createWithCheck &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;PersistentHashMap.java:92&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;в 1.5&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;hash-map&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:b&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:b&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;объявление литерала c дублирующими ключами по прежнему кидает исключение&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:b&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;#&lt;span style=&quot;color:#308080;&quot;&gt;&amp;lt;&lt;/span&gt;IllegalArgumentException java&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;lang&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;IllegalArgumentException&lt;span style=&quot;color:#400000;&quot;&gt;:&lt;/span&gt; Duplicate key&lt;span style=&quot;color:#400000;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;К макросам -&amp;gt; -&amp;gt;&amp;gt; добавилось несколько новых макросов cond-&amp;gt; и cond-&amp;gt;&amp;gt; для выполнения последовательности действий с условиями, а также есть возможность задать именнованную область с помощью as-&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;84&lt;/span&gt;&lt;br /&gt;           &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;/&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;           &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;as-&amp;gt;&lt;/span&gt; twenty-one&lt;br /&gt;                  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;*&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt; twenty-one&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#008c00;&quot;&gt;42&lt;/span&gt;&lt;/pre&gt;Для последовательности действий, где на промежуточном шаге результат действия может быть nil и необходимо прервать выполнение дальнейших шагов есть макрос some-&amp;gt; (или some-&amp;gt;&amp;gt;)&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;range&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; next inc&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;NullPointerException   &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;trace missing&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;some-&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;range&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; next inc&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Новая версия &lt;span style=&quot;font-family:inherit;&quot;&gt;gen-class&lt;/span&gt; позволяет обращаться к &lt;span style=&quot;font-family:inherit;&quot;&gt;protected final&lt;/span&gt; методам родительского класса через &lt;span style=&quot;line-height:19px;&quot;&gt;&lt;span style=&quot;font-family:inherit;&quot;&gt;:exposes-methods&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;line-height:19px;&quot;&gt;&lt;span style=&quot;font-family:inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height:19px;&quot;&gt;К мета данным (функция meta) добавлен атрибут :column, указывающий номер колонки в исходном файле. До версии 1.5 был указан только номер строки :line&lt;/span&gt;&lt;/div&gt;</description>
         <author>Алексей</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-3371341101978109462.post-1685643595931482869</guid>
         <pubDate>Sat, 09 Mar 2013 04:15:00 +0000</pubDate>
      </item>
      <item>
         <title>Google использует Common Lisp?</title>
         <link>http://hrustyashko.blogspot.com/2012/10/google-common-lisp.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Иначе зачем выпускать style-guide&amp;nbsp;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://google-styleguide.googlecode.com/svn/trunk/lispguide.xml&quot;&gt;https://google-styleguide.googlecode.com/svn/trunk/lispguide.xml&lt;/a&gt;?&lt;br /&gt;&lt;br /&gt;Нашел только одно упоминание про использование лиспа внутри google&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://googleresearch.blogspot.com/2008/11/plop-probabilistic-learning-of-programs.html&quot;&gt;http://googleresearch.blogspot.com/2008/11/plop-probabilistic-learning-of-programs.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;это plop&lt;br /&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;text-align:left;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;background-color:white;font-family:arial, sans-serif;font-size:13px;line-height:16px;&quot;&gt;A Common Lisp framework for experimenting with meta-optimizing semantic evolutionary search (&lt;/span&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://metacog.org/doc.html&quot; style=&quot;background-color:white;color:#0000cc;font-family:arial, sans-serif;font-size:13px;line-height:16px;&quot;&gt;MOSES&lt;/a&gt;&lt;span style=&quot;background-color:white;font-family:arial, sans-serif;font-size:13px;line-height:16px;&quot;&gt;) and related approaches to learning with probability distributions over program&lt;/span&gt;&lt;span style=&quot;text-align:left;&quot;&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;</description>
         <author>Алексей</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-3371341101978109462.post-1526818592875856044</guid>
         <pubDate>Thu, 11 Oct 2012 05:44:00 +0000</pubDate>
      </item>
      <item>
         <title>Прошляпил Clojure Conj</title>
         <link>http://hrustyashko.blogspot.com/2012/01/clojure-conj.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Оказывается по Clojure была конференция &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure-conj.org/&quot;&gt;Clojure Conj&lt;/a&gt;, аж на целых 3 дня. Проходила она в ноябре 2011 года. Видео доступно &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://blip.tv/clojure&quot;&gt;здесь&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Что самое приятное, так это то что есть люди заинтересованные в запуске и использовании clojure на Android. На clojure-conj был &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure-conj.org/schedule#solano&quot;&gt;доклад&lt;/a&gt; на эту тему. Правда видео я не нашел. Если у кого есть напишите в комментариях.&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure.com/blog/2011/03/23/conj-talks-all-up.html&quot;&gt;Здесь&lt;/a&gt; ссылки на презентации докладчиков.&lt;/div&gt;</description>
         <author>Алексей</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-3371341101978109462.post-5381353653743719563</guid>
         <pubDate>Fri, 20 Jan 2012 08:16:00 +0000</pubDate>
      </item>
      <item>
         <title>Опережающее объявление макроса</title>
         <link>http://hrustyashko.blogspot.com/2011/10/blog-post.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Кто-нибудь знает как в clojure сделать опережающее определение макроса?&lt;br /&gt;&lt;br /&gt;Такой код не скомпилируется, &amp;nbsp;ошибка - &quot;Unable to resolve symbol: my-inc in this context&quot;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;my-inc&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;78&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defmacro&lt;/span&gt; my-inc&lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;number&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#406080;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;~&lt;/span&gt;number &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;А так получишь ошибку в рантайме &quot;Wrong number of args (1) passed to: &quot;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;margin-bottom:0px;margin-left:0px;margin-right:0px;margin-top:0px;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;declare&lt;/span&gt; my-inc&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;my-inc&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;78&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defmacro&lt;/span&gt; my-inc&lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;number&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#406080;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;~&lt;/span&gt;number &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Я так понимаю declare приходится писать из за того что компилятор не многопроходный?&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;margin-bottom:0px;margin-left:0px;margin-right:0px;margin-top:0px;&quot;&gt;&lt;/div&gt;&lt;/div&gt;</description>
         <author>Алексей</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-3371341101978109462.post-3369000720528774652</guid>
         <pubDate>Sun, 16 Oct 2011 08:23:00 +0000</pubDate>
      </item>
      <item>
         <title>Создание экземпляра класса по имени</title>
         <link>http://hrustyashko.blogspot.com/2011/07/blog-post.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Для создания экземпляра класс в clojure можно воспользоваться специальной формой new&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;new&lt;/span&gt; String&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;или более краткой записью '.'&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;String.&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;Но не всегда этих средств достаточно. Возникает необходимость создания объекта класса, зная только имя целевого класса(например хранящегося в виде строки &quot;String&quot;). В этом случае объект можно создать воспользовавшись методами java-классов java.lang.Class(для классов с конструктором без  параметров) и java.lang.reflect.Constructor - для конструкторов с  параметрами.&lt;br /&gt;Первый шаг создания объекта по имени класса - это найти полное имя класса, решается с помощью функции ns-resolve. Поиск выполняется в текущем пространстве имен(*ns*)&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color:#308080;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color:black;font-family:'Times New Roman';white-space:normal;&quot;&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;ns-resolve&lt;/span&gt; *ns* &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;symbol&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;String&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;java&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;lang&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;String&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;В случае успеха ns-resolve возвращает экземпляр класса java.lang.Class.&lt;br /&gt;&lt;br /&gt;Если конструктор класса с параметрами, необходимо найти конструктор с подходящей сигнатурой(метод getConstructor класса java.lang.reflect.Constructor). И создать новый объект методом newInstance.&lt;br /&gt;Окончательно функция будет выглядеть так:&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defn&lt;/span&gt; new-instance &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;name &lt;span style=&quot;color:#308080;&quot;&gt;&amp;amp;&lt;/span&gt; args&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;class &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;ns-resolve&lt;/span&gt; *ns* &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;symbol&lt;/span&gt; name&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;=&lt;/span&gt; java&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;lang&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;Class &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;type&lt;/span&gt; class&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;if&lt;/span&gt; args&lt;br /&gt;        &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;type-args &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;into-array&lt;/span&gt; java&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;lang&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;Class &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;map&lt;/span&gt; #&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;type&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; args&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;          &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;.newInstance&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;.getConstructor&lt;/span&gt; class type-args&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;into-array&lt;/span&gt; args&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;.newInstance&lt;/span&gt; class&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;Пример использования&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;user&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;new-instance&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;String&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;br /&gt;user&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;new-instance&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;String&quot;&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;abc&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;abc&quot;&lt;/span&gt;&lt;br /&gt;user&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;type&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;new-instance&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;String&quot;&lt;/span&gt; &lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;123&quot;&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;java&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;lang&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;String&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;</description>
         <author>Алексей</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-3371341101978109462.post-5117866497394576226</guid>
         <pubDate>Fri, 01 Jul 2011 11:39:00 +0000</pubDate>
      </item>
      <item>
         <title>Модификация атрибутов объекта в Clojure</title>
         <link>http://hrustyashko.blogspot.com/2011/05/clojure.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Часто необходимо модифицировать состояние объекта, особенно когда работаешь с java библиотекой, смысл которой сводится к вызову callback'ов и необходимо сохранять промежуточное состояние между вызовами. Например SAX парсер.&lt;br /&gt;&lt;br /&gt;Clojure определяет три способа работы с изменяемыми данными. &amp;nbsp;Это ссылки, агенты и атомы. Все они описаны в статье Алексея Отта (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://alexott.net/ru/clojure/clojure-intro/&quot;&gt;http://alexott.net/ru/clojure/clojure-intro/&lt;/a&gt;).&lt;br /&gt;Для моего случая подходит синхронное изменение и заворачивать обращения &amp;nbsp;к изменяемым переменным в транзакции нет необходимости.&amp;nbsp;Поэтому я буду использовать атомы(atoms).&lt;br /&gt;&lt;br /&gt;Для примера опишем класс com.Example. Объявим одновременно пространство имен и класс(com.Example) с помощью макроса ns.&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;ns&lt;/span&gt; com&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;Example&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;:gen-class&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color:#400000;&quot;&gt;:state&lt;/span&gt; state&lt;br /&gt;    &lt;span style=&quot;color:#400000;&quot;&gt;:init&lt;/span&gt; init&lt;br /&gt;    &lt;span style=&quot;color:#400000;&quot;&gt;:constructors&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color:#400000;&quot;&gt;:methods&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;setAttr &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;clojure&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;lang&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;Keyword int&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; void&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt;&lt;br /&gt;              &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;getAttr &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;clojure&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;lang&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;Keyword&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; int&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt;&lt;br /&gt;              &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;removeAttr &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;clojure&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;lang&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;Keyword&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; void&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color:#400000;&quot;&gt;:main&lt;/span&gt; false&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;:init - имя конструктора&lt;br /&gt;:state - имя атрибута для хранения состояния объекта&lt;br /&gt;:constructors - описание типов параметров конструкторов класса&lt;br /&gt;:methods - описание доступных методов класса, в формате [имя [тип_параметра ...] тип_возвращаемого_значения]&lt;br /&gt;:main - false - не генерировать, автоматически, метод main(первый метод который будет вызван для java программы)&lt;br /&gt;&lt;br /&gt;Теперь код объявленных выше методов.&lt;br /&gt;&lt;br /&gt;Конструктор:&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defn&lt;/span&gt; -init &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color:#f6f8ff;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color:#000020;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;atom&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color:#000020;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;конструктор без параметров. Конструктор класса в clojure должен вернуть вектор с двумя элементами.&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;superclass-constructor-args&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt; state&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Первый элемент - &amp;nbsp;еще один вектор, содержит параметры конструктора родительского класса([] - для родительского конструктора без параметров). Второй элемент - значение переменной состояния(имя которой определяется через параметр :state). В нашем случае это хеш(maps). Применение функции atoms делает состояние объекта изменяемым.&lt;br /&gt;&lt;br /&gt;После того как state в классе объявлен как изменяемый его можно модифицировать функцией&amp;nbsp;swap!.&lt;br /&gt;&lt;br /&gt;Атрибуты объекта будут хранится как ключевые слова(keywords) а значения - это целые числа.&lt;br /&gt;Методы для сохранения и получения значения атрибутов объекта будут такими:&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defn&lt;/span&gt; -setAttr &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;this attr value&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;swap!&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;.state&lt;/span&gt; this&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; assoc attr value&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defn&lt;/span&gt; -getAttr &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;this attr&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;get&lt;/span&gt; @&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;.state&lt;/span&gt; this&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; attr&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;defn&lt;/span&gt; -removeAttr &lt;span style=&quot;color:#308080;&quot;&gt;[&lt;/span&gt;this attr&lt;span style=&quot;color:#308080;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;swap!&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;.state&lt;/span&gt; this&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt; dissoc attr&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color:#272727;font-family:arial, helvetica, sans-serif;font-size:x-small;line-height:19px;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre id=&quot;var-docstr&quot; style=&quot;background-color:transparent;border-width:0px;color:black;font-family:Inconsolata, Monaco, Consolas, 'Lucida Console', 'Courier New', Courier, monospace;&quot;&gt;И маленький пример использования&lt;/pre&gt;&lt;pre id=&quot;var-docstr&quot; style=&quot;background-color:transparent;border-width:0px;color:black;font-family:Inconsolata, Monaco, Consolas, 'Lucida Console', 'Courier New', Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Times New Roman';font-size:small;line-height:normal;white-space:normal;&quot;&gt;&lt;pre style=&quot;background-color:#f6f8ff;color:#000020;&quot;&gt;user&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;def&lt;/span&gt; ex &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;com.Example.&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#406080;&quot;&gt;#'user&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;/&lt;/span&gt;ex&lt;br /&gt;user&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;.state&lt;/span&gt; ex&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;#&lt;span style=&quot;color:#308080;&quot;&gt;&amp;lt;&lt;/span&gt;Atom@724eb043&lt;span style=&quot;color:#400000;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;user&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; ex&lt;br /&gt;#&lt;span style=&quot;color:#308080;&quot;&gt;&amp;lt;&lt;/span&gt;Example com&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;Example@30c06258&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;user&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;.setAttr&lt;/span&gt; ex &lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt;&lt;br /&gt;user&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;.setAttr&lt;/span&gt; ex &lt;span style=&quot;color:#400000;&quot;&gt;:b&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt;&lt;br /&gt;user&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;.setAttr&lt;/span&gt; ex &lt;span style=&quot;color:#400000;&quot;&gt;:super-key&lt;/span&gt; -&lt;span style=&quot;color:#008c00;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;  &lt;br /&gt;&lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt;&lt;br /&gt;user&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;.state&lt;/span&gt; ex&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;#&lt;span style=&quot;color:#308080;&quot;&gt;&amp;lt;&lt;/span&gt;Atom@724eb043&lt;span style=&quot;color:#400000;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:super-key&lt;/span&gt; -&lt;span style=&quot;color:#008c00;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:b&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;user&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;.getAttr&lt;/span&gt; ex &lt;span style=&quot;color:#400000;&quot;&gt;:b&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;&lt;br /&gt;user&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;.removeAttr&lt;/span&gt; ex &lt;span style=&quot;color:#400000;&quot;&gt;:super-key&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#7d0045;&quot;&gt;nil&lt;/span&gt;&lt;br /&gt;user&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;.state&lt;/span&gt; ex&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;                &lt;br /&gt;#&lt;span style=&quot;color:#308080;&quot;&gt;&amp;lt;&lt;/span&gt;Atom@724eb043&lt;span style=&quot;color:#400000;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#308080;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#400000;&quot;&gt;:b&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#0066ee;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#400000;&quot;&gt;:a&lt;/span&gt; &lt;span style=&quot;color:#008c00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre id=&quot;var-usage&quot;&gt;&lt;/pre&gt;&lt;/div&gt;</description>
         <author>Алексей</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-3371341101978109462.post-3176088179994863087</guid>
         <pubDate>Sat, 21 May 2011 06:24:00 +0000</pubDate>
      </item>
      <item>
         <title>Запуск одного Activity из другого</title>
         <link>http://hrustyashko.blogspot.com/2011/04/activity.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;Для того что бы в android приложении запустить одно Activity из другого(например для навигации по интерфейсу приложения) нужно воспользоваться механизмом межпроцессной коммуникации. &amp;nbsp;Для передачи данных между процессами служит объект класса Intent. Для запроса activity, описанного в объекте класса Intent, служат методы startActivity и startActivityForResult.&lt;br /&gt;Существует несколько конструкторов для создания&amp;nbsp;объекта Intent. Если говорить про запуск Activity для решения задач навигации по интерфейсу(собственных интерфейсов), то можно использовать конструктор вида&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;background:none repeat scroll 0% 0% rgb(246, 248, 255);color:#000020;&quot;&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;&amp;nbsp;public&lt;/span&gt; Intent (Context packageContext, Class&amp;lt;?&amp;gt; cls)&lt;/pre&gt;&lt;br /&gt;с жестким заданием имени класса. Так же для запуска activity понадобится описать в файле&amp;nbsp;AndroidManifest.xml вызываемую activity.&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;background:none repeat scroll 0% 0% rgb(246, 248, 255);color:#000020;&quot;&gt;&lt;span style=&quot;color:#0057a6;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#333385;&quot;&gt;activity&lt;/span&gt;&lt;span style=&quot;color:#474796;&quot;&gt; android:&lt;/span&gt;&lt;span style=&quot;color:#074726;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;com.example.MyExampleActivity&quot;&lt;/span&gt;&lt;span style=&quot;color:#474796;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:#474796;&quot;&gt;android:&lt;/span&gt;&lt;span style=&quot;color:#074726;&quot;&gt;label&lt;/span&gt;&lt;span style=&quot;color:#308080;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#1060b6;&quot;&gt;&quot;@string/app_name&quot;&lt;/span&gt;&lt;span style=&quot;color:#474796;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color:#0057a6;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;И запустить activity вызовом метода startActivity.&lt;br /&gt;&lt;br /&gt;Код на Java для запроса activity может быть записать так:&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;background:none repeat scroll 0% 0% rgb(246, 248, 255);color:#000020;&quot;&gt;this.startActivity(&lt;br /&gt;    new Intent(this, com.example.MyExampleActivity.class)&lt;br /&gt;)&lt;span style=&quot;color:#308080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;На clojure запуск одной Activity из другой будет таким:&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;background:none repeat scroll 0% 0% rgb(246, 248, 255);color:#000020;&quot;&gt;&lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;.startActivity&lt;/span&gt; this &lt;span style=&quot;color:#308080;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#200080;font-weight:bold;&quot;&gt;Intent.&lt;/span&gt; this com&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;example&lt;span style=&quot;color:#308080;&quot;&gt;.&lt;/span&gt;MyExampleActivity&lt;span style=&quot;color:#308080;&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;this - текущая activity&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;</description>
         <author>Алексей</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-3371341101978109462.post-5392444870391599925</guid>
         <pubDate>Thu, 28 Apr 2011 09:38:00 +0000</pubDate>
      </item>
      <item>
         <title>Программирование на clojure под android</title>
         <link>http://hrustyashko.blogspot.com/2011/04/clojure-android.html</link>
         <description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align:left;&quot;&gt;&lt;div style=&quot;font-family:inherit;&quot;&gt;&lt;span style=&quot;color:black;&quot;&gt;В первом посте хочу написать о том зачем эти посты вообще нужны и о чем будут последующие.&lt;/span&gt;&lt;/div&gt;&lt;div align=&quot;LEFT&quot; style=&quot;font-family:inherit;margin:0px 0px 0cm;orphans:2;widows:2;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align=&quot;LEFT&quot; style=&quot;font-family:inherit;font-style:normal;margin:0px 0px 0cm;orphans:2;widows:2;&quot;&gt;&lt;span style=&quot;color:black;&quot;&gt;&lt;b&gt;зачем:&lt;/b&gt;&amp;nbsp;учится новому, получать обратную связь, обсуждать, решать проблемы&lt;/span&gt;&lt;/div&gt;&lt;div align=&quot;LEFT&quot; style=&quot;font-family:inherit;font-style:normal;margin:0px 0px 0cm;orphans:2;widows:2;&quot;&gt;&lt;span style=&quot;color:black;&quot;&gt;&lt;b&gt;о чем:&lt;/b&gt;&amp;nbsp;о программировании на clojure под android&lt;/span&gt;&lt;/div&gt;&lt;div align=&quot;LEFT&quot; style=&quot;font-family:inherit;margin:0px 0px 0cm;orphans:2;widows:2;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align=&quot;LEFT&quot; style=&quot;font-family:inherit;font-style:normal;font-weight:normal;margin:0px 0px 0cm;orphans:2;widows:2;&quot;&gt;&lt;span style=&quot;color:black;&quot;&gt;Началось все с того что меня заинтересовала разработка под Android. Вслед за этим возник естественный&amp;nbsp;&lt;/span&gt;вопрос на чем разрабатывать. От &quot;официальных&quot; языков разработки под android(Java, С++) я был далек и&amp;nbsp;большого желания их изучать и применять не было. Но со времен института остался интерес к функциональным языкам.&amp;nbsp;Особенно к Lisp(на котором я решал исключительно студенческие задачи). Поэтому почитав о Lisp и android побольше&lt;span style=&quot;color:black;font-style:normal;font-weight:normal;&quot;&gt; я нашел для себя такую связку как clojure + android.&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color:black;font-style:normal;font-weight:normal;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://clojure.org/&quot;&gt;Clojure&lt;/a&gt;&amp;nbsp;- &lt;/span&gt;&lt;span style=&quot;color:black;font-style:normal;font-weight:normal;&quot;&gt;функциональный язык программирования, транслируется&lt;/span&gt; в Java байт код, имеет глубокую интергацию с ЯП Java. Команда clojure заявляет о поддержке платформы android(точнее dalvik - виртуальной машины andorid). По причинам глубокой интеграции с java и заявлению по поддержке android&amp;nbsp;думаю что clojure станет хорошей альтернативой java на android.&lt;/div&gt;&lt;div style=&quot;font-family:inherit;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;</description>
         <author>Алексей</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-3371341101978109462.post-4353463353847395837</guid>
         <pubDate>Mon, 18 Apr 2011 05:54:00 +0000</pubDate>
      </item>
      <item>
         <title>Телеавтоматика.рф</title>
         <link>http://feedproxy.google.com/~r/bullshit-mode-on/~3/zsZJzRIXmxo/teleautomatics-rf.html</link>
         <description>&lt;p&gt;
Весь последний год я занимался всякой херней:
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
читал русские и заграничные блоги
&lt;/li&gt;
&lt;li&gt;
тупил в Сети
&lt;/li&gt;
&lt;li&gt;
смотрел фильмы
&lt;/li&gt;
&lt;li&gt;
играл в игры
&lt;/li&gt;
&lt;li&gt;
начинал что-то изучать но не заканчивал
&lt;/li&gt;
&lt;li&gt;
немного писал на лиспе, совсем немного на питоне, джаве и аштиэмэле
&lt;/li&gt;
&lt;li&gt;
завел этот блог
&lt;/li&gt;
&lt;li&gt;
добрался до четвертой главы SICP
&lt;/li&gt;
&lt;li&gt;
пытался переписать библиотеку Iterate с Common Lisp'а на Clojure
(кодоволкер таки переписал)
&lt;/li&gt;
&lt;li&gt;
досконально изучил пятую главу CTMCP (о конкурентном
программировании и передаче сообщений), посмотрел курс лекций UC
Berkley CS 61 A и половину курса CS 61 B.

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Все это время я работал дворником: каждый день я тратил на выполнение
своих служебных обязанностей 10 минут. Работа пыльная, но если
прикинуть соотношение затрат времени (что-то около пяти часов в месяц)
и уровень оплаты, то в целом, не такая уж и плохая. Однако в феврале
произошла неведомая мне перемена в устройстве местных служб
жилищно-коммунального хозяйства и моя простая, бесхитростная и весьма
экономичная в плане ресурсозатрат работа закончилась.
&lt;/p&gt;
&lt;p&gt;
Если бы я уволился на несколько месяцев раньше — не думаю, что я стал
бы искать новую работу, но к тому времени затяжной семейный
апокалипсис подошел к концу и я подался на &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.farpost.ru&quot;&gt;барахолку&lt;/a&gt; смотреть
вакансии. По Уссурийску почти ничего не нашел, зато вакансий по
Владивостоку было несметное количество, при том что Владивосток мне
нафиг не нужен. Мать же поступила проще: она открыла газету с
объявлениями «Из рук в руки» — как по мне — последнее место где
айтишник стал бы искать работу. Как ни странно, но в газете я нашел
целых три вакансии программиста в Уссурийске. Позвонил, зашел в первые
две фирмы — одним нужен был человек для поддержки сайта, эникейщик для
неопределенных занятий. По-виду работодатель с трудом понимал что же
ему надо на самом деле. Вторыми нужен был человек для работы с
камерами наблюдения. Камеры видеонаблюдения в современном народном
хозяйстве есть ясно прослеживающийся тренд; все портило только то, что
это была всего лишь еще одна мелкая фирма с руководством, которое
хотело нанять человека для чего-то там иди поговори с нашим инженером.
&lt;/p&gt;
&lt;p&gt;
В третьей фирме я работаю уже второй месяц. Маленькая компания,
занимающаяся устанавкой камер видеонаблюдения, прокладкой всяких
разных сетей, плясками с бубном, и время от времени — написанием софта
для промышленных объектов силами руководителя, фрилансера и пары
неведомых мне личностей.
&lt;/p&gt;
&lt;p&gt;
Если раньше я работал 5 часов в месяц, и большую часть оставшегося
времени пинал балду, то теперь я работаю с 9ти до 6ти 5 дней в
неделю. Ну как сказать работаю&amp;hellip; Сейчас я занимаюсь примерно тем же,
чем занимался последний год в свободное время: это учеба и
программерская практика; но сейчас все серьезней, в больших объемах и
с настоящей нагрузкой, не дающей бездельничать и растрачивать свое
время попусту. Работа это переход из мира розовых пони и
программистов, пишущих на лиспе в эмаксе в суровый российский реал
ворлд, которым овладела корпорация зла: начиная с компьютера на
котором я пишу по-работе, заканчивая всеми остальными компьютерами в
городе (и во всех соседних городах тоже.)
&lt;/p&gt;
&lt;p&gt;
Мои любимые технологии из мира розовых пони проиграли в столкновении с
суровой правдой жизни. Линуксу, эмаксу (под виндой он невыносим),
лиспу и даже питону (как знать, может быть напишу еще что-нибудь на
F#), гиту (на этот счет я все еще теплю надежду покуда SVN в конец не
остоп*%дит) и гитхабу (как оплоту всего хорошего в программерском
мире) нет места в моем деле.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;P.¶.S.&lt;/b&gt; Когда через полтора месяца после начала работы дело дошло до
документирования проекта, я сдул пыль с «Путеводителя по пакету LaTeX
и его расширению LaTeX2ε», поставил TeXlive и NOWEB, открыл Emacs и
начал педалить документацию вперемешку с исходниками (знаю, я
дурак.) Да, Visio хорош чтобы по-быстрому набросать десяток-другой
схемок, но пользоваться Вордом для документирования программ это полный
пиздец, тут уж как ни крути.
&lt;/p&gt;
&lt;p&gt;
Я год писал для JVM, но за всю свою жизнь я не написал и десяти
классов на джаве. Ближайшие несколько месяцев мне предстоит иметь дело
исключительно с Java ME. Первые две недели я пытался организовать под
виндой хоть сколько-нибудь рабочее окружение для кодинга для
мобильников: перепробовал все 3 среды разработки, посмотрел на
богомерзкие средства для кодинга мышкой и взглянул на поражающий
воображение своей колоссальностью автосгенерированный Ant-скрипт для
сборки проекта. В итоге остановился на варианте Netbeans + Maven +
консолька MS PowerShell.
&lt;/p&gt;
&lt;p&gt;
Но кодинг в нашем деле — вещь десятая. Вняв мудрому наставлению,
прежде чем написать хоть одну строку я сел за &lt;i&gt;проектирование&lt;/i&gt;, черт
меня дери. Сидел себе и проектировал, открыв по случаю слайды курса
MIT 6.005 Elements of Software Construction. Да, это были две недели
дизайна стэйт машин и сетевых протоколов в контексте эргономичного
пользовательского интерфейса. Еще две недели неспешного кодирования, и
скелет программы готов. Чтобы позже не поиметь головной боли с локами
и пятью потоками решил не заморачиваясь с самого начала иметь в виду
«Десятое правило Гринспуна»
&lt;/p&gt;
&lt;blockquote&gt;

&lt;p&gt;Любая большая система на C или Java содержит тормозную и бажную
реализацию половины Common Lisp.
&lt;/p&gt;
&lt;/blockquote&gt;


&lt;p&gt;
и наваял самопальную тормозную бажную полу-Эрланг-полу-Кложу.
&lt;/p&gt;
&lt;p&gt;
Что будет дальше не знаю, но работа обещает быть интересной.
&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/bullshit-mode-on/~4/zsZJzRIXmxo&quot; height=&quot;1&quot; width=&quot;1&quot; alt=&quot;&quot;/&gt;</description>
         <guid isPermaLink="false">http://zahardzhan.github.com/2011/teleautomatics-rf</guid>
         <pubDate>Mon, 09 May 2011 00:00:00 +0000</pubDate>
      </item>
      <item>
         <title>Совместное использование Clojure и Java.</title>
         <link>http://lazy-codder.blogspot.com/2010/08/clojure-java.html</link>
         <description>&lt;div style=&quot;text-align:justify;&quot;&gt;&amp;nbsp;&amp;nbsp; &lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size:x-large;&quot;&gt;В&lt;/span&gt;&lt;/b&gt; этом посте я&amp;nbsp;на простом примере покажу&amp;nbsp;как соединить в одном проекте Clojure и Java. Сразу к делу...&lt;/div&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Создадим проект со следующим деревом каталогов по классическому шаблону для Maven проектов:&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://3.bp.blogspot.com/_Z_8vu-Cu4B4/THNEannjPHI/AAAAAAAAAO0/T-3VEZ7Olu4/s1600/clojure_test.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://3.bp.blogspot.com/_Z_8vu-Cu4B4/THNEannjPHI/AAAAAAAAAO0/T-3VEZ7Olu4/s320/clojure_test.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;В папке &lt;i&gt;&lt;b&gt;src/main/clojure&lt;/b&gt;&lt;/i&gt; будут храниться исходники Clojure скриптов. В src/main/java - Java классы соответственно. В папку &lt;i&gt;&lt;b&gt;lib&lt;/b&gt;&lt;/i&gt; помещаем &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;clojure-1.2.0.jar&lt;/span&gt;.&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;&lt;br /&gt;&lt;/div&gt;Мавеновский &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;pom.xml&lt;/span&gt; выглядит следующим образом:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;xml&quot;&gt;&lt;br /&gt;    4.0.0&lt;br /&gt;&lt;br /&gt;    test.clojure&lt;br /&gt;    TestClojure&lt;br /&gt;    1.0-SNAPSHOT&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;                    &lt;br /&gt;            &lt;br /&gt;                com.theoryinpractise&lt;br /&gt;                clojure-maven-plugin&lt;br /&gt;                1.1&lt;br /&gt;                &lt;br /&gt;                    &lt;br /&gt;                        src/main/clojure&lt;br /&gt;                    &lt;br /&gt;                    &lt;br /&gt;                        !telchat.app&lt;br /&gt;                    &lt;br /&gt;                    &lt;br /&gt;                &lt;br /&gt;            &lt;br /&gt;        &lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;        &lt;br /&gt;            org.clojure&lt;br /&gt;            clojure&lt;br /&gt;            1.2.0&lt;br /&gt;        &lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;        &lt;br /&gt;          clojure-releases&lt;br /&gt;          http://build.clojure.org/releases&lt;br /&gt;        &lt;br /&gt;        &lt;br /&gt;          clojars&lt;br /&gt;          http://clojars.org/repo/&lt;br /&gt;        &lt;br /&gt;        &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;Здесь определены зависимости &lt;i&gt;Clojure&lt;/i&gt; версии 1.2.0, указаны репозитории и подключен специальный плагин для компиляции &lt;i&gt;Clojure&lt;/i&gt; скриптов.&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;Теперь давайте немного по-программируем... Для начала определимся со средой для разработки. Лично я привык пользоваться &lt;b&gt;IntellijIDEA&lt;/b&gt;. Для написания примера я использовал &lt;b&gt;IntellijIDEA 9.0.3 Community Edition&lt;/b&gt; + &lt;b&gt;La Clojure&lt;/b&gt; плагин. Данная среда довольно удобная. &lt;i&gt;Clojure&lt;/i&gt; скрипты правильно подсвечиваются и даче работает autocomplition. Так же можно запускать REPL прямо из IDE. Хотя вы можете, так же, смело пользоваться Eclipse или, к примеру, Emacs.&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;Итак, создаем в папке &lt;i&gt;&lt;b&gt;clojure&lt;/b&gt;&lt;/i&gt; пакет &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;example.clojure.hello&lt;/span&gt; и помещаем туда файл Hello.clj.&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://4.bp.blogspot.com/_Z_8vu-Cu4B4/THNIGk6Yn9I/AAAAAAAAAO8/-IIJtx7XXjw/s1600/clojure1.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/_Z_8vu-Cu4B4/THNIGk6Yn9I/AAAAAAAAAO8/-IIJtx7XXjw/s320/clojure1.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Далее наполняем Hello.clj следующим содержанием:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;clojure&quot;&gt;(ns example.clojure.hello.Hello&lt;br /&gt;  (:gen-class&lt;br /&gt;    :methods [[sayHello[] void]&lt;br /&gt;               [sayHello[String] void]&lt;br /&gt;               [callFunction[clojure.lang.IFn] String]]))&lt;br /&gt;&lt;br /&gt;(defn -sayHello&lt;br /&gt;  ([this] (println &quot;Hello, stranger!&quot;))&lt;br /&gt;  ([this name] (println (str &quot;Hello, &quot; name &quot;!&quot;))))&lt;br /&gt;&lt;br /&gt;(defn -callFunction [this javaFunction]&lt;br /&gt;  (javaFunction (str &quot;Vasya&quot; &quot;!&quot;)))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size:small;&quot;&gt;&lt;i&gt;&lt;b&gt;Примечание&lt;/b&gt;&lt;/i&gt;. &lt;i&gt;К сожалению подсветка для Clojure кода в моем блоге не работает. Я думаю, эта проблема решится в ближайшем будущем.&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;Первой же строчкой в Hello.clj мы видим определение &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;namespace&lt;/span&gt;. Это своего рода аналог пакетов в Java. Одна разница, что &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;namespace&lt;/span&gt; в &lt;i&gt;Clojure&lt;/i&gt; должен оканчиваться именем файла, в котором находятся скрипты. В нашем случае - это Hello.clj и поэтому namespace оканчивается словом Hello.&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;Далее идет инструкция &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;(&lt;span class=&quot;Apple-style-span&quot; style=&quot;color:purple;&quot;&gt;:gen-class&lt;/span&gt;)&lt;/span&gt;. Эта инструкция сообщает, что для Hello.clj должен создаваться Hello.class. Для скомпилированного Hello.class автоматически будет создан статический метод &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;main&lt;/span&gt;, который вы можете переопределять.&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;Так же в инструкцию &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color:purple;&quot;&gt;:gen-class&lt;/span&gt;&lt;/span&gt; входит инструкция &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color:purple;&quot;&gt;:methods&lt;/span&gt;&lt;/span&gt;. В ней определены Java методы для &amp;nbsp;Hello.class.&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;(defn -sayHello)&lt;/span&gt; и &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;(defn -callFunction)&lt;/span&gt; переопределяют поведение будущих методов в Hello.class. &lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;Функция &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;sayHello&lt;/span&gt; может принимать от 0 до 1 аргументов. В эту функцию мы будем передавать строку(String) из Java.&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;Функция &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;callFunction&lt;/span&gt; принимает на вход объект типа &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;clojure.lang.IFn&lt;/span&gt;. Это интерфейс, который автоматически реализуют все функции в &lt;i&gt;Clojure&lt;/i&gt;. Мы же реализуем его вручную в Java, чтобы можно было передавать Java код в &lt;i&gt;Clojure&lt;/i&gt;.&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;Реализуем интерфейс &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;clojure.lang.IFn&lt;/span&gt;.&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;В папке java создадим три класса: &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;Function&lt;/span&gt;, &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;MyJavaFunction&lt;/span&gt; и &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;Greeting&lt;/span&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear:both;text-align:center;&quot;&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://4.bp.blogspot.com/_Z_8vu-Cu4B4/THNNZxeTVmI/AAAAAAAAAPE/SVhlnjxn32g/s1600/clojure2.png&quot; style=&quot;margin-left:1em;margin-right:1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/_Z_8vu-Cu4B4/THNNZxeTVmI/AAAAAAAAAPE/SVhlnjxn32g/s320/clojure2.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Класс &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;Function&lt;/span&gt; - абстрактный. Он реализует интерфейс &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;clojure.lang.IFn&lt;/span&gt; следующим образом:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;java&quot;&gt;import clojure.lang.IFn;&lt;br /&gt;import clojure.lang.ISeq;&lt;br /&gt;&lt;br /&gt;public abstract class Function implements IFn {&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke() throws Exception {&lt;br /&gt;        return doInvoke();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o) throws Exception {&lt;br /&gt;        return doInvoke(o);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1) throws Exception {&lt;br /&gt;        return doInvoke(o, o1);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5, o6);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5, o6, o7);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5, o6, o7, o8);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5, o6, o7, o8, o9);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9, Object o10) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9, Object o10, Object o11) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9, Object o10, Object o11, Object o12) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9, Object o10, Object o11, Object o12, Object o13) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9, Object o10, Object o11, Object o12, Object o13, Object o14) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9, Object o10, Object o11, Object o12, Object o13, Object o14, Object o15) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9, Object o10, Object o11, Object o12, Object o13, Object o14, Object o15, Object o16) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9, Object o10, Object o11, Object o12, Object o13, Object o14, Object o15, Object o16, Object o17) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16, o17);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9, Object o10, Object o11, Object o12, Object o13, Object o14, Object o15, Object o16, Object o17, Object o18) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16, o17, o18);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9, Object o10, Object o11, Object o12, Object o13, Object o14, Object o15, Object o16, Object o17, Object o18, Object o19) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16, o17, o18, o19);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object invoke(Object o, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9, Object o10, Object o11, Object o12, Object o13, Object o14, Object o15, Object o16, Object o17, Object o18, Object o19, Object... objects) throws Exception {&lt;br /&gt;        return doInvoke(o, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16, o17, o18, o19, objects);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object applyTo(ISeq iSeq) throws Exception {&lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object call() throws Exception {&lt;br /&gt;        return doInvoke();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void run() {&lt;br /&gt;        doInvoke();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public abstract Object doInvoke(Object... obj);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;Т.о. мы создали что-то вроде адаптера. Теперь мы можем расширять класс Function и переопределять только один метод &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;doInvoke(...)&lt;/span&gt;; как показано в примере &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;MyJavaFunction&lt;/span&gt;:&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre class=&quot;java&quot;&gt;public class MyJavaFunction extends Function {&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Object doInvoke(Object... obj) {&lt;br /&gt;        System.out.println(&quot;Function call from Java!&quot;);&lt;br /&gt;        System.out.println(String.format(&quot;Hello, %s&quot;, obj[0]));&lt;br /&gt;        return &quot;JAVA FUNCTION WORK SUCCESS!&quot;;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Отлично. Теперь собираем все воедино в классе &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;Greeting&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;java&quot;&gt;import example.clojure.hello.Hello;&lt;br /&gt;&lt;br /&gt;public class Greeting {&lt;br /&gt;&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;        Hello hello = new Hello();&lt;br /&gt;        if(args.length == 0) {&lt;br /&gt;            hello.sayHello();&lt;br /&gt;        } else {&lt;br /&gt;            hello.sayHello(args[0]);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        Function fun = new MyJavaFunction();&lt;br /&gt;        String result = hello.callFunction(fun);&lt;br /&gt;        System.out.println(result);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;Итак, перед сборкой и запуском несколько комментариев. В &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;Greeting&lt;/span&gt; мы создаем объект типа Hello из &lt;i&gt;Clojure&lt;/i&gt; namespace &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;example.clojure.hello.Hello&lt;/span&gt; и вызываем функцию &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;sayHello&lt;/span&gt;. Далее мы создаем объект типа &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;Function&lt;/span&gt; и передаем его в &lt;i&gt;Clojure&lt;/i&gt; функцию &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;callFunction&lt;/span&gt; и выводим на экран вернувшийся результат.&lt;/div&gt;&lt;div style=&quot;text-align:justify;&quot;&gt;&lt;br /&gt;&lt;/div&gt;Для того, чтобы собрать проект и упаковать его в jar нужно выполнить следующую команду:&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color:#cccccc;&quot;&gt;mvn clean clojure:compile install&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Чтобы запустить класс Greeting нужно выполнить команду:&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color:#cccccc;&quot;&gt;java -cp target/TestClojure-1.0-SNAPSHOT.jar:lib/clojure-1.2.0.jar Greeting&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;или&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color:#cccccc;&quot;&gt;java -cp target/TestClojure-1.0-SNAPSHOT.jar:lib/clojure-1.2.0.jar Greeting Vasya&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;(Я запускал под Linux. Символ разделения ':' в Windows другой - ';')&lt;br /&gt;&lt;br /&gt;После выполнения вы должны увидеть что-то наподобие такого:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color:#cccccc;&quot;&gt;Hello, stranger!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color:#cccccc;&quot;&gt;Function call from Java!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color:#cccccc;&quot;&gt;Hello, Vasya!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:'Courier New', Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color:#cccccc;&quot;&gt;JAVA FUNCTION WORK SUCCESS!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</description>
         <author>Илья Рудаков</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-1853351228397900107.post-2462106524432473539</guid>
         <pubDate>Mon, 23 Aug 2010 21:39:00 +0000</pubDate>
         <media:thumbnail height="72" url="http://3.bp.blogspot.com/_Z_8vu-Cu4B4/THNEannjPHI/AAAAAAAAAO0/T-3VEZ7Olu4/s72-c/clojure_test.png" width="72" xmlns:media="http://search.yahoo.com/mrss/"/>
      </item>
      <item>
         <title>Clojure</title>
         <link>http://raindog-2.livejournal.com/17140.html</link>
         <description>(может быть интересно только для программистов)&lt;br /&gt;&lt;br /&gt;Было несколько дней поиграть с Clojure.&amp;nbsp;&lt;br /&gt;Мои впечатления:&lt;strong&gt;&lt;br /&gt;&lt;br /&gt;Положительные:&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;1) REPL. Самый полезный  REPL из всех, которыми я когда-либо пользовался. По-настоящему интерактивная разработка. Написал (прямо в REPLе) - протестировал, после того, как работает - скопировал в нормальный файл. Я довольно много пользовался REPL в нескольких других языках (Forth, Python, Erlang) - но почти исключительно для экспериментиров, не для нормальной разработки. За счет особенностей языка в Clojure REPL превращается в полноценный инструмент разработки.&lt;br /&gt;&lt;br /&gt;2) Очень помогает, что maps и sets -  first-class objects, со своим синтаксисом.  Также, квадратные скобки для векторов - мне очень это помогает. Я всегда уважал идеологию Лиспа - everything is a list, но для практического программирования, думаю, нужны &amp;quot;зацепки&amp;quot;, как визуальные приправы к коду. Примерно как засечки в serif-шрифтах - они делают код более читабельным.&lt;br /&gt;&lt;br /&gt;3) Получается легко думать о задаче и выражать мысли в терминах языка. Сложный алгоритм, над которым я думал уже больше года, наконец &amp;quot;вылился&amp;quot; на бумагу, причем именно в виде Clojure-кода.&lt;br /&gt;&lt;br /&gt;4) К моей радости, получается почти не использовать рекурсию в тех случах, когда явно она не нужна. Чтобы объяснить, что я имею в виду под нужной и ненужной, надуманной рекурсией. Нужная рекурсия - например, в каком-то алгориме обхода дерева. Или в алгоритме quicksort. Потому что сам алгоритм определяется в терминах рекурсии. Надуманная рекурсия - это, например, имплементация факториала как x * f(x-1). Факториал определен как 1 * 2 * 3 * ... * N, поэтому &amp;quot;правильно&amp;quot; его имплементировать с помощью функции reduce.&lt;br /&gt;Или, например, еще пример &amp;quot;неправильной рекурсии&amp;quot;: когда нужно N раз что-то сделать, использовать tail-recursion со счетчиком N. Нет, правильная имплементация - это, например, в Руби: N.times do ....&lt;br /&gt;&lt;br /&gt;5) Вся идея persistent data structures - очень здоровая.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Отрицательные:&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;1) Изо всех щелей лезет Джава. Я понимаю все преимущества, которые мы получаем for free вместе с JVM, но все равно, на мой вкус, нужно слишком много знать о Джаве, чтобы писать на Clojure. Я к ней не прикасался уже 5 лет, но, похоже, придется.&lt;br /&gt;&lt;br /&gt;2) Язык динамический, поэтому компилятор помогает очень мало, а сообщения о run-time ошибках - совершенно неинформативные, ничего понять по ним невозможно (мне, по крайней мере). В результате - идею алгоритма я описал в Clojure коде за день, очень компактно - на страничку (на С++ заняло бы на порядок больше). Пока не запустил, находился в эйфории....Но теперь уже 3 дня не могу этот код отладить. В общем, делаю гораздо больше ошибок, чем в Haskell-коде (там, правда, другая история - скомпилировать невозможно, пока все ошибки не найдешь, зато в run-time - все магически работает с первого раза). И даже в Erlang - хотя он тоже динамический. И ошибок делал меньше, и находил их гораздо быстрее. Не знаю, почему. Возможно, потому что Erlang проще как язык и встроенных возможностей меньше. Ну и pattern matching в Erlang очень помогает - хотя ошибка происходит в runtime, но сразу понятно, в каком месте, что конкретно неcmatchилось.&lt;br /&gt;&lt;br /&gt;3) Документация хуже чем у всех последних языков, которые я изучал. Онлайн-документация мне не нравится - и поиск по ней организован плохо, и объяснения не всегда достаточные. Книги у меня уже все три (Practical Clojure &amp;lt; Programming Clojure &amp;lt;&amp;lt; Joy of Clojure), но ни одна из них не работает в качестве reference.&lt;br /&gt;&lt;br /&gt;4) Легкий дискомфорт оттого, что nil и пустой список - это разные вещи. Например, функции типа get или nth работают совсем по-разному на nil и пустых структурах данных. И еще один уровень сложности - булевы переменные, что считается true и что - нет. В общем, я понимаю, это дает больше flexibility, но мне больше нравился чистый подход Erlang, когда нет никаких &amp;quot;специальных&amp;quot; вещей типа nil, и даже булевых переменных нет. Паттерн матчинг - и вперед; true - это просто атом. Но это уже так, &amp;quot;вкусовщина&amp;quot;.&lt;br /&gt;&lt;br /&gt;5) Идея о том, что любые коллекции могут притворяться sequence, с одной стороны, хороша. С другой стороны, там под низом все равно сидит конкретная структура данных, и что во что преобразовывается - не всегда понятно. Точнее, понятно, описано, но - неинтуитивно как-то. И не только в случах с sequence. Например, к записи (в смысле defrecord) можно добавить поле в рантайм, как к обычной hash map, от этого она не перестает быть записью. Но если удалить поле, то она превращается в map. Запомнить несложно. Но в языке как-то уж очень много таких &amp;quot;специальных правил&amp;quot;. С другой стороны, Perl я люблю, несмотря на количество специальных правил, как родного уродца. Так что, может, и тут постепенно &amp;quot;сроднюсь&amp;quot;.&lt;br /&gt;&lt;br /&gt;Если взвесить за и против, положительные впечатления значительно перевешивают. Единственная реальная проблема - (2), c малополезными сообщениями об ошибках. Надеюсь улучшить навыки отладки со временем.&lt;br /&gt;&lt;br /&gt;Да, еще пару слов о среде разработки. Лучше всего работало - просто REPL в командной строке и открытый файл в vi, в другом окне. За тем исключением, что REPL не имеет истории (или я не нашел, как ей пользоваться). &lt;br /&gt;Пробовал установить plug-in к Eclipse. Почти все хорошо, но раздражает то, что я не могу понять его логики. Иногда мне достаточно сохранить .clj-файл, чтобы в REPL в консоли увидел все изменения. А иногда - нет, нужно явно выделять и копировать из редактора в REPL. А вчера начал разбираться с defrecord - вообще отакзывалось принимать новые определения записи с тем же именем, пришлось перезапустить Eclipse.&lt;br /&gt;Посмотрю еще на VimClojure.&lt;br /&gt;&lt;br /&gt;В общем, пока что, Clojure - это очень интересно!&lt;a rel=&quot;nofollow&quot; name='cutid1-end'&gt;&lt;/a&gt;</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:raindog_2:17140</guid>
         <pubDate>Fri, 10 Sep 2010 23:41:53 +0000</pubDate>
      </item>
      <item>
         <title>Game of Life and Clojure</title>
         <link>http://raindog-2.livejournal.com/16470.html</link>
         <description>(это продолжение п&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://raindog-2.livejournal.com/16199.html&quot;&gt;рошлой заметки о программировании на Closure&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Итак, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Conway&amp;amp;quot;s_Game_of_Life&quot;&gt;игра Жизнь&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Идея имплементации такая. Популяция описывается массивом позиций занятых клеток. Каждая позиция - это просто пара [x,y]. &lt;br /&gt;Дальше для каждой отдельно выбранной занятой позиции [x,y] строим таблицу координата -&amp;gt; значение, где координаты - это cоседи клетки [x, y] и она сама. Для соседей значение = 1, для самой клетки - значение = 10.&lt;br /&gt;Потом &amp;quot;складываем&amp;quot; все таблицы для всех клеток популяции. В полученной таблице живые клетки следующей популяции будут равны 3 (новорожденные) или 12 или 13 (старые клетки, которые имели одного или двух соседей). Фильтруем таблицу по значениям и берем ее ключи - это и есть следующее поколение популяции.&lt;br /&gt;&lt;br /&gt;На языке Clojure это будет выражаться так (не пинать больно, я только на прошлой неделе стал изучать Closure):&lt;br /&gt;&lt;br /&gt;Относительные координаты 8 соседей каждой клетки:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(def nbr-deltas [[-1 -1][-1 0][-1 1][0 -1][0 1][1 -1][1 0][1 1]])&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Функция, которая расчитывает координаты соседей клетки [x y]:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(defn nbr-cells [[x y]] (map (fn [[a b]] [(+ x a)(+ y b)]) nbr-deltas))&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Таблица значений для одной клетки cell (cell - то же самое, что [x y]):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(defn cell-table [cell] (apply conj {cell 10} (map #(vec [% 1]) (nbr-cells cell))))&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Складываем все таблицы для популяции cells:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(defn all-table [cells] (apply merge-with + (map cell-table cells)))&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Все, осталось только отфильтровать эту таблицу по значениям и взять ее ключи:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(defn next-gen [cells] (keys (filter #(#{3 12 13} (second %)) (all-table cells))))&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Функция next-gen берет на входе популяцию и возвращает следующее состояние популяции.&lt;br /&gt;Готово! Для имплементации правил понадобилось всего 4 функции - красота!&lt;br /&gt;&lt;br /&gt;Чтобы расчитать на n поколений вперед, используем цикл (ну, через рекурсию):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(defn n-next-gen [n cells] (if (== n 0) cells (recur (- n 1) (next-gen cells))))&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;(Наверное, это можно было изящнее записать, с помощью loop, но я пока не разобрался как).&lt;br /&gt;&lt;br /&gt;Для тестирования хорошо использовать одну из первых &amp;quot;трудных&amp;quot; популяций Жизни: r-пентамино:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(def r-pentomino [[0 1][1 1][2 1][1 2][2 0]])&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.conwaylife.com/wiki/index.php?title=R-pentomino&quot;&gt;Как известно&lt;/a&gt;, эволюция этой популяции стабилизируется только на 1103 поколении, и она с этого момента насчитывает 116 клеток.&lt;br /&gt;Проверяем:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(count (n-next-gen 1103 r-pentomino))&lt;/code&gt;&lt;br /&gt;116 &lt;br /&gt;&lt;br /&gt;Ура! Все работает. Расчет занял 12 секунд на МacBook Pro (2.53 GHz Intel Core 2 Duo, 4GB RAM), то есть около 100 поколений в секунду.&lt;br /&gt;Теперь интересно попробовать поизменять детали имплементации и посмотреть, как это влияет на производительность.&lt;br /&gt;&lt;br /&gt;В имплеменации только одна деталь, специфическая для Clojure - функция merge-with. Если забыть об этой детали, имплементацию можно без проблем портировать на другие языки. Что я и попробую сделать - интересно, как это будет выглядеть и как быстро будет считаться. Вместо merge-with нужно будет что-то придумать, в зависимости от возможностей языка.&lt;br /&gt;&lt;br /&gt;Ну и, конечно, следующий шаг - нужно сделать простенький GUI.&lt;a rel=&quot;nofollow&quot; name='cutid1-end'&gt;&lt;/a&gt;</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:raindog_2:16470</guid>
         <pubDate>Wed, 25 Aug 2010 07:39:53 +0000</pubDate>
      </item>
      <item>
         <title>Clojure</title>
         <link>http://raindog-2.livejournal.com/16199.html</link>
         <description>(запись может быть интересна только программистам)&lt;br /&gt;Какое-то время я следовал правилу - в год изучать по языку. Так &amp;quot;прошел&amp;quot; Haskell, D, Lua, Erlang. Сейчас взялся за Clojure.&lt;br /&gt;&lt;br /&gt;Купил даже книгу &amp;quot;Practical Clojure&amp;quot; - люблю бумажные книги о языках,  читать книги с экрана мне не нравится.&lt;br /&gt;&lt;br /&gt;Ниже - первые впечатления о Clojure и связанные вопросы.&lt;br /&gt;&lt;br /&gt;В языке много неортогональностей. Одно и то же можно делать разными способами, что, в-общем, мне нравится (TIMTOWTDI, Perl мне нравится больше Python). Но хорошо понимать trade-offs и зачем в принципе включены разные возможности. Например, в Erlang мне очень понравились атомы - это то, что в некоторых других языках называют еще символами. Просто слова, которые означают самих себя. В Erlang даже нет отдельного булевского типа, true и false - это просто атомы. В сочетании с pattern matching атомы очень-очень удобны. В Closure есть символы... но есть и keywords. Зачем нужны keywords, если вместно них можно использовать symbols? В книге об этом ничего не говорится, или я пропустил.&lt;br /&gt;&lt;br /&gt;Дальше, векторы и списки. Когда что использовать? Если нужно быстрый nth, то, понятно - вектор. Если добавлять что-то в голову - наверное, список. Но что, если мне нужен просто маленький tuple, скажем, просто пара значений? Отдельного типа данных tuple нет. Что лучше - список или вектор? или вообще что-то другое? и в каком смысле лучше - скорость, память? Как-то про это тоже ничего в книге не нашел.&lt;br /&gt;&lt;br /&gt;Теперь pattern matching. Это понятие вообще в книге не упоминается, и в языке нет такого продвинутого pattern matching-а, как в Haskell или  Erlang.&lt;br /&gt;Но тем не менее, я могу определить функцию как &lt;br /&gt;(defn f [[x y] z] (+ x y z))&lt;br /&gt;и она будет ожидать два аргумента, первый из которых - вектор, и сразу bind-ить его элементы как x и y. То есть вызвать ее можно будет как (f [1 2] 3)&lt;br /&gt;Но оказывается - не обязательно вектор. Можно вызвать функцию и так: (f '(1 2) 3)&lt;br /&gt;А вот так не работает: (f 1 2) - выбрасывает эксепшн, что к типу Integer нельзя применить операцию nth. Ага. Значит никакого matching-а типов не делается, просто к типу применяется операция nth. Интересно, можно ли туда передать еще что-нибудь, что откликается на nth? Что? Все это как-то путем проб и ошибок, а, казалось правила binding должны быть высечены в камне... в книге как-то я вообще об этом ничего не было... или я пропустил?&lt;br /&gt;&lt;br /&gt;Дальше еще одно. В философии языка все время делается упор на immutable data, чистое функциональное программирование,где все side effects четко выделены. Хорошо, но почему я тогда могу спокойно переопределить переменную? И, главное, все функции, которые ее видели при определении, ведут себя не как closure. Вместо того, чтобы запомнить ее значение на момент создания, они используют ее текущее значение на момент вызова. &lt;br /&gt;Например,&lt;br /&gt;&lt;br /&gt;(def pi 3.14)&lt;br /&gt;(defn area [r] (* pi r r))&lt;br /&gt;(area 1)&lt;br /&gt;3.14&lt;br /&gt;(def pi 3)&lt;br /&gt;(area 1)&lt;br /&gt;3&lt;br /&gt;&lt;br /&gt;Ну и в чем тогда отличие от глобальных переменных в императивных языках программирования?&lt;br /&gt;&lt;br /&gt;Дальше, STM - тут все очень интересно и классно. Целых 3 разных инструмента - refs,  atoms, agents. Пока что я просто не понимаю, когда и как все это использовать, но думаю, с практикой это придет. Вначале я подумал, что agents - это то же самое, что процессы в Erlang, но, оказалось, увы, не совсем. Но все равно, STM и persistent data structures - это все очень интересно. На C++ ный multithreaded код мне уже давно страшно смотреть. А приходится.&lt;br /&gt;&lt;br /&gt;Да, теперь интересно найти какую-то GUI или graphics бибилиотеку для Clojure, чтобы поэкспериментировать. Я попробовал написать игру &amp;quot;жизнь&amp;quot;, и к моему удивлению это очень просто получилось, вся имплементация на Clojure заняла 10 строчек и все заработало с первого раза. Это хороший знак, у меня так было только с Haskell-ем, чтобы что-то с первого же раза работало as intended. Но красивого вывода на экран нет - а хочется. Как я понял, clojure-народ пользуется для GUI жавским Swing-ом. Как-то неохота его изучать, не знаю, есть ли другие удобные способы.&lt;br /&gt;&lt;br /&gt;А в общем - очень интересный язык! Сегодня попробую поиграть с мультиметодами.&lt;br /&gt;&lt;br /&gt;P.S. Описал свою имплементацию Жизни в &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://raindog-2.livejournal.com/16470.html&quot;&gt;следующей заметке&lt;/a&gt;.&lt;br /&gt;&lt;a rel=&quot;nofollow&quot; name='cutid1-end'&gt;&lt;/a&gt;&amp;nbsp;</description>
         <guid isPermaLink="false">urn:lj:livejournal.com:atom1:raindog_2:16199</guid>
         <pubDate>Tue, 24 Aug 2010 21:25:13 +0000</pubDate>
      </item>
      <item>
         <title>Разговор со спикерами FPConf (часть 2)</title>
         <link>http://habrahabr.ru/post/264737/</link>
         <description>&lt;br/&gt;Привет!&lt;br/&gt;
&lt;br/&gt;
Конференция &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://fpconf.ru/&quot;&gt;FPConf&lt;/a&gt; уже завтра, сегодня последний шанс купить билет и присоединиться! Регистрация — &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://fpconf.ru/&quot;&gt;тут&lt;/a&gt;.&lt;br/&gt;
&lt;br/&gt;
Накануне мы решили задать нашим спикерам один довольно неоднозначный вопрос. Большая часть ответов была опубликована вчера — &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://habrahabr.ru/company/railsclub/blog/264695/&quot;&gt;тут&lt;/a&gt;&lt;br/&gt;
&lt;br/&gt;
А сегодня мы получили ответ от нашего гостя Эдварда Кметта. Пока публикуем без перевода, обновим пост после конференции.&lt;br/&gt;
&lt;br/&gt;
&lt;img src=&quot;https://habrastorage.org/getpro/habr/post_images/b9b/b0f/0ff/b9bb0f0ffe8c47b637a470dd809b267e.jpg&quot; alt=&quot;image&quot;/&gt;&lt;br/&gt;
&lt;br/&gt;
Вопрос был такой:&lt;br/&gt;
&lt;br/&gt;
&lt;i&gt;В объектно-ориентированных языках есть широко известный список паттернов проектирования (design patterns) от «Банды четырех» (Gang of Four). В функциональных языках такого известного списка не существует. С вашей точки зрения, почему так?&lt;br/&gt;
Подобные паттерны не нужны при программировании на функциональных языках или просто их канонический список еще не сложился?&lt;/i&gt;&lt;br/&gt;
&lt;br/&gt;
 &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://habrahabr.ru/post/264737/#habracut&quot;&gt;Читать дальше &amp;rarr;&lt;/a&gt;</description>
         <author>elena_voronina</author>
         <guid isPermaLink="false">http://habrahabr.ru/post/264737/</guid>
         <pubDate>Fri, 14 Aug 2015 06:34:09 +0000</pubDate>
      </item>
      <item>
         <title>Разговор со спикерами FPConf</title>
         <link>http://habrahabr.ru/post/264695/</link>
         <description>&lt;br/&gt;Привет!&lt;br/&gt;
&lt;br/&gt;
Конференция &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://fpconf.ru/&quot;&gt;FPConf&lt;/a&gt; уже в эту субботу, нас аж 160 и еще не поздно заскочить в последний вагон. Регистрация — &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://fpconf.ru/&quot;&gt;тут&lt;/a&gt;.&lt;br/&gt;
&lt;br/&gt;
А накануне мы решили задать нашим спикерам один довольно неоднозначный вопрос. Публикуем ответы, ваши варианты в комментах люто приветствуются!&lt;br/&gt;
&lt;br/&gt;
&lt;img src=&quot;https://habrastorage.org/getpro/habr/post_images/b9b/b0f/0ff/b9bb0f0ffe8c47b637a470dd809b267e.jpg&quot; alt=&quot;image&quot;/&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;i&gt;В объектно-ориентированных языках есть широко известный список паттернов проектирования (design patterns) от «Банды четырех» (Gang of Four). В функциональных языках такого известного списка не существует. С вашей точки зрения, почему так?&lt;br/&gt;
Подобные паттерны не нужны при программировании на функциональных языках или просто их канонический список еще не сложился?&lt;/i&gt;&lt;br/&gt;
&lt;br/&gt;
 &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://habrahabr.ru/post/264695/#habracut&quot;&gt;Читать дальше &amp;rarr;&lt;/a&gt;</description>
         <author>elena_voronina</author>
         <guid isPermaLink="false">http://habrahabr.ru/post/264695/</guid>
         <pubDate>Thu, 13 Aug 2015 13:04:31 +0000</pubDate>
      </item>
   </channel>
</rss>
<!-- fe2.yql.bf1.yahoo.com compressed/chunked Thu Oct  1 23:22:57 UTC 2015 -->
