unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* need for 'dynamical-let'?
@ 2015-07-23 20:54 Stephen Leake
  2015-07-23 20:58 ` Stephen Leake
                   ` (4 more replies)
  0 siblings, 5 replies; 16+ messages in thread
From: Stephen Leake @ 2015-07-23 20:54 UTC (permalink / raw)
  To: emacs-devel

I'm switching on lexical-binding in some files.

In several cases, the byte compiler is complaining:

xgit.el:993:30:Error: add-to-list cannot use lexical var `branch-list'

So I have to change code like this:

(let (branch-list
      ...)
   (add-to-list branch-list (substring branch-entry 2) t)


to:

(defvar dvc-branch-list);; add-to-list can't use lexical var
(let (
      ...)
   (add-to-list 'dvc-branch-list (substring branch-entry 2) t)


This pollutes the global name space, and disguises the local nature of
'branch-list'.

Can we define a macro 'dynamical-let' that would implement this
pattern, but with hidden variables?

-- 
-- Stephe



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

* Re: need for 'dynamical-let'?
  2015-07-23 20:54 need for 'dynamical-let'? Stephen Leake
@ 2015-07-23 20:58 ` Stephen Leake
  2015-07-23 21:03 ` Dmitry Gutov
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 16+ messages in thread
From: Stephen Leake @ 2015-07-23 20:58 UTC (permalink / raw)
  To: emacs-devel

Stephen Leake <stephen_leake@stephe-leake.org> writes:

> I'm switching on lexical-binding in some files.
>
> In several cases, the byte compiler is complaining:
>
> xgit.el:993:30:Error: add-to-list cannot use lexical var `branch-list'
>
> So I have to change code like this:
>
> (let (branch-list
>       ...)
>    (add-to-list branch-list (substring branch-entry 2) t)
>
>
> to:
>
> (defvar dvc-branch-list);; add-to-list can't use lexical var
> (let (
>       ...)
>    (add-to-list 'dvc-branch-list (substring branch-entry 2) t)
>
>
> This pollutes the global name space, and disguises the local nature of
> 'branch-list'.
>
> Can we define a macro 'dynamical-let' that would implement this
> pattern, but with hidden variables?


Also, how do I know which functions I write also can't use lexical
variables? Using 'symbol-value' would be one clue, apparently. I hope
the byte-compiler will complain?

-- 
-- Stephe



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

* Re: need for 'dynamical-let'?
  2015-07-23 20:54 need for 'dynamical-let'? Stephen Leake
  2015-07-23 20:58 ` Stephen Leake
@ 2015-07-23 21:03 ` Dmitry Gutov
  2015-07-24  8:16   ` Stephen Leake
  2015-07-24  4:23 ` Stephen J. Turnbull
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 16+ messages in thread
From: Dmitry Gutov @ 2015-07-23 21:03 UTC (permalink / raw)
  To: Stephen Leake, emacs-devel

On 07/23/2015 11:54 PM, Stephen Leake wrote:

> So I have to change code like this:
>
> (let (branch-list
>        ...)
>     (add-to-list branch-list (substring branch-entry 2) t)
>
>
> to:
>
> (defvar dvc-branch-list);; add-to-list can't use lexical var
> (let (
>        ...)
>     (add-to-list 'dvc-branch-list (substring branch-entry 2) t)

You should use `push'. Or maybe `cl-pushnew'.



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

* need for 'dynamical-let'?
  2015-07-23 20:54 need for 'dynamical-let'? Stephen Leake
  2015-07-23 20:58 ` Stephen Leake
  2015-07-23 21:03 ` Dmitry Gutov
@ 2015-07-24  4:23 ` Stephen J. Turnbull
  2015-07-24  4:40   ` David Kastrup
  2015-07-24  7:58   ` Stephen Leake
  2015-07-24 16:54 ` Dmitri Paduchikh
  2015-07-24 23:32 ` Stefan Monnier
  4 siblings, 2 replies; 16+ messages in thread
From: Stephen J. Turnbull @ 2015-07-24  4:23 UTC (permalink / raw)
  To: Stephen Leake; +Cc: emacs-devel

Stephen Leake writes:

 > Can we define a macro 'dynamical-let' that would implement this
 > pattern, but with hidden variables?

First, was there a typo in your post?  add-to-list normally takes a
(quoted) symbol.  Since the argument isn't quoted, it appears that the
effect is that you are attempting to add-to-list to the variable (not
the value!) nil.  Assuming that was a typo....

`dynamical-let' is about as ugly as ugly can get, and anyway it
shouldn't be necessary.  The variable is lexically apparent and its
value is not magical in any way.  Your code *should* work.

Try running your code in the interpreter.  I suspect it will work when
the function is actually called (in compiled code there's a compiler
macro so the function is never called).  Why not fix that instead?

Or, perhaps, as Dmitry and the add-to-list docstring suggest, you
should convert the code to use `push' or `pushnew' instead.  The
inconvenience of the busybody compiler macro may be considered a
"feature" intended to encourage you to modernize your code.




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

* Re: need for 'dynamical-let'?
  2015-07-24  4:23 ` Stephen J. Turnbull
@ 2015-07-24  4:40   ` David Kastrup
  2015-07-24  7:58   ` Stephen Leake
  1 sibling, 0 replies; 16+ messages in thread
From: David Kastrup @ 2015-07-24  4:40 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: Stephen Leake, emacs-devel

"Stephen J. Turnbull" <stephen@xemacs.org> writes:

> Stephen Leake writes:
>
>  > Can we define a macro 'dynamical-let' that would implement this
>  > pattern, but with hidden variables?
>
> First, was there a typo in your post?  add-to-list normally takes a
> (quoted) symbol.  Since the argument isn't quoted, it appears that the
> effect is that you are attempting to add-to-list to the variable (not
> the value!) nil.  Assuming that was a typo....
>
> `dynamical-let' is about as ugly as ugly can get, and anyway it
> shouldn't be necessary.  The variable is lexically apparent and its
> value is not magical in any way.  Your code *should* work.

add-to-list is a function (not a macro) taking a symbol as indicator of
a variable.  So lookup happens at run time when the lexical environment
is already gone.  No way this can happen lexically.

-- 
David Kastrup



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

* Re: need for 'dynamical-let'?
  2015-07-24  4:23 ` Stephen J. Turnbull
  2015-07-24  4:40   ` David Kastrup
@ 2015-07-24  7:58   ` Stephen Leake
  1 sibling, 0 replies; 16+ messages in thread
From: Stephen Leake @ 2015-07-24  7:58 UTC (permalink / raw)
  To: emacs-devel

"Stephen J. Turnbull" <stephen@xemacs.org> writes:

> Stephen Leake writes:
>
>  > Can we define a macro 'dynamical-let' that would implement this
>  > pattern, but with hidden variables?
>
> First, was there a typo in your post?  add-to-list normally takes a
> (quoted) symbol.  

Yes, that's a typo

> `dynamical-let' is about as ugly as ugly can get, and anyway it
> shouldn't be necessary.  The variable is lexically apparent and its
> value is not magical in any way.  Your code *should* work.

add-to-list uses 'symbol-value' on the quoted symbol. As David Kastrup
points out, and as symbol-value doc string says, that does not see
lexical values. So the code will not work.

> Or, perhaps, as Dmitry and the add-to-list docstring suggest, you
> should convert the code to use `push' or `pushnew' instead.  

I was working in Emacs 24.3, where the add-to-list doc string does not
mention "push". But the Emacs master doc string does mention it.

> The inconvenience of the busybody compiler macro may be considered a
> "feature" intended to encourage you to modernize your code.

Ok.

-- 
-- Stephe



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

* Re: need for 'dynamical-let'?
  2015-07-23 21:03 ` Dmitry Gutov
@ 2015-07-24  8:16   ` Stephen Leake
  2015-07-24  9:38     ` Dmitry Gutov
  0 siblings, 1 reply; 16+ messages in thread
From: Stephen Leake @ 2015-07-24  8:16 UTC (permalink / raw)
  To: emacs-devel

Dmitry Gutov <dgutov@yandex.ru> writes:

> On 07/23/2015 11:54 PM, Stephen Leake wrote:
>
>> So I have to change code like this:
>>
>> (let (branch-list
>>        ...)
>>     (add-to-list branch-list (substring branch-entry 2) t)
>>
>>
>> to:
>>
>> (defvar dvc-branch-list);; add-to-list can't use lexical var
>> (let (
>>        ...)
>>     (add-to-list 'dvc-branch-list (substring branch-entry 2) t)
>
> You should use `push'. Or maybe `cl-pushnew'.

Except that 't' means add at tail, not at head. Is there a cl-* for
that? I only found 'cl-revappend'.

I can use 'append', followed by 'delete-dups'.

-- 
-- Stephe



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

* Re: need for 'dynamical-let'?
  2015-07-24  8:16   ` Stephen Leake
@ 2015-07-24  9:38     ` Dmitry Gutov
  0 siblings, 0 replies; 16+ messages in thread
From: Dmitry Gutov @ 2015-07-24  9:38 UTC (permalink / raw)
  To: Stephen Leake, emacs-devel

On 07/24/2015 11:16 AM, Stephen Leake wrote:

> Except that 't' means add at tail, not at head. Is there a cl-* for
> that? I only found 'cl-revappend'.

I don't know the code you're editing, but I haven't had a need for that. 
Instead, in similar situations, I `push' in a loop, and do a (setq foo 
(nreverse foo)) in the end.

> I can use 'append', followed by 'delete-dups'.

That's also an option.



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

* Re: need for 'dynamical-let'?
  2015-07-23 20:54 need for 'dynamical-let'? Stephen Leake
                   ` (2 preceding siblings ...)
  2015-07-24  4:23 ` Stephen J. Turnbull
@ 2015-07-24 16:54 ` Dmitri Paduchikh
  2015-07-25  6:41   ` Dmitri Paduchikh
  2015-07-24 23:32 ` Stefan Monnier
  4 siblings, 1 reply; 16+ messages in thread
From: Dmitri Paduchikh @ 2015-07-24 16:54 UTC (permalink / raw)
  To: Stephen Leake; +Cc: emacs-devel

Stephen Leake <stephen_leake@stephe-leake.org> writes:

SL> Can we define a macro 'dynamical-let' that would implement this
SL> pattern, but with hidden variables?

Not sure about pattern with hidden variables, but `dynamical-let' which
would always establish dynamic binding will be useful for writing macros.
Currently, if I understand right, expansion of the macro

(defmacro foo ()
  '(let ((some-variable t))
     (bar)))

is treated differently depending on the current value of `lexical-binding':
the macro will create lexical binding where this variable is t, and dynamic
binding otherwise. This is bad as it can easily introduce unintended
behavior changes to code. `dynamical-let' would provide some control to
macro writers. Natively supported `lexical-let' would be also good to have.
But may be give them somewhat shorter names.



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

* Re: need for 'dynamical-let'?
  2015-07-23 20:54 need for 'dynamical-let'? Stephen Leake
                   ` (3 preceding siblings ...)
  2015-07-24 16:54 ` Dmitri Paduchikh
@ 2015-07-24 23:32 ` Stefan Monnier
  4 siblings, 0 replies; 16+ messages in thread
From: Stefan Monnier @ 2015-07-24 23:32 UTC (permalink / raw)
  To: Stephen Leake; +Cc: emacs-devel

> (let (branch-list
>       ...)
>    (add-to-list 'branch-list (substring branch-entry 2) t)

This is butt-ugly and ridiculously inefficient.
In such code, don't use add-to-list (which is OK for configuring
global vars, but not for such situations) and don't use the t argument
which makes the operation O(N).
As Dmitry says, using `push' or `cl-pushnew', and if need the object in
some other order, re-order them later, e.g. with nreverse.


        Stefan



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

* Re: need for 'dynamical-let'?
  2015-07-24 16:54 ` Dmitri Paduchikh
@ 2015-07-25  6:41   ` Dmitri Paduchikh
  2015-07-25 22:22     ` Stefan Monnier
  0 siblings, 1 reply; 16+ messages in thread
From: Dmitri Paduchikh @ 2015-07-25  6:41 UTC (permalink / raw)
  To: emacs-devel; +Cc: Stephen Leake

It seems that the situation with advices even worse than with macros. As
I understand it, the code of advice may be compiled at runtime but it is
unknown in what context compilation will be done. There is even no
expansion point for it, so it seems that compilation is done in a
completely random environment. Nothing can be said about value of
`lexical-binding' and set of defvars. Not sure that my understanding is
correct though.



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

* Re: need for 'dynamical-let'?
  2015-07-25  6:41   ` Dmitri Paduchikh
@ 2015-07-25 22:22     ` Stefan Monnier
  2015-07-26  0:02       ` Dmitri Paduchikh
  0 siblings, 1 reply; 16+ messages in thread
From: Stefan Monnier @ 2015-07-25 22:22 UTC (permalink / raw)
  To: Dmitri Paduchikh; +Cc: Stephen Leake, emacs-devel

> It seems that the situation with advices even worse than with macros. As
> I understand it, the code of advice may be compiled at runtime but it is
> unknown in what context compilation will be done.

That's true for old-style `defadvice', but not for new-style
`advice-add'.


        Stefan



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

* Re: need for 'dynamical-let'?
  2015-07-25 22:22     ` Stefan Monnier
@ 2015-07-26  0:02       ` Dmitri Paduchikh
  2015-07-26  6:51         ` Stefan Monnier
  2015-07-26 15:37         ` raman
  0 siblings, 2 replies; 16+ messages in thread
From: Dmitri Paduchikh @ 2015-07-26  0:02 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Stephen Leake, emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> It seems that the situation with advices even worse than with macros. As
>> I understand it, the code of advice may be compiled at runtime but it is
>> unknown in what context compilation will be done.

SM> That's true for old-style `defadvice', but not for new-style
SM> `advice-add'.

Understood. Is it planned to obsolete `defadvice'?



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

* Re: need for 'dynamical-let'?
  2015-07-26  0:02       ` Dmitri Paduchikh
@ 2015-07-26  6:51         ` Stefan Monnier
  2015-07-26  8:17           ` Dmitri Paduchikh
  2015-07-26 15:37         ` raman
  1 sibling, 1 reply; 16+ messages in thread
From: Stefan Monnier @ 2015-07-26  6:51 UTC (permalink / raw)
  To: Dmitri Paduchikh; +Cc: Stephen Leake, emacs-devel

>>> It seems that the situation with advices even worse than with macros. As
>>> I understand it, the code of advice may be compiled at runtime but it is
>>> unknown in what context compilation will be done.
SM> That's true for old-style `defadvice', but not for new-style
SM> `advice-add'.
> Understood. Is it planned to obsolete `defadvice'?

Yes,


        Stefan



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

* Re: need for 'dynamical-let'?
  2015-07-26  6:51         ` Stefan Monnier
@ 2015-07-26  8:17           ` Dmitri Paduchikh
  0 siblings, 0 replies; 16+ messages in thread
From: Dmitri Paduchikh @ 2015-07-26  8:17 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Stephen Leake, emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>>>> It seems that the situation with advices even worse than with macros. As
>>>> I understand it, the code of advice may be compiled at runtime but it is
>>>> unknown in what context compilation will be done.
SM>>> That's true for old-style `defadvice', but not for new-style
SM>>> `advice-add'.
>> Understood. Is it planned to obsolete `defadvice'?
SM> Yes,

Ah, thank you for clarifications.



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

* Re: need for 'dynamical-let'?
  2015-07-26  0:02       ` Dmitri Paduchikh
  2015-07-26  6:51         ` Stefan Monnier
@ 2015-07-26 15:37         ` raman
  1 sibling, 0 replies; 16+ messages in thread
From: raman @ 2015-07-26 15:37 UTC (permalink / raw)
  To: Dmitri Paduchikh; +Cc: Stephen Leake, Stefan Monnier, emacs-devel

Please dont obsolete defadvice yet  -- emacspeak is entirely written in
defadvice, and even if we were to verify that the new advice mechanism
lets it do everything it does with defadvice, rewriting it in terms of
nadvice would be a large project in of its own. 
-- 



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

end of thread, other threads:[~2015-07-26 15:37 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-23 20:54 need for 'dynamical-let'? Stephen Leake
2015-07-23 20:58 ` Stephen Leake
2015-07-23 21:03 ` Dmitry Gutov
2015-07-24  8:16   ` Stephen Leake
2015-07-24  9:38     ` Dmitry Gutov
2015-07-24  4:23 ` Stephen J. Turnbull
2015-07-24  4:40   ` David Kastrup
2015-07-24  7:58   ` Stephen Leake
2015-07-24 16:54 ` Dmitri Paduchikh
2015-07-25  6:41   ` Dmitri Paduchikh
2015-07-25 22:22     ` Stefan Monnier
2015-07-26  0:02       ` Dmitri Paduchikh
2015-07-26  6:51         ` Stefan Monnier
2015-07-26  8:17           ` Dmitri Paduchikh
2015-07-26 15:37         ` raman
2015-07-24 23:32 ` Stefan Monnier

Code repositories for project(s) associated with this public inbox

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

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