Пользователь
0,0
рейтинг
18 января 2011 в 11:13

Разработка → Пример сайта на Common Lisp

Введение





Это статья написана, чтобы иллюстрировать применение возможностей Common Lisp к типичным задачам веб-разработки.

Я постараюсь показать, как на лиспе реализовываются основные применяемые в веб-программировании вещи — шаблонизация, роутинг и кеширование. Также я оставил немножко места для макросов.

Статья в большой степени учебная, тем не менее это вполне работающий веб-сайт — rigidus.ru



Шаблоны и их компиляция



{namespace tpl}
{template root}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">{\n}
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">{\n}
  <head>{\n}
	<title>{$headtitle}</title>{\n}
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />{\n}
	<link rel="stylesheet" type="text/css" media="screen" href="/style.css" />{\n}
	<link rel="Shortcut Icon" type="image/x-icon" href="/favicon.ico" />{\n}
  </head>{\n}
  <body id="top">{\n}
    {$content | noAutoescape}{\n}
  </body>{\n}
</html>{\n}
{/template}


Этот простой шаблон с помощью библиотеки CL-CLOSURE-TEMPLATE на лету компилируется в машинный код функции root, находящейся в пакете tpl. Таким образом, применение данных к шаблону — это вызов скомпилированной функции:

(tpl:root (list :headtitle "Мой заголовок"
                :content "Hello world"))


Вместо «Hello world» можно подставить вызов функции, в которую компилируется другой шаблон — например шаблон «base», обеспечивающий минимальную сетку для сайта:

{template base}
<div id="center">
  <div class="col1 left">
    <a id="logo" href="index.html">
      <img src="http://www.gravatar.com/avatar/d8a986606b9d5e4769ba062779e95d9f?s=45"
           style="border: 1px solid #7F7F7F"/>
    </a>
    <ul id="nav">
      {foreach $elt in $navpoints}
      {call navelt data="$elt" /}
      {/foreach}
    </ul>
  </div>
  {$content |noAutoescape}
  <div class="clear">.</div>
</div>
<div id="footer">
  <p>
    <a href="/about">About</a> |
    <a href="/contacts">Contacts</a>
  </p>
</div>
{/template}


Теперь, воспользовавшись примером вводной статьи habrahabr.ru/blogs/webdev/111365 и нашим свежесозданным шаблоном, мы могли бы написать request-dispatcher для сайта из одной страницы так:

(defun request-dispatcher (request)
   (tpl:root (list :headtitle "My home page"
                   :content (tpl:base (list :navpoints ..тут-меню..
                                           :content ..тут-контент..)))))


Маршруты RESTAS



Библиотека RESTAS освобождает нас от увлекательного написания диспетчеров.
Теперь диспетчер будет создан на базе задаваемых нами маршрутов (routes), которые мы определяем вот так:

(restas:define-route main ("")
  (tpl:main (list :headtitle "My main page"
                  :content "Hello! <a href=\"/articles\">Articles</a>")))

(restas:define-route css ("/css/:cssfile")
  (hunchentoot:handle-static-file (format nil "~a/css/~a" *base-dir* cssfile)))


— Что это за бред? — спросит искушенный веб-разработчик. — Это я же должен задавать для каждого css-файла свой маршрут?

— Вовсе нет! — отвечу я. Можно задавать лямбду :requirement, которая решит, подходит ли маршрут или нет. Вот обновленный код, который отдает файл, если находит его на диске в каталоге сайта:

