Technical Q on redefining `defun' and `return-from'. 
Author Message
 Technical Q on redefining `defun' and `return-from'.

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

    (defun extremely-long-function-name (x)
      ...
      (return-from extremely-long-function-name 'a)
      ...
      (return-from extremely-long-function-name 'b)
      )

can be replaced by

    (defun-rf extremely-long-function-name (x)
      ...
      (rf 'a)
      ...
      (rf 'b)
      )

--
Prof. Jonathan King,    Mathematics dept, Univ. of Florida



Sat, 24 Nov 2001 03:00:00 GMT  
 Technical Q on redefining `defun' and `return-from'.


Quote:
>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

>    (defun extremely-long-function-name (x)
>      ...
>      (return-from extremely-long-function-name 'a)
>      ...
>      (return-from extremely-long-function-name 'b)
>      )

>can be replaced by

>    (defun-rf extremely-long-function-name (x)
>      ...
>      (rf 'a)
>      ...
>      (rf 'b)
>      )

(defmacro defun-rf (func-name arglist &rest body)
  `(defun ,func-name ,arglist
     (flet ((rf (value) (return-from ,func-name value)))

This doesn't handle documentation strings or declarations at the beginning
of the function body; I leave that as an exercise for the reader.

--

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.



Sat, 24 Nov 2001 03:00:00 GMT  
 Technical Q on redefining `defun' and `return-from'.


Quote:


>>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

>>    (defun extremely-long-function-name (x)
>>      ...
>>      (return-from extremely-long-function-name 'a)
>>      ...
>>      (return-from extremely-long-function-name 'b)
>>      )

>>can be replaced by

>>    (defun-rf extremely-long-function-name (x)
>>      ...
>>      (rf 'a)
>>      ...
>>      (rf 'b)
>>      )

>(defmacro defun-rf (func-name arglist &rest body)
>  `(defun ,func-name ,arglist
>     (flet ((rf (value) (return-from ,func-name value)))

>This doesn't handle documentation strings or declarations at the beginning
>of the function body; I leave that as an exercise for the reader.

As the original question asked for two macros, the following
simple mod of Barry's solution does the trick:

(defmacro defun-rf (func-name arglist &rest body)
  `(defun ,func-name ,arglist
     (macrolet ((rf (value) (list 'return-from ',func-name value)))

Bernhard
--
--------------------------------------------------------------------------
Bernhard Pfahringer
Austrian Research Institute for  http://www.ai.univie.ac.at/~bernhard/



Sat, 24 Nov 2001 03:00:00 GMT  
 Technical Q on redefining `defun' and `return-from'.

Quote:

>As the original question asked for two macros, the following
>simple mod of Barry's solution does the trick:

>(defmacro defun-rf (func-name arglist &rest body)
>  `(defun ,func-name ,arglist
>     (macrolet ((rf (value) (list 'return-from ',func-name value)))


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.

--

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.



Sat, 24 Nov 2001 03:00:00 GMT  
 Technical Q on redefining `defun' and `return-from'.

| 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



Sun, 25 Nov 2001 03:00:00 GMT  
 Technical Q on redefining `defun' and `return-from'.

Quote:


> | 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.

--

  "One smaller motivation which, in part, stems from altruism is Microsoft-
   bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]



Sun, 25 Nov 2001 03:00:00 GMT  
 Technical Q on redefining `defun' and `return-from'.


Quote:


>>As the original question asked for two macros, the following
>>simple mod of Barry's solution does the trick:

>>(defmacro defun-rf (func-name arglist &rest body)
>>  `(defun ,func-name ,arglist
>>     (macrolet ((rf (value) (list 'return-from ',func-name value)))

>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:

(defmacro defun-rf (func-name arglist &rest body)
  `(defun ,func-name ,arglist
     (macrolet ((rf (value) `(return-from ,',func-name ,value)))

Bernhard

--
--------------------------------------------------------------------------
Bernhard Pfahringer
Austrian Research Institute for  http://www.ai.univie.ac.at/~bernhard/



Sun, 25 Nov 2001 03:00:00 GMT  
 Technical Q on redefining `defun' and `return-from'.


Quote:


> > | 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.

Scott

--
Scott D. Anderson
Spelman College, Atlanta, Georgia

http://www.spelman.edu/~anderson/

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.



Sun, 25 Nov 2001 03:00:00 GMT  
 Technical Q on redefining `defun' and `return-from'.

Quote:



> >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

> >    (defun extremely-long-function-name (x)
> >      ...
> >      (return-from extremely-long-function-name 'a)
> >      ...
> >      (return-from extremely-long-function-name 'b)
> >      )

> >can be replaced by

> >    (defun-rf extremely-long-function-name (x)
> >      ...
> >      (rf 'a)
> >      ...
> >      (rf 'b)
> >      )

> (defmacro defun-rf (func-name arglist &rest body)
>   `(defun ,func-name ,arglist
>      (flet ((rf (value) (return-from ,func-name value)))

> 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

--
Prof. Jonathan King,    Mathematics dept, Univ. of Florida



Sun, 25 Nov 2001 03:00:00 GMT  
 
 [ 10 post ] 

 Relevant Pages 

1. Qs re 'Write & 'Read

2. Redefining 'Class'Output

3. Technical: Definition of ``alyasing''

4. Praegitzer Industries Inc.'s Technical Symposium '97

5. Newbie Qs: startup time, Module.constants, chdir, Ruby distro's library

6. return -code return doesn't play nice with set

7. NMTVCUSTOMDRAW does not return 'isChecked'

8. Intellimouse Returns 'File Not Open'

9. Clearing Error()'s and Errorcode()'s return values

10. Change request: return value from 'trap'

11. 'each' returning array

12. Newbie confusion about 'return'

 

 
Powered by phpBB® Forum Software