zsh-users
 help / color / mirror / code / Atom feed
* Feature request: a new warning option
@ 2019-10-09  4:02 Sebastian Gniazdowski
  2019-10-09  8:45 ` Roman Perepelitsa
  2019-10-09 18:15 ` Bart Schaefer
  0 siblings, 2 replies; 15+ messages in thread
From: Sebastian Gniazdowski @ 2019-10-09  4:02 UTC (permalink / raw)
  To: Zsh Users

Hello,
how about detecting situations in the code like the following:

fun() { some code possibly returning false }
(( condition )) && fun || print "Some 'else'-instruction"

The warning would be triggered when:
- a an || would occur after an instruction preceded by &&,
- the instruction wouldn't be an always-true instruction, i.e. not
((1)), local var="value", etc. – this would also include prints etc.,
as the stdout can be closed and such instruction CAN fail – the
usefulness of the option is visible here, it would make the users
conscious of such fact.

Is this doable? To detect a preceding && and a following ||, and check
if the instruction is a function or a print?

The name of such option could be: warn_symmetric_cond, it would
describe the fact of symmetric way of condition processing.

To solve the warning, the users could e.g. convert the fun into { fun;
((1)) } or use an if.
-- 
Sebastian Gniazdowski
News: https://twitter.com/ZdharmaI
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
Blog: http://zdharma.org

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

* Re: Feature request: a new warning option
  2019-10-09  4:02 Feature request: a new warning option Sebastian Gniazdowski
@ 2019-10-09  8:45 ` Roman Perepelitsa
  2019-10-09  8:49   ` Peter Stephenson
  2019-10-09 11:56   ` Sebastian Gniazdowski
  2019-10-09 18:15 ` Bart Schaefer
  1 sibling, 2 replies; 15+ messages in thread
From: Roman Perepelitsa @ 2019-10-09  8:45 UTC (permalink / raw)
  To: Sebastian Gniazdowski; +Cc: Zsh Users

On Wed, Oct 9, 2019 at 6:03 AM Sebastian Gniazdowski
<sgniazdowski@gmail.com> wrote:
>
> Hello,
> how about detecting situations in the code like the following:
>
> fun() { some code possibly returning false }
> (( condition )) && fun || print "Some 'else'-instruction"

I've made a quick-and-dirty search over powerlevel10k source code to
see how often this warning would have false positives. Here are a few
examples of `x && y || z` constructs where `y` can fail and yet the
code is correct.

  (( $+GITSTATUS_DAEMON_PID_POWERLEVEL9K )) &&
     gitstatus_start POWERLEVEL9K ||
     _p9k_gitstatus_disabled=1

  mkdir -p ${dst:h} && cp -f $src $dst || return

  _p9k_cached_cmd_stdout node -v && [[ $_p9k_ret == v?* ]] || return

`x && y || z` is not `x ? y : z` even though it's often abused as
such. I think the solution is to use `x && y || z` when you mean it,
which is to say *only* when both `x` and `y` may be falsy. The ternary
can be expressed with an `if`.

Compare:

  (( condition )) && fun || print "Some 'else'-instruction"

vs

  if (( condition )) { fun } else { print "Some 'else'-instruction" }

The latter is longer but is at least as clear. It also comes with
curlies that make it easy to split the statement into multiple lines
if necessary, or to add extra statements inside the branches.

I myself am guilty of using `x && y || z` in place of a ternary
and this leads to bugs that your proposed warning is meant to flag.
However, if I were to enable this warning, I wouldn't be able to
use `x && y || z` when it is the best tool for the job. Hence I'm
leaning towards unlearning my current habbit and starting to use
`if-else` more.

What do you think?

Roman.

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

