Gmail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
Remembering information during compilation
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  Messages 1 - 25 of 47 - Collapse all  -  Translate all to Translated (View all originals)   Newer >
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Spiros Bousbouras  
View profile  
 More options Nov 8, 5:18 am
Newsgroups: comp.lang.lisp
From: Spiros Bousbouras <spi...@gmail.com>
Date: Sat, 07 Nov 2009 18:18:19 GMT
Local: Sun, Nov 8 2009 5:18 am
Subject: Remembering information during compilation
I'm trying to construct a macro called memory. The syntax is
memory (&rest body) and doing  (memory form) should expand to

(SYMBOL-MACROLET ((CELL XXX))
   form)

where XXX should be replaced by the number of surrounding memory
invocations. So for example

(memory
  (format t "CELL has value ~a~%" cell)
  (memory  (format t "CELL has value ~a~%" cell))
  (format t "CELL has value ~a~%" cell))

should expand to

(SYMBOL-MACROLET ((CELL 1))
  (FORMAT T "CELL has value ~a~%" CELL)
  (SYMBOL-MACROLET ((CELL 2))
     (FORMAT T "CELL has value ~a~%" CELL))
  (FORMAT T "CELL has value ~a~%" CELL))

and produce
    CELL has value 1
    CELL has value 2
    CELL has value 1

Note how in the second invocation of memory, CELL is assigned the form
2 because it is inside 2 nested invocations of memory. No matter how
deeply nested (within reason) the invocations of memory are CELL should
get the correct value. Below are my efforts but they have not met with
success.

