Регистрация | Войти
Lisp — программируемый язык программирования
RSS
Засланый казачок в семейство Lisp
LinkFly - 12.07.2010 22:40, Сообщений - 6
Засланый казачок в семейство Lisp систем или откуда взялся Clojure

Недавно в конференции lisp@conference.jabber.ru зашла речь о противопоставлении Clojure Common Lisp 'у.
С моей стороны, было сомнение в определении в Common Lisp синтаксического сахара для быстрой записи
структур данных (а точнее - короткой записи), например таких как Хэш-таблицы. Один из аргументов был
следующий: избытычный синтаксис усложняет использование макросов. Но как известно "хорошая мысля
приходит опосля" :) Так что есть одно "НО"! Необязательно сокращённую запись структур данных делать
такую кривую как в Clojure, можно сделать вполне в духе не нарушая дизайна, а именно:

;;; Синтаксис для хэш-таблиц
(defun disp-maps (stream char arg)
  (declare (ignore char arg))
  (princ (cons 'hashmap (read stream nil))))


(defun hashmap (&rest keys-and-vals)
  (let ((hash-table (make-hash-table)))
    (loop for (key value . rest) on keys-and-vals by #'cddr       
         do (setf (gethash key hash-table) value)
         finally (return hash-table))))

(set-dispatch-macro-character #\# #\M #'disp-maps)

;;; Проверка
(setq ht #M(:key1 'val1 :key2 'val2))
(maphash #'(lambda (k v) (print (list k v))) ht)

Вот только неизбежное зло: надо помнить что #M по сути превращается в (hashmap ...)
В остальном всё вполне в духе Common Lisp. Плиз покритикуйте сие творчество... Кстати, может лучше
#H ?
[#]
На самом деле, это иллизия, что буквальная запись стурктур данных усложняет жизнь макросам.  Ведь есть же в CL #() для векторов и ничего, как-то живем :)

Также ошибочно считать, что в CL нет буквальной записи.  Ее нет только из коробки, но разве это проблема:
http://github.com/vseloved/rutils/blob/master/hash-table.lisp#L9a

А вот в Clojure, да, нет возможности сделать что-то подобное... :)
vseloved - 13.07.2010 14:25
[#] Ответ на комментарий от vseloved 13.07.2010 14:25
Пример metabang-bind показывает, что литералы объект бывают полезны - там можно делать деструктурирование массивов.
Проблемы буквальной записи объектов в том, что могут быть проблемы с сохранением их в fasl. Из плюсов же: константность (можно использовать load-time-value, но с литералом проще), возможность анализировать литералы в макросах.

Насчет иллюзии про сложности с макросами согласен. Макросы усложняются не сложной записью объектов, а сложной записью выражений, связанных с передачей управления. Для макроса же просто будет объект.
dmitry_vk - 13.07.2010 15:15
[#]
Мне тоже пришлось сделать подобную процедуру чтения для #<FUNCTION NAME> и #<PACKAGE NAME>, а то не получается восстановить эти объекты после их записи в строки. Ещё может быть полезно #S() для множеств (раз уж в стандарте есть #(), #2A(), ... и есть #H() в библиотеках).

Что касается макросов при нерегулярном синтаксисе - я тоже не вижу тут проблем, если, например, такая нерегулярная запись

for i = 1 .. 10 {
print 10 + i;
}

одназначным образом преобразуется в регулярную, то и с использованием макросов на таком коде не возникнет проблем.
treep - 14.07.2010 08:37
[#] Ответ на комментарий от vseloved 13.07.2010 14:25
Опасность в том, что наблюдается отход от единообразия.
Вот к примеру, запись (vector 3 4) против записи #(3 4). Читабельность против сокращенной записи.
Если кол-во синтаксического сахара для записи разнообразных типов/структур будет увеличиваться, то
лисп-сообщество ещё больше будет походить на сектантство. Я полагаю надо выдерживать генеральную
линию: "Единство кода и данных". (vector 3 4) это и код и данные. И я вижу что как всегда и везде могу
применить ф-ию apply с vector или разобрать этот список для какого либо анализа или генерации кода (врочем разбор массива в bind это конечно контраргумент). Но если проводить усовершенствования в стиле
#{:key1 'val1 :key2 'val2} это в итоге перерастёт в нагромождение разнообразного синтаксиса. Lisp-way это если
записать так: (mk-hash :key1 'val1 :key2 'val2) - к примеру. Вполне вписывается в дизайн языка и не привносит
никаких ненужных нюансов.
И всё же отдельной, так сказать,  концепцией - можно ввести (а точнее следовать уже введённому) способ
сокращённой записи разнообразных структур через #, второй символ соотв. типу и скобок, например #H()
Но тогда, надо вести учёт соответствия символов в сокращённом синтаксисе и символов функций/макросов.
И это довольно элементарно, ну будет некая системная табличка:
---------------------------
H  | MK-HASH
---------------------------
...  | ...
---------------------------
Используя эту табличку я смогу спокойно манипулировать данными введёнными посредством сокращённой
записи.
LinkFly - 14.07.2010 17:22
[#] Ответ на комментарий от LinkFly 14.07.2010 17:22
Я думаю, что "сахар" это хорошо и он позволит привлечь больше PHP-программистов. А "единство кода и данных" это не необходимость, а просто такая возможность, которая может быть полезной в некоторых случаях.
archimag - 14.07.2010 17:27
[#] Ответ на комментарий от LinkFly 14.07.2010 17:22
Да ну, какое сектанство?  Common Lisp сообщество всегда было самое прагматичное.  А наиболее прагматичный вариант — это дать возможность программисту самому решать и предоставить разумный вариант по умолчанию.

На счет страха, что будет зоопарк: на самом деле, таких особых структур данных, которые требуют спец записи — раз, два и обчелся.  Векторы, хеши, возможно, множества, деревья (хотя те в общем-то во многих случаях легко выражаются через списки), регексы (то, что и в других языках, в общем).  А всё остальное — специфично.  Тем не менне, для своих нужд тоже можно сделать какую-то спец. нотацию (для дат там, например, IP-адресов или как в http://www.weitz.de/cl-interpol/).  Всегда должен быть выбор, так что make-hash тоже разумно иметь как альтернативу.
vseloved - 14.07.2010 20:02
@2009-2010 lisper.ru