Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Packages and macros are driving me slowly insane...

2 views
Skip to first unread message

Michael Hudson

unread,
Dec 4, 1999, 3:00:00 AM12/4/99
to
Let me explain what I am trying to achieve. It's basically generic
arithmetic. I have a `field' structure that contains functions on how to
add, subtract, etc field elements:

(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

Joe Marshall

unread,
Dec 4, 1999, 3:00:00 AM12/4/99
to
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/)


Michael Hudson <mw...@cam.ac.uk> wrote in message
news:m3aenqi...@atrus.jesus.cam.ac.uk...

Michael Hudson

unread,
Dec 5, 1999, 3:00:00 AM12/5/99
to
"Joe Marshall" <jmar...@alum.mit.edu> writes:

> 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

0 new messages