This doesn't handle documentation strings or declarations at the beginning of the function body; I leave that as an exercise for the reader.
-- Barry Margolin, bar...@bbnplanet.com GTE Internetworking, Powered by BBN, Burlington, 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.
>In article <xndd7z6jwr6....@infinity.math.ufl.edu>, >Jonathan King <squ...@infinity.math.ufl.edu> wrote: >>Hello. I thought I knew how to do the following but after some >>experimentation see that the waters are deeper than I realized.
>> What is a correct way to define macros `defun-rf' and `rf' >>so that a creation such as
Bernhard -- -------------------------------------------------------------------------- Bernhard Pfahringer Austrian Research Institute for http://www.ai.univie.ac.at/~bernhard/ Artificial Intelligence bernh...@ai.univie.ac.at
Bernhard Pfahringer <bernh...@hummel.ai.univie.ac.at> wrote: >As the original question asked for two macros, the following >simple mod of Barry's solution does the trick:
Someone who doesn't know how to write the macro also often isn't qualified to decide whether it *should* be a macro. There's nothing about RF that requires it to be a macro, so I implemented it as a function.
BTW, I notice you avoided using nested backquote. That was the other reason I did it with FLET: I don't have a Common Lisp implementation on my machine, so I either don't test or do a little testing using Emacs Lisp, and it doesn't do nested backquotes properly (at least in Emacs 19.34). I wasn't sure whether it should be `(return-from ,,func-name ,value) or `(return-from ,',func-name ,value), and my environment didn't allow testing it. But then I realized that FLET could be used, so the problem was solved.
There's one semantic difference between the two versions. If the body of the function contains a block that uses the same name as the function, the macro will return from the inner block (because Lisp macros are not hygienic) while the function will return from the outer block. The macro could be made to return from the outer block by having the DEFUN-RF expansion contain its own block with a gensym'ed name and having RF return from that instead of the function name. But FLET solves it so much more nicely, by using normal lexical scoping.
-- Barry Margolin, bar...@bbnplanet.com GTE Internetworking, Powered by BBN, Burlington, 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.
* Jonathan King <squ...@infinity.math.ufl.edu> | Hello. I thought I knew how to do the following but after some | experimentation see that the waters are deeper than I realized.
I suggest you do (block nil ... (return <whatever>) ...) instead.
#:Erik -- @1999-07-22T00:37:33Z -- pi billion seconds since the turn of the century
Erik Naggum <e...@naggum.no> writes: > * Jonathan King <squ...@infinity.math.ufl.edu> > | Hello. I thought I knew how to do the following but after some > | experimentation see that the waters are deeper than I realized.
> I suggest you do (block nil ... (return <whatever>) ...) instead.
But then he'll have to watch out for looping constructs which introduce "spurious" nil blocks, thus lexically shadowing his nil block, which as I take it, he'd probably want to avoid (although this is an interpretation of his design "spec"). OTOH, I still don't know what kind of functions he intends to write. If they contain so many RETURN-FROM forms, that he wants to automate the stuff, I'm concerned whether not some other construct might be a better fit for his problem.
So all in all, _if_ he really needs this sort of stuff, I'd think that Barry's solution (a macro introducing an flet to capture the block label -- whether one would use nil and return or the function name and return-from is technically equivalent here, if I'm not mistaken, but probably the function name is more descriptive) seems best.
But I'd still be interested why he has so many RETURN-FROM forms. Note: I'm not saying that this is evil, or that I can't imagine any problem space that might call for so many returns. But given that CL has so many other ways of expressing many of the problems that returns are used for in other languages, I'm wondering whether there's not something more descriptive. Either an existing construct of CL, or a more descriptive macro, which conveys his intent better.
Regs, Pierre.
-- Pierre Mai <p...@acm.org> PGP and GPG keys at your nearest Keyserver "One smaller motivation which, in part, stems from altruism is Microsoft- bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]
>In article <7jjuet$17t...@www.univie.ac.at>, >Bernhard Pfahringer <bernh...@hummel.ai.univie.ac.at> wrote: >>As the original question asked for two macros, the following >>simple mod of Barry's solution does the trick:
>Someone who doesn't know how to write the macro also often isn't qualified >to decide whether it *should* be a macro. There's nothing about RF that >requires it to be a macro, so I implemented it as a function.
>BTW, I notice you avoided using nested backquote. That was the other >reason I did it with FLET: I don't have a Common Lisp implementation on my >machine, so I either don't test or do a little testing using Emacs Lisp, >and it doesn't do nested backquotes properly (at least in Emacs 19.34). I >wasn't sure whether it should be `(return-from ,,func-name ,value) or >`(return-from ,',func-name ,value), and my environment didn't allow testing >it. But then I realized that FLET could be used, so the problem was >solved.
You're absolutely right, there is no reason to have RF implemented as a macro. It's only effect would be inlining. A good optimizing compiler would do this for simple local functions anyway, I suppose. Even if not, the small extra function-call effort is probably not worth thinking about in this case.
To answer your nested back-quote question, I was in a hurry and not sure either, so I did the explicit cons-thingy. The following nested back-quote stuff works as well:
-- -------------------------------------------------------------------------- Bernhard Pfahringer Austrian Research Institute for http://www.ai.univie.ac.at/~bernhard/ Artificial Intelligence bernh...@ai.univie.ac.at
> > * Jonathan King <squ...@infinity.math.ufl.edu> > > | Hello. I thought I knew how to do the following but after some > > | experimentation see that the waters are deeper than I realized.
> > I suggest you do (block nil ... (return <whatever>) ...) instead.
> But then he'll have to watch out for looping constructs which > introduce "spurious" nil blocks, thus lexically shadowing his nil > block, which as I take it, he'd probably want to avoid (although this > is an interpretation of his design "spec").
I had a situation like this once, and I did:
(defun extremely-long-and-descriptive-function-name (...) (block function ... (return-from function 'a) ...))
This approach is almost identical to Erik's but avoids the problem of intervening NIL blocks and is a pretty simple solution--not nearly as sophisticated as Barry's.
As to whether needing that many return-froms is a bad sign, I don't think so. I actually didn't need that many, and my editor was smart enough that I didn't actually have to retype the long function name, just meta-click or some such incantation to copy it down. I just did it so that the code seemed more concise and generic. If I changed the name of the function, I didn't want to have to remember to change the return-froms. So, as long as it's in moderation, I don't see a problem here.
Barry Margolin <bar...@bbnplanet.com> writes: > In article <xndd7z6jwr6....@infinity.math.ufl.edu>, > Jonathan King <squ...@infinity.math.ufl.edu> wrote: > >Hello. I thought I knew how to do the following but after some > >experimentation see that the waters are deeper than I realized.
> > What is a correct way to define macros `defun-rf' and `rf' > >so that a creation such as
> This doesn't handle documentation strings or declarations at the beginning > of the function body; I leave that as an exercise for the reader.
...
Thank you Barry Margolin --this does just what I wanted. It also put me wise to `flet'. Thanks also to Bernhard Pfahringer Erik Naggum Pierre R. Mai for other solutions/comments. -Jonathan