Как да дефинирате структури в Lisp, като използвате параметри в дефиницията

Искам да напиша код на Lisp като този

(defstruct board
    (size 7)
    (matrix (make-array (list size size))
    (red-stones 0)
    (black-stones 0))

за да се определи структура, която представлява дъската на играта.

Искам да мога да създам нова дъска с make-board, която ще създаде матрицата в движение с даденото измерение (размер x размер), така че да не се налага да извиквам make-board от друга функция, която прави матрица.

Въпреки това, когато заредя този код в интерпретатора на clisp и се опитам да направя нова платка (с make-board), получавам съобщение за грешка, което ми казва, че „размер“ няма стойност.

Има ли някакъв начин да се използват полетата на структурата в самата дефиниция на структурата?

Или трябва да направя това?

(defstruct board
    size
    matrix
    (red-stones 0)
    (black-stones 0))

(defun create-board (size)
    (make-board :size size :matrix (make-array (list size size))) )

Наистина не ми харесва да имам едновременно make-board и create-board, защото това може да доведе до програмни грешки.


person Genba    schedule 04.12.2010    source източник
comment
Предлагам ви да се запознаете с CLOS, който по същество е системата обект/клас за Common Lisp. С вашата дъска, дефинирана като клас, ще можете да посочите методи чрез (defmethod create-board ((type-of thing))).. Тоест, различни методи за работа с едно и също клас в зависимост от това какъв вид информация предоставя потребителският формуляр. Ако все пак влезете в тази заешка дупка, предлагам това въведение в CLOS, както и включване на :CL-MOP системата Closer To MOP за метакласове, ql: възможност за бързо зареждане.   -  person miercoledi    schedule 10.10.2014


Отговори (2)


Можете да използвате конструктор боа:

(defstruct (board
    (:constructor make-board (&optional (size 7)
                              &aux (matrix (make-array (list size size))))))
  (size)
  (matrix)
  (red-stones 0)
  (black-stones 0))

CLHS документация за defstruct и списъци с ламбда BOA.

person Svante    schedule 04.12.2010

Наистина не ми харесва да имам едновременно make-board и create-board, защото това може да доведе до програмни грешки.

Има справедливо мнение, но тогава наличието на size и matrix също може да доведе до програмни грешки.

Не е необходимо O(n), за да се измери размерът на масив, така че просто бих премахнал напълно слота size. Ако обичайно искате тази стойност за board, лесно е да направите проста обвиваща функция.

Ако искате по-общо решение за „някои от моите слотове се определят от някои от другите ми слотове“, Cells, въпреки че не изглежда да е особено активен в наши дни.

И накрая, бих използвал defclass вместо defstruct, освен ако нямате причина да не го правите.

person Ken    schedule 04.12.2010
comment
Страницата Cells common-lisp.net е остаряла. Разработката продължава на github.com/kennytilton/cells и Cells скоро ще бъдат налични в quicklisp. - person Ramarren; 04.12.2010