Обо мне

Моя фотография
Дикий Полярный Сов
Показаны сообщения с ярлыком LISP. Показать все сообщения
Показаны сообщения с ярлыком LISP. Показать все сообщения

воскресенье, 12 декабря 2010 г.

Идея для футболки

Пришла в голову офигенная идея для футболки. Носить обязательно на девушке.

Итак, на груди надпись:
'(       )
Между скобками, естественно, ОНИ. А ниже надпись:
LISP - тема списков раскрыта
Ящитаю, будет бомба.

четверг, 9 декабря 2010 г.

четверг, 18 марта 2010 г.

Новое и рабочие моменты

Всем привет! Достаточно долго не писал, но совершил над собой волевое усилие, и вот я снова здесь.

Что же интересного произошло за последние дни? Ну, я практически добил Practical Common LISP - осталась глава про format, пакеты и несколько глав с примерами. Такими темпами скоро буду "On Lisp" начинать, наверное.

На работе - выпустили версию 6.0 :] И попутно обновили тултипы (хотя мне таки милее jQuery'вские наработки в этой области).

Также пощупал F#. Впечатления в целом положительные, а по сравнению с C# так вообще отличные. Конечно, немного расстраивает жесткая типизация, с другой - что ни делается, все к лучшему. Однако наличие в нем доступа к CLI не может не радовать - то, чем привлек меня в свое время Clojure (обширная библиотека), только без страшных джавовских наворотов (ну не могу я этого понять, чесслово, в дотнете гораздо все прозрачнее).

Наконец-то толком занялся институтскими делами, в частности, домашними заданиями. Теперь осталось только собраться, сосредоточиться и подтянуться.

Посмотрим, что получится.

вторник, 9 марта 2010 г.

Компилируем бинарники из лиспа - SBCL и clisp

Давно не писал, потому что пока что почти все вечера у меня заняты погружением в Коммон Лисп.

Пощупал Clojure, и она мне, в целом, понравилась, если бы не одно "но" - совершенно неочевидные внутренние механизмы джавы, благодаря которым я вообще не понимаю, что к чему, что это за classpath, зачем он нужен, почему его надо явно указывать и с какой стати мой простейший скрипт на две строчки тормозит полторы секунды перед выполнением. Конечно же, если вникнуть во внутреннее устройство джавки и научиться компилировать мои clojure-произведения в *.jar, все будет работать быстрее. Но это впереди, а пока что я решил закончить-таки Practical Common LISP.

И сегодня я расскажу, как компилировать бинарник в SBCL и clisp.

Итак, начнем с SBCL. Подготовив наш файл к запуску, а именно - написав функцию, которая будет запускаться первой (этакий int main() :] ), мы грузим sbcl-овский REPL и пишем там:

(load "our-file-name")

Получив в ответ "Т", мы, в принципе, готовы приступать к компиляции. Вводим в REPL:

(sb-ext:save-lisp-and-die "binary-file-name" :executable t :toplevel 'function-name)

По идее, функция #'save-lisp-and-die просто сохраняет состояние интерпретатора лиспа, если бы не... параметр :executable вместе с :toplevel. Они содержат явное указание - скомпилировать бинарник, при запуске которого выполнится функция function-name. В качестве дополнительного требования к function-name sbcl просит явно вызывать функцию (quit).

Итак, когда я попробовал указанные выше манипуляции впервые и получил результат, радости моей не было предела. До тех пор, пока я не взглянул на размер бинарника - а он оказался, ни много ни мало, 28 мегабайт. Ага, для простенького скрипта. Ну, это остается на совести создателей SBCL, тем более, думаю, вряд ли сейчас для кого-то проблема бинарники в 20+ мег. Впрочем, глубоко этот вопрос я не ковырял, скорее всего, можно и сократить объем файла.

Теперь перейдем к clisp:

(load "our-file-name")
(ext:saveinitmem "binary-file-name" :executable t :init-function 'function-name :quiet t)


Здесь видим, что :toplevel меняется на :init-function и, кроме того, добавляется параметр :quiet, который препятствует показу баннера clisp перед запуском вашей программы. Меня такие вещи бесят. Кому нравится - не указывайте :quiet вообще.

Добавлю, что ваша программа должна содержать вызов функции #'ext:exit, чтобы она нормально завершила работу (иначе после того, как ваша программа завершится, пользователю покажут clisp-овский REPL).

Бинарник таким образом получается всего 5,5 мег.

понедельник, 15 февраля 2010 г.

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

Со следующей недели буду снова ходить в институт, параллельно сдавая несданные долги. Надеюсь, в этом году у меня все получится.

С удивлением узнал, что внутре Android'а - неонка ядро Linux.

Углубился в изучение Common LISP, пока что очень нравится, хоть и весьма сложно (местами).

Сегодня с утра в офисе целый час не было интернета. Вот до чего доводит монопольный провайдер =/

Засим разрешите откланяться, пойду работать.

P.S. Твиттер довел меня до мании выражать все мысли кратко, чтобы укладываться в 140 символов. Надо что-то с этим делать.

пятница, 12 февраля 2010 г.

SICP


Читаю SICP. По первости ломает мозг напрочь. Привык уже к императивным языкам, а тут функциональный, да еще с такой-то теорией.

Очень понравилось адаптировать примеры к моим условиям - можно, конечно, скачать mit-scheme и переписывать все с книги, но гораздо интереснее реализовывать то же самое на, к примеру, elisp'е.

Вчера, к примеру, столкнулся с проблемой. Задача - написать функцию, складывающую первый аргумент с модулем второго, не используя функции модуля. Пример на Scheme:

(define (a-plus-abs-b a b) ((if (> b 0) + -) a b))

Однако в CommonLISP'е и elisp'е такой пример не заработал - не понравилось им выражение (if (> b 0) + -), стоящее на месте, где лисп ожидал увидеть имя функции. В итоге, после размышлений, решил попробовать (пример на elisp):

(defun a-plus-abs-b (a b)
  (apply (if (> b 0) '+ '-) (list a b)))

То бишь, применить функцию "+" либо "-" к списку аргументов. Чуть позже подсказали другой способ - используя funcall:


(defun a-plus-abs-b (a b)
  (funcall (if (> b 0) '+ '-) a b))

Вот такие дела. Очень рекомендую.

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

четверг, 11 февраля 2010 г.

Божественный Лисп, Emacs-style

Сегодня написал свою первую функцию на elisp, которая хоть что-то делает ;)

Суть вот в чем - команда clipboard-kill-ring-save в emacs помещает содержимое выделенного региона в kill-ring (буфер обмена) и в буфер обмена операционной системы (таким образом я "выношу" информацию из редактора). До сих пор о том, что команда отработала как надо, я узнавал по пропадающей подсветке региона (transient-mark), но сегодня столкнулся с проблемой - когда я выделяю весь буфер (\C-x h), его содержимое не подсвечивается. Таким образом, я не могу узнать, сохранилось ли содержимое в буфер обмена, или я промазал мимо клавиш ;)

Решение достаточно простое - добавить в .emacs строки:


(defun my-own-clipboard-kill-ring-save (beg end)
  (interactive "r")
  (clipboard-kill-ring-save beg end)
  (message "SAVED TO CLIPBOARD") )


и

(global-set-key "\C-xj" 'my-own-clipboard-kill-ring-save)

Таким образом, при нажатии комбинации клавиш \C-x j мы не только положим содержимое выделенного региона в буфер обмена, но и получим в минибуфере сообщение "SAVED TO CLIPBOARD".

Enjoy.