zsh-workers
 help / color / mirror / code / Atom feed
* Anonymous function syntax and "sh" emulation
@ 2015-08-21  4:16 Bart Schaefer
  2015-08-21 14:52 ` Peter Stephenson
  0 siblings, 1 reply; 4+ messages in thread
From: Bart Schaefer @ 2015-08-21  4:16 UTC (permalink / raw)
  To: zsh-workers

This works in both zsh and sh emulation:

  () { print hello; }

So does this:

  function () { print hello; }

This works in zsh emulation but not in sh emulation:

  function { print hello; }

The error is "parse error near `}'".  If you write it as

  function {
    print hello
  }

then the error is "parse error near `print'".  Since this is the example
syntax in the "Anonymous Functions" subsection of the manual, it seems
that it either ought to work, or there ought to be a warning.


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

* Re: Anonymous function syntax and "sh" emulation
  2015-08-21  4:16 Anonymous function syntax and "sh" emulation Bart Schaefer
@ 2015-08-21 14:52 ` Peter Stephenson
  2015-08-21 15:29   ` Bart Schaefer
  0 siblings, 1 reply; 4+ messages in thread
From: Peter Stephenson @ 2015-08-21 14:52 UTC (permalink / raw)
  To: zsh-workers

On Thu, 20 Aug 2015 21:16:38 -0700
Bart Schaefer <schaefer@brasslantern.com> wrote:
> This works in zsh emulation but not in sh emulation:
> 
>   function { print hello; }

This is a combination of two effects.

The one specific to sh is, as you might guess, IGNOREBRACES.  Clearly
we're not supposed to ignore a brace as the start of a function, so I
think this can be considered a bug.  I think compensating for this is
unproblematic, since we see the raw string input coming from lex.c and
hence any quoting that should stop this being treated as the start of a
function, so I've done that.

What's worried me is the other part of the effect, which isn't specific
to sh emulation, which is that the first word after "function" is
treated as not a command word, while the remaining words are treated as
command words:

% alias first='fn1 fn2' second='fn3 fn4'
% function first second { print This is a function; }
% functions first fn3 fn4
first () {
	print This is a function
}
fn3 () {
	print This is a function
}
fn4 () {
	print This is a function
}

I would hazard a guess this is a bad thing, which hasn't been noticed
because multiple words after "function" aren't very common.

More tentatively, I suspect it may have been a trick to get the shell to
cough up an INBRACE before we had the test I've just patched below.  So
I suspect we can just move the "incmdpos = 1" until after we've found
something that is either not a STRING or a possibly tokenized "{".  Not
included in the patch below, but I'll do it unless anyone contradicts.
Does not cause any tests to fail.

pws

diff --git a/Src/parse.c b/Src/parse.c
index 1a74164..c2dcd2b 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -1602,7 +1602,8 @@ par_funcdef(int *cmplx)
 
     incmdpos = 1;
     while (tok == STRING) {
-	if (*tokstr == Inbrace && !tokstr[1]) {
+	if ((*tokstr == Inbrace || *tokstr == '{') &&
+	    !tokstr[1]) {
 	    tok = INBRACE;
 	    break;
 	}


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

* Re: Anonymous function syntax and "sh" emulation
  2015-08-21 14:52 ` Peter Stephenson
@ 2015-08-21 15:29   ` Bart Schaefer
  2015-08-21 16:03     ` Peter Stephenson
  0 siblings, 1 reply; 4+ messages in thread
From: Bart Schaefer @ 2015-08-21 15:29 UTC (permalink / raw)
  To: zsh-workers

On Aug 21,  3:52pm, Peter Stephenson wrote:
}
} What's worried me is the other part of the effect, which isn't specific
} to sh emulation, which is that the first word after "function" is
} treated as not a command word, while the remaining words are treated as
} command words:
} 
} I would hazard a guess this is a bad thing, which hasn't been noticed
} because multiple words after "function" aren't very common.

This is especially interesting in that exactly the opposite happens when
defining multiple functions WITHOUT the "function" keyword:

torch% alias first='fn1 fn2' second='fn3 fn4'
torch% first second () { print $0 }
torch% functions
fn1 () {
        print $0
}
fn2 () {
        print $0
}
second () {
        print $0
}


} I suspect we can just move the "incmdpos = 1" until after we've found
} something that is either not a STRING or a possibly tokenized "{".  Not
} included in the patch below, but I'll do it unless anyone contradicts.

I would say that prefixing with "function" is a good workaround for the
function/alias conflict (maybe even update FAQ 2.3 to describe this),
so it is good if none of the words are treated as command aliases.


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

* Re: Anonymous function syntax and "sh" emulation
  2015-08-21 15:29   ` Bart Schaefer
@ 2015-08-21 16:03     ` Peter Stephenson
  0 siblings, 0 replies; 4+ messages in thread
From: Peter Stephenson @ 2015-08-21 16:03 UTC (permalink / raw)
  To: zsh-workers

Test.

diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst
index 74f8815..4721e09 100644
--- a/Test/C04funcdef.ztst
+++ b/Test/C04funcdef.ztst
@@ -295,6 +295,19 @@
 >}
 >This is the correct output.
 
+ unfunction command_not_found_handler # amusing but unhelpful
+ alias first='firstfn1 firstfn2' second='secondfn1 secondfn2'
+ function first second { print This is function $0; }
+ first
+ second
+ firstfn1
+ secondfn1
+127:No alias expansion after "function" keyword
+>This is function first
+>This is function second
+?(eval):6: command not found: firstfn1
+?(eval):7: command not found: secondfn1
+
 %clean
 
  rm -f file.in file.out


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

end of thread, other threads:[~2015-08-21 16:03 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-21  4:16 Anonymous function syntax and "sh" emulation Bart Schaefer
2015-08-21 14:52 ` Peter Stephenson
2015-08-21 15:29   ` Bart Schaefer
2015-08-21 16:03     ` 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).