unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Re: 'let' for functions ?
       [not found] <1036073066.48586.0@iris.uk.clara.net>
@ 2002-10-31 14:18 ` Hannu Koivisto
  2003-04-26 19:19   ` Ed L Cashin
  0 siblings, 1 reply; 4+ messages in thread
From: Hannu Koivisto @ 2002-10-31 14:18 UTC (permalink / raw)


chris@example.org writes:

> I just wondered if it is possible to get the lexical scoping effect for
> functions that 'let' and related functions provide for variables.

Note that Emacs Lisp is dynamically scoped, thus let does not
provide lexical scoping but dynamic scoping.

> i.e I want to be able to do something like this :
>
> (let ((funca funcb))
>    (require 'foolib))

You can use flet (or labels if you need recursion) from the cl
package:

(require 'cl)

(flet ((funca (&rest args)
         (apply 'funcb args)))
  (require 'foolib))

-- 
Hannu

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: 'let' for functions ?
  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
  0 siblings, 1 reply; 4+ messages in thread
From: Ed L Cashin @ 2003-04-26 19:19 UTC (permalink / raw)


Hannu Koivisto <azure@iki.fi> writes:

> chris@example.org writes:
>
>> I just wondered if it is possible to get the lexical scoping effect for
>> functions that 'let' and related functions provide for variables.
>
> Note that Emacs Lisp is dynamically scoped, thus let does not
> provide lexical scoping but dynamic scoping.
>
>> i.e I want to be able to do something like this :
>>
>> (let ((funca funcb))
>>    (require 'foolib))
>
> You can use flet (or labels if you need recursion) from the cl
> package:
>
> (require 'cl)
>
> (flet ((funca (&rest args)
>          (apply 'funcb args)))
>   (require 'foolib))

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'd be very interested, though, to see such a simple implementation of
labels if there's an elisp guru who would enjoy trying to find it.
The hard part for me was recursion support.

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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: 'let' for functions ?
  2003-04-26 19:19   ` Ed L Cashin
@ 2003-04-26 20:01     ` Oliver Scholz
  2003-04-26 20:20       ` Ed L Cashin
  0 siblings, 1 reply; 4+ messages in thread
From: Oliver Scholz @ 2003-04-26 20:01 UTC (permalink / raw)


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

You need not fear the cl package. If you put 
`(eval-when-compile (require 'cl)' into your code, the compiled
package won't require cl.

However, since this is, as you say, a nice exercise, I give it a
shot. (Although I am supposed to be doing something different, too
...)

> I'd be very interested, though, to see such a simple implementation of
> labels if there's an elisp guru who would enjoy trying to find it.
> The hard part for me was recursion support.

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


    Oliver
-- 
7 Floréal an 211 de la Révolution
Liberté, Egalité, Fraternité!

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: 'let' for functions ?
  2003-04-26 20:01     ` Oliver Scholz
@ 2003-04-26 20:20       ` Ed L Cashin
  0 siblings, 0 replies; 4+ messages in thread
From: Ed L Cashin @ 2003-04-26 20:20 UTC (permalink / raw)


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/

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2003-04-26 20:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [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 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).