help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: sending function arguments to recursive function calls


From: Drew Adams
Subject: RE: sending function arguments to recursive function calls
Date: Sat, 4 May 2013 08:30:39 -0700

> I am very new to e-lisp and lisp, and I expect the answer to my
> question to be quite obvious when I see it.

Newbie or not, you gave a great description of what you encountered.

> I am puzzled by the function text-scale-adjust in lisp/face-remap.el.
> The function takes (inc) as input parameter, and calls and passes this
> (inc) to itself.

Actually, it does not call itself.  It sets up a keymap so that when you hit -,
0, or + it gets called again with (abs INC) as its arg.  That's not the same
thing as a recursive call.  (But this is not relevant to the problem.)

> If I copy this function to *scratch* and evaluate the defun with C-x
> C-e, I expect not to have broken anything. What happens instead is
> that the function's call to itself breaks.
> The line (lambda () (interactive) (text-scale-adjust (abs inc))))))
> complains that inc is not defined:
> "Symbol's value as variable is void: inc"
> 
> If I return to the original function in face-remap.el and evaluate the
> defun there again with C-x C-e, the function starts working again.
> 
> What is the difference between the defun in face-remap.el, and its
> copied version in *scratch*, that makes the propagation of inc work in
> the first case but not in the second?
> 
> I vaguely suspect it has to do with autoloads, but mainly because this
> is what is most obscure to me at this point.

Nope.  Welcome to the joys of Emacs Lisp's way of mixing lexical and dynamic
binding/scope.

The key to the puzzle is this little declaration in the first comment of the
file:

;;; face-remap.el --- Functions for ... -*- lexical-binding: t -*-

That `lexical-binding t' tells Emacs that the code in this file is meant to be
understood with the variable `lexical-binding' bound to t (locally).

If you add and evaluate the following sexp to your *scratch* buffer then you
will get the same effect as for the file:

(set (make-local-variable 'lexical-binding) t)

The problem was that the code you evaluated was not interpreted using lexical
bindings, so the lambda form did not contain any environment for looking up the
value of variable INC.

An alternative to using a lexical binding here would be to simply use this:

 `(lambda () (interactive) (text-scale-adjust (abs ',inc)))

That substitutes the value of INC from the initial call to `text-scale-adjust'
into the lambda.  So instead of there being a variable INC to look up there is a
literal value (e.g. 2).

Good question, BTW.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]