zsh-workers
 help / color / mirror / code / Atom feed
* bug: nested for loop body is executed once!
@ 2021-08-13  3:13 Daniil Iaitskov
  2021-08-13  3:47 ` Matthew Martin
  2021-08-13  3:50 ` Lawrence Velázquez
  0 siblings, 2 replies; 4+ messages in thread
From: Daniil Iaitskov @ 2021-08-13  3:13 UTC (permalink / raw)
  To: zsh-workers

[-- Attachment #1: Type: text/plain, Size: 778 bytes --]

Hi,

I just spot a following bug on Big Sur zsh 5.8 (x86_64-apple-darwin20.0)

$ K="1 2 3"
> $ for i in $(for j in $K; do echo "ddd/$j" ; done) ; do echo  "$i" ; done
> ddd/1
> 2
> 3
>

I would expect following output

> ddd/1
> ddd/2
> ddd/3
>

this breaks referential transparency - sorry for FP buzzwords ;)
because

$ for i in $(for j in $(echo 1 2 3); do echo "ddd/$j" ; done) ; do echo
>  "$i" ; done
>

produce expected output:

> ddd/1
> ddd/2
> ddd/3
>


I don't know if this is a feature due to some legacy optimizations.
I mostly use BASH and this behavior differs from BASH.
BASH behaves exactly as I expect.

P.S.
Wow! Are you still using just a mailing list for bug tracking?!
I hope my HTML email will be rendered correctly ;)

-- 

Best regards,
Daniil Iaitskov

[-- Attachment #2: Type: text/html, Size: 1867 bytes --]

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

* Re: bug: nested for loop body is executed once!
  2021-08-13  3:13 bug: nested for loop body is executed once! Daniil Iaitskov
@ 2021-08-13  3:47 ` Matthew Martin
  2021-08-13  3:50 ` Lawrence Velázquez
  1 sibling, 0 replies; 4+ messages in thread
From: Matthew Martin @ 2021-08-13  3:47 UTC (permalink / raw)
  To: zsh-workers

On Thu, Aug 12, 2021 at 11:13:09PM -0400, Daniil Iaitskov wrote:
> Hi,
> 
> I just spot a following bug on Big Sur zsh 5.8 (x86_64-apple-darwin20.0)
> 
> $ K="1 2 3"
> > $ for i in $(for j in $K; do echo "ddd/$j" ; done) ; do echo  "$i" ; done
> > ddd/1
> > 2
> > 3

That's because zsh doesn't do word splitting on parameter expansions by
default. Running under set -x is illuminating.

+zsh:3> j=1 2 3
+zsh:3> echo 'ddd/1 2 3'
+zsh:3> i=ddd/1
+zsh:3> echo ddd/1
ddd/1
+zsh:3> i=2
+zsh:3> echo 2
2
+zsh:3> i=3
+zsh:3> echo 3
3

j is assigned '1 2 3' and the result of the command substitution is
'ddd/1 2 3'. However word splitting does happen on unquoted command
substitutions, so i is assigned to thrice.

> I would expect following output
> 
> > ddd/1
> > ddd/2
> > ddd/3

You want an array: K=(1 2 3)

At which point you could skip the command substitution and instead
for i in ddd/$^K; do ...


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

* Re: bug: nested for loop body is executed once!
  2021-08-13  3:13 bug: nested for loop body is executed once! Daniil Iaitskov
  2021-08-13  3:47 ` Matthew Martin
@ 2021-08-13  3:50 ` Lawrence Velázquez
  2021-08-14 15:07   ` Daniel Shahaf
  1 sibling, 1 reply; 4+ messages in thread
From: Lawrence Velázquez @ 2021-08-13  3:50 UTC (permalink / raw)
  To: Daniil Iaitskov; +Cc: zsh-workers

On Thu, Aug 12, 2021, at 11:13 PM, Daniil Iaitskov wrote:
> I just spot a following bug on Big Sur zsh 5.8 (x86_64-apple-darwin20.0)

It's not a bug.

> > $ K="1 2 3"
> > $ for i in $(for j in $K; do echo "ddd/$j" ; done) ; do echo  "$i" ; done
> > ddd/1
> > 2
> > 3
> 
> I would expect following output
> > ddd/1
> > ddd/2
> > ddd/3

By default, zsh does not word-split unquoted parameter expansions;
this behavior differs from most Bourne-adjacent shells.  Observe
that your "inner" loop actually only loops once, with $j taking on
the entire value of $K:

    % K="1 2 3"
    % for j in $K; do echo "<ddd/$j>"; done
    <ddd/1 2 3>

However, zsh *does* word-split unquoted command substitutions, so
the output of $(for j in $K; do echo "ddd/$j" ; done) is split into
'ddd/1', '2', and '3', and $i takes on each value in turn.

> > $ for i in $(for j in $(echo 1 2 3); do echo "ddd/$j" ; done) ; do echo  "$i" ; done
> 
> produce expected output:
> > ddd/1
> > ddd/2
> > ddd/3

In this example, $(echo 1 2 3) is word-split because it is a command
substitution.  Thus, $j takes on the values '1', '2', and '3', as
you expected.

> I don't know if this is a feature due to some legacy optimizations.
> I mostly use BASH and this behavior differs from BASH.
> BASH behaves exactly as I expect.

Actually, many zsh users consider the word-splitting of unquoted
parameter expansions to be a misfeature, which zsh's default behavior
remedies.  In any case, it's very much intentional.  You can obtain
word-splitting behavior with the ${=foo} form:

    % K="1 2 3"
    % for j in ${=K}; do echo "<ddd/$j>"; done
    <ddd/1>
    <ddd/2>
    <ddd/3>

You can also set SH_WORD_SPLIT, or rewrite the code to use an array.
If you're running code that relies on word-splitting (a POSIX script,
perhaps), you can run it under sh emulation.

> Wow! Are you still using just a mailing list for bug tracking?!

Yes.

-- 
vq


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

* Re: bug: nested for loop body is executed once!
  2021-08-13  3:50 ` Lawrence Velázquez
@ 2021-08-14 15:07   ` Daniel Shahaf
  0 siblings, 0 replies; 4+ messages in thread
From: Daniel Shahaf @ 2021-08-14 15:07 UTC (permalink / raw)
  To: Lawrence Velázquez, Daniil Iaitskov; +Cc: zsh-workers

Lawrence Velázquez wrote on Fri, 13 Aug 2021 03:50 +00:00:
> On Thu, Aug 12, 2021, at 11:13 PM, Daniil Iaitskov wrote:
> > Wow! Are you still using just a mailing list for bug tracking?!
> 
> Yes.

We do have various ways to track bugs, such as Etc/BUGS, but bug
_reports_ should go to the mailing list, yes.


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

end of thread, other threads:[~2021-08-14 15:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-13  3:13 bug: nested for loop body is executed once! Daniil Iaitskov
2021-08-13  3:47 ` Matthew Martin
2021-08-13  3:50 ` Lawrence Velázquez
2021-08-14 15:07   ` Daniel Shahaf

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