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

Re: Weird error message when using bash or ksh form of array initialization



Thanks folks for the explanation of what's happening.

It kind of strikes me as not a good language design when entering
similar valid constructs from a couple of other POSIX-compatible
shells causes such a damaging misinterpretation to take place. You say:

  typeset -a foo=()
  typeset -a sources

defines "typeset", "-a" and "foo=" as functions? Wow! I'd be hard
pressed to find many would would find that an advantage.

It reminds me of this example sometimes mentioned in the context of
Fortran. If one writes:

  DO 10 I=1.5
instead of
  DO 10 I=1,5

both are valid but mean very different things. The first sets variable
DO10I to 1.5 in one of the weird, but acceptable, ways. The second is
probably a much more common Fortran statement to start a loop.

I mention this because when you read about this with respect to
Fortran, it is not generally given in the context how this distinction
is a interesting thing that programmer should be aware of, or what a
great language Fortran is because it allows such things to be
confused. Rather it is given as a consequence of the weakness of some
language-design decisions.

In the context of zsh, we have one of the zsh function forms:

   word ... () [ term ] command

competing (and winning) with this erroneous statement:
   typeset -a xx=()

Given that the relevant function form used is zsh specific, it doesn't
strike me that the convenience this form allows outweighs the damage
of the consequences of its inadvertent misuse above.

Is it really that helpful to allow define several functions with the
same body? If so, there are other ways to do this.

Here are some simple solutions to make what's happening clearer, reduce
confusion and give a better error message.
   * change "command" to "compound command" above.
   * disallow the shared-body multiple function definition, i.e.
remove ... above
   * disallow that specific kind of function in ksh and bash emulation form
      since it isn't POSIX 1003.1 anyway.

Comments in line, but I think they say pretty much the same as above.

On Sun, Aug 24, 2008 at 4:32 PM, Bart Schaefer
<schaefer@xxxxxxxxxxxxxxxx> wrote:
> On Aug 24, 12:05pm, Rocky Bernstein wrote:
> }
> } When I run this (erroneous?) program:
> }
> }   typeset -a fd=()
>
> Zsh does not support that syntax;

I realize that. And IMHO I think it should support it when bash or ksh
emulation is in force ;-). But more troublesome is the fact that it gives
an error message that is probably going to be a bit puzzling to most
people who know ksh and bash, but zsh less so.

> typeset is a command, not a keyword,
> so its arguments are parsed like normal shell words, not like parameter
> assignments.

Um. Okay. "typeset" is not a reserved word in POSIX shell, bash or ksh
either. That in of itself is not a big problem. It is when it is combined
with this zsh-specific function definition form:

   word ... () [ term ] command

that we get bad karma. The above is not a POSIX 1003.1 function
form. The following is:

   fname() compound-command[io-redirect ...]
                ^^^^^^^^^^^^^

So changing "command" above to "compound command" would be enough to
give a more meaningful error message. There are other possibilities.

>
> As Mikael pointed out, the above syntax defines three functions, named
> "typeset", "-a", and "fd=", because the shell word "()" is a token that
> denotes that a function name precedes it and a function body follows.
>
> Quoting it as 'fd=()' like Mikael suggested would prevent the function
> definition interpretation, but produces the error "can't assign initial
> value for array".

I think it interesting that like zsh, Ruby does in fact does allow
function (or more appropriately, methods) to have a '=' suffix. But
where Ruby differs is that this allows for a semantic simplification
by allowing one to write something that looks like an assignment
statement when it is in fact a method call (usually setting an
instance variable).  Furthermore, there is syntactic sugar to allows
spaces around the equals. So in contrast, zsh allows  function
definitions with = suffixes, but other parts of the zsh language work
to not allow it the benefits it might otherwise have and that, for
example, that Ruby exploits.



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