четверг, 2 мая 2013 г.

Slime/Swank, Quicklisp and long running programs

I have a small problem with Slime/Swank and long running servers.

These servers run for weeks and month, with an older version of Swank loaded. I periodically connect to them to change a function or two (quick fixes and small functionality updates), without restarting.

Now, when a Quicklisp update arrives, versions of Slime on my local machine and Swank on remote machines diverge. Even if I upgrade Swank in all remote installations, I need to reload Swank  in each of these image. 

That's quite interesting if it is possible to do so w/o actually restarting the image. Will try.
Typcally slime/swank version difference does not matter much, but to be on the safe side, it is better to keep them syncronized.

A wider questoin is whether it is a good practice to upgrate your dependencies inside your running servers. And whether it makes sense to automate this.

пятница, 19 апреля 2013 г.

nconc

Lispers know that destructive list functions are dangerous, that you should know that the data is fresh consed. I've known this too, but still today I was still bitten by nconc. When I applied it to two arguments that shared structure, it returned a circular list. Try this:

(setf *print-circle* t)
(let ((x (list 1 2 3)))
   (nconc x x))

Be careful!

Lisp Blog

Recently I have been programming quite a lot in Common Lisp. Full time for about 5 months on a professional code base, written by some cool guys who now work either at Lisp vendor companies or as successful independent consultants.

I have learned a number of lessons.

Community

The Lisp community does exist :)  only it has to be viewed globally. There is merit in attempting to maintain local communities, of course, but one cannot hope to achieve as much of activity around Lisp as we have around Python, for example.

Therefore, I will not continue writing this blog in Russian. Need to reach out to a wider audience.

Using Lisp in startups

It might be hard to persuade your company to use Lisp, (no, quoting Paul Graham is not enough, though it helps). However, if you encounter a company, especially a startup, that does use Lisp, despite the obvious obstacles such as lack of good Lisp programmers, and a rather steep learning curve for existing programmers, that company deserves attention. Chances are something interesting is happening there.

Lisp Libraries and Technologies

I have learned and used GBBOpen, Screamer, have seen how Weblocks is being used as a RAD tool (and want to try it myself later). I am going to write about this later in this blog so stay tuned :)

понедельник, 23 августа 2010 г.

Закрыть все буфера TRAMP'а в Emacs

Вот так в emacs'е можно закрыть все буфера tramp'а. Чтобы не искать руками в ibuffer, просто набираем M-x kill-tramp-buffers. Иногда мне это нужно, чтобы не путаться, на какой машине я редактирую сейчас файлы, переходя от одной машине к другой.

