Reputation: 154
For my project, I specifically need a structure that has (among other things) 2 slots:
That function slot must evaluate the current-state and return a result based on it. However, I can't find how to do this properly. Here's a segment of my code.
(defstruct state moves-left)
(defstruct problem
(current-state)
(solution (function (lambda () (null (state-moves-left :current-state)))))
)
No errors on compiling, but they happen when I interpret this:
> (setq p0 (make-problem :current-state (make-state)))
> (funcall (problem-solution p0))
SYSTEM::%STRUCTURE-REF: :CURRENT-STATE is not a structure of type STATE
Anyone knows how to solve this? I usually just use common functions, but these structure and slots are hard requirements.
EDIT: thanks for the answers. After learning this was impossible, I reread the requirements more thoroughly and posted the answer here.
Upvotes: 3
Views: 1230
Reputation: 154
After learning this was impossible, I reread the requirements more thoroughly and found out this function will actually receive an argument (a state). So, the code now works:
(defstruct problem
(current-state)
(solution (function (lambda (state) (not (null (state-moves-left state))))))
)
Upvotes: 0
Reputation: 139261
You could have a separate create function:
(defun create-problem (state)
(let ((problem (make-problem :current-state state)))
(setf (problem-solution problem)
(lambda ()
(null (state-moves-left (problem-current-state problem)))))
problem))
But: Why not use a function/method directly?
(defmethod problem-solution ((p problem))
(null (state-moves-left (problem-current-state p))))
Upvotes: 5
Reputation: 27424
The reason for the error is that structures in Common Lisp cannot be used as classes: inside the function default value of the slot solution
there is no way of referring to the slots of the structure itself (as you are trying to do with (state-moves-left :current-state)
.
If you insist in using structures instead of classes, one possibility is to define the function with a parameter, and pass the structure itself when the function is called. Something like:
(defstruct problem
(current-state)
(solution (function (lambda (p) (null (state-moves-left p))))))
(let ((p0 (make-problem :current-state (make-state))))
(funcall (problem-solution p0) p0))
Upvotes: 3