One thing that bothers me about this macro: it looks like it doesn't nest
well. What does
(····@
@ 'outer
(····@
@ 'inner))
return? I think it *should* return OUTER, but I suspect it actually
returns INNER (I haven't tried it).
--
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Barry Margolin wrote:
> One thing that bothers me about this macro: it looks like it doesn't nest
> well. What does
>
> (····@
> @ 'outer
> (····@
> @ 'inner))
>
> return? I think it *should* return OUTER, but I suspect it actually
> returns INNER (I haven't tried it).
Kenny's recent post has already convinced me that I shouldn't traverse
deeply into the forms but only do a shallow traversal. Your example is
another good argument in that direction.
With a shallow traversal things get considerably simpler.
(defmacro prog! (&body body)
(let ((result (gensym)))
`(let ((,result nil))
(macrolet ((! (form)
`(progn
(setq ,',result
(multiple-value-list ,form))
(values-list ,',result))))
,@body
(values-list ,result)))))
So now we can do the following.
(prog!
(...)
(! (...))
(...))
I like this more than other proposals with prog1/progn or (let ...)
because there, the before and after parts are not at the same level.
(This is only an aesthetical issue.)
I like Erik's proposal to use the $ sign for my macro. The ! might give
Schemers a headache. ;)
I think a proper name that includes "return" (like prog-return) instead
of a marker like ! or $ can be misleading because "return" usually means
to return immediately.
About the consing of multiple-value-list: I guess a good solution for
that would be to provide two versions, prog$ and multiple-value-prog$.
(So the above macro would be the multiple-value-prog$ version.)
Thanks again for all the comments.
Pascal
--
Given any rule, however �fundamental� or �necessary� for science, there
are always circumstances when it is advisable not only to ignore the
rule, but to adopt its opposite. - Paul Feyerabend
Pascal Costanza <········@web.de> writes:
> Barry Margolin wrote:
> > One thing that bothers me about this macro: it looks like it doesn't nest
> > well. What does
> > (····@
> > @ 'outer
> > (····@
> > @ 'inner))
> > return? I think it *should* return OUTER, but I suspect it actually
> > returns INNER (I haven't tried it).
>
> Kenny's recent post has already convinced me that I shouldn't traverse
> deeply into the forms but only do a shallow traversal. Your example is
> another good argument in that direction.
>
> With a shallow traversal things get considerably simpler.
>
> (defmacro prog! (&body body)
> (let ((result (gensym)))
> `(let ((,result nil))
> (macrolet ((! (form)
> `(progn
> (setq ,',result
> (multiple-value-list ,form))
> (values-list ,',result))))
> ,@body
> (values-list ,result)))))
>
> So now we can do the following.
>
> (prog!
> (...)
> (! (...))
> (...))
>
> I like this more than other proposals with prog1/progn or (let ...)
> because there, the before and after parts are not at the same
> level. (This is only an aesthetical issue.)
>
> I like Erik's proposal to use the $ sign for my macro. The ! might
> give Schemers a headache. ;)
>
> I think a proper name that includes "return" (like prog-return)
> instead of a marker like ! or $ can be misleading because "return"
> usually means to return immediately.
What about SAVE-FOR-RETURN ?
I am personally wary of using simgle character markers as they may be
used as macro characters by somebody else.
Cheers
--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488
715 Broadway 10th Floor fax +1 - 212 - 995 4122
New York, NY 10003, USA http://bioinformatics.cat.nyu.edu
"Hello New York! We'll do what we can!"
Bill Murray in `Ghostbusters'.
Marco Antoniotti wrote:
> Pascal Costanza <········@web.de> writes:
>
>>I think a proper name that includes "return" (like prog-return)
>>instead of a marker like ! or $ can be misleading because "return"
>>usually means to return immediately.
>
>
> What about SAVE-FOR-RETURN ?
>
> I am personally wary of using simgle character markers as they may be
> used as macro characters by somebody else.
You're right - on the other hand, SAVE-FOR-RETURN is quite long. What
about LIFT?
Here is the current version of my set of macros, in case anyone is
interested. I think that I have successfully balanced many of the forces
that were mentioned in this thread.
(defmacro multiple-value-progl (mark &body body)
(let ((result (gensym "RESULT-")))
`(let (,result)
(macrolet ((,mark (form)
`(progn
(setq ,',result
(multiple-value-list ,form))
(values-list ,',result))))
,@body
(values-list ,result)))))
(defmacro progl (mark &body body)
(let ((result (gensym "RESULT-")))
`(let ((,result nil))
(macrolet ((,mark (form) `(setq ,',result ,form)))
,@body
,result))))
(defmacro multiple-value-prog-lift (&body body)
`(multiple-value-progl lift ,@body))
(defmacro prog-lift (&body body)
`(progl lift ,@body))
So now the default case is as follows.
(prog-lift
(before ...)
(lift (actual-result ...))
(after ...))
...but you can also have:
(progl outer-lift
(...)
(progl inner-lift)
(...)
(outer-lift (...))
(inner-lift (...))
(...))
(...))
And all of these optionally with multiple values.
Did I already mention that Common Lisp is a f**king great language? ;-)
Pascal
--
Given any rule, however �fundamental� or �necessary� for science, there
are always circumstances when it is advisable not only to ignore the
rule, but to adopt its opposite. - Paul Feyerabend
Pascal Costanza <········@web.de> writes:
> (progl outer-lift
I first read that as "prog1". I had not read a real "1" in this
font today and didn't remember what it looked like. Perhaps a
different name would be better.
Kalle Olavi Niemitalo wrote:
> Pascal Costanza <········@web.de> writes:
>
>
>>(progl outer-lift
>
>
> I first read that as "prog1". I had not read a real "1" in this
> font today and didn't remember what it looked like. Perhaps a
> different name would be better.
Oh dear - yes, I haven't thought of that. So I switch to prog$.
Pascal
--
Given any rule, however �fundamental� or �necessary� for science, there
are always circumstances when it is advisable not only to ignore the
rule, but to adopt its opposite. - Paul Feyerabend
Marco Antoniotti <·······@cs.nyu.edu> writes:
> I am personally wary of using simgle character markers as they may
> be used as macro characters by somebody else.
Something that's faintly bothered me for a while is wondering how you
cope with using two different lisp packages that use the same macro
character for different things. Is this ever a problem in practice?
Cheers,
M.
--
: Giant screaming pieces of excrement, they are.
I have a feeling that some of the people in here have a
MUCH more exciting time relieving themselves than I do.
-- Mike Sphar & Dave Brown, asr
Michael Hudson wrote:
> Marco Antoniotti <·······@cs.nyu.edu> writes:
>
>> I am personally wary of using simgle character markers as they may
>> be used as macro characters by somebody else.
>
> Something that's faintly bothered me for a while is wondering how you
> cope with using two different lisp packages that use the same macro
> character for different things. Is this ever a problem in practice?
>
rename-package
Oleg
Oleg <············@myrealbox.com> writes:
> Michael Hudson wrote:
>
> > Marco Antoniotti <·······@cs.nyu.edu> writes:
> >
> >> I am personally wary of using simgle character markers as they may
> >> be used as macro characters by somebody else.
> >
> > Something that's faintly bothered me for a while is wondering how you
> > cope with using two different lisp packages that use the same macro
> > character for different things. Is this ever a problem in practice?
> >
>
> rename-package
RENAME-PACKAGE does not apply in this case. The "space" of macro
characters is the read table, and there are no provisions to change it
at read time, short of doing
#.(setf *readtable* my-readtable)
(which - of course - is affected by *READ-EVAL*).
Cheers
--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488
715 Broadway 10th Floor fax +1 - 212 - 995 4122
New York, NY 10003, USA http://bioinformatics.cat.nyu.edu
"Hello New York! We'll do what we can!"
Bill Murray in `Ghostbusters'.
Marco Antoniotti <·······@cs.nyu.edu> writes:
> RENAME-PACKAGE does not apply in this case. The "space" of macro
> characters is the read table, and there are no provisions to change it
> at read time, short of doing
>
> #.(setf *readtable* my-readtable)
>
> (which - of course - is affected by *READ-EVAL*).
Is it possible to use eval-when instead? I have tried this,
with the meta package, but have not had any success:
(eval-when (:compile-toplevel :load-toplevel :execute)
(setf *readtable* *meta-readtable*))
--- or something like that.
--
Raymond Wiker Mail: ·············@fast.no
Senior Software Engineer Web: http://www.fast.no/
Fast Search & Transfer ASA Phone: +47 23 01 11 60
P.O. Box 1677 Vika Fax: +47 35 54 87 99
NO-0120 Oslo, NORWAY Mob: +47 48 01 11 60
Try FAST Search: http://alltheweb.com/
Raymond Wiker <·············@fast.no> writes:
> Marco Antoniotti <·······@cs.nyu.edu> writes:
>
> > RENAME-PACKAGE does not apply in this case. The "space" of macro
> > characters is the read table, and there are no provisions to change it
> > at read time, short of doing
> >
> > #.(setf *readtable* my-readtable)
> >
> > (which - of course - is affected by *READ-EVAL*).
>
> Is it possible to use eval-when instead? I have tried this,
> with the meta package, but have not had any success:
>
> (eval-when (:compile-toplevel :load-toplevel :execute)
> (setf *readtable* *meta-readtable*))
The above should work. As a matter of fact it works in my usage of
the META package.
Cheers
--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488
715 Broadway 10th Floor fax +1 - 212 - 995 4122
New York, NY 10003, USA http://bioinformatics.cat.nyu.edu
"Hello New York! We'll do what we can!"
Bill Murray in `Ghostbusters'.
* Raymond Wiker <·············@fast.no>
| Is it possible to use eval-when instead? I have tried this,
| with the meta package, but have not had any success:
|
| (eval-when (:compile-toplevel :load-toplevel :execute)
| (setf *readtable* *meta-readtable*))
Allegro CL�offers a convenient way to access readtables via the named
readtables features. The obvious macro `in-syntax� then takes a symbol
as argument and assigns the corresponding readtable to *readtable*.
--
Erik Naggum, Oslo, Norway
Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.
Oleg <············@myrealbox.com> writes:
> Michael Hudson wrote:
>
> > Marco Antoniotti <·······@cs.nyu.edu> writes:
> >
> >> I am personally wary of using simgle character markers as they may
> >> be used as macro characters by somebody else.
> >
> > Something that's faintly bothered me for a while is wondering how you
> > cope with using two different lisp packages that use the same macro
> > character for different things. Is this ever a problem in practice?
> >
>
> rename-package
No, I said "macro character", not "package name".
Cheers,
M.
--
ZAPHOD: Listen three eyes, don't try to outwierd me, I get stranger
things than you free with my breakfast cereal.
-- The Hitch-Hikers Guide to the Galaxy, Episode 7
Michael Hudson <···@python.net> writes:
> Marco Antoniotti <·······@cs.nyu.edu> writes:
>
> > I am personally wary of using simgle character markers as they may
> > be used as macro characters by somebody else.
>
> Something that's faintly bothered me for a while is wondering how you
> cope with using two different lisp packages that use the same macro
> character for different things. Is this ever a problem in practice?
I think it is fine as long as you advertise it clearly and you set up
your read tables accordingly. E.g. it used to be cutsomary practice
to write Theorem Provers in Lisp and denote variables ("logical
variables" that is) with the notation `?var'. The understanding being
that this would translate into something like
?var ==> #<VARIABLE var>
This means that if I am using a certain system which I know uses a
peculiar macro character, then I know what to expect.
Pragmatically, I think that macro characters are useful for special
languages which are used in circumscribed loci (for lack of a better
word). E.g. if I write a file containing a specialized language and I
have full control in the way I READ it, then I am relatively safe.
Of course all of this does not quite answer your question. IMHO what
has happened is that CLers know that macro charcaters are to be used
sparingly, therefore, no major clashes have happened in the past in
mixing and matching separate libraries.
Of course YMMV.
Cheers
--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488
715 Broadway 10th Floor fax +1 - 212 - 995 4122
New York, NY 10003, USA http://bioinformatics.cat.nyu.edu
"Hello New York! We'll do what we can!"
Bill Murray in `Ghostbusters'.
Hello!
Marco Antoniotti <·······@cs.nyu.edu> wrote:
>[...]
>Of course all of this does not quite answer your question. IMHO what
>has happened is that CLers know that macro charcaters are to be used
>sparingly, therefore, no major clashes have happened in the past in
>mixing and matching separate libraries.
Another convention would be that your package doesn't automatically
modify the readtable referenced from *readtable* at all, but provides
a function to install the specific things.
I.e. you can do things like
(let ((*readtable* *readtable*))
(foo-package:setup-reader-macros)
(load ...)) ; or (read-from-string ...) or ...
Kind regards,
Hannah.
······@schlund.de (Hannah Schroeter) writes:
> Hello!
>
> Marco Antoniotti <·······@cs.nyu.edu> wrote:
>
> >[...]
>
> >Of course all of this does not quite answer your question. IMHO what
> >has happened is that CLers know that macro charcaters are to be used
> >sparingly, therefore, no major clashes have happened in the past in
> >mixing and matching separate libraries.
>
> Another convention would be that your package doesn't automatically
> modify the readtable referenced from *readtable* at all, but provides
> a function to install the specific things.
>
> I.e. you can do things like
> (let ((*readtable* *readtable*))
> (foo-package:setup-reader-macros)
> (load ...)) ; or (read-from-string ...) or ...
Yep. That is what I meant when I was referring to "circumscribed use
of language extensions". I.e. you would have a LOAD-XXX function that
set up the approrpiate read table as you show.
Cheers
--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488
715 Broadway 10th Floor fax +1 - 212 - 995 4122
New York, NY 10003, USA http://bioinformatics.cat.nyu.edu
"Hello New York! We'll do what we can!"
Bill Murray in `Ghostbusters'.
······@schlund.de (Hannah Schroeter) writes:
> I.e. you can do things like
> (let ((*readtable* *readtable*))
> (foo-package:setup-reader-macros)
> (load ...)) ; or (read-from-string ...) or ...
I guess this needs a copy-readtable call either in the LET, or in
foo-package:setup-reader-macros. Which place is better?
Hello!
Kalle Olavi Niemitalo <···@iki.fi> wrote:
>······@schlund.de (Hannah Schroeter) writes:
>> I.e. you can do things like
>> (let ((*readtable* *readtable*))
>> (foo-package:setup-reader-macros)
>> (load ...)) ; or (read-from-string ...) or ...
>I guess this needs a copy-readtable call either in the LET, or in
>foo-package:setup-reader-macros. Which place is better?
Perhaps more the let, as it is the place which "means" the save of
the readtable.
How about this:
(defmacro with-saved-readtable (&body body)
`(let ((*readtable* (copy-readtable *readtable*)))
,@body))
Kind regards,
Hannah.
Hello!
Raymond Wiker <·············@fast.no> wrote:
>······@schlund.de (Hannah Schroeter) writes:
>> (defmacro with-saved-readtable (&body body)
>> `(let ((*readtable* (copy-readtable *readtable*)))
>> ,@body))
> Note that this is not necessary if "body" is just a call to
>load or compile-file.
But
(with-saved-readtable
(setup-alternative-read-syntax)
;; "foo" relies on the alternative read syntax
(load "foo")
;; "bar" also
(compile-file "bar"))
Kind regards,
Hannah.
* Michael Hudson wrote:
> Something that's faintly bothered me for a while is wondering how you
> cope with using two different lisp packages that use the same macro
> character for different things. Is this ever a problem in practice?
I think it is, and I think the answer is you really don't cope. I try
and make code I write which defines readmacros check to see if they
are already defined, and complain in that case.
--tim