;;; a shortcut to kill all tramp buffers at once
;;;
(require 'ibuffer)

(defun tramp-buffer-p (buf)
"is this buffer tramp's one"
(or (string-match "^\\*tramp" (buffer-name buf))
(tramp-tramp-file-p (with-current-buffer buf
(ibuffer-buffer-file-name)))))

(defun kill-tramp-buffers ()
"kill all TRAMP buffers"
(interactive)
(dolist (buf (buffer-list))
(when (tramp-buffer-p buf)
(kill-buffer buf))))

пятница, 4 сентября 2009 г.

Наваял в первом приближении нечто, способное генерить код, похожий на PHP

Фактически это pretty-printer скобочный выражений, которые должны примерно соответсвовать языку PHP. Но! Есть macroexpand. Правда макросы определяются на host-языке, т.е. на Common Lisp, а не на target языке, т.е. в самом языке нет (пока) defmacro, macrolet, symbol-macrolet, (мне кажется что expansion code все равно надо писать на common lisp, а не на PHP, так что полезность defmacro et al. в target языке под вопросом). Глюков там еще хватает. Лежит на github'е но это пока довольно бесполезная штука. Потому что чем писать на PHP в скобочном синтаксисе, лучше писать в родном. В скобочном синтаксисе надо писать на LISP или Scheme, а это совсем другое, кроме макросов все же хочется иметь полноценные замыкания, полноценную lambda. Для этого надо делать flattening envionrment'а (не знаю как это переводится) через lambda lifting (тоже не знаю), что нафиг убъет всю читаемость сгенеренного кода. Вот уже неделю думаю, читаю умные книжки, надо такое делать или нет, или пускай будет PHP в скобочном варианте с макросами? Хотя emacs lisp ведь без замыканий живет и ничего. Надо осилить Lisp in Small Pieces, начиная от денотационной семантики и дальше, может натолкнет на какие-то мысли.

понедельник, 3 августа 2009 г.

pretty printer

А еще в Common LISP есть совершенно замечательный настраиваемый pretty-printer, который можно использовать не только для того, чтобы печатать в синтаксисе лиспа. Вот, например, как генерится код на Паскале.

четверг, 30 июля 2009 г.

Кодогенерация: Common Lisp vs. Emacs Lisp

Одно из применений лиспа - это генерация кода, в т.ч. не только на лиспе, но и на других языках. Вот я думаю, может для этой задачи ограничиться Emacs Lisp, а не тащить common lisp?

Потенциальные преимущества:

  • Emacs есть везде и под все, а Common Lisp - нет (для меня несущественно, но все же).
  • Собственно генерация кода нужна именно для автоматизации программирования, что в принципе кажется Emacs'овой задачей.
  • Язык сам по себе попроще будет, при этом, просмотрев исходники parenscript, на первый взгляд не нашел там ничего такого, что нельзя было бы сделать на Emacs Lisp. Местами используется CLOS, но это несущественно.

Недостатки:
  • В Emacs Lisp нет READ-макросов, что несколько ограничивает создание DSL, и делает невозможными красоты типа CL-INTERPOL
  • При макроподстановке не выполняется destructuring, (собственно он в Emacs Lisp обнаружен не был), что тоже может быть неудобно.
  • Отсутствие lexical closures в основной верии Emacs, lexical-let не в счет - не могу понять последствия для этой задачи.

четверг, 25 июня 2009 г.

Читаю книжку Programming Clojure

Нужно написать нечто, и кажется что на JVM это нечто будет работать лучше всего. Хотя проект не терпит всякие "альтерниативные" языки в production коде, так как мои знания Джавы мягко говоря не очень, то мне или долго писать на Java, или выучить Clojure и быстро на нем переписать прототип, ранее сделанный на Сommon LISP, чтобы быстрее заняться другими делами, и если все будет хорошо, потом уже аккуратно сделать Java вараинт.

Книжка не очень большая, меньше 300 страниц, и легко читается, по крайней мере первые 4 главы прочел уже довольно быстро. Сам Clojure хорош (по сравнению с Java так вообще, но ... если вам не надо Java, то возьмите лучше Common LISP. Из JVM-hosted языков знаком немного с Jython, и отличие вижу в том, что в то время как Jython старается как можно больше быть похожим на C Python, Clojure этим не страдает, его задача - максимально легко использовать Java с помошью приятного функционального язычка, а на что оно похоже - не важно.

четверг, 18 июня 2009 г.

Closure Oriented Programming

Closure Oriented Programming (from http://letoverlambda.com/) hinders interactive development. I find it much easier to have separate defuns operating on complex data structures than function that are deeply nested within a "network" of closures. Despite we have fewer code lines with closures, than with declaring separate structs or classes, with more traditional approach, the code and data is much easier to explore from REPL.

вторник, 9 июня 2009 г.

let*

Почему-то не нравится let*. Хочется писать вложенные let, хоть это и больше скобок и индентации.

пятница, 5 июня 2009 г.

SXHASH

Странно работает SXHASH. Если считать хеш символа, то в 32-bit SBCL значения идут чуть ли не подряд (fixnum в районе 300 тыс. ). В Clozure CL вообще кажется идут ASCII коды символов! Если я взял символы от A до Z, как мне получить значения хеша, равномено распределенные в некотором интервале?

четверг, 4 июня 2009 г.

SLIME и PACKAGES

Обнаружил, что надо в файле обяазательно писать (in-package :mypacakge), чтобы из буфера slime-compile-defun и прочие делали это в правильном пекедже. SLIME просто ищет in-package в тексте буфера.

пятница, 29 мая 2009 г.

Книги по ЛИСПу

Хочется самые правильные книги по LISP проработать качественно. А именно хочется прорешать все упражнения. У Эли Бендерского заняло чуть меньше года прорешать весь SICP на Common LISP. У меня прорешать его на Scheme заняло месяца 2 или 3. Но во первых не все, а где-то три четверти, и я довольно плотно за него тогда взялся. Сейчас так не получится, так что надо рассчитывать, что PAIP со всем упражениями займет не меньше чем полгода, а то и год. Чтобы все это мне не надоело, его надо будет это чередовать с другими книжками, так что, надеюсь, On LISP и Let Over Lambda будут прочитаны гораздо раньше чем PAIP. Остается домучить LISP in Small Pieces, и AMOP. Еще есть в электронном виде какая-то книжица по CLOS, даже не знаю стоит ли она прочтения. Вобщем, минимум на год вперед чтения по LISP'у хватает, быстрее все осилить может и можно, но зачем?

Обзор Common LISP

Прослушал обзорный доклад Всеволода о среде Сommon LISP' а, включая особенности языка, ИДЕ, библиотеки, коммьюнити и пр. Я ничего не ожидал от этого доклада, ну что еще можно сказать. На удивление, презентация была очень хорошо подготовлена, и оказалась рассчитанной примерно на мой уровень, уровень человека, который уже успел попробовать Common LISP на практике, но еще маловато знает. В презентации оказалось полно buzzwords, которые нужно знать, я надеюсь, он ее выложит, и там будут кликабельные ссылки.

вторник, 26 мая 2009 г.

Guide to Lisp Style

Хочется выписать отдельно тут:

  • Be specific
  • Use abstractions
  • Be concise
  • Use the provided tools
  • Don't be obscure
  • Be consistent

PAIP

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

четверг, 21 мая 2009 г.

Немного отвлекся от Common LISP и наваял первую наивную прогу на Emacs Lisp :)

Берет бинарный файл, и оформляет в виде C-шного массива:


(defun file-to-c-array (filename)
"convert a binary file into a C array of characters"
(interactive "fFile Name: ")
(let* ((buf (find-file-noselect filename))
(oldbuf (current-buffer)))
(save-excursion
(insert "\nconst unsigned char key[] = {")
(set-buffer buf)
(beginning-of-buffer)
(let ((i 0))
(while (not (eobp))
(let* ((c (following-char)))
(forward-char)
(set-buffer oldbuf)
(when (zerop (mod i 8))
(insert "\n\t"))
(incf i)
(insert (format "0x%x, " c))
(set-buffer buf))))
(set-buffer oldbuf)
(delete-backward-char 2)
(insert "\n};\n"))))

пятница, 15 мая 2009 г.

Насчет FFI - не все так хорошо по сравнению с ctypes

Нужно было прикрутить библиотеку к ЛИСПу на винде. Взял Clozure CL. Использовать его FFI на винде как-то не получилось, долго разбираться. Пытался поставить CFFI через ADSF-Install, но ASDF-Install на винде тоже работать не захотел :( Ну я понимаю, что, помучавшись, можно все сделать, но я плюнул, запустил питон, оказалось, что тоже вполне юзабелен из Emacs'а (я к Emacs'у фактически начал привыкать после SLIME'а, до этого всегда и везде был vim). Ну и через минут десять я эту библиотеку из питона уже юзал. И только где-то через час-другой стало нехватать лиспа. Вобщем, сделайте кто-то нормальный LISP environment под виндой с FFI, очень надо!

среда, 13 мая 2009 г.

Зачем нужен ЛИСП C программисту?

Например, что вы делаете, когда вам нужно научитья пользоваться программой? Читаете документацию? Или просто запускаете и смотрите что и как? Скорее всего и то и другое. А что если нужно научиться пользоваться новой для вас библиотекой? Документация - замечательно. А как запустить? Если у нас есть DLL'ка, ее нужно сначала загрузить в адресное пространоство процесса, а затем уметь дергать функции в этой DLL'ке с правильной calling convention, передавать правильные аргументы и правильно интерпретировать значания. Кажется, без написания тестовых программ никак.

Но я уже достаточно давно использую для похожих целей python. В начале, я попробовал (на C++) Boost.python и Python C API - хорошо, но можно потеряться в темплейтах если что-то вдруг не заработает c Boost.Python. Затем, юзал SWIG. Тоже ничего, но там такое надо бывает написать в .i файле, придумывать какие-то typemaps для чуть более чем тривиальных случаев. Не хочется такое повторять. Boost.Python и SWIG плохи тем что интерфейс надо оборачивать и писать какой-то код. Быстро поэкспериментировать не получится.

Ничего особо писать не нужно в ctypes, но как-то сложилось, что я его не слишком использовал. А зря.

Сейчас обнаружил, что все варианты FFI в Сommon LISP чем-то похожи на ctypes. Итак, если разобраться в FFI в LISP, что же мы получаем? У нас есть некий процесс, в пространство которого мы можем загрузить любую DLL'ку, подергать ее. При этому это все делается в REPL, плюс под рукой есть мощный язык с помощью которого можно всем этим рулить, прототипировать, экспериментировать. Python с ctypes тоже тут неплох, просто в SLIME получше среда, да и макросами можно весь FFI быстро обернуть. См ранее об libgcrpyt

Имею кучу гемора с установкой чего-то нормального лиспового на винде

Чаще всего рекомендуют CLISP, якобы на винде работающий нормально. Мне, правда больше по душе Clozure, и вроде встало нормально, SLIME запустился. Сначала не появлялся REPL отдельным окном, но потом прочилал в доке, что теперь REPL'а по умолчанию нет (!), и надо специально попросить, сказав в Emacs'е (slime-setup '(slime-repl)). В Clozure CL интересный FFI, будем смотреть сейчас.