Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Bug with unset variables

On Fri, Nov 13, 2020 at 2:52 AM Roman Perepelitsa
<roman.perepelitsa@xxxxxxxxx> wrote:
> On Thu, Nov 12, 2020 at 10:08 PM Felipe Contreras
> <felipe.contreras@xxxxxxxxx> wrote:
> >
> > On Thu, Nov 12, 2020 at 1:11 PM Roman Perepelitsa
> > <roman.perepelitsa@xxxxxxxxx> wrote:
> >>
> > > Note that these two snippets have different effect:
> > >
> > >   var foo
> > >
> > > and
> > >
> > >   var foo
> > >   delete foo
> > >
> > > Just line in zsh, and unlike ksh/bash.
> >
> > No. That code doesn't even work in JavaScript:
> I didn't realize you cannot unset variables in JavaScript. Then
> comparing it with shells isn't very useful.
> >  "unset foo" and "foo = undefined" do *exactly* the same thing
> `undefined` is just a value, so `foo = undefined` simply changes the
> value of foo. You can still pass foo around, just like you could do it
> if it held any other value. Unsetting a parameter in a shell is quite
> different. It's impossible to detect a difference between these two
> cases: 1) foo was never declared, and 2) foo was declared and
> subsequently unset. (At least in global scope. Shells differ w.r.t.
> local variables.)

The two things are functionally *exactly* the same.

In JavaScript if you don't declare foo, accessing it gives you the
value of "undefined", and if you declare it and "unset" it, it also
gives you "undefined". Exactly the same as in shell.

You just don't want to accept they are functionally the same because
you don't want them to be the same.

> We'll need another language that allows unsetting variables to have a
> meaningful comparison. How about elisp? As I mentioned earlier, it
> shares two important properties with ksh/bash/zsh -- dynamic typing
> and dynamic scope. In elisp declaring a variable and then unsetting it
> is not equivalent to just declaring a variable. Like in zsh and unlike
> ksh/bash.

Lisp doesn't allow defining variables without a value.

> > In JavaScript "var foo" does not set foo to an empty string.
> It sets *some* value, specifically `undefined`. In shells there is no
> such value, so assigning `undefined` is not an option.

Once again: a distinction without a difference.


> I don't think this discussion will affect anything of substance. I'm
> continuing merely out of politeness. You've asked why I consider the
> behavior of zsh natural and I'm doing my best to explain.

Yes, but you have avoided some of my strongest arguments, for example this:

  func () {
    [[ -n "$1" ]] && var=$1
    dosomething ${var-other}

  func () {
    typeset var
    [[ -n "$1" ]] && var=$1
    dosomething ${var-other}

You have never explained how it makes sense that adding that extra
line changes the behavior.

> I'm not arguing that what zsh does is
> objectively *more* natural, only that it's also consistent and has
> precedence in other languages (elisp).

And I've shown you how you are comparing apples to oranges.

> I think I've found a language that has constructs equivalent to
> typeset and unset with the same semantics as in ksh/bash. In Lua this
> snippet:
>   local x
>   x = nil
> Is equivalent to this:
>   local x
> Moreover, variables to which nil has been assigned are
> indistinguishable from variables that have never been declared.
> "Variable foo is nil" has the same meaning as "variable foo does not
> exist". Like in shells and unlike JavaScript.

Exactly the same thing as in JavaScript, just s/nil/undefined/.

Either way, "local x" in Lua does exactly the same thing as it does in Bash.

When you compare apples to apples the behavior is exactly the same in
all languages.


Felipe Contreras

Messages sorted by: Reverse Date, Date, Thread, Author