From: rock69
Subject: Which ones come first? - Macro question -
Date: 
Message-ID: <3e032f3d-32f0-4548-a05d-52d991ca7e93@a70g2000hsh.googlegroups.com>
I can't find any info on this matter. Do reader macros (such as
BACKQUOTE, for instance) expand before ordinary macros, or is it the
other way around? For example, if a backquote expression is passed as
an argument to an ordinary macro, will it get expanded first, or will
it be passed as it is (backquote and all) to the parameter (I'm not
sure parameter or argument are the right worda, not being a function,
but I hope you know what I mean) and then get expanded?

And as far backquotes go, when they're nested, in what order do they
expand? 'Cause I really just can't get it, as much as I'm trying to
work it out.

From: Kenny
Subject: Re: Which ones come first? - Macro question -
Date: 
Message-ID: <48bb029b$0$7345$607ed4bc@cv.net>
rock69 wrote:
> I can't find any info on this matter. Do reader macros (such as
> BACKQUOTE, for instance) expand before ordinary macros, or is it the
> other way around? For example, if a backquote expression is passed as
> an argument to an ordinary macro, will it get expanded first, or will
> it be passed as it is (backquote and all) to the parameter (I'm not
> sure parameter or argument are the right worda, not being a function,
> but I hope you know what I mean) and then get expanded?

Well, you /are/ talking about passing a backquoted form to a macro, and 
that is pretty scary. But the short answer is that macros see the 
source, so a backquoted form would not be evaluated.

One good idea in general fro learning macrology is to put a print 
statement at the top of the macro body, outside any intended backquote 
return form. This was quite illuminating for me when I could not 
understand why this:

   (my-macro 'one-thing)

...had my implementation of my-macro stumped by a list being received 
instead of an atom, the symbol. The list was '(quote one-thing).

> 
> And as far backquotes go, when they're nested, in what order do they
> expand? 'Cause I really just can't get it, as much as I'm trying to
> work it out.

backquotes themselves are pretty simple, just a fancy way to generate a 
list where most things are hardcoded symbols but one or two vary at run 
time. When debugging in an environemnt without my tools I do a lot of:

   (print `(what the hell is ,this))

hth, kt
From: Rainer Joswig
Subject: Re: Which ones come first? - Macro question -
Date: 
Message-ID: <joswig-EBB44B.21001631082008@news-europe.giganews.com>
In article 
<····································@a70g2000hsh.googlegroups.com>,
 rock69 <···········@gmail.com> wrote:

> I can't find any info on this matter. Do reader macros (such as
> BACKQUOTE, for instance) expand before ordinary macros, or is it the
> other way around? For example, if a backquote expression is passed as
> an argument to an ordinary macro, will it get expanded first, or will
> it be passed as it is (backquote and all) to the parameter (I'm not
> sure parameter or argument are the right worda, not being a function,
> but I hope you know what I mean) and then get expanded?
> 
> And as far backquotes go, when they're nested, in what order do they
> expand? 'Cause I really just can't get it, as much as I'm trying to
> work it out.

read macros are expanded at read time.

`(foo ,a)  will be expanded at read time to some implementation
specific thing.

For example:

  (SYSTEM::BQ-LIST (QUOTE FOO) A)

When you evaluate above it returns a list.

If you define a simple macro that just returns its argument:

CL-USER 95 > (defmacro foo4 (a) a)
FOO4

Now you see that you get the read backquote form passed to
the macro and returned.

CL-USER 96 > (macroexpand '(foo4 `(foo ,(sin 3))))
(SYSTEM::BQ-LIST (QUOTE FOO) (SIN 3))
T

Basically the result is the same like: 

 (LIST (QUOTE FOO) (SIN 3))

-- 
http://lispm.dyndns.org/
From: Rob Warnock
Subject: Re: Which ones come first? - Macro question -
Date: 
Message-ID: <g8Gdnc02L-2FOCbVnZ2dnUVZ_t3inZ2d@speakeasy.net>
Rainer Joswig  <······@lisp.de> wrote:
+---------------
|  rock69 <···········@gmail.com> wrote:
| > I can't find any info on this matter. Do reader macros (such as
| > BACKQUOTE, for instance) expand before ordinary macros, or is it the
| > other way around? ...
| 
| read macros are expanded at read time.
| `(foo ,a)  will be expanded at read time to some implementation
| specific thing. For example:
|   (SYSTEM::BQ-LIST (QUOTE FOO) A)
+---------------

However, depending on which implementation one is using and the
default values of the printer variables (or values one has set),
one might not see the true internal form (as above), but instead
just see the backquoted form printed out again, e.g.:

    > (quote `(foo ,a))

    `(FOO ,A)
    > 

However, most [but not all!!] CLs will show the "real" internal form
if you turn off pretty-printing. I've found it helpful to keep a tiny
utility function in my toolbox for just this purpose:  ;-}

    > (defun no-pp (x)
	(let ((*print-pretty* nil))
	  (write x)))

    NO-PP
    > (no-pp (quote `(foo ,a)))
    (LISP::BACKQ-LIST (QUOTE FOO) A)
    `(FOO ,A)
    > 

Note that we see the form printed twice: once with pretty-printing
turned off when printed by the WRITE, and then again with the default
pretty-printing back on when the *value* of the WRITE (just its argument)
is printed by the top-level REPL.

Rocco, nota bene!! You will see that Rainer's & my CL implementations
display *different* forms as the output of the `(FOO ,A) form!!!  Which
is right?!? Answer: *BOTH!* *NEITHER!* THERE IS NO "RIGHT"!  ;-} ;-}
It's implementation-dependent. He's using Lispworks, I think,
and I'm using CMUCL.

