unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* defvar without value
@ 2020-04-01  0:03 Michael Heerdegen
  2020-04-01  0:36 ` Drew Adams
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Michael Heerdegen @ 2020-04-01  0:03 UTC (permalink / raw)
  To: Emacs Development

Hello,

Using `defvar' (on top-level) without specifying a value differs in two
ways from calls that specify a value: (1) the variable's value is not
set, and (2) the variable is made special only in the context of the
(rest of the) current file or buffer.

I wonder if it is good that these two things are chained together, and
if there are alternatives to what we have now.  Latest changes have
revealed that in some cases, people wanted (1) to always get compiler
warnings when a variable is not explicitly bound, but they didn't intend
that the variable is not always special.  Dunno to how many people this
happened, but it is a kind of pitfall.


TIA,

Michael.



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

* RE: defvar without value
  2020-04-01  0:03 defvar without value Michael Heerdegen
@ 2020-04-01  0:36 ` Drew Adams
  2020-04-01  0:59 ` Stefan Monnier
  2020-04-01  1:21 ` Noam Postavsky
  2 siblings, 0 replies; 14+ messages in thread
From: Drew Adams @ 2020-04-01  0:36 UTC (permalink / raw)
  To: Michael Heerdegen, Emacs Development

> Using `defvar' (on top-level) without specifying a value differs in two
> ways from calls that specify a value: (1) the variable's value is not
> set, and (2) the variable is made special only in the context of the
> (rest of the) current file or buffer.
> 
> I wonder if it is good that these two things are chained together, and
> if there are alternatives to what we have now.  Latest changes have
> revealed that in some cases, people wanted (1) to always get compiler
> warnings when a variable is not explicitly bound, but they didn't
> intend
> that the variable is not always special.  Dunno to how many people this
> happened, but it is a kind of pitfall.

I've thought the same thing.  I don't see a logical connection.  If that's right then linking them is a bit ugly.

For one thing, it seems wrong that the only way to proclaim that a variable is to special globally is to give it a defvar default value.



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

* Re: defvar without value
  2020-04-01  0:03 defvar without value Michael Heerdegen
  2020-04-01  0:36 ` Drew Adams
@ 2020-04-01  0:59 ` Stefan Monnier
  2020-04-01 22:45   ` Michael Heerdegen
  2020-04-01  1:21 ` Noam Postavsky
  2 siblings, 1 reply; 14+ messages in thread
From: Stefan Monnier @ 2020-04-01  0:59 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: Emacs Development

> Using `defvar' (on top-level) without specifying a value differs in two
> ways from calls that specify a value: (1) the variable's value is not
> set, and (2) the variable is made special only in the context of the
> (rest of the) current file or buffer.
>
> I wonder if it is good that these two things are chained together, and
> if there are alternatives to what we have now.

I guess we could add something like (defvar-dynamic VAR) which sets the
`special` bit on the variable, just like (defvar VAR VAL) does, but
leaves the variable's value unchanged (currently, you'd have to do
(progn (defvar VAR 'dummy) (makunbound 'VAR)) to get a similar effect).

Similarly, we could add something like (defvar-lexical VAR VAL) which
defines the var and sets it but doesn't set the `special` bit
(currently, we have `internal-make-var-non-special` to serve the same
need).


        Stefan




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

* Re: defvar without value
  2020-04-01  0:03 defvar without value Michael Heerdegen
  2020-04-01  0:36 ` Drew Adams
  2020-04-01  0:59 ` Stefan Monnier
@ 2020-04-01  1:21 ` Noam Postavsky
  2020-04-01  1:53   ` Michael Heerdegen
  2 siblings, 1 reply; 14+ messages in thread
From: Noam Postavsky @ 2020-04-01  1:21 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: Emacs Development

On Tue, 31 Mar 2020 at 20:09, Michael Heerdegen
<michael_heerdegen@web.de> wrote:

> (1) the variable's value is not set

> people wanted (1) to always get compiler
> warnings when a variable is not explicitly bound,

s/compiler warnings/runtime errors/? I can't see how the compiler
could give warnings for this situation without overwhelmingly too many
false positives.



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

* Re: defvar without value
  2020-04-01  1:21 ` Noam Postavsky
