Hello,
I have the following code :
;;; Given a structure, composed of substructures, it is possible
to
;;; create aliases which return the substructures immediately,
by
;;; abbreviating the functions needed to access
them.
(defstruct connector
(value 0 :type integer)
(comment "" :type string))
(defstruct compound
(input-a (make-connector) :type connector)
(input-b (make-connector) :type connector)
(output (make-connector) :type connector))
(defstruct cp-system
(buffer (make-compound) :type compound)
(register (make-compound) :type compound)
(alu (make-compound) :type compound)
(memory (make-compound) :type compound))
(defparameter *aliases*
'((cp-system-buffer buffer-input-a compound-input-a)
(cp-system-buffer buffer-input-b compound-input-b)
(cp-system-buffer buffer-output compound-output)
(cp-system-register register-input-a compound-input-a)
(cp-system-register register-input-b compound-input-b)
(cp-system-register register-output compound-output)
(cp-system-alu alu-input-a compound-input-a)
(cp-system-alu alu-input-b compound-input-b)
(cp-system-alu alu-output compound-output)
(cp-system-memory memory-input-a compound-input-a)
(cp-system-memory memory-input-b compound-input-b)
(cp-system-memory memory-output compound-output)))
(defun process-alias (e)
`(defun ,(second e) (s)
(,(third e) (,(first e) s))))
(defun process-aliases (list accu)
(if (null list)
accu
(if (null accu)
(process-aliases (cdr list)
(cons (process-alias (car list)) nil))
(process-aliases (cdr list)
(nconc accu (cons (process-alias (car list))
nil))))))
(defmacro create-aliases ()
(process-aliases *aliases* '(progn)))
;;; Execution of the macro (create-aliases) creates all
necessary
;;; accessor-
functions.
(create-aliases)
However, I would like to use the macro create-aliases more
generically, as in
(create-aliases *aliases*)
The problem is that in that case a parameter of the macro create-
aliases only processes the name, which is not a list, of course, and
thus generates a compile-time error.
I also tried the backquote operator, but I haven't got much success
with it either.
Regards,
Jurgen
jurgen_defurne wrote:
...
> However, I would like to use the macro create-aliases more
> generically, as in
>
> (create-aliases *aliases*)
It all depends on when and how the argument to create-aliases is bound.
Here's an example that illustrates several possibilities.
(defmacro m (x)
(cond ((listp x)
(if (eq (car x) 'quote)
(format t "quoted: ~{~S~}~%" (cadr x))
(format t "list: ~{~S~}~%" x)))
((symbolp x)
(cond ((not (boundp x))
`(format t "lexical: ~{~S~}~%" ,x))
((listp (symbol-value x))
(format t "dynamic-immediate: ~{~S~}~%"
(symbol-value x)))
(t
`(if (listp ,x)
(format t "dynamic-rebound: ~{~S~}~%" ,x)
(format t "dynamic-bad: ~S~%" ,x)))))
(t
(format t "bad: ~S~%" x))))
(m '(1 2 3))
(m (1 2 3))
(let ((q '(4 5 6)))
(m q))
(let ((p3 '(7 8 9)))
(declare (special p3))
(m p3))
(defparameter p1 '(1 2 3))
(defparameter p2 "hi")
(m p1)
(m p2)
(let ((p2 '(4 5 6)))
(m p2))
(m "hi")
In short, explicit lists can be processed immediately inside the macro.
Lexical variables cannot; the macro must return a form to evaluate
them. Dynamic variables (defparameter, defvar) can be processed either way.
- Daniel
On 20 Feb., 08:17, "jurgen_defurne" <··············@pandora.be> wrote:
> On Feb 19, 12:57 pm, "jurgen_defurne" <··············@pandora.be>
> wrote:
>
>
>
> > Hello,
>
> > I have the following code :
>
> > ;;; Given a structure, composed of substructures, it is possible
> > to
> > ;;; create aliases which return the substructures immediately,
> > by
> > ;;; abbreviating the functions needed to access
> > them.
>
> > (defstruct connector
> > (value 0 :type integer)
> > (comment "" :type string))
>
> > (defstruct compound
> > (input-a (make-connector) :type connector)
> > (input-b (make-connector) :type connector)
> > (output (make-connector) :type connector))
>
> > (defstruct cp-system
> > (buffer (make-compound) :type compound)
> > (register (make-compound) :type compound)
> > (alu (make-compound) :type compound)
> > (memory (make-compound) :type compound))
>
> > (defparameter *aliases*
> > '((cp-system-buffer buffer-input-a compound-input-a)
> > (cp-system-buffer buffer-input-b compound-input-b)
> > (cp-system-buffer buffer-output compound-output)
> > (cp-system-register register-input-a compound-input-a)
> > (cp-system-register register-input-b compound-input-b)
> > (cp-system-register register-output compound-output)
> > (cp-system-alu alu-input-a compound-input-a)
> > (cp-system-alu alu-input-b compound-input-b)
> > (cp-system-alu alu-output compound-output)
> > (cp-system-memory memory-input-a compound-input-a)
> > (cp-system-memory memory-input-b compound-input-b)
> > (cp-system-memory memory-output compound-output)))
>
> > (defun process-alias (e)
> > `(defun ,(second e) (s)
> > (,(third e) (,(first e) s))))
>
> > (defun process-aliases (list accu)
> > (if (null list)
> > accu
> > (if (null accu)
> > (process-aliases (cdr list)
> > (cons (process-alias (car list)) nil))
> > (process-aliases (cdr list)
> > (nconc accu (cons (process-alias (car list))
> > nil))))))
>
> > (defmacro create-aliases ()
> > (process-aliases *aliases* '(progn)))
>
> > ;;; Execution of the macro (create-aliases) creates all
> > necessary
> > ;;; accessor-
> > functions.
> > (create-aliases)
>
> > However, I would like to use the macro create-aliases more
> > generically, as in
>
> > (create-aliases *aliases*)
>
> > The problem is that in that case a parameter of the macro create-
> > aliases only processes the name, which is not a list, of course, and
> > thus generates a compile-time error.
>
> > I also tried the backquote operator, but I haven't got much success
> > with it either.
>
> > Regards,
>
> > Jurgen
>
> Thinking this through, I found the solution this morning.
>
> (defmacro create-aliases (list)
> (process-aliases (symbol-value *aliases*) '(progn)))
list?
>
> ;;; Execution of the macro (create-aliases) creates all
> ;;; necessary accessor-functions.
> (create-aliases *aliases*)
If you compile the file without loading it, what happens?
Sometimes you might want to make sure that you can
compile the file in a fresh Lisp or make sure that
the source gets loaded first.
A DEFPARAMETER doesn't get executed at compile time.
But the compiler executes the Macros during compile time.
Even those that are defined in the file you compile.
If a macro then references a variable that is in
the same file...
See also EVAL-WHEN .
>
> Jurgen
From: John Thingstad
Subject: Re: How to process contents of a list variable through a macro ?
Date:
Message-ID: <op.tn1o4gdjpqzri1@pandora.upc.no>
On Tue, 20 Feb 2007 09:16:48 +0100, ······@corporate-world.lisp.de
<······@corporate-world.lisp.de> wrote:
>
> A DEFPARAMETER doesn't get executed at compile time.
> But the compiler executes the Macros during compile time.
> Even those that are defined in the file you compile.
> If a macro then references a variable that is in
> the same file...
>
A DEFPARAMETER does (!) get executed at compile time.
It is a DEFVAR declaration that dosn't.
--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
On Feb 20, 12:34 pm, "John Thingstad" <··············@chello.no>
wrote:
> On Tue, 20 Feb 2007 09:16:48 +0100, ······@corporate-world.lisp.de
>
> <······@corporate-world.lisp.de> wrote:
>
> > A DEFPARAMETER doesn't get executed at compile time.
> > But the compiler executes the Macros during compile time.
> > Even those that are defined in the file you compile.
> > If a macro then references a variable that is in
> > the same file...
>
> A DEFPARAMETER does (!) get executed at compile time.
> It is a DEFVAR declaration that dosn't.
That's wrong.
CLHS:
If a defvar or defparameter form appears as a top level form, the
compiler must recognize that the name has been proclaimed special.
However, it must neither evaluate the initial-value form nor assign
the dynamic variable named name at compile time.
>
> --
> Using Opera's revolutionary e-mail client:http://www.opera.com/mail/
On Feb 20, 1:03 pm, ·······@corporate-world.lisp.de" <······@corporate-
world.lisp.de> wrote:
> On Feb 20, 12:34 pm, "John Thingstad" <··············@chello.no>
> wrote:
>
> > On Tue, 20 Feb 2007 09:16:48 +0100, ······@corporate-world.lisp.de
>
> > <······@corporate-world.lisp.de> wrote:
>
> > > A DEFPARAMETER doesn't get executed at compile time.
> > > But the compiler executes the Macros during compile time.
> > > Even those that are defined in the file you compile.
> > > If a macro then references a variable that is in
> > > the same file...
>
> > A DEFPARAMETER does (!) get executed at compile time.
> > It is a DEFVAR declaration that dosn't.
>
> That's wrong.
>
> CLHS:
>
> If a defvar or defparameter form appears as a top level form, the
> compiler must recognize that the name has been proclaimed special.
However, it must neither evaluate the initial-value form nor assign
the dynamic variable named name at compile time.
>
>
>
> > --
> > Using Opera's revolutionary e-mail client:http://www.opera.com/mail/
And that is probably why I need to add the (symbol-value) to obtain
the value of the variable.
Anyway, I have it working now.
Jurgen
From: John Thingstad
Subject: Re: How to process contents of a list variable through a macro ?
Date:
Message-ID: <op.tn1zw4ibpqzri1@pandora.upc.no>
On Tue, 20 Feb 2007 13:03:41 +0100, ······@corporate-world.lisp.de
<······@corporate-world.lisp.de> wrote:
> On Feb 20, 12:34 pm, "John Thingstad" <··············@chello.no>
> wrote:
>> On Tue, 20 Feb 2007 09:16:48 +0100, ······@corporate-world.lisp.de
>>
>> <······@corporate-world.lisp.de> wrote:
>>
>> > A DEFPARAMETER doesn't get executed at compile time.
>> > But the compiler executes the Macros during compile time.
>> > Even those that are defined in the file you compile.
>> > If a macro then references a variable that is in
>> > the same file...
>>
>> A DEFPARAMETER does (!) get executed at compile time.
>> It is a DEFVAR declaration that dosn't.
>
> That's wrong.
>
> CLHS:
>
> If a defvar or defparameter form appears as a top level form, the
> compiler must recognize that the name has been proclaimed special.
> However, it must neither evaluate the initial-value form nor assign
> the dynamic variable named name at compile time.
>
>>
>> --
>> Using Opera's revolutionary e-mail client:http://www.opera.com/mail/
>
>
Hyperspec:
"defparameter unconditionally assigns the initial-value to the dynamic
variable named name.
defvar, by contrast, assigns initial-value (if supplied) to the dynamic
variable named name only
if name is not already bound."
So defvar values get assigned a value when they are first loaded and then
remain the same.
defparameter values by contrast get assigned te initial value each time
they are evalueated
/compiled.
--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: John Thingstad
Subject: Re: How to process contents of a list variable through a macro ?
Date:
Message-ID: <op.tn1z5ys5pqzri1@pandora.upc.no>
On Tue, 20 Feb 2007 16:28:06 +0100, John Thingstad
<··············@chello.no> wrote:
>
> Hyperspec:
>
> "defparameter unconditionally assigns the initial-value to the dynamic
> variable named name.
> defvar, by contrast, assigns initial-value (if supplied) to the dynamic
> variable named name only
> if name is not already bound."
>
> So defvar values get assigned a value when they are first loaded and
> then remain the same.
> defparameter values by contrast get assigned te initial value each time
> they are evalueated
> /compiled.
>
Sorry.. It says reloaded. Not compiled. It just always happens when
I compile a buffer from the editor. (As it should.)
--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/