common lisp: значение слота для структур defstruct

В общем lisp, что я могу использовать для доступа к слоту структуры, используя имя/символ слота?

Я хочу

(defstruct point (x 0) (y 0))    
(defmacro -> (struct slot) `(slot-value ,struct ,slot))

(setf p (make-point))
(setf (slot-value p 'x) 1)
(setf (-> p 'y) 2)

Я использую clozure cl, и в clozure cl это работает. Однако, насколько мне известно, это нестандартное поведение (эквивалентно «неопределенному поведению» С++). Я не планирую переходить на другую реализацию CL, так что мне продолжать использовать slot-value для структур или есть лучший способ сделать это?


person SigTerm    schedule 22.06.2013    source источник


Ответы (1)


Обычно вы должны использовать функции доступа со структурами.

Ваш код определяет функции доступа point-x и point-y. Вы можете использовать их.

Вы также можете использовать SLOT-VALUE со структурами в реализациях, которые его поддерживают. Я думаю, что это большинство реализаций (GCL будет исключением). Существует программное обеспечение Lisp, которое предполагает, что SLOT-VALUE работает для структур. Я не думаю, что реализации уберут его поддержку. Этого нет в стандарте, потому что некоторые разработчики не хотели бы предоставлять эту функциональность в развернутых приложениях.

Так что оба пути хороши.

Если вы хотите иметь короткие имена, используйте аксессоры:

CL-USER 109 > (defstruct (point :conc-name)
                (x 0) (y 0))
POINT

CL-USER 110 > (make-point :x 5 :y 3)
#S(POINT :X 5 :Y 3)

CL-USER 111 > (setf p1 *)
#S(POINT :X 5 :Y 3)

CL-USER 112 > (x p1)
5

CL-USER 113 > (setf p2 (make-point :x 2 :y 3))
#S(POINT :X 2 :Y 3)

CL-USER 114 > (list p1 p2)
(#S(POINT :X 5 :Y 3) #S(POINT :X 2 :Y 3))

CL-USER 115 > (mapcar 'x (list p1 p2))
(5 2)

Конфликты имен между различными функциями доступа должны быть предотвращены пакетом.

Если вы хотите написать более короткую версию SLOT-VALUE, это тоже нормально. Напишите макрос. Или напишите встроенную функцию. Конечно - почему бы и нет?

Как я уже сказал, SLOT-VALUE работает со структурами в большинстве реализаций. В этом случае вас не должно волновать, что спецификация ANSI CL этого не определяет. Во многих отношениях реализации расширяют спецификацию ANSI CL. Например, SLOT-VALUE работая над структурами, реализуя потоки как классы CLOS, реализуя условия как классы CLOS, предоставляя протокол метаобъектов, ...

person Rainer Joswig    schedule 22.06.2013
comment
Вы можете использовать их. Я знаю это, но из С++ это довольно длинно/многословно. В C++/C доступ к полям осуществляется через . или же ->. т.е. point p; p.x = 0;. Поэтому я хотел более короткий синтаксис. Я определил макрос -›, но обнаружил, что значение слота не должно использоваться в структурах (хотя оно работает во многих реализациях). Вот почему я задал вопрос. - person SigTerm; 22.06.2013