all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* The Paul Graham's "Revenge of the nerds" cummulator function and the solution in Emacs Lisp
@ 2009-06-08 21:23 Tiago Charters de Azevedo
  2009-06-09  6:40 ` Tassilo Horn
  0 siblings, 1 reply; 3+ messages in thread
From: Tiago Charters de Azevedo @ 2009-06-08 21:23 UTC (permalink / raw
  To: help-gnu-emacs

I've been reading  Paul Graham's "Revenge of the nerds"
(http://www.paulgraham.com/icad.html) particularly  the appendix. It states the
problem of writing "a function that generates accumulators-- a function that takes
a number n, and returns a function that takes another number i and returns n
incremented by i. (That's incremented by, not plus. An accumulator has to
accumulate.)"

Should not the function foo in Common Lisp  work with Emacs Lisp?

(defun foo (n)
  (lambda (i)     
    (incf n i))) 

by setting

(setq a (foo 3))

followed  by 

(funcall a 1)

When I try to evaluate (funcall a 1) in Emacs (in emacs-lisp mode) I get:

Debugger entered--Lisp error: (void-variable n)
  (+ n i)
  (setq n (+ n i))
  (incf n i)
  (lambda (i) (incf n i))(1)
  funcall((lambda (i) (incf n i)) 1)
  eval((funcall a 1))
  eval-last-sexp-1(nil)
  eval-last-sexp(nil)
  call-interactively(eval-last-sexp


It seems that emacs considers that n is a local variable because it is inside a
lambda expression?

Is this a bug? Or I'm missing something?

Thanks

tca

-- 
URL: http://www.diale.org
Email: tca@cii.fc.ul.pt

Phone: +351 21 7904874 (internal: 4274)
Fax: +351 21 795 4288




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

* Re: The Paul Graham's "Revenge of the nerds" cummulator function and the solution in Emacs Lisp
       [not found] <mailman.243.1244499530.2239.help-gnu-emacs@gnu.org>
@ 2009-06-09  0:27 ` Barry Margolin
  0 siblings, 0 replies; 3+ messages in thread
From: Barry Margolin @ 2009-06-09  0:27 UTC (permalink / raw
  To: help-gnu-emacs

In article <mailman.243.1244499530.2239.help-gnu-emacs@gnu.org>,
 Tiago Charters de Azevedo <tca@cii.fc.ul.pt> wrote:

> I've been reading  Paul Graham's "Revenge of the nerds"
> (http://www.paulgraham.com/icad.html) particularly  the appendix. It states 
> the
> problem of writing "a function that generates accumulators-- a function that 
> takes
> a number n, and returns a function that takes another number i and returns n
> incremented by i. (That's incremented by, not plus. An accumulator has to
> accumulate.)"
> 
> Should not the function foo in Common Lisp  work with Emacs Lisp?

Emacs Lisp has dynamic scoping, not lexical scoping.  If you want to 
emulate lexical scoping, (require 'cl-macs) and use lexical-let:

(defun foo (n)
  (lexical-let ((lexn n))
    (lambda (i)
      (incf lexn n))))

> 
> (defun foo (n)
>   (lambda (i)     
>     (incf n i))) 
> 
> by setting
> 
> (setq a (foo 3))
> 
> followed  by 
> 
> (funcall a 1)
> 
> When I try to evaluate (funcall a 1) in Emacs (in emacs-lisp mode) I get:
> 
> Debugger entered--Lisp error: (void-variable n)
>   (+ n i)
>   (setq n (+ n i))
>   (incf n i)
>   (lambda (i) (incf n i))(1)
>   funcall((lambda (i) (incf n i)) 1)
>   eval((funcall a 1))
>   eval-last-sexp-1(nil)
>   eval-last-sexp(nil)
>   call-interactively(eval-last-sexp
> 
> 
> It seems that emacs considers that n is a local variable because it is inside 
> a
> lambda expression?
> 
> Is this a bug? Or I'm missing something?
> 
> Thanks
> 
> tca

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***


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

* Re: The Paul Graham's "Revenge of the nerds" cummulator function and the solution in Emacs Lisp
  2009-06-08 21:23 Tiago Charters de Azevedo
@ 2009-06-09  6:40 ` Tassilo Horn
  0 siblings, 0 replies; 3+ messages in thread
From: Tassilo Horn @ 2009-06-09  6:40 UTC (permalink / raw
  To: help-gnu-emacs

Tiago Charters de Azevedo <tca@cii.fc.ul.pt> writes:

Hi Tiago,

> Should not the function foo in Common Lisp work with Emacs Lisp?
>
> (defun foo (n)
>   (lambda (i)     
>     (incf n i))) 

No, that won't work because emacs has no lexical scoping and that code
is a closure.  See the elisp manual:

,----[ (info "(elisp)Extent") ]
|    To illustrate this, the function below, `make-add', returns a
| function that purports to add N to its own argument M.  This would work
| in Common Lisp, but it does not do the job in Emacs Lisp, because after
| the call to `make-add' exits, the variable `n' is no longer bound to
| the actual argument 2.
| 
|      (defun make-add (n)
|          (function (lambda (m) (+ n m))))  ; Return a function.
|           => make-add
|      (fset 'add2 (make-add 2))  ; Define function `add2'
|                                 ;   with `(make-add 2)'.
|           => (lambda (m) (+ n m))
|      (add2 4)                   ; Try to add 2 to 4.
|      error--> Symbol's value as variable is void: n
| 
|    Some Lisp dialects have "closures," objects that are like functions
| but record additional variable bindings.  Emacs Lisp does not have
| closures.
`----

Bye,
Tassilo
-- 
Chuck Norris once rode a bull, and nine months later it had a calf. 





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

end of thread, other threads:[~2009-06-09  6:40 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <mailman.243.1244499530.2239.help-gnu-emacs@gnu.org>
2009-06-09  0:27 ` The Paul Graham's "Revenge of the nerds" cummulator function and the solution in Emacs Lisp Barry Margolin
2009-06-08 21:23 Tiago Charters de Azevedo
2009-06-09  6:40 ` Tassilo Horn

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.