Как определять структуры в Лиспе, используя параметры в определении

Я хочу написать такой код на Лиспе

(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:quickload-able.   -  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