Unlike the Scheme standard, which specifies a specific reader
transformation to be used for backquote & friends:

    `form ==> (quasiquote form)
    ,form ==> (unquote form)
    ,@form ==> (unquote-splicing form)

the CLHS does not:

    2.4.6 Backquote
    ...
    An implementation is free to interpret a backquoted form F1 as
    any form F2 that, when evaluated, will produce a result that is
    the same under equal as the result implied by the above definition,
    provided that the side-effect behavior of the substitute form F2
    is also consistent with the description given above. The constructed
    copy of the template might or might not share list structure with
    the template itself.

and:

    2.4.6.1 Notes about Backquote

    Since the exact manner in which the Lisp reader will parse an
    expression involving the backquote reader macro is not specified,
    an implementation is free to choose any representation that preserves
    the semantics described.

    Often an implementation will choose a representation that facilitates
    pretty printing of the expression, so that (pprint `(a ,b)) will
    display `(a ,b) and not, for example, (list 'a b). However, this
    is not a requirement. 
    
    ...[and then mentions the Scheme standard for a possible
        but *not* required choice of internal representation]...

You have been warned!  ;-}


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Rainer Joswig
Subject: Re: Which ones come first? - Macro question -
Date: 
Message-ID: <joswig-582609.11244701092008@news-europe.giganews.com>
In article <································@speakeasy.net>,
 ····@rpw3.org (Rob Warnock) wrote:

> Rainer Joswig  <······@lisp.de> wrote:
> +---------------
> |  rock69 <···········@gmail.com> wrote:
> | > I can't find any info on this matter. Do reader macros (such as
> | > BACKQUOTE, for instance) expand before ordinary macros, or is it the
> | > other way around? ...
> | 
> | read macros are expanded at read time.
> | `(foo ,a)  will be expanded at read time to some implementation
> | specific thing. For example:
> |   (SYSTEM::BQ-LIST (QUOTE FOO) A)
> +---------------
> 
> However, depending on which implementation one is using and the
> default values of the printer variables (or values one has set),
> one might not see the true internal form (as above), but instead
> just see the backquoted form printed out again, e.g.:
> 
>     > (quote `(foo ,a))
> 
>     `(FOO ,A)
>     > 

That's the main purpose for a special internal representation, I'd say.
Otherwise it would be the same to use
  (SYSTEM::BQ-LIST (QUOTE FOO) A)
and
  (LIST (QUOTE FOO) A)

> However, most [but not all!!] CLs will show the "real" internal form
> if you turn off pretty-printing. I've found it helpful to keep a tiny
> utility function in my toolbox for just this purpose:  ;-}
> 
>     > (defun no-pp (x)
> 	(let ((*print-pretty* nil))
> 	  (write x)))
> 
>     NO-PP
>     > (no-pp (quote `(foo ,a)))
>     (LISP::BACKQ-LIST (QUOTE FOO) A)
>     `(FOO ,A)
>     > 
> 
> Note that we see the form printed twice: once with pretty-printing
> turned off when printed by the WRITE, and then again with the default
> pretty-printing back on when the *value* of the WRITE (just its argument)
> is printed by the top-level REPL.
> 
> Rocco, nota bene!! You will see that Rainer's & my CL implementations
> display *different* forms as the output of the `(FOO ,A) form!!!  Which
> is right?!? Answer: *BOTH!* *NEITHER!* THERE IS NO "RIGHT"!  ;-} ;-}
> It's implementation-dependent. He's using Lispworks, I think,
> and I'm using CMUCL.
> 
> Unlike the Scheme standard, which specifies a specific reader
> transformation to be used for backquote & friends:
> 
>     `form ==> (quasiquote form)
>     ,form ==> (unquote form)
>     ,@form ==> (unquote-splicing form)
> 
> the CLHS does not:
> 
>     2.4.6 Backquote
>     ...
>     An implementation is free to interpret a backquoted form F1 as
>     any form F2 that, when evaluated, will produce a result that is
>     the same under equal as the result implied by the above definition,
>     provided that the side-effect behavior of the substitute form F2
>     is also consistent with the description given above. The constructed
>     copy of the template might or might not share list structure with
>     the template itself.
> 
> and:
> 
>     2.4.6.1 Notes about Backquote
> 
>     Since the exact manner in which the Lisp reader will parse an
>     expression involving the backquote reader macro is not specified,
>     an implementation is free to choose any representation that preserves
>     the semantics described.
> 
>     Often an implementation will choose a representation that facilitates
>     pretty printing of the expression, so that (pprint `(a ,b)) will
>     display `(a ,b) and not, for example, (list 'a b). However, this
>     is not a requirement. 

!

>     
>     ...[and then mentions the Scheme standard for a possible
>         but *not* required choice of internal representation]...
> 
> You have been warned!  ;-}
> 
> 
> -Rob
> 
> -----
> Rob Warnock			<····@rpw3.org>
> 627 26th Avenue			<URL:http://rpw3.org/>
> San Mateo, CA 94403		(650)572-2607

-- 
http://lispm.dyndns.org/
From: Dan Weinreb
Subject: Re: Which ones come first? - Macro question -
Date: 
Message-ID: <be9d2ecb-fe9d-4f55-9859-5ec565ec6544@25g2000hsx.googlegroups.com>
On Sep 1, 4:17 am, ····@rpw3.org (Rob Warnock) wrote:
> Rainer Joswig  <······@lisp.de> wrote:
> +---------------
> |  rock69 <···········@gmail.com> wrote:
> | > I can't find any info on this matter. Do reader macros (such as
> | > BACKQUOTE, for instance) expand before ordinary macros, or is it the
> | > other way around? ...
> |
> | read macros are expanded at read time.
> | `(foo ,a)  will be expanded at read time to some implementation
> | specific thing. For example:
> |   (SYSTEM::BQ-LIST (QUOTE FOO) A)
> +---------------
>
> However, depending on which implementation one is using and the
> default values of the printer variables (or values one has set),
> one might not see the true internal form (as above), but instead
> just see the backquoted form printed out again, e.g.:
>
>     > (quote `(foo ,a))
>
>     `(FOO ,A)
>     >
>
> However, most [but not all!!] CLs will show the "real" internal form
> if you turn off pretty-printing. I've found it helpful to keep a tiny
> utility function in my toolbox for just this purpose:  ;-}
>
>     > (defun no-pp (x)
>         (let ((*print-pretty* nil))
>           (write x)))
>
>     NO-PP
>     > (no-pp (quote `(foo ,a)))
>     (LISP::BACKQ-LIST (QUOTE FOO) A)
>     `(FOO ,A)
>     >
>
> Note that we see the form printed twice: once with pretty-printing
> turned off when printed by the WRITE, and then again with the default
> pretty-printing back on when the *value* of the WRITE (just its argument)
> is printed by the top-level REPL.
>
> Rocco, nota bene!! You will see that Rainer's & my CL implementations
> display *different* forms as the output of the `(FOO ,A) form!!!  Which
> is right?!? Answer: *BOTH!* *NEITHER!* THERE IS NO "RIGHT"!  ;-} ;-}
> It's implementation-dependent. He's using Lispworks, I think,
> and I'm using CMUCL.
>
> Unlike the Scheme standard, which specifies a specific reader
> transformation to be used for backquote & friends:
>
>     `form ==> (quasiquote form)
>     ,form ==> (unquote form)
>     ,@form ==> (unquote-splicing form)
>
> the CLHS does not:
>
>     2.4.6 Backquote
>     ...
>     An implementation is free to interpret a backquoted form F1 as
>     any form F2 that, when evaluated, will produce a result that is
>     the same under equal as the result implied by the above definition,
>     provided that the side-effect behavior of the substitute form F2
>     is also consistent with the description given above. The constructed
>     copy of the template might or might not share list structure with
>     the template itself.
>
> and:
>
>     2.4.6.1 Notes about Backquote
>
>     Since the exact manner in which the Lisp reader will parse an
>     expression involving the backquote reader macro is not specified,
>     an implementation is free to choose any representation that preserves
>     the semantics described.
>
>     Often an implementation will choose a representation that facilitates
>     pretty printing of the expression, so that (pprint `(a ,b)) will
>     display `(a ,b) and not, for example, (list 'a b). However, this
>     is not a requirement.
>
>     ...[and then mentions the Scheme standard for a possible
>         but *not* required choice of internal representation]...
>
> You have been warned!  ;-}
>
> -Rob
>
> -----
> Rob Warnock                     <····@rpw3.org>
> 627 26th Avenue                 <URL:http://rpw3.org/>
> San Mateo, CA 94403             (650)572-2607

Way back when, I didn't see any problem with putting things like that
into the spec.  Now, I wonder whether giving all the implementors such
flexibility is worth the possible cost in incompatible or inconsistent
behavior between implementations.
From: Rob Warnock
Subject: Re: Which ones come first? - Macro question -
Date: 
Message-ID: <F_ydnREZ5s5OqyDVnZ2dnUVZ_rmdnZ2d@speakeasy.net>
Dan Weinreb <···@alum.mit.edu> wrote:
+---------------
| ····@rpw3.org (Rob Warnock) wrote:
| > Unlike the Scheme standard, which specifies a specific reader
| > transformation to be used for backquote & friends:
| >   `form ==> (quasiquote form)
| >   ,form ==> (unquote form)
| >   ,@form ==> (unquote-splicing form)
| > the CLHS does not:
| >   2.4.6 Backquote
| >   ...
| >   An implementation is free to interpret a backquoted form F1 as
| >   any form F2 that, when evaluated, will produce a result that is
| >   the same under equal as the result implied by the above definition...
...
| > You have been warned! ;-}
| 
| Way back when, I didn't see any problem with putting things like that
| into the spec.  Now, I wonder whether giving all the implementors such
| flexibility is worth the possible cost in incompatible or inconsistent
| behavior between implementations.
+---------------

