* 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
2009-06-08 21:23 The Paul Graham's "Revenge of the nerds" cummulator function and the solution in Emacs Lisp 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
[parent not found: <mailman.243.1244499530.2239.help-gnu-emacs@gnu.org>]
* 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
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 --
2009-06-08 21:23 The Paul Graham's "Revenge of the nerds" cummulator function and the solution in Emacs Lisp Tiago Charters de Azevedo
2009-06-09 6:40 ` Tassilo Horn
[not found] <mailman.243.1244499530.2239.help-gnu-emacs@gnu.org>
2009-06-09 0:27 ` Barry Margolin
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).