@ 2020-04-01  1:53   ` Michael Heerdegen
  0 siblings, 0 replies; 14+ messages in thread
From: Michael Heerdegen @ 2020-04-01  1:53 UTC (permalink / raw)
  To: Noam Postavsky; +Cc: Emacs Development

Noam Postavsky <npostavs@gmail.com> writes:

> > people wanted (1) to always get compiler
> > warnings when a variable is not explicitly bound,
>
> s/compiler warnings/runtime errors/?

I guess, yes, maybe I remembered wrong.  But it's probably still a valid
use case.

Michael.



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

* Re: defvar without value
  2020-04-01  0:59 ` Stefan Monnier
@ 2020-04-01 22:45   ` Michael Heerdegen
  2020-04-02  2:37     ` Stefan Monnier
  0 siblings, 1 reply; 14+ messages in thread
From: Michael Heerdegen @ 2020-04-01 22:45 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Emacs Development

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

> I guess we could add something like (defvar-dynamic VAR) which sets the
> `special` bit on the variable, just like (defvar VAR VAL) does, but
> leaves the variable's value unchanged (currently, you'd have to do
> (progn (defvar VAR 'dummy) (makunbound 'VAR)) to get a similar
> effect).

Yes, I guess that would be nice... we/you/someone wanted to add `fluid-let'
(i.e. a dynamically binding `let') anyway.  I guess this can all be done
at once.

> Similarly, we could add something like (defvar-lexical VAR VAL) which
> defines the var and sets it but doesn't set the `special` bit

Uses of that exceed my current imagination.  Ah, ok, following
(top-level) defuns would become closures referencing the VAR
automatically, right?

Michael.



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