The biggest problem I've seen with it is that it pretty much precludes
doing a "CLsh" (a "Common Lisp Shell") that would work *exactly* the
same way that "Scsh" <http://www.scsh.net/> does, for two reasons:

1. Since in Scheme QUASIQUOTE is a macro [well, in R4RS it's called
   "essential syntax", but it's almost always implemented as a macro],
   it's possible to have *other* macros that perform "implicit
   quasiquotation" and thus can be defined to use comma (UNQUOTE)
   and comma-at (UNQUOTE-SPLICING) for their own purposes. Common
   Lisp, however, forbids any use of comma or comma-at not inside
   a backquoted form, and there's no (standard-defined) way for any
   "implicitly quasiquotating" macro to suppress the error check in
   the reader.

   This isn't a *total* killer, if one is willing to bend the Scsh
   syntax a bit [which one will *anyway*, since a "CLsh" would be
   using CL syntax, not Scheme]. Then one can (somewhat clumsily)
   work around the issue. That is, instead of the following, which is
   legal Scsh [RUN is a macro which performs "implicit quasiquoting"]:

       (run (ls ,@flags ,dir))

    to make it legal CL one would have to type this [mutatis mutandis
    in the definition of RUN]:

       (run `(ls ,@flags ,dir))

2. Since "an implementation is free to interpret a backquoted form" in
   many different ways, macros such as RUN above aren't guaranteed to be
   able to predict what the reader expanded a backquoted argument form
   into, and thus may have trouble performing its tree-walk. Even worse,
   in some (many?) cases the backquote/comma/comma-at (sub)forms will have
   disappeared *entirely* by the time a macro such as RUN sees the input
   [re-written into LIST/LIST*/CONS/etc. instead of LISP::BACKQ-LIST/
   LISP::BACKQ-CONS/LISP::BACKQ-APPEND/etc.], significantly raising the
   number of patterns the macro has to able to match.

   I haven't actually tried to work out a significant subset of Scsh
   in CL to see yet, but I suspect that even this isn't a total killer,
   either, as one can imagine a common library routine with some
   implementation-specific feature tests that attempts to "back-convert"
   the macro's arguments into some standard (Scheme-like?) form, said
   library routine being called by CLsh macros to "normalize" backquoted
   forms. But even if it's possible, it would certainly add a large pile
   of complexity.


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Thomas F. Burdick
Subject: Re: Which ones come first? - Macro question -
Date: 
Message-ID: <a72762cf-72f2-435d-886d-0102d10815e7@v13g2000pro.googlegroups.com>
On 2 sep, 14:51, ····@rpw3.org (Rob Warnock) wrote:
> Dan Weinreb <····@alum.mit.edu> wrote:
>
> +---------------
> | ····@rpw3.org (Rob Warnock) wrote:
> | > Unlike the Scheme standard, which specifies a specific reader
> | > transformation to be used for backquote & friends:
> | >   `form ==> (quasiquote form)
> | >   ,form ==> (unquote form)
> | >   ,@form ==> (unquote-splicing form)
> | > the CLHS does not:
> | >   2.4.6 Backquote
> | >   ...
> | >   An implementation is free to interpret a backquoted form F1 as
> | >   any form F2 that, when evaluated, will produce a result that is
> | >   the same under equal as the result implied by the above definition...
> ...
> | > You have been warned! ;-}
> |
> | Way back when, I didn't see any problem with putting things like that
> | into the spec.  Now, I wonder whether giving all the implementors such
> | flexibility is worth the possible cost in incompatible or inconsistent
> | behavior between implementations.
> +---------------
>
> The biggest problem I've seen with it is that it pretty much precludes
> doing a "CLsh" (a "Common Lisp Shell") that would work *exactly* the
> same way that "Scsh" <http://www.scsh.net/> does, for two reasons:
>
> 1. Since in Scheme QUASIQUOTE is a macro [well, in R4RS it's called
>    "essential syntax", but it's almost always implemented as a macro],
>    it's possible to have *other* macros that perform "implicit
>    quasiquotation" and thus can be defined to use comma (UNQUOTE)
>    and comma-at (UNQUOTE-SPLICING) for their own purposes. Common
>    Lisp, however, forbids any use of comma or comma-at not inside
>    a backquoted form, and there's no (standard-defined) way for any
>    "implicitly quasiquotating" macro to suppress the error check in
>    the reader.

[snip]

> 2. Since "an implementation is free to interpret a backquoted form" in
>    many different ways, macros such as RUN above aren't guaranteed to be
>    able to predict what the reader expanded a backquoted argument form
>    into, and thus may have trouble performing its tree-walk. Even worse,
>    in some (many?) cases the backquote/comma/comma-at (sub)forms will have
>    disappeared *entirely* by the time a macro such as RUN sees the input
>    [re-written into LIST/LIST*/CONS/etc. instead of LISP::BACKQ-LIST/
>    LISP::BACKQ-CONS/LISP::BACKQ-APPEND/etc.], significantly raising the
>    number of patterns the macro has to able to match.

You're making it too hard again Rob :-) -- in CL we have an extensible
readtable! If one were to do a CLsh, I'd think you'd want your user to
use at least a readtable with read-case set to :invert so you could
interact more easily with the unix world. Given that, it would be
fairly reasonable to install your own backquote and comma reader
macros that read a predictable quasiquote-like structure. Appendix C
from CLtL2 has a portable implementation that could be used as a
starting point.

The main problem with this approach is that for once it's us and not
the Schemers who have roll-your-own compatibility problems. If your
macro wraps its body forms in rpw-quasiquote:backquote and my
readtable turns comma into tfb-bq:comma, we have a problem. So, no
ecosystem of implicitly-backquoting macros, unless someone makes a
canonical quasiquote package, but it shouldn't prevent something like
a CLsh from coming about.

>    I haven't actually tried to work out a significant subset of Scsh
>    in CL to see yet, but I suspect that even this isn't a total killer,
>    either, as one can imagine a common library routine with some
>    implementation-specific feature tests that attempts to "back-convert"
>    the macro's arguments into some standard (Scheme-like?) form, said
>    library routine being called by CLsh macros to "normalize" backquoted
>    forms. But even if it's possible, it would certainly add a large pile
>    of complexity.

If you do work out some portion of a clsh, make noise about it!

PS - I'm not trying to pick on you, just had the same reaction twice
in a row to one of your interesting articles.
From: Michael Weber
Subject: Re: Which ones come first? - Macro question -
Date: 
Message-ID: <de25adba-a0b4-42e1-bb1c-991e689c7879@56g2000hsm.googlegroups.com>
On Sep 2, 4:51 pm, "Thomas F. Burdick" <········@gmail.com> wrote:
> The main problem with this approach is that for once it's us and not
> the Schemers who have roll-your-own compatibility problems. If your
> macro wraps its body forms in rpw-quasiquote:backquote and my
> readtable turns comma into tfb-bq:comma, we have a problem. So, no
> ecosystem of implicitly-backquoting macros, unless someone makes a
> canonical quasiquote package, but it shouldn't prevent something like
> a CLsh from coming about.

You mean a package like this: http://common-lisp.net/project/cl-quasi-quote/

M/
From: Thomas F. Burdick
Subject: Re: Which ones come first? - Macro question -
Date: 
Message-ID: <6d2f0949-4a24-4848-a981-9b7c189d605e@b30g2000prf.googlegroups.com>
On 2 sep, 17:14, Michael Weber <·········@foldr.org> wrote:
> On Sep 2, 4:51 pm, "Thomas F. Burdick" <········@gmail.com> wrote:
>
> > The main problem with this approach is that for once it's us and not
> > the Schemers who have roll-your-own compatibility problems. If your
> > macro wraps its body forms in rpw-quasiquote:backquote and my
> > readtable turns comma into tfb-bq:comma, we have a problem. So, no
> > ecosystem of implicitly-backquoting macros, unless someone makes a
> > canonical quasiquote package, but it shouldn't prevent something like
> > a CLsh from coming about.
>
> You mean a package like this:http://common-lisp.net/project/cl-quasi-quote/
>
> M/

Nope, not at all. I mean a documented implementation of Common Lisp's
backquote syntax that reads to macros. cl-quasi-quote seems to be an
undocumented string generation library. It may be useful, but it's
certainly not what I was talking about.
From: Pascal J. Bourguignon
Subject: Re: Which ones come first? - Macro question -
Date: 
Message-ID: <87od39q91z.fsf@hubble.informatimago.com>
rock69 <···········@gmail.com> writes:

> I can't find any info on this matter. Do reader macros (such as
> BACKQUOTE, for instance) expand before ordinary macros, or is it the
> other way around? For example, if a backquote expression is passed as
> an argument to an ordinary macro, will it get expanded first, or will
> it be passed as it is (backquote and all) to the parameter (I'm not
> sure parameter or argument are the right worda, not being a function,
> but I hope you know what I mean) and then get expanded?

Reader macros are expanded at read time.

Notice however, that they may expand either to atoms, or to a special
operator, function or macro call.  In the later case, and if it is
read as code, the macro call will be expanded at macroexpansion time.

Of course, if what is read is code, it will be executed at run time.


Backquotes will usually expand to code that will be executed at
run-time.  It is possible that an implementation makes it expand (at
read time) to a macro call, that will be expanded at macro-expansion
time, but I don't think it's often the case.


> And as far backquotes go, when they're nested, in what order do they
> expand? 'Cause I really just can't get it, as much as I'm trying to
> work it out.

It's written in CLHS.  Until you find where, don't nest them. 

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

"Indentation! -- I will show you how to indent when I indent your skull!"