(defstruct (field (:conc-name field))
(+ #'+ :read-only t)
(- #'- :read-only t)
(* #'* :read-only t)
(/ #'/ :read-only t)
(-zero 0 :read-only t)
(-one 1 :read-only t))
(defconstant +default-field+
(make-field))
As typing
(funcall (field+ field) (field-one field) random-field-element)
would rapidly get tedious, I want to define a macro `with-field-ops'
so that I can write:
(with-field-ops field
(f+ f1 random-field-element))
I came up with this:
(defmacro with-field-ops (field &body body)
`(let ((ff+ (field+ ,field))
(ff- (field- ,field))
(ff* (field* ,field))
(ff/ (field/ ,field))
(f0 (field-zero ,field))
(f1 (field-one ,field)))
(declare (ignorable ff+ ff- ff* ff/ f0 f1))
(macrolet ((f+ (x y) `(funcall ff+ ,x ,y))
(f- (x y) `(funcall ff- ,x ,y))
(f* (x y) `(funcall ff* ,x ,y))
(f/ (x y) `(funcall ff/ ,x ,y)))
,@body)))
which is a bit cludgy, but works if I type it at the toplevel. However
if I chuck the above code in a "FIELD" package, this happens:
;; Loading file /home/mwh21/src/c2/16.1/field.lisp ...
;; Loading of file /home/mwh21/src/c2/16.1/field.lisp is finished.
T
CL-USER[9]> (use-package "FIELD")
T
CL-USER[10]> (with-field-ops +default-field+ (f+ f1 f0))
*** - EVAL: the function F+ is undefined
It's obvious why this happens:
CL-USER[13]> (macroexpand '(with-field-ops +default-field+ (f+ f1 f0)))
(LET
((FIELD::FF+ (FIELD+ +DEFAULT-FIELD+)) (FIELD::FF- (FIELD- +DEFAULT-FIELD+))
(FIELD::FF* (FIELD* +DEFAULT-FIELD+)) (FIELD::FF/ (FIELD/ +DEFAULT-FIELD+))
(FIELD::F0 (FIELD-ZERO +DEFAULT-FIELD+))
(FIELD::F1 (FIELD-ONE +DEFAULT-FIELD+))
)
(DECLARE
(IGNORABLE FIELD::FF+ FIELD::FF- FIELD::FF* FIELD::FF/ FIELD::F0 FIELD::F1)
)
(MACROLET
((FIELD::F+ (FIELD::X FIELD::Y) `(FUNCALL FIELD::FF+ ,FIELD::X ,FIELD::Y))
(FIELD::F- (FIELD::X FIELD::Y) `(FUNCALL FIELD::FF- ,FIELD::X ,FIELD::Y))
(FIELD::F* (FIELD::X FIELD::Y) `(FUNCALL FIELD::FF* ,FIELD::X ,FIELD::Y))
(FIELD::F/ (FIELD::X FIELD::Y) `(FUNCALL FIELD::FF/ ,FIELD::X ,FIELD::Y))
)
(F+ F1 F0)
) ) ;
T
But it's not obvious (to me) what to do about it... is what I'm doing
bad practice for some reason?
It's a bit like with-slots, I suppose.
TIA,
Michael
Michael Hudson <mw...@cam.ac.uk> wrote in message
news:m3aenqi...@atrus.jesus.cam.ac.uk...
> The "FIELD" package should export those symbols that you want to
> `capture' in the body of WITH-FIELD-OPS, (namely F+, F-, F*, and F/)
Thanks. Obvious, but I still wouldn;t have thought of it for some
time, methinks.
Cheers,
Michael