Subject: Re: zsh -n does not detect incorrect associative array declaration
From: Bart Schaefer <[email-masked]>
To: Zsh hackers list <[email-masked]>
Cc: Paul Wayper <[email-masked]>
Date: Tue, 22 Mar 2016 23:40:54 -0700
List-Id: Zsh Workers List <zsh-workers.zsh.org>

On Tue, Mar 22, 2016 at 7:28 PM, Paul Wayper <[email-masked]> wrote:
> On 23/03/16 11:20, Bart Schaefer wrote:
>>
>> Technically, the shell is ALSO prohibited by NO_EXEC from executing
>> the "typeset" command, and therefore can't possibly know that "fn"
>> represents an associative array in the first place.
>>
>> The NO_EXEC option is only useful for the most rudimentary of syntax
>> checks.  It cannot detect/predict execution-time inaccuracies.
>
> Given that situation, should we update the zsh manual to point out that
> the -n option cannot check the syntax of commands that are evaluated, so
> that this is more explicit?  I'd be happy to write such an update and
> push it if you'd prefer that.

I don't have a preference here, but I don't think there's any reason
for the zsh manual to be any more explicit than the manual for any
other shell; for example bash:

     -n      Read commands but do not execute them.  This may be used
             to check a shell script  for  syntax  errors.   This  is
             ignored by interactive shells.

> However, I don't see why you can't at least check that the syntax is
> correct for things that don't use evaluation.  That by far must be the
> majority of such cases.

There's nothing *syntactically* wrong with

fn=(foo_key foo_val bar_key)

Even when executing commands normally, the syntax analyzer does not
know that the assignment will fail if there are an odd number of
values in the list.  That's a semantic error discoverable only when
the assignment is performed.  The shell language is interpreted, not
truly compiled, so parameter type information is not used in syntax
analysis.  Plus, you're still ignoring the fact that the shell doesn't
know "fn" is associative because it was not allowed to interpret the
foregoing "typeset" command.

Aside:  In your original zsh_bad_array.zsh example you can tell that
it was a semantic/runtime error rather than a syntax error because
when the script was run WITHOUT "-n" the statements before and after
the bad assignment were still executed.  An actual syntax error would
have aborted the entire script, probably with a "parse error" printed
to stderr.

Contrast this with ksh where associative array assignments look like

fn=( [foo_key]=foo_val [bar_key]= )

There the parser doesn't need to know the type of fn because the
association is explicit in the format of the parenthesized list.  If
we ever get around to implementing that bit of ksh syntax your
assertion would become valid.  (But in that case the assignment
forcibly changes the type of "fn" to become an associative array so
the typeset is irrelevant.)