(let ((a 0))
   (defmacro memory (&rest body)
      (prog2
         (incf a)
         `(symbol-macrolet ((cell ,a))
             ,@body)
         (decf a))))

With the test I gave above it produces
    CELL has value 1
    CELL has value 1
    CELL has value 1

So the second invocation of memory in the test does not increase by 1
the value of CELL.

The second attempt wouldn't be completely satisfactory even if it
worked because it exposes to the outside world an internal part of the
implementation , the variable B. But it doesn't work.

(defparameter b 0)

(defmacro memory2 (&rest body)            
  (prog2
     (defparameter b (+ b 1))
     `(symbol-macrolet ((cell ,b))
         ,@body)
     (defparameter b (- b 1))))

Once again doing

(memory2
  (format t "CELL has value ~a~%" cell)
  (memory2  (format t "CELL has value ~a~%" cell))
  (format t "CELL has value ~a~%" cell))

produces
    CELL has value 1
    CELL has value 1
    CELL has value 1

I tried some variations of the above but no luck. So first why do my
attempts above not work ? I assume that by the time the code generated
from the macro expansion gets compiled the statement (decf a) has
already been executed. Am I right ?

It would be convenient if Lisp had some kind of minimal-compile
function so that you could do  (minimal-compile form)  and it would
return what results after minimal compilation of the form. With
such a thing one could define memory as

(let ((a 0))
   (defmacro memory (&rest body)
      (prog2
         (incf a)
         (minimal-compile
            `(symbol-macrolet ((cell ,a))
                ,@body))
         (decf a))))

Does anyone know an implementation with such a facility ? Any other
solutions to the problem ?

--
Shakespeare also predicted structured programming:
"Go to, go to, thou are a foolish fellow. Let me be clear of thee."
Twelfth Night, Act IV, Scene 1.

from http://www.iidb.org/vbb/showthread.php?p=3352214#post3352214


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Pascal J. Bourguignon  
View profile  
 More options Nov 8, 5:41 am
Newsgroups: comp.lang.lisp
From: p...@informatimago.com (Pascal J. Bourguignon)
Date: Sat, 07 Nov 2009 19:41:47 +0100
Local: Sun, Nov 8 2009 5:41 am
Subject: Re: Remembering information during compilation

Spiros Bousbouras <spi...@gmail.com> writes:
> I'm trying to construct a macro called memory.

(defparameter *cell* 0)
(define-symbol-macro cell *cell*)
(defmacro memory (&rest body)
  `(let ((*cell* (1+ *cell*)))
     ,@body)))

C/USER[100]> (memory
              (format t "CELL has value ~a~%" cell)
              (memory  (format t "CELL has value ~a~%" cell))
              (format t "CELL has value ~a~%" cell))
CELL has value 1
CELL has value 2
CELL has value 1
NIL

--
__Pascal Bourguignon__


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kaz Kylheku  
View profile  
 More options Nov 8, 5:44 am
Newsgroups: comp.lang.lisp
From: Kaz Kylheku <kkylh...@gmail.com>
Date: Sat, 7 Nov 2009 18:44:28 +0000 (UTC)
Local: Sun, Nov 8 2009 5:44 am
Subject: Re: Remembering information during compilation
On 2009-11-07, Spiros Bousbouras <spi...@gmail.com> wrote:

> It would be convenient if Lisp had some kind of minimal-compile
> function ...

Indeed, it would help a certain troll in another thread to have a fraction of a
valid point.

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kaz Kylheku  
View profile  
 More options Nov 8, 5:53 am
Newsgroups: comp.lang.lisp
From: Kaz Kylheku <kkylh...@gmail.com>
Date: Sat, 7 Nov 2009 18:53:49 +0000 (UTC)
Local: Sun, Nov 8 2009 5:53 am
Subject: Re: Remembering information during compilation
On 2009-11-07, Spiros Bousbouras <spi...@gmail.com> wrote:

Why does cell have to be a symbol macro? How about simply generating:

(let ((cell (1+ cell)) ...)

Take advantage of the LET scoping rule which allows you to shadow an outer
variable, but use its avlue to initialize the shadowing one.

You just need to bootstrap this somehow for the outermost invocation.  Here is
where a symbol macro comes in: a global one made with define-symbol-macro,
to avoid introducing cell as a dynamic variable.


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Pascal Costanza  
View profile  
 More options Nov 8, 6:04 am
Newsgroups: comp.lang.lisp
From: Pascal Costanza <p...@p-cos.net>
Date: Sat, 07 Nov 2009 20:04:32 +0100
Local: Sun, Nov 8 2009 6:04 am
Subject: Re: Remembering information during compilation

What do you want the following to evaluate to?

(setq f (memory
           (lambda ()
             (memory (print cell)))))

(funcall f)

If you want this to evaluate to 1, the other Pascal's solution is fine.

IF you want this to evaluate to 2, here is another solution:

(define-symbol-macro cell 0)

(defmacro memory (&body body &environment env)
   (let ((new-cell-value (1+ (macroexpand 'cell env))))
     `(symbol-macrolet ((cell ,new-cell-value))
        ,@body)))

One important thing to keep in mind: Don't use side effects in macro
definitions. In both your solutions, you tried to achieve the result by
assigning to a local or global variable as part of the macroexpansion
process. However, you cannot predict whether or when, and how often, a
particular macro will be invoked. For example, development environments
may offer users to expand macros on demand, compilers may expand macros
several times for analysis, higher-order macros may expand inner macro
for analysis as well, etc., etc. So make sure that your macros are
always side-effect-free (unless you really know what you're doing).

Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vassil Nikolov  
View profile  
 More options Nov 8, 6:55 am
Newsgroups: comp.lang.lisp
From: Vassil Nikolov <vniko...@pobox.com>
Date: Sat, 07 Nov 2009 14:55:07 -0500
Local: Sun, Nov 8 2009 6:55 am
Subject: Re: Remembering information during compilation

On Sat, 07 Nov 2009 18:18:19 GMT, Spiros Bousbouras <spi...@gmail.com> said:

> I'm trying to construct a macro called memory. The syntax is
> memory (&rest body) and doing  (memory form) should expand to
> (SYMBOL-MACROLET ((CELL XXX))
>    form)
> where XXX should be replaced by the number of surrounding memory
> invocations.

  Surrounding how?  Lexically or dynamically?

  ---Vassil.

--
"Even when the muse is posting on Usenet, Alexander Sergeevich?"


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Spiros Bousbouras  
View profile  
 More options Nov 8, 9:06 am
Newsgroups: comp.lang.lisp
From: Spiros Bousbouras <spi...@gmail.com>
Date: Sat, 7 Nov 2009 14:06:40 -0800 (PST)
Local: Sun, Nov 8 2009 9:06 am
Subject: Re: Remembering information during compilation

On 7 Nov, 18:41, p...@informatimago.com (Pascal J. Bourguignon) wrote:

> Spiros Bousbouras <spi...@gmail.com> writes:
> > I'm trying to construct a macro called memory.

> (defparameter *cell* 0)
> (define-symbol-macro cell *cell*)
> (defmacro memory (&rest body)
>   `(let ((*cell* (1+ *cell*)))
>      ,@body)))

This is a good approximation to what I asked for. The following is
even better:

(defparameter b 0)
(defmacro memory (&rest body)
   `(let ((b (1+ b)))
      (symbol-macrolet ((cell b))
        ,@body)))

It makes cell only available within body not everywhere. A difference
from my vision is that in the code above cell expands to a variable
instead of a numerical constant but that's fairly unimportant.  I'm a
bit more annoyed by the fact that your solution also exposes an
implementation detail to the world. I would prefer a 100% clean
solution like what we would have if memory were a function when we
would use closures.

--
Who's your mama ?


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Spiros Bousbouras  
View profile  
 More options Nov 8, 9:20 am
Newsgroups: comp.lang.lisp
From: Spiros Bousbouras <spi...@gmail.com>
Date: Sat, 7 Nov 2009 14:20:42 -0800 (PST)
Local: Sun, Nov 8 2009 9:20 am
Subject: Re: Remembering information during compilation

On 7 Nov, 18:53, Kaz Kylheku <kkylh...@gmail.com> wrote:

> Why does cell have to be a symbol macro? How about simply generating:

> (let ((cell (1+ cell)) ...)

> Take advantage of the LET scoping rule which allows you to shadow an outer
> variable, but use its avlue to initialize the shadowing one.

It doesn't have to be a symbol macro. The point of the exercise is to
investigate methods by which different invocations of the same macro
can share information. Many of the technical details are unimportant.
Having said that , it would be nice to have a way for this sharing of
information to happen through objects only the macro knows about.

> You just need to bootstrap this somehow for the outermost invocation.  Here is
> where a symbol macro comes in: a global one made with define-symbol-macro,
> to avoid introducing cell as a dynamic variable.

It would be good if this bootstrapping could be done through the
macro
definition itself.

--
To have absolutely if l' this large Mister is loved!
Translation on 2-11-2009 by
http://uk.babelfish.yahoo.com/translate_txt of
"A posséder absolument si l'on aime ce grand monsieur!


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Spiros Bousbouras  
View profile  
 More options Nov 8, 9:23 am
Newsgroups: comp.lang.lisp
From: Spiros Bousbouras <spi...@gmail.com>
Date: Sat, 7 Nov 2009 14:23:36 -0800 (PST)
Local: Sun, Nov 8 2009 9:23 am
Subject: Re: Remembering information during compilation
On 7 Nov, 19:55, Vassil Nikolov <vniko...@pobox.com> wrote:

> On Sat, 07 Nov 2009 18:18:19 GMT, Spiros Bousbouras <spi...@gmail.com> said:

> > I'm trying to construct a macro called memory. The syntax is
> > memory (&rest body) and doing  (memory form) should expand to
> > (SYMBOL-MACROLET ((CELL XXX))
> >    form)
> > where XXX should be replaced by the number of surrounding memory
> > invocations.

>   Surrounding how?  Lexically or dynamically?

Lexically. See the examples above. I'm not even sure what a
dynamic surrounding would be.

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Madhu  
View profile  
 More options Nov 8, 11:52 am
Newsgroups: comp.lang.lisp
From: Madhu <enom...@meer.net>
Date: Sun, 08 Nov 2009 06:22:05 +0530
Local: Sun, Nov 8 2009 11:52 am
Subject: Re: Remembering information during compilation
* Kaz Kylheku <20091107104314....@gmail.com> :
Wrote on Sat, 7 Nov 2009 18:44:28 +0000 (UTC):

| On 2009-11-07, Spiros Bousbouras <spi...@gmail.com> wrote:
|> It would be convenient if Lisp had some kind of minimal-compile
|> function ...
|
| Indeed, it would help a certain troll in another thread to have a
| fraction of a valid point.

Assuming you are baiting me here by calling me a troll, I think you are
rather sore for pointing out you had no clue what minimal compilation
was and its implications to symbol macro-expansion

--
Madhu


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Barry Margolin  
View profile  
 More options Nov 8, 4:50 pm
Newsgroups: comp.lang.lisp
From: Barry Margolin <bar...@alum.mit.edu>
Date: Sun, 08 Nov 2009 00:50:47 -0500
Local: Sun, Nov 8 2009 4:50 pm
Subject: Re: Remembering information during compilation
In article
<52b2c0f6-8c87-498c-a716-11efaf7a0...@o10g2000yqa.googlegroups.com>,
 Spiros Bousbouras <spi...@gmail.com> wrote:

> On 7 Nov, 19:55, Vassil Nikolov <vniko...@pobox.com> wrote:
> > On Sat, 07 Nov 2009 18:18:19 GMT, Spiros Bousbouras <spi...@gmail.com> said:

> > > I'm trying to construct a macro called memory. The syntax is
> > > memory (&rest body) and doing  (memory form) should expand to
> > > (SYMBOL-MACROLET ((CELL XXX))
> > >    form)
> > > where XXX should be replaced by the number of surrounding memory
> > > invocations.

> >   Surrounding how?  Lexically or dynamically?

> Lexically. See the examples above. I'm not even sure what a
> dynamic surrounding would be.

(defun fun1 ()
  (memory
     (print cell)
     (fun2)
     (print cell)))

(defun fun2
  (memory
    (print cell)))

When PRINT in FUN2 is called, there's one lexical surrounding
invocation, two dynamic ones.

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vassil Nikolov  
View profile  
 More options Nov 9, 3:08 am
Newsgroups: comp.lang.lisp
From: Vassil Nikolov <vniko...@pobox.com>
Date: Sun, 08 Nov 2009 11:08:07 -0500
Local: Mon, Nov 9 2009 3:08 am
Subject: Re: Remembering information during compilation

On Sat, 7 Nov 2009 14:23:36 -0800 (PST), Spiros Bousbouras <spi...@gmail.com> said:

> On 7 Nov, 19:55, Vassil Nikolov <vniko...@pobox.com> wrote:
>> On Sat, 07 Nov 2009 18:18:19 GMT, Spiros Bousbouras <spi...@gmail.com> said:

>> > I'm trying to construct a macro called memory. The syntax is
>> > memory (&rest body) and doing  (memory form) should expand to
>> > (SYMBOL-MACROLET ((CELL XXX))
>> >    form)
>> > where XXX should be replaced by the number of surrounding memory
>> > invocations.

>> Surrounding how?  Lexically or dynamically?
> Lexically.

  Then a solution cannot be based on a special variable (at least not
  a naïve solution; and even if a complicated solution could, I don't
  think it would be worth the candles).

  ---Vassil.

--
"Even when the muse is posting on Usenet, Alexander Sergeevich?"


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Spiros Bousbouras  
View profile  
 More options Nov 10, 8:36 am
Newsgroups: comp.lang.lisp
From: Spiros Bousbouras <spi...@gmail.com>
Date: Mon, 9 Nov 2009 13:36:37 -0800 (PST)
Local: Tues, Nov 10 2009 8:36 am
Subject: Re: Remembering information during compilation
On 7 Nov, 19:04, Pascal Costanza <p...@p-cos.net> wrote:

> What do you want the following to evaluate to?

No preference , the question was for educational purposes.

This is interesting. I did some experiments trying to understand why
it behaves the way it does. Let's also define

(defmacro memory2 (&body body)
   (let ((new-cell-value (1+ (macroexpand 'cell))))
     `(symbol-macrolet ((cell ,new-cell-value))
        ,@body)))

(let ((f1
         (memory
           (lambda ()
             (memory (format t "Calling f1 gives ~a~%" cell)))))
      (f2
         (memory2
           (lambda ()
             (memory2 (format t "Calling f2 gives ~a~%" cell))))))
   (funcall f1)
   (funcall f2)
    '|                            |)

I get
Calling f1 gives 2
Calling f2 gives 1

Let me see if I understand the reason for the difference between
memory and memory2. The first call to the two macros expands to the
same thing and places what follows in the scope of (after expansions)
(symbol-macrolet ((cell 1))
The difference lies in the behaviour of the line
(let ((new-cell-value (1+ (macroexpand 'cell env))))
   vs
(let ((new-cell-value (1+ (macroexpand 'cell))))
in the second call to the macros. There
(macroexpand 'cell env) evaluates to 1 whereas
(macroexpand 'cell) evaluates to 0.
The reason is the following excerpt in the macroexpand page in
the HS:

    In addition to macro definitions in the global environment,
    any local macro definitions established within env by
    macrolet or symbol-macrolet are considered. If only form is
    supplied as an argument, then the environment is effectively
    null, and only global macro definitions as established by
    defmacro are considered.

I assume the last line should actually read "defmacro or
define-symbol-macro are considered".

Is my understanding correct ?

--
<Khassaki> HI EVERYBODY!!!!!!!!!!
<Judge-Mental> try pressing the the Caps Lock key
<Khassaki> O THANKS!!! ITS SO MUCH EASIER TO WRITE NOW!!!!!!!
<Judge-Mental> fuck me
   http://www.bash.org/?835030


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Spiros Bousbouras  
View profile  
 More options Nov 10, 8:50 am
Newsgroups: comp.lang.lisp
From: Spiros Bousbouras <spi...@gmail.com>
Date: Mon, 9 Nov 2009 13:50:16 -0800 (PST)
Local: Tues, Nov 10 2009 8:50 am
Subject: Re: Remembering information during compilation
On 7 Nov, 19:04, Pascal Costanza <p...@p-cos.net> wrote:

> One important thing to keep in mind: Don't use side effects in macro
> definitions. In both your solutions, you tried to achieve the result by
> assigning to a local or global variable as part of the macroexpansion
> process. However, you cannot predict whether or when, and how often, a
> particular macro will be invoked. For example, development environments
> may offer users to expand macros on demand, compilers may expand macros
> several times for analysis, higher-order macros may expand inner macro
> for analysis as well, etc., etc. So make sure that your macros are
> always side-effect-free (unless you really know what you're doing).

So you're saying that setq (or setf) should not appear in the code of
the macroexpansion function ? Why , what could go wrong ?

--
Who's your mama ?


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Pascal J. Bourguignon  
View profile  
 More options Nov 10, 12:40 pm
Newsgroups: comp.lang.lisp
From: p...@informatimago.com (Pascal J. Bourguignon)
Date: Tue, 10 Nov 2009 02:40:18 +0100
Local: Tues, Nov 10 2009 12:40 pm
Subject: Re: Remembering information during compilation

Spiros Bousbouras <spi...@gmail.com> writes:
> On 7 Nov, 19:04, Pascal Costanza <p...@p-cos.net> wrote:

>> One important thing to keep in mind: Don't use side effects in macro
>> definitions. In both your solutions, you tried to achieve the result by
>> assigning to a local or global variable as part of the macroexpansion
>> process. However, you cannot predict whether or when, and how often, a
>> particular macro will be invoked. For example, development environments
>> may offer users to expand macros on demand, compilers may expand macros
>> several times for analysis, higher-order macros may expand inner macro
>> for analysis as well, etc., etc. So make sure that your macros are
>> always side-effect-free (unless you really know what you're doing).

> So you're saying that setq (or setf) should not appear in the code of
> the macroexpansion function ? Why , what could go wrong ?

(defvar *c* 0)

(defmacro  m ()
   (incf *c*)
   `',*c*)

(defun f ()
   (list (m) (m)))

(f) --> (1 2) ; or
    --> (42 87) ; or anything else.

(f) --> (1 2) ; or
    --> (3 4) ; or
    --> (36 99) ; or anything else.

For example, here is what you get with clisp:

C/USER[5]> (f) ; interpreted
(1 2)
C/USER[6]> (f) ; minimal compilation is cached.
(1 2)
C/USER[7]> (compile 'f) ; execute minimal compilation once again
F ;
NIL ;
NIL
C/USER[8]> (f) ; hence the new result
(3 4)
C/USER[9]> (f)
(3 4)

--
__Pascal Bourguignon__
http://www.informatimago.com


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Pascal Costanza  
View profile  
 More options Nov 10, 8:04 pm
Newsgroups: comp.lang.lisp
From: Pascal Costanza <p...@p-cos.net>
Date: Tue, 10 Nov 2009 10:04:52 +0100
Local: Tues, Nov 10 2009 8:04 pm
Subject: Re: Remembering information during compilation

Yes, this is correct. The Common Lisp environment objects effectively
give you a first-class representation of (compile-time) lexical
environments.

Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Pascal Costanza  
View profile  
 More options Nov 10, 8:10 pm
Newsgroups: comp.lang.lisp
From: Pascal Costanza <p...@p-cos.net>
Date: Tue, 10 Nov 2009 10:10:03 +0100
Local: Tues, Nov 10 2009 8:10 pm
Subject: Re: Remembering information during compilation

Spiros Bousbouras wrote:
> On 7 Nov, 19:04, Pascal Costanza <p...@p-cos.net> wrote:
>> One important thing to keep in mind: Don't use side effects in macro
>> definitions. In both your solutions, you tried to achieve the result by
>> assigning to a local or global variable as part of the macroexpansion
>> process. However, you cannot predict whether or when, and how often, a
>> particular macro will be invoked. For example, development environments
>> may offer users to expand macros on demand, compilers may expand macros
>> several times for analysis, higher-order macros may expand inner macro
>> for analysis as well, etc., etc. So make sure that your macros are
>> always side-effect-free (unless you really know what you're doing).

> So you're saying that setq (or setf) should not appear in the code of
> the macroexpansion function ? Why , what could go wrong ?

As I said, a macro may be expanded more than once. For example, in the
LispWorks IDE (and others), I can right-click on an s-expression and
macroexpand it, to see what the result of macroexpansion will be. This
will trigger any side effects the macro definition may produce.

Here is another example: Assume you have a 'with-locked macro that
supposedly takes a lock on an object and then executes some code. Since
taking locks is expensive, it may want to avoid doing so. So it does
something like this:

(defmacro with-lock (object &body body &environment env)
   (if (contains object (walk body env))
     `(call-with-locked-object ,object (lambda () ,@body))
     `(progn ,@body)))

(defun contains (object expanded-body)
   ... some form of membership test ...)

(defun walk (code env)
   ... something that repeatedly calls
       (macroexpand code env)
       to expand all macros in code
   ...)

> Who's your mama ?

I don't know why that would be relevant in this thread.

Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Spiros Bousbouras  
View profile  
 More options Nov 11, 8:36 am
Newsgroups: comp.lang.lisp
From: Spiros Bousbouras <spi...@gmail.com>
Date: Tue, 10 Nov 2009 13:36:42 -0800 (PST)
Local: Wed, Nov 11 2009 8:36 am
Subject: Re: Remembering information during compilation
On 10 Nov, 01:40, p...@informatimago.com (Pascal J. Bourguignon)
wrote:

If that's what Pascal meant I'm not surprised. But he referred to the
code in my first post, for example

(let ((a 0))
   (defmacro memory (&rest body)
      (prog2
         (incf a)
         `(symbol-macrolet ((cell ,a))
             ,@body)
         (decf a))))

His phrasing above and the example gave me the impression that he was
saying that all assignments are dangerous even if the effects of the
assignment do not persist after the macroexpansion function has
finished executing. If that's what he meant then I do find it
surprising. For example I don't see what could go wrong with my code
above regardless of how many times the macro gets expanded.

In any case, it seems that if one wants to have macros share
information (apart from trivial cases perhaps) then this cannot be
achieved behind the scenes so to speak. What I mean behind the scenes
is the way you would do it with functions:

(let ((a))
   (defun foo ...
   (defun bar ...)

Any changes to a one function makes the other knows about but the
rest of the code is ignorant about a.  With macros however one has to
put any changes to the shared information in the code the macro
produces thereby leaking what ought to be internal implementation. I
consider this a blemish in Lisp.

--
Capitalization is the difference between "I had to help my uncle Jack
off a horse.." and "I had to help my uncle jack off a horse.."
    http://www.bash.org/?367896


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Pascal Costanza  
View profile  
 More options Nov 11, 11:40 am
Newsgroups: comp.lang.lisp
From: Pascal Costanza <p...@p-cos.net>
Date: Wed, 11 Nov 2009 01:40:58 +0100
Local: Wed, Nov 11 2009 11:40 am
Subject: Re: Remembering information during compilation

I didn't read your code carefully enough, so I indeed didn't notice that
  the side effect didn't persist. However, this code could still create
problems, for example when a user tries to macroexpand some particular
form while some other code is compiled in a background thread, and two
invocations of 'memory are thus expanded at the same time. You would
either need to synchronize the accesses to the 'a variable, for example
by using locks or STM (har :P ), or you should just use local bindings
for 'a.

> In any case, it seems that if one wants to have macros share
> information (apart from trivial cases perhaps) then this cannot be
> achieved behind the scenes so to speak. What I mean behind the scenes
> is the way you would do it with functions:

> (let ((a))
>    (defun foo ...
>    (defun bar ...)

> Any changes to a one function makes the other knows about but the
> rest of the code is ignorant about a.  With macros however one has to
> put any changes to the shared information in the code the macro
> produces thereby leaking what ought to be internal implementation. I
> consider this a blemish in Lisp.

You can hide the shared information in a package.

Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Thomas A. Russ  
View profile  
 More options Nov 11, 12:51 pm
Newsgroups: comp.lang.lisp
From: t...@sevak.isi.edu (Thomas A. Russ)
Date: 10 Nov 2009 17:51:34 -0800
Local: Wed, Nov 11 2009 12:51 pm
Subject: Re: Remembering information during compilation

Well, I'm not convinced that this has to work the way you may wish it
to.  In particular, the expansion of macros inside BODY doesn't have to
occur in the dynamic scope of the expansion of MEMORY.

So, for example, it seems to me it is perfectly permissible, and in fact
the most likely implementation, that when macros are being expanded the
following happens:

The macro MEMORY is encountered by the code walker or compiler.  It is
expanded, and given the BODY contents.  The BODY contents are not
evaluated, but merely returned inside the SYMBOL-MACROLET form.  The
macroexpansion function for MEMORY returns the new form.

This new form is now walked by the code walker, so if there is any
macros in the newly returned form, they will also be properly expanded.
But since the macro-expansion function has already returned, the value
of variable A has been restored.  So the next expansion doesn't see any
dynamic change.

In fact, I'm pretty sure it has to work this way, since otherwise macros
that expand into code headed by other macros would not work properly.
There will not be any invocation of macro-expansion functions during the
invocation of a macro-expansion function.

You could probably observe this by tracing the macro-expansion function
that corresponds to your macro.  I would expect to see it return before
any other macro expansion occurs.

--
Thomas A. Russ,  USC/Information Sciences Institute


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tobias C. Rittweiler  
View profile  
 More options Nov 11, 7:31 pm
Newsgroups: comp.lang.lisp
From: "Tobias C. Rittweiler" <t...@freebits.de.invalid>
Date: Wed, 11 Nov 2009 09:31:58 +0100
Local: Wed, Nov 11 2009 7:31 pm
Subject: Re: Remembering information during compilation

Spiros Bousbouras <spi...@gmail.com> writes:
> (let ((a 0))
>    (defmacro memory (&rest body)
>       (prog2
>          (incf a)
>          `(symbol-macrolet ((cell ,a))
>              ,@body)
>          (decf a))))

(Mind Thoms Russ' response!)

> In any case, it seems that if one wants to have macros share
> information (apart from trivial cases perhaps) then this cannot be
> achieved behind the scenes so to speak. What I mean behind the scenes
> is the way you would do it with functions:

> (let ((a))
>    (defun foo ...
>    (defun bar ...)

> Any changes to a one function makes the other knows about but the
> rest of the code is ignorant about a.  With macros however one has to
> put any changes to the shared information in the code the macro
> produces thereby leaking what ought to be internal implementation.

Where is it leaking? Because you can introspectively look at a macro's
expansion? Do you consider reflection to be "blemish" in general?

> I consider this a blemish in Lisp.

Impenetrable encapsulation is only longed for by the timid. :-)

  -T.


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Spiros Bousbouras  
View profile  
 More options Nov 18, 1:34 am
Newsgroups: comp.lang.lisp
From: Spiros Bousbouras <spi...@gmail.com>
Date: Tue, 17 Nov 2009 06:34:46 -0800 (PST)
Local: Wed, Nov 18 2009 1:34 am
Subject: Re: Remembering information during compilation
On 11 Nov, 00:40, Pascal Costanza <p...@p-cos.net> wrote:

Is there any established way for how such parallel
expansion/compilation is supposed to work ? Intuitively it seems to
me that in the scenario you're describing the implementation ought to
create one copy of a for the compilation and another for any
expansions which are not part of the compilation. If it doesn't do
that what makes you think that even your code will work correctly ?
There may be clashes with the use of new-cell-value.

You can but still I find it kludgy. You already have the datum in a
variable i.e. in memory but in order to share it with a different
invocation of the macro you have to "print" it and then read it back
in again. Very ugly.  Apart from aesthetics there's another issue :
"Practical Common Lisp" says in footnote 4 of chapter 4 : "Not all
Lisp objects can be written out in a way that can be read back in".
What if it is such an object you want to share ?

--
Never attribute to conspiracy what can adequately be explained by
shared attitudes.


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Pillsy  
View profile  
 More options Nov 18, 1:48 am
Newsgroups: comp.lang.lisp
From: Pillsy <pillsb...@gmail.com>
Date: Tue, 17 Nov 2009 06:48:30 -0800 (PST)
Local: Wed, Nov 18 2009 1:48 am
Subject: Re: Remembering information during compilation
On Nov 10, 4:36 pm, Spiros Bousbouras <spi...@gmail.com> wrote:
[...]

> In any case, it seems that if one wants to have macros share
> information (apart from trivial cases perhaps) then this cannot be
> achieved behind the scenes so to speak. What I mean behind the scenes
> is the way you would do it with functions:
> (let ((a))
>    (defun foo ...
>    (defun bar ...)
> Any changes to a one function makes the other knows about but the
> rest of the code is ignorant about a.

This is a trick I've used once or twice in the past, and I'm just
submitting it as an idea in part because I'd like to see if there are
problems with it that I haven't considered up until now. It's hardly
something I do every day, and I know this corner of macrology is
generally riddled with pitfalls.

The idea is that you have easy access to uninterned symbols, and those
symbols not only have their value cells, but also function cells and
property lists to play with. You could do something like this:

(let ((closed (closed "BACKING-")))
   (defmacro foo (name &rest args)
      (setf (get closed name) (stuff-from-foo-args args))
      (generate-foo-expansion name args closed))
   (defmacro bar (name &rest args)
      (setf (get closed name) (stuff-from-bar-args args))
      (generate-bar-expansion name args closed)))

Is there something horribly wrong with this approach?

Cheers,
Pillsy


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Spiros Bousbouras  
View profile  
 More options Nov 18, 2:16 am
Newsgroups: comp.lang.lisp
From: Spiros Bousbouras <spi...@gmail.com>
Date: Tue, 17 Nov 2009 07:16:49 -0800 (PST)
Local: Wed, Nov 18 2009 2:16 am
Subject: Re: Remembering information during compilation
On 11 Nov, 01:51, t...@sevak.isi.edu (Thomas A. Russ) wrote:

I would be surprised if you or anyone else were convinced since I
already said in my opening post that I tested it and it doesn't work.

> The macro MEMORY is encountered by the code walker or compiler.  It is
> expanded, and given the BODY contents.  The BODY contents are not
> evaluated, but merely returned inside the SYMBOL-MACROLET form.  The
> macroexpansion function for MEMORY returns the new form.

> This new form is now walked by the code walker, so if there is any
> macros in the newly returned form, they will also be properly expanded.
> But since the macro-expansion function has already returned, the value
> of variable A has been restored.  So the next expansion doesn't see any
> dynamic change.

Or as I said in my OP : "I assume that by the time the code generated
from the macro expansion gets compiled the statement (decf a) has
already been executed."

--
The worst part of living on the West Coast is having to remember to
say "no mayonnaise" when ordering a burger.
  tinyurl.com/mayo-quote


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Pillsy  
View profile  
 More options Nov 18, 3:25 am
Newsgroups: comp.lang.lisp
From: Pillsy <pillsb...@gmail.com>
Date: Tue, 17 Nov 2009 08:25:36 -0800 (PST)
Local: Wed, Nov 18 2009 3:25 am
Subject: Re: Remembering information during compilation
On Nov 17, 9:48 am, Pillsy <pillsb...@gmail.com> wrote:
[...]

> (let ((closed (closed "BACKING-")))
>    (defmacro foo (name &rest args)
>       (setf (get closed name) (stuff-from-foo-args args))
>       (generate-foo-expansion name args closed))
>    (defmacro bar (name &rest args)
>       (setf (get closed name) (stuff-from-bar-args args))
>       (generate-bar-expansion name args closed)))
> Is there something horribly wrong with this approach?

Well, one thing that's potentially horribly wrong with the approach is
its dependence on compile-time side-effects. This problem seems pretty
avoidable if all you want to do is establish a private chanell that
can be accessed by your expansions; that may not be enough for your
purposes. But if it is, there's always

(let ((closed (gensym "CLOSED-")))
  (defmacro foo (name &rest stuff)
    `(progn
        (setf (get ',closed ',name) ,(mangle-foo-args args))
        ,(foo-expand name args closed)))
  (defmacro bar (name &rest stuff)
    `(progn
        (setf (get ',closed ',name) ,(mangle-bar-args args))
        ,(foo-expand name args closed))))

Cheers,
Pillsy


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Messages 1 - 25 of 47   Newer >
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google