* Re: Feature request: a new warning option
  2019-10-09  8:45 ` Roman Perepelitsa
@ 2019-10-09  8:49   ` Peter Stephenson
  2019-10-09 11:56   ` Sebastian Gniazdowski
  1 sibling, 0 replies; 15+ messages in thread
From: Peter Stephenson @ 2019-10-09  8:49 UTC (permalink / raw)
  To: zsh-users

On Wed, 2019-10-09 at 10:45 +0200, Roman Perepelitsa wrote:
> I myself am guilty of using `x && y || z` in place of a ternary
> and this leads to bugs that your proposed warning is meant to flag.
> However, if I were to enable this warning, I wouldn't be able to
> use `x && y || z` when it is the best tool for the job. Hence I'm
> leaning towards unlearning my current habbit and starting to use
> `if-else` more.
> 
> What do you think?

For clear code, if-then-else is defnitely preferable anyway.
The problems with && / || are very subtle and often don't register even
if you're aware of the possibility.

pws

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

* Re: Feature request: a new warning option
  2019-10-09  8:45 ` Roman Perepelitsa
  2019-10-09  8:49   ` Peter Stephenson
@ 2019-10-09 11:56   ` Sebastian Gniazdowski
  2019-10-09 12:08     ` Roman Perepelitsa
  1 sibling, 1 reply; 15+ messages in thread
From: Sebastian Gniazdowski @ 2019-10-09 11:56 UTC (permalink / raw)
  To: Roman Perepelitsa; +Cc: Zsh Users

On Wed, 9 Oct 2019 at 10:45, Roman Perepelitsa
<roman.perepelitsa@gmail.com> wrote:
> I myself am guilty of using `x && y || z` in place of a ternary
> and this leads to bugs that your proposed warning is meant to flag.
> However, if I were to enable this warning, I wouldn't be able to
> use `x && y || z` when it is the best tool for the job. Hence I'm
> leaning towards unlearning my current habbit and starting to use
> `if-else` more.
>
> What do you think?

I like the ternary-use of &&/||. I format the code as follows:

(( condition )) && \
    code || \
    code

I even use the ((1)) addition to the code || often. However, I might
get onto the alternate syntax-way you've proposed, it looks nice.

As for the non-ternary, i.e. symmetric-and-still-correct use of &&/||
I would say: the code that is needy of using &&/|| in such a way can
skip this hypothetical new warning option. Covering 8 out of 10
functions with it is still a good result (this reminds me the previous
discussion we've had).

I in general am a very happy user of warn_create_global and I see how
much warning-options can give, hence the feature request. I however
don't use warn_nested_var, I'm now starting to wonder why, as even
that I've sometimes write code using variables from upper scope, the
"covering 8 out ouf 10 functions..." point would apply here too. It's
however a recent option, not forever-present like the
warn_create_global. I wonder if a very much compressed way of enabling
warn_nested_var only on shells that have it exists.

-- 
Sebastian Gniazdowski
News: https://twitter.com/ZdharmaI
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
Blog: http://zdharma.org

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

* Re: Feature request: a new warning option
  2019-10-09 11:56   ` Sebastian Gniazdowski
@ 2019-10-09 12:08     ` Roman Perepelitsa
  2019-10-09 13:17       ` Sebastian Gniazdowski
  0 siblings, 1 reply; 15+ messages in thread
From: Roman Perepelitsa @ 2019-10-09 12:08 UTC (permalink / raw)
  To: Sebastian Gniazdowski; +Cc: Zsh Users

