unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
From: Ed L Cashin <ecashin@uga.edu>
Subject: Re: 'let' for functions ?
Date: Sat, 26 Apr 2003 16:20:28 -0400	[thread overview]
Message-ID: <87he8l104z.fsf@cs.uga.edu> (raw)
In-Reply-To: uwuhh3u4w.fsf@ID-87814.user.dfncis.de

Oliver Scholz <alkibiades@gmx.de> writes:

> Ed L Cashin <ecashin@uga.edu> writes:
> [...]
>> As an exercise I tried in vain to create a simple implementation of
>> labels that wouldn't require loading cl.  I couldn't do it, though,
>> and had to get on with what I was supposed to be doing.  ;)
...
> I am not a Lisp-Guru, but here is my version anyways. I'd like to hear
> whether there is any problem with this approach:
>
> (defmacro my-simple-labels (spec &rest body)
>   ;; We `fset' the symbols temporarily and restore the original state
>   ;; after the body form was executed.
>   (let ((symbol (make-symbol "symbol"))
> 	(definition (make-symbol "definition"))
> 	(sfunc (make-symbol "sfunc")))
>     `(progn
>        (let (,symbol)
> 	 (dolist (,definition ',spec)
> 	   (setq ,symbol (car ,definition))
> 	   ;; Store function definition, if necessary.
> 	   (when (fboundp ,symbol)
> 	     (put ,symbol 'my-simple-labels (symbol-function ,symbol)))
> 	   ;; New function definition.
> 	   (fset ,symbol (cons 'lambda (cdr ,definition)))))
>        (unwind-protect (progn ,@body)
> 	 ;; Clean-up
> 	 (let (,sfunc)
> 	   (dolist (,symbol ',(mapcar 'car spec))
> 	     (setq ,sfunc (get ,symbol 'my-simple-labels))
> 	     (if ,sfunc
> 		 (fset ,symbol ,sfunc)
> 	       (fmakunbound ,symbol))))))))

Hey, wow.  (And you claim not to be a lisp guru! ;)  

It seems to work well for these two tests: recursion and mutual
recursion.

  (my-simple-labels
   ((f (s n) 
       (if (> n 0)
  	 (progn
  	   (insert (format "s: %s\n" s))
  	   (f s (1- n))))))
   (f "hi" 4))
  
Inserts "s: hi\n" four times.

  (my-simple-labels
   ((f (s n) 
       (if (> n 0)
  	 (progn
  	   (insert (format "f: %s\n" s))
  	   (g s (1- n)))))
    (g (s n)
       (if (> n 0)
  	 (progn 
  	   (insert (format "g: %s\n" s))
  	   (f s (1- n))))))
   (f "hi" 4))

Inserts "f: hi\n" and "g: hi\n" alternately, twice each.

-- 
--Ed L Cashin     PGP public key: http://noserose.net/e/pgp/

      reply	other threads:[~2003-04-26 20:20 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1036073066.48586.0@iris.uk.clara.net>
2002-10-31 14:18 ` 'let' for functions ? Hannu Koivisto
2003-04-26 19:19   ` Ed L Cashin
2003-04-26 20:01     ` Oliver Scholz
2003-04-26 20:20       ` Ed L Cashin [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87he8l104z.fsf@cs.uga.edu \
    --to=ecashin@uga.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).