all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* sending function arguments to recursive function calls
@ 2013-05-04 13:01 Gauthier Östervall
  2013-05-04 15:30 ` Drew Adams
  2013-05-05  1:22 ` Stefan Monnier
  0 siblings, 2 replies; 21+ messages in thread
From: Gauthier Östervall @ 2013-05-04 13:01 UTC (permalink / raw)
  To: help-gnu-emacs

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.

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.

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.



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

* RE: sending function arguments to recursive function calls
  2013-05-04 13:01 sending function arguments to recursive function calls Gauthier Östervall
@ 2013-05-04 15:30 ` Drew Adams
  2013-05-07 11:25   ` Gauthier Östervall
  2013-05-05  1:22 ` Stefan Monnier
  1 sibling, 1 reply; 21+ messages in thread
From: Drew Adams @ 2013-05-04 15:30 UTC (permalink / raw)
  To: 'Gauthier Östervall', help-gnu-emacs

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




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

* Re: sending function arguments to recursive function calls
  2013-05-04 13:01 sending function arguments to recursive function calls Gauthier Östervall
  2013-05-04 15:30 ` Drew Adams
@ 2013-05-05  1:22 ` Stefan Monnier
  1 sibling, 0 replies; 21+ messages in thread
From: Stefan Monnier @ 2013-05-05  1:22 UTC (permalink / raw)
  To: help-gnu-emacs

> 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

Reality is that there are 2 Emacs Lisps.  One is the dynamically scoped
Elisp, and the other is the lexically scoped Elisp.
They are very similar, but they are two different languages.

When evaluating code (e.g. with C-x C-e), Emacs has to "guess" which
in Elisp this is supposedly written.  It does that by checking the value
of `lexical-binding' variable.  In face-remap.el, this variable is set
to t, whereas in *scratch* it is set to nil, so by moving the code from
one buffer to the other, you asked Emacs to interpret this code in "the
other Elisp".  And this failed because the code you copied relies on
behavior specific to lexical scoping (a lot of Elisp code doesn't care
either way).


        Stefan




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