On Wed, Oct 9, 2019 at 1:56 PM Sebastian Gniazdowski
<sgniazdowski@gmail.com> wrote:
> I would say: the code that is needy of using &&/|| in such a way can
> skip this hypothetical new warning option. Covering 8 out of 10
> functions with it is still a good result (this reminds me the previous
> discussion we've had).

I'm not opposed to warnings that may have false positives. That's why
they are warnings rather than errors.

My point here is different. Imagine the documentation for the new
warning:

  Warns if `x && y || z` cannot be proven through static analysis to
  be equivalent to `if x; then y; else z; fi`.

Doesn't this strike you as odd? If the latter construct has the
desired semantics, why not use it in the first place? It'll obviate
the need for a new warning and convey the intention to humans reading
the code.

Roman.

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

* Re: Feature request: a new warning option
  2019-10-09 12:08     ` Roman Perepelitsa
@ 2019-10-09 13:17       ` Sebastian Gniazdowski
  2019-10-09 13:24         ` Peter Stephenson
  2019-10-09 13:40         ` Roman Perepelitsa
  0 siblings, 2 replies; 15+ messages in thread
From: Sebastian Gniazdowski @ 2019-10-09 13:17 UTC (permalink / raw)
  To: Roman Perepelitsa; +Cc: Zsh Users

On Wed, 9 Oct 2019 at 14:08, Roman Perepelitsa
<roman.perepelitsa@gmail.com> wrote:
>
>   Warns if `x && y || z` cannot be proven through static analysis to
>   be equivalent to `if x; then y; else z; fi`.
>
> Doesn't this strike you as odd? If the latter construct has the
> desired semantics, why not use it in the first place? It'll obviate
> the need for a new warning and convey the intention to humans reading
> the code.

The x && y || z is less verbose. It doesn't require `then' and `else'
and `fi'. I'm writing from my point of view – that are the reasons why
I use &&/||.

-- 
Sebastian Gniazdowski
News: https://twitter.com/ZdharmaI
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
Blog: http://zdharma.org

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

* Re: Feature request: a new warning option
  2019-10-09 13:17       ` Sebastian Gniazdowski
@ 2019-10-09 13:24         ` Peter Stephenson
  2019-10-09 13:41           ` Sebastian Gniazdowski
       [not found]           ` <CAKc7PVBQnt_ZE3X=8gz5R_VURwaTL3mDL=X-7H__yYqAjvXoWA__41912.055101578$1570628583$gmane$org@mail.gmail.com>
  2019-10-09 13:40         ` Roman Perepelitsa
  1 sibling, 2 replies; 15+ messages in thread
From: Peter Stephenson @ 2019-10-09 13:24 UTC (permalink / raw)
  To: zsh-users

On Wed, 2019-10-09 at 15:17 +0200, Sebastian Gniazdowski wrote:
> On Wed, 9 Oct 2019 at 14:08, Roman Perepelitsa
> <roman.perepelitsa@gmail.com> wrote:
> > 
> > 
> >   Warns if `x && y || z` cannot be proven through static analysis to
> >   be equivalent to `if x; then y; else z; fi`.
> > 
> > Doesn't this strike you as odd? If the latter construct has the
> > desired semantics, why not use it in the first place? It'll obviate
> > the need for a new warning and convey the intention to humans reading
> > the code.
>
> The x && y || z is less verbose. It doesn't require `then' and `else'
> and `fi'. I'm writing from my point of view – that are the reasons why
> I use &&/||.

Hmm... that's fair enough, but if you're happy to trade off against
readability I think you have to take possible difficulties with the
syntax on the chin...

pws

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

* Re: Feature request: a new warning option
  2019-10-09 13:17       ` Sebastian Gniazdowski
  2019-10-09 13:24         ` Peter Stephenson
@ 2019-10-09 13:40         ` Roman Perepelitsa
  2019-10-09 17:36           ` Daniel Shahaf
  1 sibling, 1 reply; 15+ messages in thread
From: Roman Perepelitsa @ 2019-10-09 13:40 UTC (permalink / raw)
  To: Sebastian Gniazdowski; +Cc: Zsh Users

On Wed, Oct 9, 2019 at 3:17 PM Sebastian Gniazdowski
<sgniazdowski@gmail.com> wrote:
> The x && y || z is less verbose. It doesn't require `then' and `else'
> and `fi'. I'm writing from my point of view – that are the reasons why
> I use &&/||.

Supposing that "if-then-else is too verbose" is a problem that
warrants extending zsh, a natural solution would be to provide an
alternative syntax for the same construct. Something analogous to
`x ? y : z` from C and other languages derived from it.

Note that C had an extra reason besides terseness to introduce this
syntax: if-then-else is a statement while the ternary is an
expression. This reason doesn't apply to zsh, which leaves saving
on typing as the only benefit of the contemplated innovation.
Since `x ? y : z` already has a meaning in zsh, the new syntax would
have to be different and likely unfamiliar to users.

All-in-all, doesn't seem worth the trouble. if-then-else has the
desired semantics, isn't more verbose than in other languages,
and is easy to read even for people unfamiliar with zsh.

Roman.

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

* Re: Feature request: a new warning option
  2019-10-09 13:24         ` Peter Stephenson
@ 2019-10-09 13:41           ` Sebastian Gniazdowski
  2019-10-09 14:07             ` Ray Andrews
       [not found]           ` <CAKc7PVBQnt_ZE3X=8gz5R_VURwaTL3mDL=X-7H__yYqAjvXoWA__41912.055101578$1570628583$gmane$org@mail.gmail.com>
  1 sibling, 1 reply; 15+ messages in thread
From: Sebastian Gniazdowski @ 2019-10-09 13:41 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: zsh-users

On Wed, 9 Oct 2019 at 15:25, Peter Stephenson <p.stephenson@samsung.com> wrote:
>
> Hmm... that's fair enough, but if you're happy to trade off against
> readability I think you have to take possible difficulties with the
> syntax on the chin...

I thought that:

[[ -z $ver ]] && ver="unknown (no .git/refs/heads/master)" || ver=${ver[1,7]}

is more or equally readable to:

if [[ -z $ver ]]; then
    ver="unknown (no .git/refs/heads/master)"
else
    ver=${ver[1,7]}
fi

especially if I would format it like I would today:

[[ -z $ver ]] && \
    ver="unknown (no .git/refs/heads/master)" || \
    ver=${ver[1,7]}

but I'm seeing your point. This is like commenting or not the code – I
was for a long long time pro-commenting, to just drop it recently,
actually finding pleasure in writing a condensed, I could agree –
(less /un)readable code.

-- 
Sebastian Gniazdowski
News: https://twitter.com/ZdharmaI
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
Blog: http://zdharma.org

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

* Re: Feature request: a new warning option
       [not found]           ` <CAKc7PVBQnt_ZE3X=8gz5R_VURwaTL3mDL=X-7H__yYqAjvXoWA__41912.055101578$1570628583$gmane$org@mail.gmail.com>
@ 2019-10-09 14:04             ` Stephane Chazelas
  0 siblings, 0 replies; 15+ messages in thread
From: Stephane Chazelas @ 2019-10-09 14:04 UTC (permalink / raw)
  To: Sebastian Gniazdowski; +Cc: Peter Stephenson, zsh-users

2019-10-09 15:41:41 +0200, Sebastian Gniazdowski:
[...]
> I thought that:
> 
> [[ -z $ver ]] && ver="unknown (no .git/refs/heads/master)" || ver=${ver[1,7]}
> 
> is more or equally readable to:
> 
> if [[ -z $ver ]]; then
>     ver="unknown (no .git/refs/heads/master)"
> else
>     ver=${ver[1,7]}
> fi
[...]

but thyes are different things.

a && b || c, is "run c unles both a and b succeed".

You typically use these things in if statements like

if a && b || c; then
  ...
fi


You could always do something like:

alias -g '^=else'
if ((x)){echo yes} ^ {echo no}

(can be shortened to if((x)){echo yes} ^ {echo no} with zsh -o
noglobqual -o shglob).

Or even:

alias -g '&|=else'
alias '?=if'
? ((x)){echo yes}&|{echo no}

-- 
Stephane

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

* Re: Feature request: a new warning option
  2019-10-09 13:41           ` Sebastian Gniazdowski
@ 2019-10-09 14:07             ` Ray Andrews
  2019-10-09 15:19               ` Peter Stephenson
  0 siblings, 1 reply; 15+ messages in thread
From: Ray Andrews @ 2019-10-09 14:07 UTC (permalink / raw)
  To: zsh-users

On 2019-10-09 6:41 a.m., Sebastian Gniazdowski wrote:
> but I'm seeing your point. This is like commenting or not the code – I
> was for a long long time pro-commenting, to just drop it recently,
> actually finding pleasure in writing a condensed, I could agree –
> (less /un)readable code.
>
Just a comment from the unwashed:

Maybe I'm the only one, but it has always seemed to me that in the 
entire cycle of developing software, the time spent entering keystrokes 
is a tiny fraction.  You save a few seconds typing a line, but come back 
to it a while later and you spend hours figuring out your own code.  Zsh 
has incredibly compact syntax already, and if I don't comment every 
line, since I can go months without writing anything, when I come back, 
I've forgotten the syntax and must refer to my comments.  They say that 
with Perl, every keystroke needs a sentence of comment to understand 
it.  My notion of the ideal language would be quite verbose and 
self-explanatory.  IMHO the last thing zsh needs is more terse syntax.  
Just my two cents.


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

* Re: Feature request: a new warning option
  2019-10-09 14:07             ` Ray Andrews
@ 2019-10-09 15:19               ` Peter Stephenson
  0 siblings, 0 replies; 15+ messages in thread
From: Peter Stephenson @ 2019-10-09 15:19 UTC (permalink / raw)
  To: zsh-users

On Wed, 2019-10-09 at 07:07 -0700, Ray Andrews wrote:
> Maybe I'm the only one, but it has always seemed to me that in the 
> entire cycle of developing software, the time spent entering keystrokes 
> is a tiny fraction.  You save a few seconds typing a line, but come back 
> to it a while later and you spend hours figuring out your own code.

This is certainly my experience, and of course it's a lot worse if it's
somebody else's code, which is an important point in any medium to large
scale software projects.

There's the separate question of whether short code is more readable in
some circumstances, which can be the case (or we'd be using some
derivative of COBOL or PROLOG for programming).  But if what it's doing
is obscure --- what you're reading isn't what you think you're reading
--- this advantage goes away.

pws

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

* Re: Feature request: a new warning option
  2019-10-09 13:40         ` Roman Perepelitsa
@ 2019-10-09 17:36           ` Daniel Shahaf
  0 siblings, 0 replies; 15+ messages in thread
From: Daniel Shahaf @ 2019-10-09 17:36 UTC (permalink / raw)
  To: zsh-users

Roman Perepelitsa wrote on Wed, Oct 09, 2019 at 15:40:48 +0200:
> Supposing that "if-then-else is too verbose" is a problem that
> warrants extending zsh, a natural solution would be to provide an
> alternative syntax for the same construct. Something analogous to
> `x ? y : z` from C and other languages derived from it.

Extending the SHORT_LOOPS form of «if» to allow an «else» comes to mind, but
I'm honestly not sure if it'd be a good change to make.

> Note that C had an extra reason besides terseness to introduce this
> syntax: if-then-else is a statement while the ternary is an
> expression. This reason doesn't apply to zsh, which leaves saving
> on typing as the only benefit of the contemplated innovation.
> Since `x ? y : z` already has a meaning in zsh, the new syntax would
> have to be different and likely unfamiliar to users.
> 
> All-in-all, doesn't seem worth the trouble. if-then-else has the
> desired semantics, isn't more verbose than in other languages,
> and is easy to read even for people unfamiliar with zsh.

Cheers,

Daniel

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

* Re: Feature request: a new warning option
  2019-10-09  4:02 Feature request: a new warning option Sebastian Gniazdowski
  2019-10-09  8:45 ` Roman Perepelitsa
@ 2019-10-09 18:15 ` Bart Schaefer
  2019-10-10  3:29   ` Sebastian Gniazdowski
  1 sibling, 1 reply; 15+ messages in thread
From: Bart Schaefer @ 2019-10-09 18:15 UTC (permalink / raw)
  To: Sebastian Gniazdowski; +Cc: Zsh Users

On Tue, Oct 8, 2019 at 9:03 PM Sebastian Gniazdowski
<sgniazdowski@gmail.com> wrote:
>
> The warning would be triggered when:
> - a an || would occur after an instruction preceded by &&,
> - the instruction wouldn't be an always-true instruction

To add to what's already been bandied about:

This seems like something better suited for a shell script "lint" type
program, rather than something to emit as a run-time warning from the
shell itself.  There's also the question of when this warning would be
emitted; if at execute time, is it really doing anything useful?  If
at parse time, the parser has to become aware of even more semantics.

Creation of global variables and references to unset variables can't
really be detected by syntax examination, but all the cases the shell
could successfully warn about in this scheme are, I think, resolvable
by looking at the individual pipelines.  If you want a runtime
warning, maybe do something with ${(z)ZSH_DEBUG_CMD} in a TRAPDEBUG
function?

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

* Re: Feature request: a new warning option
  2019-10-09 18:15 ` Bart Schaefer
@ 2019-10-10  3:29   ` Sebastian Gniazdowski
  0 siblings, 0 replies; 15+ messages in thread
From: Sebastian Gniazdowski @ 2019-10-10  3:29 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On Wed, 9 Oct 2019 at 20:15, Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> This seems like something better suited for a shell script "lint" type
> program

True, it's well suited for such program, but maybe it isn't that bad
also for the shell?

> rather than something to emit as a run-time warning from the
> shell itself.  There's also the question of when this warning would be
> emitted; if at execute time, is it really doing anything useful?

I think yes: it would work similar to warn_create_global – when
working on a script it would emit such warnings and inform the
programmer of the problem. The programmer would then react and change
the code, preventing it to be released to the public, like in the case
of creating a global.

> If you want a runtime
> warning, maybe do something with ${(z)ZSH_DEBUG_CMD} in a TRAPDEBUG
> function?

Thanks, that's an interesting idea.
--
Sebastian Gniazdowski
News: https://twitter.com/ZdharmaI
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
Blog: http://zdharma.org

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

end of thread, other threads:[~2019-10-10  3:30 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-09  4:02 Feature request: a new warning option Sebastian Gniazdowski
2019-10-09  8:45 ` Roman Perepelitsa
2019-10-09  8:49   ` Peter Stephenson
2019-10-09 11:56   ` Sebastian Gniazdowski
2019-10-09 12:08     ` Roman Perepelitsa
2019-10-09 13:17       ` Sebastian Gniazdowski
2019-10-09 13:24         ` Peter Stephenson
2019-10-09 13:41           ` Sebastian Gniazdowski
2019-10-09 14:07             ` Ray Andrews
2019-10-09 15:19               ` Peter Stephenson
     [not found]           ` <CAKc7PVBQnt_ZE3X=8gz5R_VURwaTL3mDL=X-7H__yYqAjvXoWA__41912.055101578$1570628583$gmane$org@mail.gmail.com>
2019-10-09 14:04             ` Stephane Chazelas
2019-10-09 13:40         ` Roman Perepelitsa
2019-10-09 17:36           ` Daniel Shahaf
2019-10-09 18:15 ` Bart Schaefer
2019-10-10  3:29   ` Sebastian Gniazdowski

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).