(restas:define-route static
    ("/:staticfile"
     :requirement (lambda ()
                    (let ((request-file
                           (pathname
                            (format nil "~a/~a" *base-dir*
                                    (hunchentoot:request-uri hunchentoot:*request*))))
                          (files (directory (format nil "~a/*.*" *base-dir*))))
                      (not (null (find request-file files :test #'equal))))))
  (hunchentoot:handle-static-file (format nil "~a/~a" *base-dir* staticfile)))


Здесь мы просто определили маршруты для главной страницы и для отдачи css-файлов — как видите можно использовать, :wildcards

Использование макросов



Я подготавливаваю статьи для сайта, используя org-mode — удобный режим Емакса, сочетающий простоту разметки (как вики) и различные удобные средства, вроде сворачивания разделов. Я написал функцию org-to-html,
которой передаю текст статьи в формате org-mode, а она автоматически строит мне html с заголовками, извлеченными из метаданнных, указанных прямо в статье, а также возвращает информацию о секциях и подсекциях.

После того, как эта функция обработает мой файл мне может понадобиться изменить некоторые заголовки и чтобы сохранить простоту вызова я использую макрос default-page:

(defmacro default-page (menu file-path &optional (body nil))
  `(let ((menu-memo ,menu))
     (multiple-value-bind (content sections directives)
         (org-to-html (alexandria:read-file-into-string ,file-path))
       (let ((title (getf directives :title)))
         ,body
         (page title menu-memo
               (tpl:default
                   (list :title title :navpoints menu-memo
                         :sections
                         (loop
                            :for i :from 1
                            :for section :in sections :collect
                            (list :anchor (format nil "anchor-~a" i)
                                  :level (format nil "level-~a" (car section))
                                  :title (cadr section)))
                         :content content)))))))


Теперь я могу не только избавиться от сложного вызова в клиентском коде, но и сделать «иньекцию» любого кода внутрь default-page, например так:

(restas:define-route about ("/about")
  (default-page (menu) (base-path "about.org")
    ;; Здесь я могу  подсчитать кол-во секций
    (let ((cnt (length sections)))
      ;; И вывести их например в заголовкe
      (setf title (format nil "~a — ~a секций" title cnt)))))


В следующем разделе этот подход используется более осмысленно.

Кеширование



Статьи у меня лежат в файлах, содержащих метаинформацию: заголовки и категории. Чтобы построить страницу "/articles" я прохожу по файлам, что может требовать времени и загружать систему. Однако эти данные можно
запомнить в замыкании, что и делает вот такой код:

(let ((memo))
  (restas:define-route articles ("/articles")
    (when (null memo)
      (setf memo
            (default-page (menu) (base-path "articles.org")
              (setf content
                    ;; Здесь код, который собирает страницу
                    ;; по файлам (я не стал его приводить)
                    ))))
    memo))


Понятно, что если необходимо, чтобы кеш устаревал с течением времени — это тоже довольно несложно реализовать. Пока мне проще зайти в slime, сделать Ctrl+X, Ctrl+E на последней строчке этого кода и он будет выполнен заново, что приведет к обнулению кеша. Загружая новую статью (что бывает не
слишком часто) я так и делаю — это хороший повод тут же добавить еще какой-нибудь функционал.

Для интересующихся деталями:
Я разместил исходный код на github.com/rigidus/rigidus.ru
А сам сайт находится на rigidus.ru
Посмотрим, как он справится с хабраэффектом.
Глухов Михаил @Rigidus
карма
26,5
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (131)

  • +3
    Все-таки, почему использовали lisp для этой задачи. Какие у него преимущества в данной области? Или просто ради интереса.
    • +3
      Просто поизвращаться…
      • +5
        Преимуществ так много, что лучше даже разбить их по категориям. Во-первых, чисто системные:
        * абсолютно нативная поддержка юникода
        * скорость (в отличии от интерпретаторов пхп или руби все компилируется в машинный код)
        * компактный код — весь сайт с отображением нескольких типов страниц, отправкой почты и преобразованием из org-mode — менее 300 строк кода и всего один файл.
        * скорость разработки — все написал не напрягаясь за пару вечеров.
        При этом куча дополнительных плюшек:
        * горячая замена кода
        * кое-что получше чем исключения (я говорю о conditions|restarts — стоит почитать)
        * потрясающаяся расширямость во всех направлениях
        * отсутствие неквалифицированных персонажей в комьюнити (если ты видишь лиспера — он априори не дурак)
        * огромное удовольствие при программировании — изучая лисп понимаешь, каким оно должно быть.
        * простота освоения — язык хорошо спроектирован, подход, применимый в одном случае (поиск в строке, например), будет работать без изменений и в другом (поиск в коллекции объектов)
        Это так, в качестве примера. Мог бы еще преимуществ накидать, но по мне так двух случайно выбранных пунктов вполне достаточно чтобы задуматься о переходе на лисп.
        • 0
          Если короче — ЕМАКС теперь еще и CMS :-)
          А остальной список из любого холивара про ЕМАКС.
        • 0
          Можно объяснить, как сочетаются отсутствие неквалифицированных персонажей и простота освоения?
          • +1
            Магия :) Лиспом занимаются в основном умные люди, с хорошим программистким опытом — они развивают язык так, чтобы он был изящным, простым и понятным, а не так, как того требует маркетинг и основная масса пользователей (большая часть которых малоквалифицирована). В результате всего что связано с лиспом мало, но оно высокого качества (я имею ввиду сообщества, библиотеки и руководства)
            • 0
              Вот, например, относительно Хаскеля существует мнение, что у него высокий входной порог, в результате чего сообщество состоит из квалифицированных программистов. Что же отпугивает неквалифицированных программистов от ЛИСПа, как считаете?
              • +1
                Имидж лиспа как академического языка (для искусственного интеллекта) с невозможным синтаксисом. С реальностью этот имидж имеет мало общего
        • +1
          > При этом куча дополнительных плюшек:

          Вы забыли упомянуть самую главную плюшку: совершенно вырвиглазный синтаксис, который для некоторых аннулирует любые другие мифические и не очень плюшки.
          • 0
            В лиспе нет синтаксиса, вернее он настолько необременительный, что не заслоняет семантику. Вы можете сделать с ним все что угодно на ваш вкус. Учитывая последнее обстоятельство стоит задуматься, почему люди, освоившие лисп предпочитают старый синтаксис без изменений — может в нем действительно что-то есть? ;-)
            • –1
              > почему люди, освоившие лисп предпочитают старый синтаксис без изменений

              А его просто нельзя изменить. Нельзя сделать язык со свойствами CL на базе С-синтаксиса.
              • 0
                какими такими особыми свойствами? (за исключением «программа — это список», аллилуйя!)
                • +1
                  Например, на этот основано метапрограммирование. Ньюансов много разных.
                  • 0
                    если под метапрограммированием вы понимаете лисповые макросы, то берем Template Haskell, metalua или Nemerle и убеждаемся, что и в языках, неоснованных на sexpr, существует метапрограммирование на уровне синтаксических деревьев.
                    • +1
                      Безусловно. Только это другие языки. Не такие как CL. И сделано там метапрограммирование совсем по другому. Я говорю о том, что конкретно CL практически не реально сделать на основе другого синтаксиса.
            • –4
              > вернее он настолько необременительный, что не заслоняет семантику

              пышь-пышь, предположим вы написали кусок программы ну хотя бы на 5 KLOC ушли на полгода, вернулись и снова посмотрели на эти 5 KLOC. у меня есть гипотеза, что время, которое вы все-таки потратите на восстановление «картинки в голове», несколько больше для lisp, чем для языка с «обременительным» и замороженным синтаксисом.
              • 0
                Гипотеза неверная, проверенно на опыте.
              • –1
                Я тоже проверял — лисп понятнее
            • 0
              Вообще-то в Clojure сделаны очень приятные косметические изменения синтаксиса. Т.е. есть куда улучшать ИМХО.

              (let ((x 2) (y 3)) ...) => (let [x 2 y 3] ...) и т.п.
              • 0
                Все это сущие пустяки. Количество скобок в лиспе можно уменьшить, если отказаться от неявного do.

                (let ((x 2) (y 3)) ...) => (let [x 2 y 3] ...) => (let x 2 y 3 (do ...)) ну и т.п. для других форм.
          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              нет, скобочки мне не особо мешают видеть структуру программы, я просто предпочитаю старый добрый алголо-подобный синтаксис.
              • НЛО прилетело и опубликовало эту надпись здесь
                • 0
                  разумеется, а вы где-то видели, чтобы я за всех людей на земле говорил?
                  • НЛО прилетело и опубликовало эту надпись здесь
                    • 0
                      если дальше читать, то там слово «некоторых» можно обнаружить, а не «всех».

                      кому-то вырвиглазный синтаксис приятен и невырвиглазен, я с этим и не спорю.
          • 0
            Вы забыли упомянуть самую главную плюшку: совершенно вырвиглазный синтаксис, который для некоторых аннулирует любые другие мифические и не очень плюшки.

            А вот я — просто тащусь. Хотя сам совершенно не лиспер и даже не пробовал на нём программировать, но каждый раз, как посмотрю на этот код и посмотрю, как он улыбается мне — так сразу на душе так хорошо становится. Вот даже сейчас.

            И потому думаю, что я таки изучу Лисп (и в первую очередь (из-за этих (улыбающихся(скобочек)))).

            И мне на самом деле визуально приятен синтаксис Лиспа.
        • –4
          хм,

          а вот что не нравится в допустим сочетании C# и asp.net

          1) конечно же много файликов — но они почти создаются автоматический
          2) но маршутизация, привзяка к бд и прочие настройки находятся в одном xml файлике
          web.config
          3) тажке все компилится (при этом компиляция в машиный код происходит тока при первом обращении, дальше все в оперативке, что бытсрее)
          4) уже готовое и настроенное кеширование
          5) настоящая простота освоения (так как C# намного легче освоить чем лисп)

          и еще кучу плюшек которые уже сделаны за вас так, что остается буквально, создать три странички, написать в них пару строк кода и все работает…

          Т.е. тоже самое можно сделать за пол часика-) вместо нескольких вечеров=)
          • +8
            В asp.net при попытке выйти за пределы стандартной схемы начинается жуть разная. Т.е. это нормально работает только для стандартных (с точки зрения разработчиков ASP.NET) приложений. Если ваше приложение не такое, то с asp.net лучше не связываться.

            Кроме того, так же нет REPL, макросов, CLOS и т.п., т.е. более слабый язык. Да ещё и не работает на нормальных ОС.
        • +4
          Было бы очень интересно взять какую-то типовую задачу (включающую в себя шаблонизацию, роутинг, кеширование, работу с БД) и сравнить её решение на Lisp с решениями на других популярных языках (Perl, PHP, Python, Ruby, Asp.Net, etc.). Все-таки в преимуществах хочется увидеть конкретные цифры с примерами.
          • +2
            Если ваше предложение будет поддержано программистами на других языках — я не вижу причин чтобы не поучаствовать в этом соревновании :)
          • 0
            Мне бы тоже было интересно. Обычно в таких холиварных топиках очень много лулзов, главное вовремя уворачиваться, а то могу ненароком и в тебя попасть лепёшкой а потом облить помоями. ;)

          • 0
            Тогда стоило бы показать итеративный процесс разработки, а не только конечный результат. REPL — это просто невероятный плюс в Clojure. Вероятно в других языках тоже.
        • 0
          > скорость разработки — все написал не напрягаясь за пару вечеров.
          для такого объема работ — это непотребно огромное кол-во времени.
          Хватило бы часа 3 на том же PHP или Ruby
          • 0
            Думаю, вам стоит оценить объем работ, слив файл с гитхаба. То что изложено в статье — это лишь примеры подхода :)
            • –1
              Код вперемешку с версткой. Красота…
              И написание собственной велосипедной реализации того, что уже давно реализовано в нормальных фреймворках нельзя считать за рациональную трату времени.
              • 0
                > написание собственной велосипедной реализации

                О чем речь?
            • 0
              Оценил.
              Временные рамки не изменились.
              Ну, можно накинуть еще пару часов- если делать это за чашечкой чая, смотря в телевизор — т.е. совсем не напрягаясь.
    • +2
      Есть отличная статья Пола Грэма на эту тему http://www.nestor.minsk.by/sr/2003/07/30710.html.
      • +2
        Побеждая посредственность — это как раз про Михаила (Rigidus).
      • +3
        Пол Грэм мастер побеждать посредственность — написал на лиспе электронный магазин, продал его Yahoo!, а те возьми и перепиши его на C++ & Perl.

        Что-то тут явно нечисто :-)
        • 0
          Всё логично, в общем-то. Он уволился, а поддерживать не смогли, ибо в то время стали модными другие языки программирования, а лисперов всегда было сложно найти.
          • 0
            Но заработал хорошо, что характерно :)
          • +1
            > а поддерживать не смогли

            вот-вот, ключевой момент.

            где так сказать гарантия, что Грэм сам что-то «поддерживал», а не оттягивал момент колапса, вооружившись «гибкостью и экспресивностью» чудо языка и накладывая заплатки поверх заплаток?
            • –2
              это мнение основано на фактах или на домыслах? :)
              • 0
                какое мнение?

                там вообще вопрос в конце предложения стоит.
                • –2
                  Чтобы задавать такой вопрос нужно располагать какими-то сведениями, иначе это типичный журналистский вопрос
                  • +3
                    вопрос является естественным следствием того факта, что Yahoo предпочли переписать приложение целиком. почему спрашивается? Грэм, конечно же, гордо заявляет, что Yahoo просто не осилило lisp.

                    Но это «бзззз» неспроста как говорил Винни Пух. Грэм опять же сам писал, что lisp позволил им, не побоюсь этого слова, лабать со страшной скоростью, недоступной конкурентам. У меня естественно возникает сомнение, здоровый скепсис, в отношении качества кода, который стал результатом этой гонки. Но это только сомнение, ни Грэм-то, ни Yahoo, код это не показывают никому. Только сферические эссе в вакууме… Но тут видите какая ситуация, такие эссе про каждый второй язык программирования есть — кому-то монады сами баги ловят, кому-то макросы сами код пишут и так далее. Без скепсиса тут никак нельзя.
                    • 0
                      Да Грэм это вообще отдельная история.

                      Во-первых, то его приложение было гвоздями прибито к CLisp, медленной реализации.
                      Во-вторых, оно использовало «продолжения», т.е. просто не было масштабируемым.

                      Естественно, когда встал вопрос о другой нагрузке, то приложение надо было переписывать фактически полностью. На чём переписывать? Поскольку Грэма уже не было, то язык выбирали заново. Выбрали что знали лучше и что знали, что будет работать.

                      Ну, конечно, Грэм подаёт эту историю несколько по другому.
                      • –1
                        Думаю Грэм использовал преимущества интеллекта, а Yahoo — организационный ресурс. Это вопрос подхода. Останься Yahoo на лиспе — им бы пришлось поменять свой подход (разработка армией программистов) на подход Грэма (скоростная разработка кучкой спецов). Yahoo не стала меняться, по понятным причинам.
                        • 0
                          Думаю, что это удобная, но наивная точка зрения )
    • +14
      ну пишет человек на лиспе
      зачем ему писать сайт на чем-то другом если ему нравиться лисп и на нем есть возможность сделать сат
      я бы поступил аналогично
      • –7
        лол.
        ну пишет человек на ассемблере
        зачем ему писать сайт на чем-то другом если ему нравиться ассемблер и на нем есть возможность сделать сайт
        • +5
          ну вообще-то именно так.
        • +2
          а на асме особенно!
          • +2
            Да, забыл сказать — я иногда пишу на ассемблере. Но делать сайты на нем не стал, так как не вижу других преимуществ, кроме как «удивить всех». Но это одноразовый эффект…
            • +1
              Да не, я бы каждый раз, заходя на сайт, округлял глаза.
              • –1
                Вы не должны этого хотеть! ©
  • +7
    красиво, академично, но местами брейнфакоподобно
    • +1
      Погружайтесь глубже — вам понравится. Поверхностные решения могут съэкономить время и силы, но не принесут вам удовольствия :)
  • +2
    Восхищаюсь лиспом хотя и не понимаю пока код :)
    респект автору
    • 0
      В общих чертах: (function arg1 arg2 arg3) — это покрывает большую часть непоняток.
      (if (condition) {then-clause} {else-clause}) — это покрывает вторую
      Привычка ориентироваться по отступам от левого края и подсветка скобок делают лисп не сложнее питона.
      А все остальное уже и не так сложно…
      • 0
        Обожаю лисп, спасибо что напомнили про него. Самый красивый язык на мой взгляд хотя из функциональных знаю не так много их. У лиспа одна проблема — увидев и освоив его один раз не хочется браться за другие языки.
    • 0
      каждый год делал заход, чтобы понять lisp. Только в этом году получилось. На примере nu github.com/timburks/nu — хорошо сшитый с Objective-C язык, несколько проще чем common lisp + некоторые вещи взяты из ruby.
      • 0
        «That's why Nu is «C over lambda.»» — интересный проект, посмотрю :)
  • 0
    Как я понимаю, данный сайт работает без апача? чистый лисп?
    • +3
      Сервера тоже нет
      • 0
        Сервер —
      • +1
        Сорри, сорвалось.
        Сервер — Hunchentoot, я писал о его установке в вводной статье. Выглядит, просто одна из подключаемых библиотек — не накладывает практически никаких ограничений на стиль написания кода, только предоставляет полезные функции
        • +1
          Понятно, спасибо.
          Я вообще саму железяку имел в виду:)
    • +3
      Судя по заголовками, сайт работает через nginx, который просто проксирует запросы на Hunchentoot. Вот на lisper.ru/ чистый CL.
  • +1
    лови хабраеффкт! :)
    • +1
      Пока задержек не замечено… :)
      • +1
        Вот бы сравнить классику c lisp на предмет производительности с помощью habrabanch :)
        • +2
          Что имеется ввиду?
  • –6
    откуда в последнее время такой всплеск интереса к языкам 50-летней давности?
    • 0
      Это интерес не к конкретным языкам, а к функциональному программированию.
      • +2
        CL не функциональный язык. И ему не 50 лет, стандарт датируется 1994 годом кажись.
        • –3
          а лиспу — 52
          • +3
            Языка лисп нет уже давно, сейчас это семейство языков, которые достаточно сильно различаются между собой и очень далеко ушли от первоначальной идеи Маккарти.
    • +3
      LISP вечен! =)
      • –4
        Извините, вы случайно не на ПоХаПэ пишете?)
        • 0
          При желании могли бы и сами посмотреть на чем человек пишет. А язвить не стоило.
          • 0
            Самое интересное — угадал
            • 0
              Самое интересное — нет, не угадали.
  • +7
    Ничего не понял, но доставляет.
  • +1
    синтаксис языка имхо страшен =) си подобный как то роднее
    • +1
      Мне синтаксис тоже не очень нравится, но он обладает рядом важных свойств, необходимых для lisp. Так что приходится его принимать ради тех преимущества, которые даёт CL.
    • +2
      У cl нет синтаксиса.
      • 0
        Синтаксис может быть любым — изучить синтаксис одного языка, имея опыт работы с другим, не составит проблем при схожей семантике. А вот кардинально различная семантика — это уже другой вопрос.
    • 0
    • 0
      Другая парадигма -> другой тип мышления.
      LISP нужно попробовать с его сильных сторон, и после этого понимаешь, как им пользоваться и какие преимущества получаются в итоге.
  • +1
    Ну когда уже к базе данных начнем подключаться?
    • +2
      Могу написать и об этом. Но так уж получилось, что если ваши данные вмещаются в гигабайт и нет необходимости в транзакциях (что характерно для большого процента проектов) то база данных вам как-бы и не необходима…
      • 0
        У меня база статистики одного проекта пожирает в среднем 20-30гб/месяц при небольшом траффике. А другая база — приложения, для которого ведется статистика, состоит из нескольких десятков таблиц связанных между собой чуть более, чем полностью. Так что пишите — будет очень интересно почитать про работу с объемными как по весу, так и по архитектуре базами данных.
        • 0
          Окей, postgresql подойдет?
          • 0
            В данном контексте народ (и я в том числе) жаждет увидеть механизм работы с базой, как таковой. Так что вполне.
  • –7
    «шаблонизация, роутинг и кеширование» — это точно про веб-программирование?
    • +5
      Простите, а что Вас удивляет?
  • +2
    Закруглённые чешуйки у бестии на картинке символизируют бесконечные скобочки :))
    • +1
      Капитан в топике! :)
  • +1
    Можно было и шаблоны описывать лисповыми конструкциями, чтобы html искоренить из кода. Да и шаблонизация как таковая не очень и необходима, достаточно генерировать html код из лисповых конструкций. Такой подход я видел в книжке Practical Common Lisp. Получился элегантный dsl.

    И макрос default-page можно разобрать в более общий, чтобы создавать страницы и декларативно описывать их, почти как user story.

    В общем, много можно сделать. Вам огромное спасибо за труд!
    • +1
      > Можно было и шаблоны описывать лисповыми конструкциями

      На практике получается просто жуть.
      • 0
        Читаемость должна стать лучше, в голове держишь только один язык. Конечно же можно что угодно раздуть и нужно знать меру. Зато есть плюс, можно со временем строить страницу на клиенте, преобразовав код в JS.
        • +1
          Я пробовал так. В итоге когда перешёл на шаблоны, то был просто счастлив от того, насколько всё стало проще и яснее.

          Вообще, с мнением, что контент надо генерировать через шаблоны я думаю согласится любой нормальный веб-разработчик, не зависимо от используемого им языка.
          • 0
            Если прикинуть, то в замен шаблонов будет пару layout, и виджеты (меню, баннеры). Остальное это непосредственно входные данные (запрос), и функция, которая возвращает результат, которые и соединяется со всем остальным. Все эти сущности можно сделать стандартными и просто описывать также. В итоге легче следить за дублированием, потому то компоненты пере используются, легче понимается код. Но это в теории. :) Возможно, что в реальном проекте это будет жутким нагромождением. :)
            • +1
              Ну так шаблоны же позволяют тоже самое, только они не забивают мусором основной код и их могу править дизайнеры.
              • 0
                Естественно нужно всё это отдельно от основного кода хранить. :) Разве дизайнеры не понимают встроенного языка? Вообще можно сделать дизайнерам утилиту, которая позволит делать всё на лету. :)
                • 0
                  Самое главное не написал, на лету графически.
                • +2
                  Дизайнеру, как и самому программисту, проще и удобней редактировать код, максимально приближенный к целевой разметке.

                  Кроме того, в данном приложении автор использует библиотеку cl-closure-template. которая имеет ещё и совсем другие преимущества (хотя это и не важно для данного приложения), я писал об этом здесь
                  • 0
                    Да, но если использовать встроенный язык, то можно абстрагироваться от особенностей браузеров и генерировать специфичный для каждого из них код. Это сразу понизит уровень работы.

                    И если проект не такой большой, программист сам может применять стили оформления. Которые может сделать дизайнер. :) Дизайнер делает свою работу в своих терминах, а программист формирует стиль, который он может применить к любому коду.

                    В любом случае завязываться на дизайнера не стоит. Лучше сразу делать все лаконично и с наименьшим дублированием.
                    • +1
                      Ну так на шаблонах и получается же лаконичнее!

                      У генерации контента с помощью встроенного eDSL фактически вообще нет никаких преимущества. Я только для демонстрационных приложений объёмом в 10 строк использую cl-who.
                      • 0
                        Хорошо, сдаюсь. Шаблоны крутота. Но если нет дизайнера под рукой, то встроенный язык супер решение. :)
                        • 0
                          Я когда писал lisper.ru, то дизайнера у меня не было и я сначала делал именно на встроенном языке. По результатам этого опыта и я пришел к шаблонам, как к оптимальному решению )
                          • 0
                            А встроенный язык сам писал?
                            • 0
                              Да. Ну да они все примерно одинаковые )
  • +2
    Ваши статьи уговорили меня присмотреться к CL. Вы этого добивались, признайтесь? :) Реинкарнировать интерес к Lisp'у? Или вам просто интересно находить ему нетипичное применение?

    Сейчас начал почитывать книжку Land of Lisp (сайт книжки просто покорил), написана очень хорошо и доступно, как по мне. Ничего архисложного не вижу. Есть ещё Practical Common Lisp. Если подсяду — она на очереди. А какой материал вы бы посоветовали начинающему лисперу?
    • 0
      Я очень рад тому что смог повлиять на ваше мнение. Рекомендую начать с Practical Common Lisp — я начинал с нее, мне понравилось. Еще литература есть на сайте, которомы посвящена статья… Много полезного и интересного можно найти на lisper.ru

      • 0
        Меня очень заразила книжка Пола Грэма ANSI Common Lisp, найти не так просто а грамотного перевода вроде вообще нет. Есть несколько глав перевода тут, может еще кому понравится. Сразу скажу перевод не мой, просто я успел скопировать почти перед закрытием странички автора.
        • 0
          Я пробовал организовать перевод в вики на своем сайте, думаю подниму в ближайшее время снова
        • 0
          Чтение книг на английском не должно быть проблемой для технаря, ведь на русском практически ничего никогда нет, так что не привыкать. Всё или переводное, при чём зачастую сомнительного качества, или неактуальное (единственное исключение на моей памяти — отечественные книги по LaTeX).

          Спасибо за наводку.
        • 0
          Начал читать «ANSI Common Lisp», но уже через несколько часов чтения понял, что мой мозг не успевает за развитием событий, всё описывается слишком стремительно. А так как Lisp весьма специфичный язык, мне, как начинающему лисперу, нужно что-то более разжёванное. В общем не знаю как должно быть, но «Land of Lisp» читается хорошо, без отторжения материала. Нагромождение скобок уже почти перестало взрывать мозг :) Думаю, что после такого «CL для чайников» более серьёзные книги будут восприниматься легче.

          Пока не понял зачем мне Common Lisp, но он очарователен :)
    • +1
      похоже на энциклопедию профессора фортрана
    • 0
      Возможно вам понравится Clojure, который старается исправить некоторые «слабости» CL.
      • 0
        Вряд ли можно говорить о том, что Clojure исправляет «слабости», скорей это просто несколько другой язык с заметно отличающейся идеологией.
        • 0
          Разработка Clojure началась с «исправить признанные недостатки массовых Лиспов». Это не единственная, но одна из основных причин.

          Там есть целая статья на тему «недостатков».
  • 0
    Что такое «массовые лиспы»? Какие у них общие недостатки.

    Ну да пустой разговор. Вряд ли кто-либо из программистов на CL согласится с тем, что Clojure хоть что-нибудь исправляет.
    • 0
      блин, куда-то не туда коммента пошёл (
  • 0
    Чем вызвана задержка перед выдачей каждой страницы? Ожидание более 2 секунд, и потом за 20 мс передается, это касается только HTML страницы, CSS и другие файлы загружаются без такой большой задержки.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.