Про reader-macros
Sep. 10th, 2008 09:58 amReader-macros — это механизм в Common Lisp, позволяющий добавить/переопределить собственный синтаксис объектов.
Одна из основных проблем reader-macros'ов — это коллизии префиксов (dispatch characters).
Непонятно, почему создатели языка не поступили так же, как и с обычными символами — не воспользовались пакетами (packages) для разрешения коллизий. Ведь это кажется таким очевидным.
И использование пакетов для разрешения конфликтов позволяет выбирать, какие синтаксисы использовать, а какие — нет.
Например, такая простая реализация (не факт, что она правильная, но работает) использует символы (symbols) (а не символы (characters)) для выбора способа чтения объекта (с примером простой реализации такого способа чтения объектов для clsql).
(eval-when (:compile-toplevel :load-toplevel) (defun get-reader-function (symbol) (let ((package (symbol-package symbol)) (name (symbol-name symbol))) (symbol-function (find-symbol (format nil "~A-READER" name) package)))) (defun symbol-dispatch-reader (stream char arg) (declare (ignore arg)) (let ((dispatch-symbol (read stream t nil t))) (funcall (get-reader-function dispatch-symbol) stream char))) (set-dispatch-macro-character #\# #\! #'symbol-dispatch-reader) (defun sql-reader (stream char) (declare (ignore char)) (let ((*readtable* (copy-readtable))) (set-macro-character #\[ #'clsql-sys::sql-reader-open) (set-macro-character #\] (get-macro-character #\))) (read stream t nil t))))
И используется это дальше так:
(clsql:query #!sql [:select [*] :from :users])
Есть ли у такого решения недостатки?