[lisp] reader macros
От: Turtle.BAZON.Group  
Дата: 03.06.08 14:04
Оценка: 10 (1)
Может, будет ещё кому интересно. Опишем, с чего начали. Имеем, к примеру, класс (и метод в нём один):

(defclass |A| ()
  ((p1
     :type integer
     :accessor p1
     :initarg :p1)))

(defmethod doit ((obj |A|) (value integer))
  (format t "~%~A + ~A = ~A~&" (p1 obj) value (+ (p1 obj) value)))


Что мы имеем в стандартной поставке? То, что к свойствам и методам мы можем получить доступ через его аксессор в виде (p1 obj). А хочется

  1. иметь более привычный вид obj.p1 (но это не самое главное);
  2. в случае реализации IDE с использованием ООП для автоподстановки надо объект поместить перед вызовом метода или доступа к свойствам;

Собственно, для этого нам необходимо вмешаться в чтение и интерпретацию данных и определить свои правила (то, что видно как >;, на самом деле просто >):

(defun string-to-symbol (name)
  (with-input-from-string (stream name)
    (read stream t nil t)))

(defun reverse-symbol-string (symbol-name)
  (let ((amp-position (search "&" symbol-name))
        (dot-position (search "." symbol-name)))
    (if (and (eq amp-position 0)
             (and (not (eq dot-position nil))
                  (>; dot-position 1)))
      (let ((object (subseq symbol-name (+ amp-position 1) dot-position))
            (method (subseq symbol-name (+ dot-position 1))))
        `(,(string-to-symbol method) ,(string-to-symbol object)))
      `(,(string-to-symbol symbol-name)))))

(defun reverse-symbol (symbol)
  (reverse-symbol-string (symbol-name symbol)))

(defun perform-transformation (symbol parameters)
  (append (reverse-symbol symbol) parameters))

(defun transform-oo (original)
  (if (>; (length original) 0)
    (let ((function (first original))
          (parameters (rest original)))
     (if (symbolp function)
       (perform-transformation function parameters)
       original))
    original))

;;; собственно, именно здесь мы и вклиниваемся, то есть
;;; определяем, что во время чтения списка (между скобочками)
;;; мы будем полученный результат трансформировать во что-нибудь
;;; более удобочитаемое для лисп-машины.
(set-macro-character #\(
  #'(lambda (stream char)
      (let ((original (read-delimited-list #\) stream t)))
        (transform-oo original))))


Собственно, тестим (тут '&' может видеться как '&;'):


;;; перепишем старый наш метод класса на иной с продвинутой нотацией
(defmethod doit ((obj |A|) (value integer))
  (format t "~%~A + ~A = ~A~&" (&;obj.p1) value (+ (&obj.p1) value)))

;;; создадим экземпляр класса
(setf a (make-instance '|A| :p1 4))


;;; а тут вызываем у него метод doit
(&;a.doit 3)


В общем, работает....
[4]> (&a.doit 3)

4 + 3 = 7
NIL


Выводы:


Для чего нужен знак '&' в начале объекта — я уже толком и не помню...
Re: [lisp] reader macros
От: MasterZiv СССР  
Дата: 03.06.08 16:53
Оценка:
Turtle.BAZON.Group пишет:

> Что мы имеем в стандартной поставке? То, что к свойствам и методам мы

> можем получить доступ через его аксессор в виде (p1 obj). А хочется
>
> 1. иметь более привычный вид obj.p1 (но это не самое главное);
> 2. в случае реализации IDE с использованием ООП для автоподстановки
> надо объект поместить перед вызовом метода или доступа к свойствам;

Любой нормальный лиспер за такое вас будет презирать.
А то и до рукоприкладства дойдет.

Это — лирическое отступление.

LISP — язык с префиксной нотацией (преимущественно, за исключением
спецсинтаксиса вызова CONS() ).
Вы делаете инфикс. Нехорошо.

Метод в LISP в S-выражении стоит на первом месте в списке
не только потому, что это — функция. Метод в LISP НЕ ПРИНАДЛЕЖИТ
никакому классу (объекту класса). В LISP — мультиметоды.
Почему вы его хотите привязать именно к первому его параметру ?
А почему не ко второму ? Или к третьему ?
Или так :

(a b c).some-method

Вы это делаете для IDE ? LISP-овым IDE такое не понравится.
И они замечательно работают без всего этого.

В общем, штука полезна только в одном — попрограммировать
LISP reader.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: [lisp] reader macros
От: Turtle.BAZON.Group  
Дата: 04.06.08 05:31
Оценка:
MZ>Любой нормальный лиспер за такое вас будет презирать.
MZ>А то и до рукоприкладства дойдет.

Ну пусть презирает сколько влезет. Тут же демонстрация reader macro.

MZ>LISP — язык с префиксной нотацией (преимущественно, за исключением

MZ>спецсинтаксиса вызова CONS() ).
MZ>Вы делаете инфикс. Нехорошо.

Я могу сделать хоть постфиксную нотацию, если она мне будет позволять решать мои задачи более эффективно.

MZ>Метод в LISP в S-выражении стоит на первом месте в списке

MZ>не только потому, что это — функция. Метод в LISP НЕ ПРИНАДЛЕЖИТ
MZ>никакому классу (объекту класса). В LISP — мультиметоды.

То, что есть в лисп и писали 2 года и сделали объектную систему под названием CLOS для всего и для ничего в частности, не говорит, что она есть самая удобная в каком-нибудь частном случае. Благо, лисп позволяет сделать так, как удобно.

MZ>Почему вы его хотите привязать именно к первому его параметру ?

MZ>А почему не ко второму ? Или к третьему ?
MZ>Или так :
MZ>(a b c).some-method

К примеру. Можно и так.

MZ>Вы это делаете для IDE ? LISP-овым IDE такое не понравится.

MZ>И они замечательно работают без всего этого.

Потому что и лисповых IDE то, грубо говоря, не очень, да и сами не очень. Знаю две более или менее юзабельные (LispWorks и SLIME), но если подумать, то они могли бы и больше. Или хотя бы без меньших глюков.

MZ>В общем, штука полезна только в одном — попрограммировать

MZ>LISP reader.

Ахха. Поэтому тема такая и выбрана, а не "Инфиксная нотация в LISP"
Re[3]: [lisp] reader macros
От: MasterZiv СССР  
Дата: 04.06.08 12:00
Оценка:
Turtle.BAZON.Group пишет:

> Потому что и лисповых IDE то, грубо говоря, не очень, да и сами не

> очень. Знаю две более или менее юзабельные (LispWorks и SLIME), но если
> подумать, то они могли бы и больше. Или хотя бы без меньших глюков.

LispWorks слабоват в виде IDE, это — да. А Slime вполне хорош.
Или его реинкарнация на базе Eclipse — CUSP plugin.

На самом деле функциональность SLIME -а достаточно сильно зависит
от реализации лиспа, с которой он работает, от сервисов, которые
она предоставляет, поэтому надо попробовать все, чтобы осознанно
что-то говорить. Я работал с SBCL, и то вполне хорошо.
Posted via RSDN NNTP Server 2.1 beta
Re[4]: [lisp] reader macros
От: Turtle.BAZON.Group  
Дата: 04.06.08 12:19
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>LispWorks слабоват в виде IDE, это — да. А Slime вполне хорош.

MZ>Или его реинкарнация на базе Eclipse — CUSP plugin.

Вот эклипсовый cusp совсем не понял. Хотя пытался. Может, давно пытался, когда он ещё не такой юзабельный был.

MZ>На самом деле функциональность SLIME -а достаточно сильно зависит

MZ>от реализации лиспа, с которой он работает, от сервисов, которые
MZ>она предоставляет, поэтому надо попробовать все, чтобы осознанно
MZ>что-то говорить. Я работал с SBCL, и то вполне хорошо.

Я тоже работаю с SBCL. Для меня на данный момент альтернативы нет. Но если сопоставить IDEA для java и SLIME для lisp — ломка страшная.
Re: [lisp] reader macros
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 05.06.08 07:46
Оценка:
Turtle.BAZON.Group,

TBG>Может, будет ещё кому интересно. Опишем, с чего начали. Имеем, к примеру, класс (и метод в нём один):


Спасибо, мне было интересно. (на Reader Algorithm уснул)
... << RSDN@Home 1.2.0 alpha 4 rev. 1079>>
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[5]: [lisp] reader macros
От: MasterZiv СССР  
Дата: 06.06.08 06:55
Оценка:
Turtle.BAZON.Group пишет:

> Вот эклипсовый cusp совсем не понял. Хотя пытался. Может, давно пытался,

> когда он ещё не такой юзабельный был.

CUSP — это стандартный SWANK + аналог SLIME, переписанный в виде
плагина к эклипсу. В общем-то очень хорошая идея.
Но немного хромает исполнение, что-то там вечно подглючивает.
Но в целом, если чел. не может смириться с Emacs-ом, что
несложно, сам долго не мог его постигнуть, то — вполне себе вариант.
А ежели что, можно допилить напильником, ибо opensource.

> Я тоже работаю с SBCL. Для меня на данный момент альтернативы нет. Но

> если сопоставить IDEA для java и SLIME для lisp — ломка страшная.

Для лиспа всей этой IDE-шной лабуды на самом деле и не надо в таком
количестве, там язык другой, кодогенерации в офигенном объеме делать
не надо. Там другое нужно — голова разработчика.
Posted via RSDN NNTP Server 2.1 beta
Re: [lisp] reader macros
От: kzn Россия  
Дата: 06.06.08 09:09
Оценка:
Здравствуйте, Turtle.BAZON.Group, Вы писали:

TBG>Может, будет ещё кому интересно. Опишем, с чего начали. Имеем, к примеру, класс (и метод в нём один):

TBG>Для чего нужен знак '&' в начале объекта — я уже толком и не помню...

про reader macros интересно, вот только пример спорный.
Всмысле для CL есть CLOS, и пытаться изменить нотацию это как изобретать lisp без скобок. +Есть прямой недостаток:
у generic-functions один набор параметров -- т.е. тривиально не сделать
(foo a b)
(foo a b c d e :key key1)
Re[2]: [lisp] reader macros
От: MasterZiv СССР  
Дата: 06.06.08 14:09
Оценка:
kzn пишет:

> Всмысле для CL есть CLOS, и пытаться изменить нотацию это как изобретать

> lisp без скобок. +Есть прямой недостаток:
> у generic-functions один набор параметров -- т.е. тривиально не сделать
> (foo a b)
> (foo a b c d e :key key1)

Почему же , можно,

(defgeneric foo (a b (c nil) (d nil) (e nil) :key key1)) ...)

А вот как обрабатывать такое:

(defgeneric foo ( :key a b (c nil) (d nil) (e nil) ) ...)

(ответ прост — невозможно).
Posted via RSDN NNTP Server 2.1 beta
Re[6]: [lisp] reader macros
От: Turtle.BAZON.Group  
Дата: 06.06.08 14:37
Оценка:
MZ>CUSP — это стандартный SWANK + аналог SLIME, переписанный в виде
MZ>плагина к эклипсу. В общем-то очень хорошая идея.
MZ>Но немного хромает исполнение, что-то там вечно подглючивает.

Вот-вот. Это помню.

MZ>Но в целом, если чел. не может смириться с Emacs-ом, что

MZ>несложно, сам долго не мог его постигнуть, то — вполне себе вариант.
MZ>А ежели что, можно допилить напильником, ибо opensource.

Допиливать желания то как раз не очень бывает.

MZ>Для лиспа всей этой IDE-шной лабуды на самом деле и не надо в таком

MZ>количестве, там язык другой, кодогенерации в офигенном объеме делать
MZ>не надо. Там другое нужно — голова разработчика.

Голова разработчика — это необходимость в любом языке.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.