zsh-workers
 help / color / mirror / code / Atom feed
* Re: syntax error with anonymous functions when an argument begins with (
@ 2011-07-31 14:17 Jilles Tjoelker
  2011-07-31 18:39 ` Peter Stephenson
  0 siblings, 1 reply; 7+ messages in thread
From: Jilles Tjoelker @ 2011-07-31 14:17 UTC (permalink / raw)
  To: zsh-workers

> [people want stuff like () { echo yay } (a|b)]

In fact, the closing brace may validly be followed by certain keywords
in older zsh, for example

  if :; then () { echo hi; } else () { echo bye; } fi

prints "hi" in zsh 4.3.12 from FreeBSD ports.

If a regular function definition is used, like

  if :; then f() { echo hi; } else f() { echo bye; } fi; f

then the construct is POSIX compliant and works in all shells I tried
(not including patched versions of zsh).

The same applies if the function definition contains a different kind of
compound command such as if, which is unusual but POSIX compliant and
portable. For example, between two "fi" keywords a space suffices.

(On the other hand, if another command follows, such as ... fi; if ...,
a separator is required.)

So I think that unfortunately passing arguments to anonymous functions
requires an uglier syntax to avoid breaking compatibility. In any case,
placing a keyword after a closing brace that is not an anonymous
function's main command is valid and should be recognized as such.

-- 
Jilles Tjoelker


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

* Re: syntax error with anonymous functions when an argument begins with (
  2011-07-31 14:17 syntax error with anonymous functions when an argument begins with ( Jilles Tjoelker
@ 2011-07-31 18:39 ` Peter Stephenson
  2011-08-08  4:29   ` Mikael Magnusson
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Stephenson @ 2011-07-31 18:39 UTC (permalink / raw)
  To: zsh-workers

On Sun, 31 Jul 2011 16:17:15 +0200
Jilles Tjoelker <jilles@stack.nl> wrote:
> > [people want stuff like () { echo yay } (a|b)]
> 
> In fact, the closing brace may validly be followed by certain keywords
> in older zsh, for example
> 
>   if :; then () { echo hi; } else () { echo bye; } fi
> 
> prints "hi" in zsh 4.3.12 from FreeBSD ports.

You're quite right that this used to behave like if-then-else in 4.3.12
and now no longer does.

However, I don't think it's a problem that anonoymous functions work
differently from other functions: they're a new feature in recent
(theoretically unstable) versions of zsh and we can define them to work
however seems convenient.  If arguments are more useful than the
abbreviated syntax above, we can use them, suitably documented.  If
people really prefer the strict compatibility with other function
syntax, we are, as you say, stuck.  Personally, I think the function
syntax with keywords immediately following is screwy enough I don't feel
the need to follow it for anonymous functions.

But your point that we need to be careful with incompatibilities in
other cases is certainly a good one regardless of the above.  Luckily we
can see very early if the syntax is for an anonymous function, so I
think that's relatively straightforward, as follows (obviously, people
may see something I've missed).  (As we're looking for keywords, and "("
to start a subshell apparently isn't useful at this point, in fact I
hadn't broken anything I know to be correct --- but it's easy to be
safe.)

Index: Doc/Zsh/func.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/func.yo,v
retrieving revision 1.28
diff -p -u -r1.28 func.yo
--- Doc/Zsh/func.yo	19 Jun 2011 20:12:00 -0000	1.28
+++ Doc/Zsh/func.yo	31 Jul 2011 18:32:26 -0000
@@ -162,8 +162,15 @@ is not stored for future use.  The funct
 
 Arguments to the function may be specified as words following the
 closing brace defining the function, hence if there are none no
-arguments (other than tt($0)) are set.  Note that this means
-the argument list of any enclosing script or function is hidden.
+arguments (other than tt($0)) are set.  This is a difference from the
+way other functions are parsed: normal function definitions may be
+followed by certain keywords such as `tt(else)' or `tt(fi)', which will
+be treated as arguments to anonymous functions, so that a newline or
+semicolon is needed to force keyword interpretation.
+
+Note also that the argument list of any enclosing script or function is
+hidden (as would be the case for any other function called at this
+point).
 
 Redirections may be applied to the anonymous function in the same manner as
 to a current-shell structure enclosed in braces.  The main use of anonymous
Index: Src/parse.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/parse.c,v
retrieving revision 1.89
diff -p -u -r1.89 parse.c
--- Src/parse.c	28 Jul 2011 09:20:27 -0000	1.89
+++ Src/parse.c	31 Jul 2011 18:32:26 -0000
@@ -1465,7 +1465,10 @@ par_funcdef(void)
 	    ecssub = oecssub;
 	    YYERRORV(oecused);
 	}
