* Short loops? @ 1997-02-26 2:13 Bart Schaefer 1997-02-26 16:10 ` Zoltan T. Hidvegi 0 siblings, 1 reply; 10+ messages in thread From: Bart Schaefer @ 1997-02-26 2:13 UTC (permalink / raw) To: zsh-workers Nobody responded to my message to zsh-users about `while LIST { LIST }` syntax. Is this syntax broken by accident or on purpose? -- Bart Schaefer Brass Lantern Enterprises http://www.well.com/user/barts http://www.nbn.com/people/lantern ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Short loops? 1997-02-26 2:13 Short loops? Bart Schaefer @ 1997-02-26 16:10 ` Zoltan T. Hidvegi 1997-02-26 17:11 ` Bart Schaefer 0 siblings, 1 reply; 10+ messages in thread From: Zoltan T. Hidvegi @ 1997-02-26 16:10 UTC (permalink / raw) To: schaefer; +Cc: zsh-workers Bart Schaefer wrote: > Nobody responded to my message to zsh-users about `while LIST { LIST }` > syntax. Is this syntax broken by accident or on purpose? Sorry for the silence. I've got a new job and moved to the US, that's why I was a bit silent recently. I'd like to buy a computer at home within a few weeks and than I'll have more time to work on zsh again. So, the while syntax is not broken. As you write above, while LIST { LIST } works. But while foo ; { bar } is just while LIST because foo ; { bar } is a list in itself. The above syntax only works if zsh can detect the end of the LIST before reading the {. This works: integer i=0 while ((i++ < 10)) { echo $i } That's because ((i++ < 10)) { echo $i } is not a valid listso zsh can detect that the list ends in )). Similarily [[ ... ]] { ... } works as well. It is the same as if [[ ... ]] then works without a semicolon before then but if true; then doesn't. Zoltan ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Short loops? 1997-02-26 16:10 ` Zoltan T. Hidvegi @ 1997-02-26 17:11 ` Bart Schaefer 1997-02-26 17:26 ` Zoltan T. Hidvegi 0 siblings, 1 reply; 10+ messages in thread From: Bart Schaefer @ 1997-02-26 17:11 UTC (permalink / raw) To: Zoltan T. Hidvegi; +Cc: zsh-workers On Feb 26, 11:10am, (Zoltan T. Hidvegi) wrote: > Subject: Re: Short loops? > > So, the while syntax is not broken. As you write above, > while LIST { LIST } works. But > > while foo ; { bar } > > is just while LIST because foo ; { bar } is a list in itself. The above > syntax only works if zsh can detect the end of the LIST before reading the > {. The doc ought to get changed, then. The two entries for `while' (and similarly for all the "short" variants) read: `while LIST do LIST done' `while LIST { LIST }' The first and second uses of LIST both require either a newline or a trailing semicolon; the fourth use of LIST may have a newline or a semicolon or not, without affecting the result; and the third use requires not only that there NOT be a newline or semicolon, but also that the list ends with a [[ ]] (( )) ( ) or { } construct. This is, if you ask me, completely bogus from a consistency standpoint, not only in the doc but in the behavior; but its worse that the doc makes it appear consistent when it isn't. Furthermore, it's not just the case that zsh must be able to "detect the end of the list before reading the {" because this: while true { echo foo } doesn't work either, yet `true { ...' is in no sense a valid list. -- Bart Schaefer Brass Lantern Enterprises http://www.well.com/user/barts http://www.nbn.com/people/lantern ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Short loops? 1997-02-26 17:11 ` Bart Schaefer @ 1997-02-26 17:26 ` Zoltan T. Hidvegi 1997-02-26 19:09 ` Bart Schaefer 0 siblings, 1 reply; 10+ messages in thread From: Zoltan T. Hidvegi @ 1997-02-26 17:26 UTC (permalink / raw) To: schaefer; +Cc: Zsh workers list Bart Schaefer wrote: > The doc ought to get changed, then. The two entries for `while' (and > similarly for all the "short" variants) read: > > `while LIST do LIST done' > `while LIST { LIST }' > > The first and second uses of LIST both require either a newline or a > trailing semicolon; the fourth use of LIST may have a newline or a > semicolon or not, without affecting the result; and the third use > requires not only that there NOT be a newline or semicolon, but also > that the list ends with a [[ ]] (( )) ( ) or { } construct. No. No one of the above four LIST require any trailing semicolons or newlines. As decribed in the manual, reserved words like do, done, { are only recognized in command position. If you write while true { ... } then { is not in command position, it is simply an argument to true. Words are in command position after a newline or a semicolon or after )) or ]] or after do, then, {, } etc. Zsh has to know that { is not a simple argument to a command, but a reserved word. The { echo } case works and seems to be an exception to this rule but is really a pathologic special case handled explicitely in lex.c and it only works if ignorebraces is not set. This syntax worked in bash-1.14 but it no longer works in bash-2.0 because it violates POSIX. When ignorebraces is set (e.g. in sh mode) the following is perfectly valid: while true { echo foo } do ... done Here true is invoked with four arguments: {, echo, foo and }. Zoltan ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Short loops? 1997-02-26 17:26 ` Zoltan T. Hidvegi @ 1997-02-26 19:09 ` Bart Schaefer 1997-02-26 19:27 ` Zoltan T. Hidvegi 0 siblings, 1 reply; 10+ messages in thread From: Bart Schaefer @ 1997-02-26 19:09 UTC (permalink / raw) To: Zoltan T. Hidvegi; +Cc: Zsh workers list On Feb 26, 12:26pm, (Zoltan T. Hidvegi) wrote: > Subject: Re: Short loops? > > Bart Schaefer wrote: > > The doc ought to get changed, then. The two entries for `while' (and > > similarly for all the "short" variants) read: > > > > `while LIST do LIST done' > > `while LIST { LIST }' > > > > The first and second uses of LIST both require either a newline or a > > trailing semicolon; the fourth use of LIST may have a newline or a > > semicolon or not, without affecting the result; and the third use > > requires not only that there NOT be a newline or semicolon, but also > > that the list ends with a [[ ]] (( )) ( ) or { } construct. > > No. No one of the above four LIST require any trailing semicolons or > newlines. As decribed in the manual, reserved words like do, done, { are > only recognized in command position. [....] Words are > in command position after a newline or a semicolon or after )) or ]] or > after do, then, {, } etc. Which just means that `do' must be *preceded* by a newline or semicolon or whatever. Whether it's the list that requires it or the reserved word that requires it, the effect is the same and the info's syntax summary is misleading. The /bin/sh manual can get away with `while LIST do LIST done' because in /bin/sh the semicolon or newline at the end of a LIST is never optional (the definition of LIST *includes* the trailing separator in the /bin/sh manuals). Just because there's an explanation somewhere else that says that `do' is only recognized in command position, doesn't mean the manual can get away with being sloppy in the syntax summary. It's OK if you want to use LIST the way that it is used in `while LIST do LIST done', but in that case: > Zsh has to know that { is not a simple argument > to a command, but a reserved word. That's not a sufficient explanation either! It has to be not just a reserved word, but a reserved word in a spot where that particular word doesn't have an alternate meaning -- which means after )) or ]] or ) or }, but NOT after semicolon or newline. Which is *not the same* as the rule for where `do' can appear, which IMHO should mean that the syntax summary should NOT be written `while LIST { LIST }'. The doc could define a CLOSED construct to be any of (( )) [[ ]] ( ) { }, and define a CLOSEDLIST to be a LIST ending with a CLOSED but that is NOT followed by the optional separator. Then it could say: `if CLOSEDLIST { LIST } [ elif CLOSEDLIST { LIST } ] ... [ else { LIST } ]' `if CLOSEDLIST SUBLIST' `while CLOSEDLIST { LIST }' `until CLOSEDLIST { LIST }' And then I'd be happy. > The { echo } case works and seems to be > an exception to this rule but is really a pathologic special case handled > explicitely in lex.c and it only works if ignorebraces is not set. I don't know what you're talking about here at all, I fear. An exception to which rule? `}' is recognized *everywhere* when ignorebraces is not set. Which seems bizarre to me anyway -- if `{' is not recognized every- where, then `}' ought to be recognized only when an unmatched reserved `{' has preceded it. One more state flag in the lexer could fix that. -- Bart Schaefer Brass Lantern Enterprises http://www.well.com/user/barts http://www.nbn.com/people/lantern ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Short loops? 1997-02-26 19:09 ` Bart Schaefer @ 1997-02-26 19:27 ` Zoltan T. Hidvegi 1997-02-26 21:14 ` Bart Schaefer 0 siblings, 1 reply; 10+ messages in thread From: Zoltan T. Hidvegi @ 1997-02-26 19:27 UTC (permalink / raw) To: schaefer; +Cc: hzoli, zsh-workers Bart Schaefer wrote: > misleading. The /bin/sh manual can get away with `while LIST do LIST done' > because in /bin/sh the semicolon or newline at the end of a LIST is never > optional (the definition of LIST *includes* the trailing separator in the > /bin/sh manuals). Then the /bin/sh manual is wrong. if (true) then (echo foo) fi works fine in sh. Of course any corrections to the manual are welcome. The manual now contains a more or less full formal description of the grammar, but I agree, that it may be hard to interpret it correctly. In general, it is not easy to describe the exact grammar of the shell in such a way that it is easy to understand for the human readers. Note that ksh has the same problems here as zsh. In sh/ksh the question is when is it possible to omit the semicolon/newline before `then'. In zsh the brace syntax complicates this a bit, but it is really the same problem. If the newline/semicolon can be omitted in a while LIST do statement then the while LIST { ... } syntax will work as well. > > Zsh has to know that { is not a simple argument > > to a command, but a reserved word. > > That's not a sufficient explanation either! It has to be not just a > reserved word, but a reserved word in a spot where that particular word > doesn't have an alternate meaning -- which means after )) or ]] or ) or }, > but NOT after semicolon or newline. Which is *not the same* as the rule > for where `do' can appear, which IMHO should mean that the syntax summary > should NOT be written `while LIST { LIST }'. If you interpret LIST as the longest string which is synactically a list than it is correct. In while true ; { echo foo } the longest possible list is true ; { echo foo }. Zsh just parses the list as long as it can, and when the list parses sees something that cannot continue a list it returns. > > The doc could define a CLOSED construct to be any of (( )) [[ ]] ( ) { }, > and define a CLOSEDLIST to be a LIST ending with a CLOSED but that is NOT > followed by the optional separator. Then it could say: > > `if CLOSEDLIST { LIST } [ elif CLOSEDLIST { LIST } ] ... [ else { LIST } ]' > `if CLOSEDLIST SUBLIST' > `while CLOSEDLIST { LIST }' > `until CLOSEDLIST { LIST }' > > And then I'd be happy. Yes, but that would make the manual quite verbose repeating the same thing many times. > > The { echo } case works and seems to be > > an exception to this rule but is really a pathologic special case handled > > explicitely in lex.c and it only works if ignorebraces is not set. > > I don't know what you're talking about here at all, I fear. An exception > to which rule? `}' is recognized *everywhere* when ignorebraces is not } is a reserved word, and it should be recognized only in command position. But it is recognized in other places as well. > set. Which seems bizarre to me anyway -- if `{' is not recognized every- > where, then `}' ought to be recognized only when an unmatched reserved `{' > has preceded it. One more state flag in the lexer could fix that. { cannot mean command grouping in echo { ... } just line echo ( ... ) does not do that. The later is a syntax error in sh. And I think it would be even more confusing if echo } works but it stops working after you put it into a while loop using { ... }. Zoltan ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Short loops? 1997-02-26 19:27 ` Zoltan T. Hidvegi @ 1997-02-26 21:14 ` Bart Schaefer 1997-02-27 9:32 ` Peter Stephenson 0 siblings, 1 reply; 10+ messages in thread From: Bart Schaefer @ 1997-02-26 21:14 UTC (permalink / raw) To: Zoltan T. Hidvegi; +Cc: zsh-workers On Feb 26, 2:27pm, (Zoltan T. Hidvegi) wrote: > Subject: Re: Short loops? > > Bart Schaefer wrote: > > misleading. The /bin/sh manual can get away with `while LIST do LIST done' > > because in /bin/sh the semicolon or newline at the end of a LIST is never > > optional (the definition of LIST *includes* the trailing separator in the > > /bin/sh manuals). > > Then the /bin/sh manual is wrong. if (true) then (echo foo) fi works fine > in sh. Hmm. Yup, you're right; I dug up my hardcopy of the 4.2 BSD `sh' man page. I withdraw that objection. Nevertheless, the point is that the "optional" terminator mentioned in the definition of a "list" is not optional in the short forms. It *must* be left out. > > The doc could define a CLOSED construct to be any of (( )) [[ ]] ( ) { }, > > and define a CLOSEDLIST to be a LIST ending with a CLOSED but that is NOT > > followed by the optional separator. > > Yes, but that would make the manual quite verbose repeating the same thing > many times. Why would that cause it to repeat itself more than it already does? However, if something close to this text: } If you interpret LIST as the longest string which is synactically a list } than it is correct. In while true ; { echo foo } the longest possible list } is true ; { echo foo }. were added to the section on alternate forms, that would probably clarify enough. Maybe also move the reserved words section above the alternate forms, but that helps only when reading sequentially through the info. Peter, how about adding something about this to the FAQ as well? -- Bart Schaefer Brass Lantern Enterprises http://www.well.com/user/barts http://www.nbn.com/people/lantern ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Short loops? 1997-02-26 21:14 ` Bart Schaefer @ 1997-02-27 9:32 ` Peter Stephenson 1997-02-27 15:06 ` Zoltan T. Hidvegi 1997-02-27 18:16 ` Bart Schaefer 0 siblings, 2 replies; 10+ messages in thread From: Peter Stephenson @ 1997-02-27 9:32 UTC (permalink / raw) To: Zsh hackers list "Bart Schaefer" wrote: > Peter, how about adding something about this to the FAQ as well? It looks like I should be adding two things to the FAQ. This is the deyodled text. 3.6: Why does zsh not work in an Emacs shell mode any more? (The following is from Bart Schaefer again): Emacs 19.29 or thereabouts stopped using a terminal type of "emacs" in shell buffers, and instead sets it to "dumb". Zsh only kicks in its special I'm-inside-emacs initialization when the terminal type is "emacs". Placing a (setenv "TERM" "emacs") in your ~/.emacs file seems to fix this. If that confuses other programs that are run from within emacs, you can instead use (setenv "ESHELL" "~/bin/eshell") and then put `TERM=emacs exec zsh' in the file ~/bin/eshell. 3.16: How does the alternative loop syntax, e.g. `while {...} {...}' work? Zsh provides an alternative to the traditional sh-like forms with `do', while TEST; do COMMANDS; done allowing you to have the COMMANDS delimited with some other command structure, often `{...}'. However, to make this work you must make sure the TEST itself is clearly delimited. For example, this works: while (( i++ < 10 )) { echo i is $i; } but this does _not_: while let "i++ < 10"; { echo i is $i; } # Wrong! The reason is that after `while', any sort of command list is valid. This includes the whole list `let "i++ < 10"; { echo i $i; }'; the parser simply doesn't know when to stop. Furthermore, it is wrong to miss out the semicolon, as this makes the `{...}' part of the argument to `let'. So when using this syntax, the test following the `while' must be wrapped up: any of `((...))', `[[...]]', `{...}' or `(...)' will have this effect. (They have their usual syntactic meanings too, of course; they are not interchangeable.) Note that here too it is wrong to put in the semicolon, as then the case becomes identical to the preceding one: while (( i++ < 10 )); { echo i is $i; } # Wrong! The same is true of the `if' and `until' constructs: if { true } { echo yes } else { echo no } but with `for', which only needs a list of words, you can get away with it: for foo in a b; { echo foo is $a; bar=$foo; } since the parser knows it only needs everything up to the first semicolon. For the same reason, there is no problem with the `repeat', `case' or `select' constructs; in fact, `repeat' doesn't even need the semicolon since it knows the repeat count is just one word. This is independent of the behaviour of the SHORTLOOPS option (see manual), which you are in any case encouraged not to use in programs as it can be very confusing. -- Peter Stephenson <pws@ifh.de> Tel: +49 33762 77366 WWW: http://www.ifh.de/~pws/ Fax: +49 33762 77413 Deutsches Elektronen-Synchrotron --- Institut fuer Hochenergiephysik Zeuthen DESY-IfH, 15735 Zeuthen, Germany. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Short loops? 1997-02-27 9:32 ` Peter Stephenson @ 1997-02-27 15:06 ` Zoltan T. Hidvegi 1997-02-27 18:16 ` Bart Schaefer 1 sibling, 0 replies; 10+ messages in thread From: Zoltan T. Hidvegi @ 1997-02-27 15:06 UTC (permalink / raw) To: Peter Stephenson; +Cc: zsh-workers Peter Stephenson wrote: > while (( i++ < 10 )); { echo i is $i; } # Wrong! I would add that while (( i++ < 10 )) { echo i is $i } is also wrong, since newline behaves line a semicolon. And I would not encourage the usage of this brace syntax in scrips because these syntax rules are quite complicated. The old sh syntax do not have these hidden traps. A lengthy discussion of this syntax in the FAQ may seem to encourage the usage. Zoltan ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Short loops? 1997-02-27 9:32 ` Peter Stephenson 1997-02-27 15:06 ` Zoltan T. Hidvegi @ 1997-02-27 18:16 ` Bart Schaefer 1 sibling, 0 replies; 10+ messages in thread From: Bart Schaefer @ 1997-02-27 18:16 UTC (permalink / raw) To: Peter Stephenson, Zsh hackers list On Feb 27, 10:32am, Peter Stephenson wrote: } Subject: Re: Short loops? } } "Bart Schaefer" wrote: } > Peter, how about adding something about this to the FAQ as well? } } It looks like I should be adding two things to the FAQ. This is the } deyodled text. } } 3.6: Why does zsh not work in an Emacs shell mode any more? } } Placing a } } (setenv "TERM" "emacs") } } in your ~/.emacs file seems to fix this. This may not be universal, based on the discussion on zsh-users. It appears to work for the default shell-mode (shell.el) but not for the enhanced shell-mode supplied by comint (comint.el). Looking at the lisp code in comint.el, it appears emacs forces TERM=dumb for systems where emacs is compiled with terminfo, and TERM=emacs for those where it's compiled with termcap. There's no hook to override this; you can only redefine comint-exec-1 as in the sample I sent, which is bad if comint gets upgraded. This: } that are run from within emacs, you can instead use } } (setenv "ESHELL" "~/bin/eshell") } } and then put `TERM=emacs exec zsh' in the file ~/bin/eshell. ought to work in either case, though for the FAQ I'd restate it as and then put #!/bin/sh TERM=emacs exec zsh in the file ~/bin/eshell, and `chmod +x ~/bin/eshell'. Finally I'd add (via Alain Caron <alainc@nortel.ca>): If none of the above works, place [[ -n "$EMACS" ]] && unsetopt zle in your $ZDOTDIR/.zshrc file. If you want to say something about terminal mode: [[ -n "$EMACS" ]] && { [[ "$TERM" = eterm ]] && TERM=vt100 || unsetopt zle } } 3.16: How does the alternative loop syntax, e.g. `while {...} {...}' work? I agree with Zoltan's remarks about this; particularly about stronger admonition to avoid the short forms in scripts. -- Bart Schaefer Brass Lantern Enterprises http://www.well.com/user/barts http://www.nbn.com/people/lantern ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~1997-02-27 18:23 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1997-02-26 2:13 Short loops? Bart Schaefer 1997-02-26 16:10 ` Zoltan T. Hidvegi 1997-02-26 17:11 ` Bart Schaefer 1997-02-26 17:26 ` Zoltan T. Hidvegi 1997-02-26 19:09 ` Bart Schaefer 1997-02-26 19:27 ` Zoltan T. Hidvegi 1997-02-26 21:14 ` Bart Schaefer 1997-02-27 9:32 ` Peter Stephenson 1997-02-27 15:06 ` Zoltan T. Hidvegi 1997-02-27 18:16 ` Bart Schaefer
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).