In common lisp I've noticed that I can write this:
(defun foo (&key (a 1) (b 2) (c (+ a b))) (print (+ a b c)))
And when I call (foo)
, 6
is printed. So the argument c
can refer to values set for a
and b
. But I can't seem to find a way to do something similar with defstruct
. Something like:
CL-USER> (defstruct thing a b c)
THING
CL-USER> (setq q (make-thing :a 1 :b 2 :c (+ a b)))
; Evaluation aborted
CL-USER> (setq q (make-thing :a 1 :b 2 :c (+ :a :b)))
; Evaluation aborted
Is there a way to do this?
You can do this using :constructor
option of defstruct
.
CL-USER> (defstruct (thing
(:constructor make-thing (&key a b (c (+ a b)))))
a b c)
THING
CL-USER> (make-thing :a 1 :b 2)
#S(THING :A 1 :B 2 :C 3)
For more info, see CLHS entry for defstruct
.
Not that way. But using Lisp reader tricks you can do:
(make-thing :a #1=1 :b #2=2 :c (+ #1# #2#))
Otherwise use defclass
and specialize the generic function shared-initialize
.
Note that these reader macros will reference the form, not the result of evaluating it. Thus
(make-thing :id #1=(generate-unique-id) :my-id-is #1#)
will make a thing
with two distinct calls to generate-unique-id
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With