* Re: defvar without value
  2020-04-01 22:45   ` Michael Heerdegen
@ 2020-04-02  2:37     ` Stefan Monnier
  2020-04-09  1:52       ` Michael Heerdegen
  0 siblings, 1 reply; 14+ messages in thread
From: Stefan Monnier @ 2020-04-02  2:37 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: Emacs Development

> we/you/someone wanted to add `fluid-let'
> (i.e. a dynamically binding `let') anyway.

It's in `master`, called `dlet`, but it's orthogonal to `defvar-dynamic`.

>> Similarly, we could add something like (defvar-lexical VAR VAL) which
>> defines the var and sets it but doesn't set the `special` bit
> Uses of that exceed my current imagination.

How quickly one gets used to the idea of dynamic scoping, eh?

    % grep internal-make-var-non-special **/*.el
    lisp/emacs-lisp/float-sup.el:(internal-make-var-non-special 'pi)
    lisp/startup.el:(internal-make-var-non-special 'argv)
    lisp/startup.el:(internal-make-var-non-special 'argi)
    %


-- Stefan




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

* Re: defvar without value
  2020-04-02  2:37     ` Stefan Monnier
@ 2020-04-09  1:52       ` Michael Heerdegen
  2020-04-09  2:04         ` Emanuel Berg via Emacs development discussions.
  2020-04-09  2:20         ` Stefan Monnier
  0 siblings, 2 replies; 14+ messages in thread
From: Michael Heerdegen @ 2020-04-09  1:52 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Emacs Development

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

> > we/you/someone wanted to add `fluid-let'
> > (i.e. a dynamically binding `let') anyway.
>
> It's in `master`, called `dlet`, but it's orthogonal to
> `defvar-dynamic`.

Ah - ok, this has already been added.  Eh - why again is there only
`dlet' expanding `let*' and no parallel version?

Michael.



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

* Re: defvar without value
  2020-04-09  1:52       ` Michael Heerdegen
@ 2020-04-09  2:04         ` Emanuel Berg via Emacs development discussions.
  2020-04-09  2:20         ` Stefan Monnier
  1 sibling, 0 replies; 14+ messages in thread
From: Emanuel Berg via Emacs development discussions. @ 2020-04-09  2:04 UTC (permalink / raw)
  To: emacs-devel

Michael Heerdegen wrote:

>>> we/you/someone wanted to add `fluid-let' (i.e.
>>> a dynamically binding `let') anyway. It's in
>>> `master`, called `dlet`, but it's orthogonal to
>>> `defvar-dynamic`.
>
> Ah - ok, this has already been added. Eh - why again is
> there only `dlet' expanding `let*' and no
> parallel version?

Does `let' really do that anyway?

-- 
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal




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

* Re: defvar without value
  2020-04-09  1:52       ` Michael Heerdegen
  2020-04-09  2:04         ` Emanuel Berg via Emacs development discussions.
@ 2020-04-09  2:20         ` Stefan Monnier
  2020-04-09 23:34           ` Emanuel Berg via Emacs development discussions.
  2020-04-10 21:57           ` Michael Heerdegen
  1 sibling, 2 replies; 14+ messages in thread
From: Stefan Monnier @ 2020-04-09  2:20 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: Emacs Development

> Ah - ok, this has already been added.  Eh - why again is there only
> `dlet' expanding `let*' and no parallel version?

In my experience it's very rare to need the "parallel" version.


        Stefan




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

* Re: defvar without value
  2020-04-09  2:20         ` Stefan Monnier
@ 2020-04-09 23:34           ` Emanuel Berg via Emacs development discussions.
  2020-04-10 15:20             ` Bruno Félix Rezende Ribeiro
  2020-04-10 21:57           ` Michael Heerdegen
  1 sibling, 1 reply; 14+ messages in thread
From: Emanuel Berg via Emacs development discussions. @ 2020-04-09 23:34 UTC (permalink / raw)
  To: emacs-devel

Stefan Monnier wrote:

>> Ah - ok, this has already been added. Eh - why again
>> is there only `dlet' expanding `let*' and no
>> parallel version?
>
> In my experience it's very rare to need the
> "parallel" version.

You mean in this (dynamic) case, or never?

The supposedly parallel version isn't needed in my
experience if there is `let*', which there is, _but_ the
minimalist attitude of programming will make it look
wierd - hey, why is let* here, when there is no
dependent binding?

Maybe `let' will truly be parallel one day and then all
old software keeping a strict division between let and
let* will be rewarded :)

BOOM ... and they are just gone

-- 
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal




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

* Re: defvar without value
  2020-04-09 23:34           ` Emanuel Berg via Emacs development discussions.
@ 2020-04-10 15:20             ` Bruno Félix Rezende Ribeiro
  2020-04-10 23:07               ` Emanuel Berg via Emacs development discussions.
  0 siblings, 1 reply; 14+ messages in thread
From: Bruno Félix Rezende Ribeiro @ 2020-04-10 15:20 UTC (permalink / raw)
  To: emacs-devel

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

Hi Emanuel,

Emanuel Berg via "Emacs development discussions." <emacs-devel@gnu.org>
writes:

> The supposedly parallel version isn't needed in my experience if there
> is `let*' [...] Maybe `let' will truly be parallel one day [...]

That’s not the only use of ‘let’, because it’s not a weaker form of
‘let*’ as one might first think.  Both are fundamentally different in
their operation and ‘let’ is indeed parallel in some strict theoretical
sense, in the same way ‘let*’ is sequential in the same sense.  Both
forms coincide in effect only in the trivial case: when there is no
reference to (textually) earlier variables being bound in the subsequent
forms being evaluated to obtain the values to be bound to the later
ones.

For instance consider the difference between

#+BEGIN_SRC elisp
  (let ((x 0))
    (let ((x (1- x))
          (y (1+ x)))
      (cons x y)))
#+END_SRC

and 

#+BEGIN_SRC elisp
  (let ((x 0))
    (let* ((x (1- x))
           (y (1+ x)))
      (cons x y)))
#+END_SRC

The former evaluates to ~(-1 . 1)~ while the latter to ~(-1 . 0)~.  Both
are valid expressions with sensible behavior and are not
interchangeable.  The answer to which one to use does *not* follow from
the criterion: “are the variables to be bound interdependent?”, since in
both cases they are (and the behavior is different).  The real question
to answer is: “should they be bound in sequence or in parallel?”


-- 
Bruno Félix Rezende Ribeiro (oitofelix) [0x28D618AF]
<http://oitofelix.freeshell.org/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 487 bytes --]

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

* Re: defvar without value
  2020-04-09  2:20         ` Stefan Monnier
  2020-04-09 23:34           ` Emanuel Berg via Emacs development discussions.
@ 2020-04-10 21:57           ` Michael Heerdegen
  1 sibling, 0 replies; 14+ messages in thread
From: Michael Heerdegen @ 2020-04-10 21:57 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Emacs Development

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

> > Ah - ok, this has already been added.  Eh - why again is there only
> > `dlet' expanding `let*' and no parallel version?
>
> In my experience it's very rare to need the "parallel" version.

If you are not 100% sure that we will never want it, I guess it would
make sense to rename the new macro to `dlet*' now so that if we ever
want a parallel version we don't have to call it `dlet*' then.

Michael.



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

* Re: defvar without value
  2020-04-10 15:20             ` Bruno Félix Rezende Ribeiro
@ 2020-04-10 23:07               ` Emanuel Berg via Emacs development discussions.
  0 siblings, 0 replies; 14+ messages in thread
From: Emanuel Berg via Emacs development discussions. @ 2020-04-10 23:07 UTC (permalink / raw)
  To: emacs-devel

Bruno Félix Rezende Ribeiro wrote:

>> The supposedly parallel version isn't needed in my
>> experience if there is `let*' [...] Maybe `let' will
>> truly be parallel one day [...]
>
> That’s not the only use of ‘let’, because it’s not
> a weaker form of ‘let*’ as one might first think.
> Both are fundamentally different in their operation
> and ‘let’ is indeed parallel in some strict
> theoretical sense, in the same way ‘let*’ is
> sequential in the same sense. Both forms coincide in
> effect only in the trivial case: when there is no
> reference to (textually) earlier variables being bound
> in the subsequent forms being evaluated to obtain the
> values to be bound to the later ones.

OK, but then the trivial case is the sound one.
Reusing names in `let' bindings is like asking for
trouble. The only exception is when one temporarily
wants to have the old variable another value in another,
remote function. But then it should be super simple,
just assign the new value and invoke the function, and
snap back to normal.

> For instance consider the difference between
>
> #+BEGIN_SRC elisp
>   (let ((x 0))
>     (let ((x (1- x))
>           (y (1+ x)))
>       (cons x y)))
> #+END_SRC
>
> and 
>
> #+BEGIN_SRC elisp
>   (let ((x 0))
>     (let* ((x (1- x))
>            (y (1+ x)))
>       (cons x y)))
> #+END_SRC
>
> The former evaluates to ~(-1 . 1)~ while the latter to
> ~(-1 . 0)~. Both are valid expressions with sensible
> behavior and are not interchangeable. The answer to
> which one to use does *not* follow from the criterion:
> “are the variables to be bound interdependent?”, since
> in both cases they are (and the behavior is
> different).

Well... IMO your example does not demonstrate one being
parallel and one being sequential as much as it is a way
of telling what x is refered to.

And there is a better way to do that, namely calling the
variables different things. And then:

(let ((x 0))
  (let ((a (1- x))
        (y (1+ a)) )
    (cons a y) )) ; DNC

But:

(let*((x 0)
      (a (1- x))
      (y (1+ x)) )
  (cons a y) ) ; (-1 . 1)

-- 
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal




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

end of thread, other threads:[~2020-04-10 23:07 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-01  0:03 defvar without value Michael Heerdegen
2020-04-01  0:36 ` Drew Adams
2020-04-01  0:59 ` Stefan Monnier
2020-04-01 22:45   ` Michael Heerdegen
2020-04-02  2:37     ` Stefan Monnier
2020-04-09  1:52       ` Michael Heerdegen
2020-04-09  2:04         ` Emanuel Berg via Emacs development discussions.
2020-04-09  2:20         ` Stefan Monnier
2020-04-09 23:34           ` Emanuel Berg via Emacs development discussions.
2020-04-10 15:20             ` Bruno Félix Rezende Ribeiro
2020-04-10 23:07               ` Emanuel Berg via Emacs development discussions.
2020-04-10 21:57           ` Michael Heerdegen
2020-04-01  1:21 ` Noam Postavsky
2020-04-01  1:53   ` Michael Heerdegen

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