-	incmdpos = 0;
+	if (num == 0) {
+	    /* Anonymous function, possibly with arguments */
+	    incmdpos = 0;
+	}
 	zshlex();
     } else if (unset(SHORTLOOPS)) {
 	lineno += oldlineno;
@@ -1721,7 +1724,10 @@ par_simple(int *complex, int nr)
 		    ecssub = oecssub;
 		    YYERROR(oecused);
 		}
-		incmdpos = 0;
+		if (argc == 0) {
+		    /* Anonymous function, possibly with arguments */
+		    incmdpos = 0;
+		}
 		zshlex();
 	    } else {
 		int ll, sl, c = 0;
Index: Test/C04funcdef.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/C04funcdef.ztst,v
retrieving revision 1.9
diff -p -u -r1.9 C04funcdef.ztst
--- Test/C04funcdef.ztst	28 Jul 2011 09:20:07 -0000	1.9
+++ Test/C04funcdef.ztst	31 Jul 2011 18:32:26 -0000
@@ -245,6 +245,12 @@
 >empty
 >here
 
+  if true; then f() { echo foo1; } else f() { echo bar1; } fi; f
+  if false; then f() { echo foo2; } else f() { echo bar2; } fi; f
+0:Compatibility with other shells when not anonymous functions
+>foo1
+>bar2
+
 %clean
 
  rm -f file.in file.out
-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


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

* Re: syntax error with anonymous functions when an argument begins with (
  2011-07-31 18:39 ` Peter Stephenson
@ 2011-08-08  4:29   ` Mikael Magnusson
  2011-08-08  8:34     ` Peter Stephenson
  0 siblings, 1 reply; 7+ messages in thread
From: Mikael Magnusson @ 2011-08-08  4:29 UTC (permalink / raw)
  To: zsh-workers

On 31 July 2011 20:39, Peter Stephenson <p.w.stephenson@ntlworld.com> wrote:
> On Sun, 31 Jul 2011 16:17:15 +0200
> Jilles Tjoelker <jilles@stack.nl> wrote:
>> > [people want stuff like () { echo yay } (a|b)]
>>
>> In fact, the closing brace may validly be followed by certain keywords
>> in older zsh, for example
>>
>>   if :; then () { echo hi; } else () { echo bye; } fi
>>
>> prints "hi" in zsh 4.3.12 from FreeBSD ports.
>
> You're quite right that this used to behave like if-then-else in 4.3.12
> and now no longer does.

I actually had an anonymous function followed by 'done' in my .zshrc,
but when I tested the new zsh version there was no error since the
file was compiled. When I edited my .zshrc a week later though, zsh
reported errors on startup, which took me a couple of minutes to
figure out :). Is there a good reason to not stick on the
$ZSH_PATCHLEVEL on the version stored in .zwc files, assuming it's
stored as a string?

-- 
Mikael Magnusson


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

* Re: syntax error with anonymous functions when an argument begins with (
  2011-08-08  4:29   ` Mikael Magnusson
@ 2011-08-08  8:34     ` Peter Stephenson
  2011-08-08  8:40       ` Mikael Magnusson
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Stephenson @ 2011-08-08  8:34 UTC (permalink / raw)
  To: zsh-workers

On Mon, 8 Aug 2011 06:29:01 +0200
Mikael Magnusson <mikachu@gmail.com> wrote:
> I actually had an anonymous function followed by 'done' in my .zshrc,
> but when I tested the new zsh version there was no error since the
> file was compiled. When I edited my .zshrc a week later though, zsh
> reported errors on startup, which took me a couple of minutes to
> figure out :). Is there a good reason to not stick on the
> $ZSH_PATCHLEVEL on the version stored in .zwc files, assuming it's
> stored as a string?

What's supposed to happen is the version number of the wordcode gets
incremented, but I always forget.  I suspect that having to recompile on
everything committed to the archive would be too much, but as I don't
rely on compiled files I'm really just guessing.

-- 
Peter Stephenson <pws@csr.com>            Software Engineer
Tel: +44 (0)1223 692070                   Cambridge Silicon Radio Limited
Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK




Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog


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

* Re: syntax error with anonymous functions when an argument begins with (
  2011-08-08  8:34     ` Peter Stephenson
@ 2011-08-08  8:40       ` Mikael Magnusson
  0 siblings, 0 replies; 7+ messages in thread
From: Mikael Magnusson @ 2011-08-08  8:40 UTC (permalink / raw)
  To: zsh-workers

On 8 August 2011 10:34, Peter Stephenson <Peter.Stephenson@csr.com> wrote:
> On Mon, 8 Aug 2011 06:29:01 +0200
> Mikael Magnusson <mikachu@gmail.com> wrote:
>> I actually had an anonymous function followed by 'done' in my .zshrc,
>> but when I tested the new zsh version there was no error since the
>> file was compiled. When I edited my .zshrc a week later though, zsh
>> reported errors on startup, which took me a couple of minutes to
>> figure out :). Is there a good reason to not stick on the
>> $ZSH_PATCHLEVEL on the version stored in .zwc files, assuming it's
>> stored as a string?
>
> What's supposed to happen is the version number of the wordcode gets
> incremented, but I always forget.  I suspect that having to recompile on
> everything committed to the archive would be too much, but as I don't
> rely on compiled files I'm really just guessing.

It doesn't really take that long to recompile everything, but I guess
it would be a bit annoying if you have long-running shells, as those
would refuse to use .zwc files after you update... And in this case it
wasn't that the wordcode was incompatible, just that my error got
postponed until something actually had to reparse the .zshrc file. So
I guess the current way is fine :).