* Re: sending function arguments to recursive function calls
  2013-05-04 15:30 ` Drew Adams
@ 2013-05-07 11:25   ` Gauthier Östervall
  2013-05-07 14:04     ` Drew Adams
                       ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Gauthier Östervall @ 2013-05-07 11:25 UTC (permalink / raw)
  To: Drew Adams, help-gnu-emacs

On Sat, May 4, 2013 at 5:30 PM, Drew Adams <drew.adams@oracle.com> wrote:
> 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).

Thanks for the kind words and the explanation. I do not feel very
confident about having a function that relies on a file scope setting
of lexical-binding, which as in this case happens 300 lines earlier.
Wouldn't it be better to have functions that work whatever the value
of lexical-binding, if possible?

> An alternative to using a lexical binding here would be to simply use this:
>
>  `(lambda () (interactive) (text-scale-adjust (abs ',inc)))

If this alternative works whatever lexical-binding, it seems superior
to me. Isn't it?



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

* RE: sending function arguments to recursive function calls
  2013-05-07 11:25   ` Gauthier Östervall
@ 2013-05-07 14:04     ` Drew Adams
  2013-05-08 12:21       ` Stefan Monnier
  2013-05-07 14:32     ` Pascal J. Bourguignon
       [not found]     ` <mailman.25279.1367935468.855.help-gnu-emacs@gnu.org>
  2 siblings, 1 reply; 21+ messages in thread
From: Drew Adams @ 2013-05-07 14:04 UTC (permalink / raw)
  To: 'Gauthier Östervall', help-gnu-emacs

> > 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).
> 
> Thanks for the kind words and the explanation. I do not feel very
> confident about having a function that relies on a file scope setting
> of lexical-binding, which as in this case happens 300 lines earlier.
> Wouldn't it be better to have functions that work whatever the value
> of lexical-binding, if possible?

I agree.

Sometimes, however, you specifically want the function definition to take
advantage of one kind of scoping/binding or the other.

IOW, when it makes no difference, then yes, it would be nice not to be bothered
with the difference. ;-)  When it does make a difference, that is, when you want
it to make a difference, then it should be easy to choose and it should be clear
what is going on.

Emacs Lisp does not particularly make things clear, IMO.  Common Lisp does a
pretty good job of helping lexical and dynamic binding cohabit.  Emacs Lisp does
not do such a great job, IMO.  As Stefan pointed out:

  Reality is that there are 2 Emacs Lisps.  One is the
  dynamically scoped Elisp, and the other is the lexically
  scoped Elisp.  They are very similar, but they are two
  different languages.

> > An alternative to using a lexical binding here would be to 
> > simply use this:
> >  `(lambda () (interactive) (text-scale-adjust (abs ',inc)))
> 
> If this alternative works whatever lexical-binding, it seems superior
> to me. Isn't it?

Yes.  That's my opinion, anyway.  In this case (and in many others), there is no
_logical_ reason to pass a variable and have that variable be looked up
lexically when the lambda is invoked.  All that is needed is the variable's
value at the time the lambda is _constructed_.  Anything else is overkill.  

But logic is not the only thing involved here.  Disadvantages of substituting
the value can include: (a) backquote syntax, or its equivalent, is less readable
and (b) the byte compiler might not be able to compile the lambda in a
performant way.

I'm no expert on Emacs byte compilation, but it's possible that the byte
compiler just punts on a dynamically constructed sexp such as the one above,
even though it might be able to figure out that the result in this case is
straightforward.  Dunno.

Lexical binding was added to Emacs relatively recently.  With time, perhaps it
and dynamic binding will become better roommates.  And certainly, with time,
users will become more used to lexical binding and to looking out for
lexical/dynamic binding gotchas.

For one thing, you will no doubt be reflexively looking for a local-variable
binding declaration in the file, right? ;-)  And you will be looking for free
variables, and when you notice one you will ask yourself whether it will be
evaluated using lexical or dynamic binding.  IOW, you will internalize things
like this help thread.




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

* Re: sending function arguments to recursive function calls
  2013-05-07 11:25   ` Gauthier Östervall
  2013-05-07 14:04     ` Drew Adams
@ 2013-05-07 14:32     ` Pascal J. Bourguignon
       [not found]     ` <mailman.25279.1367935468.855.help-gnu-emacs@gnu.org>
  2 siblings, 0 replies; 21+ messages in thread
From: Pascal J. Bourguignon @ 2013-05-07 14:32 UTC (permalink / raw)
  To: help-gnu-emacs

Gauthier Östervall <gauthier@ostervall.se> writes:

> On Sat, May 4, 2013 at 5:30 PM, Drew Adams <drew.adams@oracle.com> wrote:
>> 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).
>
> Thanks for the kind words and the explanation. I do not feel very
> confident about having a function that relies on a file scope setting
> of lexical-binding, which as in this case happens 300 lines earlier.
> Wouldn't it be better to have functions that work whatever the value
> of lexical-binding, if possible?
>
>> An alternative to using a lexical binding here would be to simply use this:
>>
>>  `(lambda () (interactive) (text-scale-adjust (abs ',inc)))
>
> If this alternative works whatever lexical-binding, it seems superior
> to me. Isn't it?

No, it is inferior.

Here, you have to duplicate the code of the function for each occurence.

With closures (lexical binding) you only need to duplicate the enclosed
environment, the code of the function being the same for all the
closures.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
A bad day in () is better than a good day in {}.




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

* Re: sending function arguments to recursive function calls
       [not found]     ` <mailman.25279.1367935468.855.help-gnu-emacs@gnu.org>
@ 2013-05-07 14:55       ` Pascal J. Bourguignon
  2013-05-08 12:25         ` Stefan Monnier
  0 siblings, 1 reply; 21+ messages in thread
From: Pascal J. Bourguignon @ 2013-05-07 14:55 UTC (permalink / raw)
  To: help-gnu-emacs

"Drew Adams" <drew.adams@oracle.com> writes:

>> > An alternative to using a lexical binding here would be to 
>> > simply use this:
>> >  `(lambda () (interactive) (text-scale-adjust (abs ',inc)))
>> 
>> If this alternative works whatever lexical-binding, it seems superior
>> to me. Isn't it?
>
> Yes.  That's my opinion, anyway.  In this case (and in many others), there is no
> _logical_ reason to pass a variable and have that variable be looked up
> lexically when the lambda is invoked.  All that is needed is the variable's
> value at the time the lambda is _constructed_.  Anything else is overkill.  
>
> But logic is not the only thing involved here.  Disadvantages of substituting
> the value can include: (a) backquote syntax, or its equivalent, is less readable
> and (b) the byte compiler might not be able to compile the lambda in a
> performant way.
>
> I'm no expert on Emacs byte compilation, but it's possible that the byte
> compiler just punts on a dynamically constructed sexp such as the one above,
> even though it might be able to figure out that the result in this case is
> straightforward.  Dunno.

Well, the thing is that emacs lisp accepts as function any list starting
with the symbol lambda, and when calling it, it just interprets
it. Since the function is quoted not by function, then it won't be
compiled (unless explicitely requested).


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

 (byte-compile 'make-scale-adjuster)
 --> #[(inc) "\301\302\303\304\305\306\bDDDF\207" [inc lambda nil
       (interactive) text-scale-adjust abs quote] 7]

 (make-scale-adjuster 42)
 --> (lambda nil (interactive) (text-scale-adjust (abs (quote 42))))

 (eql (make-scale-adjuster 1) (make-scale-adjuster 2))
 --> nil

 (functionp (make-scale-adjuster 33))
 --> t

 (funcall (make-scale-adjuster 33))
 --> (((#:t keymap (67108912 . #[0 #1="\301\302\300!!\207" [33 text-scale-adjust abs] 3 #2="

(fn)" nil]) (67108925 . #[0 #1# [33 text-scale-adjust abs] 3 #2# nil]) (67108907 . #[0 #1# [33 text-scale-adjust abs] 3 #2# nil]) (67108909 . #[0 #1# [33 text-scale-adjust abs] 3 #2# nil]) (48 . #[0 #1# [33 text-scale-adjust abs] 3 #2# nil]) (61 . #[0 #1# [33 text-scale-adjust abs] 3 #2# nil]) (43 . #[0 #1# [33 text-scale-adjust abs] 3 #2# nil]) (45 . #[0 #1# [33 text-scale-adjust abs] 3 #2# nil]))))
 ;; Oops, I shouldn't have done that…




You could compile the lambda:

 (defun make-scale-adjuster (inc)
   (byte-compile `(lambda () (interactive) (text-scale-adjust (abs ,inc)))))

which makes you lose that compilation time each time you
callmake-scale-adjuster:

 (make-scale-adjuster 42)
  --> #[nil "\300\301\302!!\207" [text-scale-adjust abs 42] 3 nil nil]

but hopefully, you'll get back this time when calling the generated
function:

  (loop with scale-adjuster = (make-scale-adjuster 42)
        repeat a-lot
        do (funcall scale-adjuster))


Nonetheless, each time you call make-scale-adjuster, it has to return
duplicated code:

 (make-scale-adjuster 42)
  --> #[nil "\300\301\302!!\207" [text-scale-adjust abs 42] 3 nil nil]
 (make-scale-adjuster 33)
  --> #[nil "\300\301\302!!\207" [text-scale-adjust abs 33] 3 nil nil]

while only one constant changes…


 (setf lexical-binding t)
 (defun make-scale-adjuster (inc)
   (lambda () (interactive) (text-scale-adjust (abs inc))))

  (make-scale-adjuster 42)
  --> (closure ((inc . 42) t) nil (interactive) (text-scale-adjust (abs inc)))
  (make-scale-adjuster 33)
  --> (closure ((inc . 33) t) nil (interactive) (text-scale-adjust (abs inc)))


  (byte-compile 'make-scale-adjuster)
  --> #[(inc) "\300\207" [#[nil "\301\302\b!!\207" [inc text-scale-adjust abs] 3 nil nil]] 1]

  (make-scale-adjuster 42)
  --> #[nil "\301\302\b!!\207" [inc text-scale-adjust abs] 3 nil nil]
  (make-scale-adjuster 33)
  --> #[nil "\301\302\b!!\207" [inc text-scale-adjust abs] 3 nil nil]

  (eq (make-scale-adjuster 42)
      (make-scale-adjuster 33)) 
  --> t

Here when compiling the function the closure inside is compiled at the
same time, and when calling the compiled function, the same closed
function is returned.  (It is a little strange that they're eq, since
they should be different closures, when calling them we get different
results, but until emacs lisp becomes Common Lisp, we can't expect too
much of it, can we).



> Lexical binding was added to Emacs relatively recently.  With time, perhaps it
> and dynamic binding will become better roommates.  And certainly, with time,
> users will become more used to lexical binding and to looking out for
> lexical/dynamic binding gotchas.

Too bad in 2013, users must suffer those gotchas that have been debugged
in the 70's by scheme users, and integrated in the 80's by all lispers
(thru the common lisp).  


> For one thing, you will no doubt be reflexively looking for a local-variable
> binding declaration in the file, right? ;-)  And you will be looking for free
> variables, and when you notice one you will ask yourself whether it will be
> evaluated using lexical or dynamic binding.  IOW, you will internalize things
> like this help thread.

A good trick is to wrap all your special^W dynamic variables in stars:

    (defvar *dynamic-variable* 'dyn)

    (let ((lexical-variable 'lex))
      (defun f ()           
         (list *dynamic-variable* lexical-variable)))



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
You can take the lisper out of the lisp job, but you can't take the lisp out
of the lisper (; -- antifuchs


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

* Re: sending function arguments to recursive function calls
  2013-05-07 14:04     ` Drew Adams
@ 2013-05-08 12:21       ` Stefan Monnier
  2013-05-09  8:35         ` Gauthier Östervall
  0 siblings, 1 reply; 21+ messages in thread
From: Stefan Monnier @ 2013-05-08 12:21 UTC (permalink / raw)
  To: help-gnu-emacs

> Emacs Lisp does not particularly make things clear, IMO.  Common Lisp
> does a pretty good job of helping lexical and dynamic binding cohabit.

Actually, Emacs's lexical-binding variant of Elisp is pretty close to
Common Lisp: the default binding is lexical but you can use dynamic
binding for specific cases.

The difference is that Emacs has to keep the old compatibility mode
where lexical-binding is nil, whereas Common-Lisp never had such a thing.

> Lexical binding was added to Emacs relatively recently.  With time,
> perhaps it and dynamic binding will become better roommates.

When lexical-binding is t, they're very good roomates already.
Hopefully with time, the "lexical-binding = nil" case can be dropped.


        Stefan




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

* Re: sending function arguments to recursive function calls
  2013-05-07 14:55       ` Pascal J. Bourguignon
@ 2013-05-08 12:25         ` Stefan Monnier
  0 siblings, 0 replies; 21+ messages in thread
From: Stefan Monnier @ 2013-05-08 12:25 UTC (permalink / raw)
  To: help-gnu-emacs

>   (make-scale-adjuster 42)
>   --> #[nil "\301\302\b!!\207" [inc text-scale-adjust abs] 3 nil nil]
>   (make-scale-adjuster 33)
>   --> #[nil "\301\302\b!!\207" [inc text-scale-adjust abs] 3 nil nil]
>   (eq (make-scale-adjuster 42)
>       (make-scale-adjuster 33)) 
--> t

> Here when compiling the function the closure inside is compiled at the
> same time, and when calling the compiled function, the same closed
> function is returned.  (It is a little strange that they're eq, since

They're `eq' because you compiled them in dynamic-binding mode
(i.e. they won't work).

> A good trick is to wrap all your special^W dynamic variables in stars:
>     (defvar *dynamic-variable* 'dyn)

That's the Common-Lisp convention, but Elisp uses another convention,
which is to add a "package prefix" such as `mypackage-myvar'.


        Stefan




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

* Re: sending function arguments to recursive function calls
  2013-05-08 12:21       ` Stefan Monnier
@ 2013-05-09  8:35         ` Gauthier Östervall
  2013-05-09 12:23           ` Stefan Monnier
  0 siblings, 1 reply; 21+ messages in thread
From: Gauthier Östervall @ 2013-05-09  8:35 UTC (permalink / raw)
  To: Stefan Monnier, help-gnu-emacs

On Wed, May 8, 2013 at 2:21 PM, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
> Actually, Emacs's lexical-binding variant of Elisp is pretty close to
> Common Lisp: the default binding is lexical but you can use dynamic
> binding for specific cases.
>
> The difference is that Emacs has to keep the old compatibility mode
> where lexical-binding is nil, whereas Common-Lisp never had such a thing.
>
>> Lexical binding was added to Emacs relatively recently.  With time,
>> perhaps it and dynamic binding will become better roommates.
>
> When lexical-binding is t, they're very good roomates already.
> Hopefully with time, the "lexical-binding = nil" case can be dropped.

If I have an existing file with lexical-binding = nil, and I want to
add more functions to that file, what is then the preferred way to do
it?  Should I write the new function with lexical-binding = t?  Isn't
it risky or wrong to set lexical-binding at the top of the file (like
face-remap.el does), what would happen to the other functions, which
earlier had lexical-binding = nil?

Is there a way (and is it better) to set lexical-binding = t locally
for the new function?

Or is it better to make the new function work with lexical-binding =
nil, despite the caveats described by Pascal?



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

* Re: sending function arguments to recursive function calls
  2013-05-09  8:35         ` Gauthier Östervall
@ 2013-05-09 12:23           ` Stefan Monnier
  2013-05-12 13:19             ` Gauthier Östervall
  0 siblings, 1 reply; 21+ messages in thread
From: Stefan Monnier @ 2013-05-09 12:23 UTC (permalink / raw)
  To: Gauthier Östervall; +Cc: help-gnu-emacs

> Is there a way (and is it better) to set lexical-binding = t locally
> for the new function?

No.  But converting existing dynamically scoped code to lexical scoping
is usually pretty easy: set lexical-binding to t at the top of the file,
then byte-compile it, then fix the warnings, and you should be good to go.

Sometimes there's some extra tricks undetected by the simple checks
performed by the byte-compiler, so it doesn't always work as smoothly,
but in most cases it's really a straightforward process.


        Stefan



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

* Re: sending function arguments to recursive function calls
  2013-05-09 12:23           ` Stefan Monnier
@ 2013-05-12 13:19             ` Gauthier Östervall
  2013-05-13 14:55               ` Stefan Monnier
  0 siblings, 1 reply; 21+ messages in thread
From: Gauthier Östervall @ 2013-05-12 13:19 UTC (permalink / raw)
  To: Stefan Monnier, help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 1170 bytes --]

On Wed, May 8, 2013 at 2:21 PM, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
> When lexical-binding is t, they're very good roomates already.
> Hopefully with time, the "lexical-binding = nil" case can be dropped.

Does this imply that if I want to give for example window.el
lexical-binding (I do have an ulterior motive), no one would mind
having it that way?

> [...]  But converting existing dynamically scoped code to lexical scoping
> is usually pretty easy: set lexical-binding to t at the top of the file,
> then byte-compile it, then fix the warnings, and you should be good to go.
>
> Sometimes there's some extra tricks undetected by the simple checks
> performed by the byte-compiler, so it doesn't always work as smoothly,
> but in most cases it's really a straightforward process.

I have tried to do just that to window.el. It seemed indeed
straightforward to me, but I would greatly appreciate feedback on the
change. I really just added the lexical-binding at the top, and
removed seemingly unused variables. I don't know why these variables
were left (were they really unused?), but byte-compiling gives no
warning, at least.

See attached bundle.

[-- Attachment #2: make-window-lexical.txt --]
[-- Type: text/plain, Size: 4466 bytes --]

# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: gauthier@ostervall.se-20130512130720-hpthrwn048nrj4ao
# target_branch: file:///media/sf_prog/emacs/trunk/
# testament_sha1: 288aa595c17d0d7923aa72d1cbe25a3a3b081380
# timestamp: 2013-05-12 15:09:54 +0200
# base_revision_id: rgm@gnu.org-20130430101735-ccy06l3ndx4vrj18
# 
# Begin patch
=== modified file 'lisp/window.el' (properties changed: -x to +x)
--- lisp/window.el	2013-04-13 14:37:20 +0000
+++ lisp/window.el	2013-05-12 13:07:20 +0000
@@ -1,4 +1,4 @@
-;;; window.el --- GNU Emacs window commands aside from those written in C
+;;; window.el --- GNU Emacs window commands aside from those written in C  -*- lexical-binding: t -*-
 
 ;; Copyright (C) 1985, 1989, 1992-1994, 2000-2013 Free Software
 ;; Foundation, Inc.
@@ -685,11 +685,9 @@
 This function may be called only if no window on SIDE exists yet.
 The new window automatically becomes the \"major\" side window on
 SIDE.  Return the new window, nil if its creation window failed."
-  (let* ((root (frame-root-window))
-	 (left-or-right (memq side '(left right)))
+  (let* ((left-or-right (memq side '(left right)))
 	 (major (window--major-side-window side))
-	 (selected-window (selected-window))
-	 (on-side (cond
+         (on-side (cond
 		   ((eq side 'top) 'above)
 		   ((eq side 'bottom) 'below)
 		   (t side)))
@@ -698,8 +696,7 @@
 	 ;; parent window unless needed.
 	 (window-combination-resize 'side)
 	 (window-combination-limit nil)
-	 (new (split-window major nil on-side))
-	 fun)
+         (new (split-window major nil on-side)))
     (when new
       ;; Initialize `window-side' parameter of new window to SIDE.
       (set-window-parameter new 'window-side side)
@@ -749,8 +746,7 @@
   A positive value means use a slot following (that is, below or
   on the right of) the middle slot.  The default is zero."
   (let ((side (or (cdr (assq 'side alist)) 'bottom))
-	(slot (or (cdr (assq 'slot alist)) 0))
-	new)
+        (slot (or (cdr (assq 'slot alist)) 0)))
     (cond
      ((not (memq side '(top bottom left right)))
       (error "Invalid side %s specified" side))
@@ -776,9 +772,8 @@
 		  ((eq side 'right) 2)
 		  ((eq side 'bottom) 3))
 		 window-sides-slots))
-	   (selected-window (selected-window))
-	   window this-window this-slot prev-window next-window
-	   best-window best-slot abs-slot new-window)
+           window this-window this-slot prev-window next-window
+           best-window best-slot abs-slot)
 
       (cond
        ((and (numberp max-slots) (<= max-slots 0))
@@ -5713,7 +5708,7 @@
 		   0)
 		  (display-buffer-reuse-frames 0)
 		  (t (last-nonminibuffer-frame))))
-	 entry best-window second-best-window window)
+         best-window second-best-window window)
     ;; Scan windows whether they have shown the buffer recently.
     (catch 'best
       (dolist (window (window-list-1 (frame-first-window) 'nomini frames))

# Begin bundle
IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWedecm4AAeVfgAaQUPP//1qB
kgC////wUAQ+e2A7zVroA0DQpB6jTEHqZPUBppkHlAAAAjSJpqep5TyIyAAAAAAADRT0TRgiahmk
YTE2hGATTJkxCKfqmSPU2SB6mJk00ABgIDTQ0CSIRqbSMIEwmFPRqPUZGkekyYaiIvrvtah8WXqt
OO3Qj96nDbPuxEtdU906bq4tuhKEs4gdL3ef37/wQnX+TOz7O/0Qafx9gM89hRR0vAfQOQg7wAyg
4JxuiNaisWWRddptKfJkoQEuAygQPDyORisUUT0DoF05YXlz1NgQyLIRNcgaDacUxRzIAgfsIwTm
ah2/WBLepi/eRjuqOyiLZP9eKflzkQ3jL+M7WPkJaUe2ZVJYysv3/OS97MyL3f4JNz5wBkRcQyqi
O0QirBOKxMKwu7MtcyDZE8XhRBWygx3yPHq6jgWfG/BWKMtwp5bhxGIvWM1l/SjguNPlVdRenH2W
UL8xmz3mirRS1LomYRirBMEyemsm2rUZj6YZrQz2HdE34ZIYXJ1kEGcZYHsY5FSVe6VIKXz2qWqL
6mJ5FPJLfBR0aiupRoq4LJlkQFhBoKZTYK8q9rTNo5rRnWYhSYKzadOUUt4riqllFEz1PlC2xxkp
oUYc8KOARMoyYoFeSJSy2qBI6ehPM0eJguCEggJmlMjHL9nrpkpbFA+eHqpAw4uqBIYroQmRI6JV
XAgvrgGKKzPU1YkNr3yW6XrLHJOmrknkphXNvQ/s1t20U66yDN0/x49F0SnUAY/XIYy9JF9VTxYQ
1a0BgVj08KsfptNrN1QCsZMm4gXUqrbci9vDMidnrWtXNL38+eGo8LPz9verze164INs2GyHpYJ8
nC2txyPW5RtC0A9D7r8lFyxq1FQCYgsyJ0nAkIMzS8rlBcdJ5NgSdxQtI06niPx5vfHrbZSzX1ZK
VcCiZatqSvKIOY+SCi2fFIReuZyF99h1fKD7JJG4LJlDhw3Qglr5cogeumq2oGhpohusE81LgZeW
/6+C8NUR1G4/fO7Mx1bIPDBN9T4DRnmRYVr+B1NgaJ7NSR5CYXYxQOYUOybGv/laD8gJ7Ssr2KyR
rX3DgdgC6w89miN4XHQOaw1yhBBu2GoM5Lc6koJOHBTCEAkYteO2gv4Wb2QY/O1FvargvWmfQyvt
uugcaqGNdQ9Kx2knbaJqmo7khIf6KHlbVUubzXyFYiTKi0QXPKLIsHbcSttdQO0iX3n0C9UWuC5e
KW1Gnu6AG98drMnJa5drdc52iqydVSlG7mcQwc4Its5WlSgpV9NNXDwWUVWRadWTLKTAYidX749+
LPZof+T2pS1pymOSJM5uIonFA7avZlGmEGRIBN/QAQCqIetAnNkpmqUfBqMTlExi97swFDvkA67h
Ty8riYUCDK03J1pupXHbQDD0oBX5rNNVBUoOyS1lTB9mddvNoWC4qV69zKwGYJK5Tuzkv/F3JFOF
CQ515ybg

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

* Re: sending function arguments to recursive function calls
  2013-05-12 13:19             ` Gauthier Östervall
@ 2013-05-13 14:55               ` Stefan Monnier
  2013-05-17 12:20                 ` Gauthier Östervall
  0 siblings, 1 reply; 21+ messages in thread
From: Stefan Monnier @ 2013-05-13 14:55 UTC (permalink / raw)
  To: Gauthier Östervall; +Cc: help-gnu-emacs

>> When lexical-binding is t, they're very good roomates already.
>> Hopefully with time, the "lexical-binding = nil" case can be dropped.
> Does this imply that if I want to give for example window.el
> lexical-binding (I do have an ulterior motive), no one would mind
> having it that way?

Yup.  My local Emacs is currently pretty broken because I started to
compile all files as "lexical-binding = t".

> I don't know why these variables were left (were they really unused?)

That's the question that the byte-compiler can't answer: maybe they
really weren't used (so you can remove them), or maybe they were used
elsewhere via dynamic scoping (in which case you need to add a (defvar
<var>) to force the use of dynamic scoping for this variable).

It's very common to have variables that aren't used (since the
byte-compiler didn't warn about it).


        Stefan



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

* Re: sending function arguments to recursive function calls
  2013-05-13 14:55               ` Stefan Monnier
@ 2013-05-17 12:20                 ` Gauthier Östervall
  2013-05-17 12:26                   ` Dmitry Gutov
  0 siblings, 1 reply; 21+ messages in thread
From: Gauthier Östervall @ 2013-05-17 12:20 UTC (permalink / raw)
  To: Stefan Monnier, help-gnu-emacs

On Mon, May 13, 2013 at 4:55 PM, Stefan Monnier
<monnier@iro.umontreal.ca> wrote:
> That's the question that the byte-compiler can't answer: maybe they
> really weren't used (so you can remove them), or maybe they were used
> elsewhere via dynamic scoping (in which case you need to add a (defvar
> <var>) to force the use of dynamic scoping for this variable).

All the variables that the byte-compiler complained about were defined
in the first parameter of a let or a let* expression.

My understanding of let and let* is that the first parameter defines
local variables to be used in the second parameter (or later in the
first parameter in the case of let*).

The unused variables I had to remove were not referenced in the last
parameter of the let or let* (nor later in the first parameter of
let*), so I assumed they were not used anywhere.

Is there a way that such variables may be used elsewhere (via dynamic
scoping)? If yes, how?
Couldn't it be the case only if they were defined with setq (so called
free variables)?



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

* Re: sending function arguments to recursive function calls
  2013-05-17 12:20                 ` Gauthier Östervall
@ 2013-05-17 12:26                   ` Dmitry Gutov
  2013-05-17 14:31                     ` Drew Adams
  0 siblings, 1 reply; 21+ messages in thread
From: Dmitry Gutov @ 2013-05-17 12:26 UTC (permalink / raw)
  To: Gauthier Östervall; +Cc: help-gnu-emacs, Stefan Monnier

Gauthier Östervall <gauthier@ostervall.se> writes:

> On Mon, May 13, 2013 at 4:55 PM, Stefan Monnier
> <monnier@iro.umontreal.ca> wrote:
>> That's the question that the byte-compiler can't answer: maybe they
>> really weren't used (so you can remove them), or maybe they were used
>> elsewhere via dynamic scoping (in which case you need to add a (defvar
>> <var>) to force the use of dynamic scoping for this variable).
>
> All the variables that the byte-compiler complained about were defined
> in the first parameter of a let or a let* expression.
>
> My understanding of let and let* is that the first parameter defines
> local variables to be used in the second parameter (or later in the
> first parameter in the case of let*).
>
> The unused variables I had to remove were not referenced in the last
> parameter of the let or let* (nor later in the first parameter of
> let*), so I assumed they were not used anywhere.
>
> Is there a way that such variables may be used elsewhere (via dynamic
> scoping)? If yes, how?
> Couldn't it be the case only if they were defined with setq (so called
> free variables)?

This is the ugly side of dynamic scoping.

(defun foo ()
  (let ((bar 42))
    (baz)))

(defun baz ()
  bar)

(foo) ; => 42

baz ; => void-variable error



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

* RE: sending function arguments to recursive function calls
  2013-05-17 12:26                   ` Dmitry Gutov
@ 2013-05-17 14:31                     ` Drew Adams
  2013-05-19 16:57                       ` Dmitry Gutov
       [not found]                       ` <mailman.70.1368982677.22516.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 21+ messages in thread
From: Drew Adams @ 2013-05-17 14:31 UTC (permalink / raw)
  To: 'Dmitry Gutov', 'Gauthier Östervall'
  Cc: help-gnu-emacs, 'Stefan Monnier'

> This is the ugly side of dynamic scoping.
> (defun foo () (let ((bar 42)) (baz)))
> (defun baz () bar)
> (foo) ; => 42
> baz ; => void-variable error

Huh?  I guess you meant to write
(baz) ; => "void-variable bar" error

There is nothing ugly about that behavior.

The `let' binds variable `bar' for the dynamic extent of the call to `foo'.
There is no other binding of `bar' or assignment to it here, so `(baz)' refers
to an unbound variable `bar'.

What happens with lexical scoping?
(foo) ; => "void-variable bar" error
(baz) ; => "void-variable bar" error

Which is also not ugly and not unusual.  There is no binding of `bar' lexically
visible in `baz'.

Dynamic and lexical binding are very different.  That's all.  Each has its
advantages.

Lexical binding is generally cleaner (correct for funargs etc.), so it is
simpler to understand (WYSIWYG, where the `S' is all about lexical scope).  As
such, it can often allow compilation to more efficient code.  And it can
facilitate program proving and transformation, but mainly for "pure"
(referentially transparent) languages, not full Lisp.

Dynamic binding facilitates user extension ("monkey patching").  And yes, this
is particularly important for a dynamic user environment like Emacs.

It is easy to find references lauding the benefits of lexical binding (most
languages use only lexical binding).  Stallman explains well why dynamic binding
is important for Emacs:
http://www.gnu.org/software/emacs/emacs-paper.html#SEC17.

--

Some other background/discussion:

http://www.emacswiki.org/emacs/DynamicBindingVsLexicalBinding

http://en.wikipedia.org/wiki/Static_scoping#Dynamic_scoping

http://stackoverflow.com/questions/321000/what-are-the-advantages-of-dynamic-sco
ping

http://stackoverflow.com/questions/2979428/uses-for-dynamic-scope

http://c2.com/cgi/wiki?DynamicScoping

http://academic.udayton.edu/saverioperugini/courses/cps343/lecture_notes/scope.h
tml

http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node43.html

http://www.codinghorror.com/blog/2008/07/monkeypatching-for-humans.html

http://devblog.avdi.org/2008/02/23/why-monkeypatching-is-destroying-ruby/




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

* Re: sending function arguments to recursive function calls
  2013-05-17 14:31                     ` Drew Adams
@ 2013-05-19 16:57                       ` Dmitry Gutov
  2013-05-21 16:34                         ` Drew Adams
       [not found]                       ` <mailman.70.1368982677.22516.help-gnu-emacs@gnu.org>
  1 sibling, 1 reply; 21+ messages in thread
From: Dmitry Gutov @ 2013-05-19 16:57 UTC (permalink / raw)
  To: Drew Adams; +Cc: help-gnu-emacs

On 17.05.2013 18:31, Drew Adams wrote:
>> This is the ugly side of dynamic scoping.
>> (defun foo () (let ((bar 42)) (baz)))
>> (defun baz () bar)
>> (foo) ; => 42
>> baz ; => void-variable error
>
> Huh?  I guess you meant to write
> (baz) ; => "void-variable bar" error

No, I meant exactly to write variable reference, not function call, to 
illustrate that it's not defined globally.

> There is nothing ugly about that behavior.

It's ugly because this kind of code is hard to reason about and, 
consequently, hard to modify. Suppose I want to rewrite `foo' (and 
suppose it's longer than this one line).

Can I rename `bar' to something else? No idea: to be absolutely sure, I 
have to search the definitions of all functions that `foo' calls, and if 
I find a `bar' reference in any of them, I'll now have to search for any 
other functions that call them, etc. IOW, this makes for terrible 
composability.

The behavior is ugly because it allows the code to be written this way.

A worse example is when `bar' is one of the arguments to `foo' (ugh).

> The `let' binds variable `bar' for the dynamic extent of the call to `foo'.
> There is no other binding of `bar' or assignment to it here, so `(baz)' refers
> to an unbound variable `bar'.
>
> What happens with lexical scoping?
> (foo) ; => "void-variable bar" error
> (baz) ; => "void-variable bar" error

As it should. Contrast this with the situation when `bar' has been 
`defvar'ed in advance. Both functions would know that this var is 
global, so if it's renamed in some place, it definitely should be 
renamed in all functions that reference it.

This is what I can call the light side of dynamic scoping, and it's how 
the term "dynamic binding" is often defined.

> Dynamic binding facilitates user extension ("monkey patching").  And yes, this
> is particularly important for a dynamic user environment like Emacs.
>
> It is easy to find references lauding the benefits of lexical binding (most
> languages use only lexical binding).  Stallman explains well why dynamic binding
> is important for Emacs:
> http://www.gnu.org/software/emacs/emacs-paper.html#SEC17.

I could offer some criticism for the paper, but there's really no need.

Just recall that Emacs is on track to eventually replace dynamic scoping 
with lexical scoping everywhere, with exceptions for defvar'ed vars 
(controlled dynamic binding), and nobody is really arguing that Emacs 
will become too hard to customize as a result. Nobody reasonably 
well-informed, anyway.



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

* Re: sending function arguments to recursive function calls
       [not found]                       ` <mailman.70.1368982677.22516.help-gnu-emacs@gnu.org>
@ 2013-05-19 20:59                         ` Pascal J. Bourguignon
  2013-05-20 19:31                           ` Dmitry Gutov
       [not found]                           ` <mailman.94.1369078320.22516.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 21+ messages in thread
From: Pascal J. Bourguignon @ 2013-05-19 20:59 UTC (permalink / raw)
  To: help-gnu-emacs

Dmitry Gutov <dgutov@yandex.ru> writes:

> On 17.05.2013 18:31, Drew Adams wrote:
>>> This is the ugly side of dynamic scoping.
>>> (defun foo () (let ((bar 42)) (baz)))
>>> (defun baz () bar)
>>> (foo) ; => 42
>>> baz ; => void-variable error
>>
>> Huh?  I guess you meant to write
>> (baz) ; => "void-variable bar" error
>
> No, I meant exactly to write variable reference, not function call, to
> illustrate that it's not defined globally.

Then you meant to write:

    bar

not:

    baz


>> There is nothing ugly about that behavior.
>
> It's ugly because this kind of code is hard to reason about and,
> consequently, hard to modify. Suppose I want to rewrite `foo' (and
> suppose it's longer than this one line).

Yes. That's why you should adopt the CL convention of naming all the
special variables (those with dynamic binding) with stars:

(defun foo ()
  (let ((*bar* 42)) 
     (declare (special *bar*))
     (baz)))

(defun baz ()
   (declare (special *bar*))
   *bar*)


(foo) ; => 42

*bar* ; Debugger entered--Lisp error: (void-variable *bar*)



> Can I rename `bar' to something else? 

Yes.  You should name it *bar*, and declare it special locally.  Right,
for now (declare (special *bar*)) has no effect in emacs lisp since it's
the default, but it states your intent!


> No idea: to be absolutely sure,
> I have to search the definitions of all functions that `foo' calls,
> and if I find a `bar' reference in any of them, I'll now have to
> search for any other functions that call them, etc. IOW, this makes
> for terrible composability.

Definitely.  That's why the default is lexical binding, and you have to
declare specially variables with dynamic binding, either with declare
special, or globally with defvar or defparameter.


> The behavior is ugly because it allows the code to be written this way.
>
> A worse example is when `bar' is one of the arguments to `foo' (ugh).

Global or local special declarations are still possible, even for
parameters.


>> The `let' binds variable `bar' for the dynamic extent of the call to `foo'.
>> There is no other binding of `bar' or assignment to it here, so `(baz)' refers
>> to an unbound variable `bar'.
>>
>> What happens with lexical scoping?
>> (foo) ; => "void-variable bar" error
>> (baz) ; => "void-variable bar" error
>
> As it should. Contrast this with the situation when `bar' has been
> defvar'ed in advance. Both functions would know that this var is
> global, so if it's renamed in some place, it definitely should be
> renamed in all functions that reference it.
>
> This is what I can call the light side of dynamic scoping, and it's
> how the term "dynamic binding" is often defined.
>
>> Dynamic binding facilitates user extension ("monkey patching").  And yes, this
>> is particularly important for a dynamic user environment like Emacs.
>>
>> It is easy to find references lauding the benefits of lexical binding (most
>> languages use only lexical binding).  Stallman explains well why dynamic binding
>> is important for Emacs:
>> http://www.gnu.org/software/emacs/emacs-paper.html#SEC17.
>
> I could offer some criticism for the paper, but there's really no need.
>
> Just recall that Emacs is on track to eventually replace dynamic
> scoping with lexical scoping everywhere, with exceptions for defvar'ed
> vars (controlled dynamic binding), and nobody is really arguing that
> Emacs will become too hard to customize as a result. Nobody reasonably
> well-informed, anyway.

Of course.  As long as dynamic binding is still available for the few
cases where it's needed, as in Common Lisp.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
A bad day in () is better than a good day in {}.
You can take the lisper out of the lisp job, but you can't take the lisp out
of the lisper (; -- antifuchs


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

* Re: sending function arguments to recursive function calls
  2013-05-19 20:59                         ` Pascal J. Bourguignon
@ 2013-05-20 19:31                           ` Dmitry Gutov
       [not found]                           ` <mailman.94.1369078320.22516.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 21+ messages in thread
From: Dmitry Gutov @ 2013-05-20 19:31 UTC (permalink / raw)
  To: Pascal J. Bourguignon; +Cc: help-gnu-emacs

"Pascal J. Bourguignon" <pjb@informatimago.com> writes:
> Then you meant to write:
>
>     bar
>
> not:
>
>     baz
>

Right. Sorry.

>> It's ugly because this kind of code is hard to reason about and,
>> consequently, hard to modify. Suppose I want to rewrite `foo' (and
>> suppose it's longer than this one line).
>
> Yes. That's why you should adopt the CL convention of naming all the
> special variables (those with dynamic binding) with stars:
>

I agree it's a good convention in CL (and Clojure), but Elisp has its
own convention: name the variable starting with the package prefix.
Until we have real modularity, it should be good enough.

>> Can I rename `bar' to something else? 
>
> Yes.  You should name it *bar*, and declare it special locally.  Right,
> for now (declare (special *bar*)) has no effect in emacs lisp since it's
> the default, but it states your intent!

Yes, I think, currently only byte-compiler looks at it, and warns the
user when it sees undeclared variables.

>> No idea: to be absolutely sure,
>> I have to search the definitions of all functions that `foo' calls,
>> and if I find a `bar' reference in any of them, I'll now have to
>> search for any other functions that call them, etc. IOW, this makes
>> for terrible composability.
>
> Definitely.  That's why the default is lexical binding, and you have to
> declare specially variables with dynamic binding, either with declare
> special, or globally with defvar or defparameter.
>
>
>> The behavior is ugly because it allows the code to be written this way.
>>
>> A worse example is when `bar' is one of the arguments to `foo' (ugh).
>
> Global or local special declarations are still possible, even for
> parameters.

...in CL, right? Your earmuff example didn't work for me in Emacs with
lexical-binding t, `(declare (special *bar*))' doesn't replace the need
for `defvar'ing it.

I'm not sure how I feel about special local variables and parameters.
The problem with tracking down callers/callees graph applies to both of
these types, as far as I can tell, so each local variable of this kind
might as well be declared global.

During the few years I've been using Emacs, I think I've only used the
ability to change the value of a parameter in a caller function once,
deep inside the Helm codebase. Sure enough, in a few months, the caller
function code has changed, and my function broke.



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

* Re: sending function arguments to recursive function calls
       [not found]                           ` <mailman.94.1369078320.22516.help-gnu-emacs@gnu.org>
@ 2013-05-20 19:55                             ` Pascal J. Bourguignon
  0 siblings, 0 replies; 21+ messages in thread
From: Pascal J. Bourguignon @ 2013-05-20 19:55 UTC (permalink / raw)
  To: help-gnu-emacs

Dmitry Gutov <dgutov@yandex.ru> writes:

> During the few years I've been using Emacs, I think I've only used the
> ability to change the value of a parameter in a caller function once,
> deep inside the Helm codebase. Sure enough, in a few months, the caller
> function code has changed, and my function broke.

Definitely.  

But then any kind of patching is doomed, if not integrated in the
upstream.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
A bad day in () is better than a good day in {}.
You can take the lisper out of the lisp job, but you can't take the lisp out
of the lisper (; -- antifuchs


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

* RE: sending function arguments to recursive function calls
  2013-05-19 16:57                       ` Dmitry Gutov
@ 2013-05-21 16:34                         ` Drew Adams
  0 siblings, 0 replies; 21+ messages in thread
From: Drew Adams @ 2013-05-21 16:34 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: help-gnu-emacs

> Just recall that Emacs is on track to eventually replace dynamic scoping
> with lexical scoping everywhere, with exceptions for defvar'ed vars
> (controlled dynamic binding), and nobody is really arguing that Emacs
> will become too hard to customize as a result. Nobody reasonably
> well-informed, anyway.

Which is just to say that Emacs Lisp now aims to end up like Common Lisp (30 years later): lexical scoping unless the variable is "special" (which for Emacs Lisp means defvar'd, so far).

IOW, nothing new here.  No rejection of dynamic scoping.  Reasonable cohabitation of lexical and dynamic scoping.  That's still the aim, AFAIU, and a good one.



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

end of thread, other threads:[~2013-05-21 16:34 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-05-04 13:01 sending function arguments to recursive function calls Gauthier Östervall
2013-05-04 15:30 ` Drew Adams
2013-05-07 11:25   ` Gauthier Östervall
2013-05-07 14:04     ` Drew Adams
2013-05-08 12:21       ` Stefan Monnier
2013-05-09  8:35         ` Gauthier Östervall
2013-05-09 12:23           ` Stefan Monnier
2013-05-12 13:19             ` Gauthier Östervall
2013-05-13 14:55               ` Stefan Monnier
2013-05-17 12:20                 ` Gauthier Östervall
2013-05-17 12:26                   ` Dmitry Gutov
2013-05-17 14:31                     ` Drew Adams
2013-05-19 16:57                       ` Dmitry Gutov
2013-05-21 16:34                         ` Drew Adams
     [not found]                       ` <mailman.70.1368982677.22516.help-gnu-emacs@gnu.org>
2013-05-19 20:59                         ` Pascal J. Bourguignon
2013-05-20 19:31                           ` Dmitry Gutov
     [not found]                           ` <mailman.94.1369078320.22516.help-gnu-emacs@gnu.org>
2013-05-20 19:55                             ` Pascal J. Bourguignon
2013-05-07 14:32     ` Pascal J. Bourguignon
     [not found]     ` <mailman.25279.1367935468.855.help-gnu-emacs@gnu.org>
2013-05-07 14:55       ` Pascal J. Bourguignon
2013-05-08 12:25         ` Stefan Monnier
2013-05-05  1:22 ` Stefan Monnier

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.