From: jurgen_defurne
Subject: How to process contents of a list variable through a macro ?
Date: 
Message-ID: <1171886252.583028.218890@l53g2000cwa.googlegroups.com>
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

From: D Herring
Subject: Re: How to process contents of a list variable through a macro ?
Date: 
Message-ID: <76-dnSKu0ta2d0TYnZ2dnUVZ_vKunZ2d@comcast.com>
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
From: Lars Rune Nøstdal
Subject: Re: How to process contents of a list variable through a macro ?
Date: 
Message-ID: <pan.2007.02.19.12.06.10.943081@gmail.com>
On Mon, 19 Feb 2007 03:57:32 -0800, jurgen_defurne wrote:

> (defmacro create-aliases ()
>   (process-aliases *aliases* '(progn)))

(defmacro create-aliases (aliases)
  `(process-aliases ,aliases '(progn)))


..something like that I think. Haven't checked though... :P

-- 
Lars Rune Nøstdal
http://nostdal.org/
From: jurgen_defurne
Subject: Re: How to process contents of a list variable through a macro ?
Date: 
Message-ID: <1171955871.210490.126820@m58g2000cwm.googlegroups.com>
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)))

;;; Execution of the macro (create-aliases) creates all
;;; necessary accessor-functions.
(create-aliases *aliases*)

Jurgen
From: ······@corporate-world.lisp.de
Subject: Re: How to process contents of a list variable through a macro ?
Date: 
Message-ID: <1171959407.682752.131590@p10g2000cwp.googlegroups.com>
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/
From: ······@corporate-world.lisp.de
Subject: Re: How to process contents of a list variable through a macro ?
Date: 
Message-ID: <1171973021.327280.178770@t69g2000cwt.googlegroups.com>
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/
From: jurgen_defurne
Subject: Re: How to process contents of a list variable through a macro ?
Date: 
Message-ID: <1171980120.123473.47270@a75g2000cwd.googlegroups.com>
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/