If I call the field macro from toplevel it works ok;
but it fails when I try to embed it in foo--how to fix this?
(defstruct (struc (:conc-name nil)) a b))
(defparameter s (make-struc :a 1 :b 2))
(defmacro field (struc fld val)
`(setf (,fld ,struc) ,val ))
(defun foo (s f)
(let ((value nil))
(format t "~A> " f)
(setf value (read))
(field s f value)))
CL-USER> (foo s 'a)
A> 34
==>(FUNCTION: undefined function #1=(SETF F))
I want functionality similar to below. However,
I want to update struct values, not just return a list:
(defparameter ldep '(name age ssn child-tax-credit?))
(defstruct (dep (:conc-name nil)) name age ssn child-tax-credit?)
(defparameter dep (make-dep :name "nobody" :age 136))
(setf (child-tax-credit? dep) 'yes)
(defun get-input (section)
(setf *inputs* (mapcar #'input section)))
(defun input(field)
(let ((prompt nil))
(format t "~A> " field)
(setf prompt (read))
(list field prompt)))
CL-USER> (get-input ldep)
NAME> "mr smith"
AGE> 34
SSN> "xxx"
CHILD-TAX-CREDIT?> 'no
((NAME "mr smith") (AGE 34) (SSN "xxx") (CHILD-TAX-CREDIT? 'NO))
·········@yahoo.com writes:
> If I call the field macro from toplevel it works ok;
> but it fails when I try to embed it in foo--how to fix this?
Have a look at:
http://groups.google.com/group/comp.lang.lisp/browse_frm/thread/24af86e25777fa0c/34681fc951fb42b2?lnk=st&q=defmacro+defstruct+case+group%3Acomp.lang.lisp+&rnum=7&hl=en#34681fc951fb42b2
--
__Pascal Bourguignon__ http://www.informatimago.com/
"This statement is false." In Lisp: (defun Q () (eq nil (Q)))
Pascal Bourguignon wrote:
> ·········@yahoo.com writes:
>
> > If I call the field macro from toplevel it works ok;
> > but it fails when I try to embed it in foo--how to fix this?
>
> Have a look at:
>
> http://groups.google.com/group/comp.lang.lisp/browse_frm/thread/24af86e25777fa0c/34681fc951fb42b2?lnk=st&q=defmacro+defstruct+case+group%3Acomp.lang.lisp+&rnum=7&hl=en#34681fc951fb42b2
>
>
> --
> __Pascal Bourguignon__ http://www.informatimago.com/
>
> "This statement is false." In Lisp: (defun Q () (eq nil (Q)))
But I am able to access the slot names. I just want to know how to
update a slot value for a function that accepts a struc and slot
parameter .
·········@yahoo.com writes:
> But I am able to access the slot names. I just want to know how to
> update a slot value for a function that accepts a struc and slot
> parameter .
CL-USER> (defstruct example x y)
EXAMPLE
CL-USER> (defparameter structure (make-example :x 'old-x :y 'old-y))
STRUCTURE
CL-USER> structure
#S(EXAMPLE :X OLD-X :Y OLD-Y)
CL-USER> (funcall (fdefinition (list 'setf (progn (format t "~&Where? ")
(read))))
'new-value structure)
Where? example-y
NEW-VALUE
CL-USER> structure
#S(EXAMPLE :X OLD-X :Y NEW-VALUE)
Using fdefinition to retrieve the structure's slot writer at
run time so that it can be funcalled is clunky. I presume
that the design of CL intends that you use CLOS for this
kind of thing.
CL-USER> (defclass example2 ()
((x :initarg :x)
(y :initarg :y)))
#<STANDARD-CLASS EXAMPLE2 {48B6F92D}>
CL-USER> (defparameter class (make-instance 'example2 :x 'old-x :y 'old-y))
CLASS
CL-USER> (describe class)
#<EXAMPLE2 {4800F9E5}> is an instance of class #<STANDARD-CLASS EXAMPLE2
{48B6F92D}>:
The following slots have :INSTANCE allocation:
X OLD-X
Y OLD-Y
CL-USER> (setf (slot-value class (progn (format t "~&Where? ")
(read)))
'new-value)
Where? y
NEW-VALUE
CL-USER> (describe class)
#<EXAMPLE2 {4800F9E5}> is an instance of class #<STANDARD-CLASS EXAMPLE2
{48B6F92D}>:
The following slots have :INSTANCE allocation:
X OLD-X
Y NEW-VALUE
Alan Crowe
Edinburgh
Scotland
·········@yahoo.com writes:
> Pascal Bourguignon wrote:
>> ·········@yahoo.com writes:
>>
>> > If I call the field macro from toplevel it works ok;
>> > but it fails when I try to embed it in foo--how to fix this?
>>
>> Have a look at:
>>
>> http://groups.google.com/group/comp.lang.lisp/browse_frm/thread/24af86e25777fa0c/34681fc951fb42b2?lnk=st&q=defmacro+defstruct+case+group%3Acomp.lang.lisp+&rnum=7&hl=en#34681fc951fb42b2
>
> But I am able to access the slot names. I just want to know how to
> update a slot value for a function that accepts a struc and slot
> parameter .
You have the right to think a little, and to program.
(defmacro defstruct* (opts &rest slots)
(let ((slot-list (mapcar (lambda (s) (if (consp s) (car s) s)) slots))
(struct-name opts)
(conc-name nil)
(include nil))
(cond ((consp opts)
(setf struct-name (car opts)
include (second (assoc :INCLUDE (cdr opts)))
conc-name (second (assoc :CONC-NAME (cdr opts))))
(if conc-name
(setf conc-name (format nil "~A" conc-name))
(setf conc-name (format nil "~A-" struct-name)))
(when include
(setf slot-list (append (structure-slot-names include) slot-list))))
(t (setf conc-name (setf conc-name (format nil "~A-" struct-name)))))
`(progn
(setf (get ',struct-name 'original-defstruct-slots)
(list
,@(mapcar
(lambda (s)
(let ((accessor (intern (format nil "~A~A" conc-name s))))
`(list ',s
(function ,accessor)
(function (setf ,accessor)))))
slot-list)))
(defstruct ,opts ,@slots))))
(defun structure-slot-readers (structure-name)
"Given the name of structure, return the reader functions."
(mapcar (function second) (structure-slot-alist structure-name)))
(defun structure-slot-reader (structure-name slot-name)
"Given the name of a structure and a slot, return reader functions."
(second (assoc slot-name (structure-slot-alist structure-name))))
(defun structure-slot-writers (structure-name)
"Given the name of structure, return the reader functions."
(mapcar (function third) (structure-slot-alist structure-name)))
(defun structure-slot-writer (structure-name slot-name)
"Given the name of a structure and a slot, return reader functions."
(third (assoc slot-name (structure-slot-alist structure-name))))
(defun field-value (structure field)
(funcall (structure-slot-reader (type-of structure) field) structure))
(defun (setf field-value) (value structure field)
(funcall (structure-slot-writer (type-of structure) field) value structure))
LISP> (defparameter *p* (make-phew))
*P*
LISP> (field-value *p* 'baz)
1
LISP> (setf (field-value *p* 'baz) 2)
2
LISP> *p*
#S(PHEW :BAR NIL :BAZ 2 :BEAR NIL :BAHS NIL)
(defun list-all-structure-slots (struct name)
(mapcar (lambda (accessor) (funcall accessor struct))
(structure-slot-readers name)))
LISP> (list-all-structure-slots *p* (type-of *p*))
(NIL 2 NIL NIL)
--
__Pascal Bourguignon__ http://www.informatimago.com/
"You question the worthiness of my code? I should kill you where you
stand!"