проблема макроса lisp defclass - PullRequest
       5

проблема макроса lisp defclass

1 голос
/ 22 декабря 2010

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

Я пытаюсь написать макрос, который определит два класса clsql для меня, чтобы обойти проблему с библиотекой. Мне бы хотелось, чтобы классы были названы x и `x-insert``, поэтому внутри макроса я бы хотел, чтобы макрос вычислял имя символа x-insert, но у меня возникли сложности с этим. Моя попытка ниже, но я нахожусь в тупике на две вещи.

Как мне получить это, чтобы создать имена классов. Если я удаляю пробел в ,class -insert, он не будет eval, что я понимаю, поэтому я предполагаю, что упускаю какой-то простой способ сказать ему игнорировать пробел и создать имя как одно слово, и вторая проблема заставить его создать два класса, а не один, так как он расширяет только последнюю часть макроса по сравнению с тем, что я вижу при использовании макроса.

Возможно, я все делаю неправильно, поэтому не стесняйтесь пнуть меня в правильном направлении.

(defmacro gen-pair (class base-slots pkey-slot base-table)
  `(clsql:def-view-class ,class -insert()
     (
      ,base-slots
     )
     (:base-table ,base-table)
   )

  `(clsql:def-view-class ,class (,class -insert)
     (
      ,pkey-slot
     )
     (:base-table ,base-table)
   )
)

1 Ответ

7 голосов
/ 22 декабря 2010

Трудно начать объяснение здесь, поскольку у вас, похоже, есть целый набор заблуждений.

Первый вопрос (как составлять имена символов): макросы Lisp не работают с text , но на код .В форме обратной цитаты ,class соответствует коду, переданному в параметр class макроса, в данном случае, скорее всего, к имени класса.Запись другого символа после этого волшебным образом не объединяет имена символов;зачем это?Если вы хотите составить новое имя символа, вы должны создать его:

,(intern (string-upcase (concatenate 'string
                                     (symbol-name class)
                                     "-insert")))

Второй вопрос (почему кажется, что он расширяет только вторую часть): содержимое формы defmacro оценивается внеявный progn (поэтому он не жалуется на недопустимое количество аргументов здесь).Возвращаемое значение последней формы - это возвращаемое значение всей формы defmacro.В этом случае возвращаемое значение - это код, созданный этой формой обратной кавычки.Макрос определяет функцию, которая расширяет форму в новую форму;Вы не можете расширить это в две несвязанные формы.Вы должны создать форму progn, которая содержит две формы, которые вы хотите иметь.

Третий вопрос (почему ваш код выглядит так сильно отличается от того, что пишет Лисперс): не бросайте круглые скобки, как обрезки ногтей.В сети летают несколько гидов в стиле Лисп.Читать их. Wer die Form beherrscht, kann mit ihr spielen (примерно: если вы знаете правильный путь, вы можете поиграть с ним).

Четвертый вопрос (как обойти воспринимаемое ограничение clsql): вы могли бы задать этот вопрос напрямую, нет?Какое ограничение вы имеете в виду?

...