-- 
Mikael Magnusson


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

* Re: syntax error with anonymous functions when an argument begins with (
  2011-07-27 16:48 Mikael Magnusson
@ 2011-07-27 19:22 ` Peter Stephenson
  0 siblings, 0 replies; 7+ messages in thread
From: Peter Stephenson @ 2011-07-27 19:22 UTC (permalink / raw)
  To: zsh workers

I think the fact the shell parses the token immediately after the "}" as
a command word is an accident; for a real command to follow, we'd need a
separator, just as with the end of a simple command line.  Anyway,
resetting the flags seems to work.

Index: Src/parse.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/parse.c,v
retrieving revision 1.88
diff -p -u -r1.88 parse.c
--- Src/parse.c	19 Jun 2011 20:12:00 -0000	1.88
+++ Src/parse.c	27 Jul 2011 18:30:44 -0000
@@ -1465,6 +1465,7 @@ par_funcdef(void)
 	    ecssub = oecssub;
 	    YYERRORV(oecused);
 	}
+	incmdpos = 0;
 	zshlex();
     } else if (unset(SHORTLOOPS)) {
 	lineno += oldlineno;
@@ -1720,6 +1721,7 @@ par_simple(int *complex, int nr)
 		    ecssub = oecssub;
 		    YYERROR(oecused);
 		}
+		incmdpos = 0;
 		zshlex();
 	    } else {
 		int ll, sl, c = 0;
Index: Test/C04funcdef.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/C04funcdef.ztst,v
retrieving revision 1.8
diff -p -u -r1.8 C04funcdef.ztst
--- Test/C04funcdef.ztst	19 Jun 2011 20:12:00 -0000	1.8
+++ Test/C04funcdef.ztst	27 Jul 2011 18:30:44 -0000
@@ -1,3 +1,8 @@
+%prep
+
+  mkdir funcdef.tmp
+  cd funcdef.tmp
+
 %test
 
   fn1() { return 1; }
@@ -228,6 +233,18 @@
 >	print Following bit
 >}
 
+  touch yes no
+  () { echo $1 } (y|z)*
+  (echo here)
+  () { echo $* } some (y|z)*
+  () { echo empty };(echo here)
+0:Anonymous function arguments and command arguments
+>yes
+>here
+>some yes
+>empty
+>here
+
 %clean
 
  rm -f file.in file.out


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

* syntax error with anonymous functions when an argument begins with (
@ 2011-07-27 16:48 Mikael Magnusson
  2011-07-27 19:22 ` Peter Stephenson
  0 siblings, 1 reply; 7+ messages in thread
From: Mikael Magnusson @ 2011-07-27 16:48 UTC (permalink / raw)
  To: zsh workers

% () { echo yay } hello (a|b)
zsh: parse error near `('
% () { echo yay } (a|b)
zsh: parse error near `('
% () { echo yay } .(#c0)(a|b)
yay
% () { echo yay } ./(a|b)
yay

-- 
Mikael Magnusson


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

end of thread, other threads:[~2011-08-08  8:40 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-31 14:17 syntax error with anonymous functions when an argument begins with ( Jilles Tjoelker
2011-07-31 18:39 ` Peter Stephenson
2011-08-08  4:29   ` Mikael Magnusson
2011-08-08  8:34     ` Peter Stephenson
2011-08-08  8:40       ` Mikael Magnusson
  -- strict thread matches above, loose matches on Subject: below --
2011-07-27 16:48 Mikael Magnusson
2011-07-27 19:22 ` Peter Stephenson

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

	https://git.vuxu.org/mirror/zsh/

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 NNTP newsgroup(s).