On 5/11/06, James Vega <[EMAIL PROTECTED]> wrote:
On Tue, May 09, 2006 at 06:43:22PM +0200, Axel Liljencrantz wrote:
> A problem with the set syntax has been nagging me for a long time. Set
> allows you to assign and erase slices of arrays using a convenient
> syntax like:
>
> set foo[1 3 7] foo bar baz
>
> in order to assign to the first, third and seventh element of the
> array foo, and with the same logic you can also use 'set -e foo[ 2 4]'
> to erase the second and fourth element of foo. This seems like it's
> all very clever, but unfortunatly it's actually a bit useless. The
> problem is that one rarely specifys the slicing indexes literally like
> that. What you'd want to do is something like
>
> set foo[(seq 3 5)] foo bar baz

Since () should just run the inner command and leave the result in their
place, I don't see why this couldn't work.  You'd just need to modify
the seq call slightly so that the indices are separated by spaces
instead of newlines.

  set foo[(seq -s" " 3 5)] foo bar baz

Absolutley, that always worked, and it still does. But it's a
workaround. Another situation with the same problem is if you have an
array if indices and one of values, you'd want to use

set foo[$indices] $values

Witout the suggested changed, you'd have to write

set foo["$indices"] $values

which still works. It's just that I dislike having to use workarounds
to access semi-common functionality.

Also keep in mind that the changes I propose are backwards compatible,
i.e. you can stlkl use

set foo[1 2 3] a b c

same as always.


On a side note,

  > echo foo{(seq 2)}
  foo1 foo2

already works as one would expect.  It becomes more problematic when you
add items outside the command expansion, but not overly so.  For
example,

  > echo foo{1,(seq -s, 2 3)}
  foo1 foo2 foo3

works as expected.  I'm actually quite surprised by the results of

  > echo foo{1,(seq 2 3)}
  foo1 foo2 foo1 foo3

as I see no reason why foo1 would be repeated between foo2 and foo3.

You have to look at parameter expansion as an outer product. If you
have four different parameter expansions (e.g. two different command
substitutions, one variable expansion and one brace expansion), with
each expansion producing 3 different values, your single argument will
be expanded into 3^4 = 81 different values:

fish> set var A B C;
fish> echo (echo a\nb\nc)_(echo 1\n2\n3)$var{I,II,III}

a_1AI a_1AII a_1AIII a_1BI a_1BII a_1BIII a_1CI a_1CII a_1CIII a_2AI
a_2AII a_2AIII a_2BI a_2BII a_2BIII a_2CI a_2CII a_2CIII a_3AI a_3AII
a_3AIII a_3BI a_3BII a_3BIII a_3CI a_3CII a_3CIII b_1AI b_1AII b_1AIII
b_1BI b_1BII b_1BIII b_1CI b_1CII b_1CIII b_2AI b_2AII b_2AIII b_2BI
b_2BII b_2BIII b_2CI b_2CII b_2CIII b_3AI b_3AII b_3AIII b_3BI b_3BII
b_3BIII b_3CI b_3CII b_3CIII c_1AI c_1AII c_1AIII c_1BI c_1BII c_1BIII
c_1CI c_1CII c_1CIII c_2AI c_2AII c_2AIII c_2BI c_2BII c_2BIII c_2CI
c_2CII c_2CIII c_3AI c_3AII c_3AIII c_3BI c_3BII c_3BIII c_3CI c_3CII
c_3CIII

This is not how either bash or rc does it.

In bash, if you have two commandsubstitutions, the last argument of
the first substitution is joined with the first argument of the second
substitution, but they are otherwise kept separate:

bash> echo $(echo -e "a\nb\nc")_$(echo -e "a\nb\nc")
a b c_a b c

I think that is not only unintuitive, but at least as importantly it
is useless. The fish syntax allows you to combine many types of
expansion in useful ways, the bash syntx use useful when, exactly?

In rc, if you have two command substitutions, they must both produce
exactly the same numbert of arguments, and they will be combined
pairwise. This is more reasonable than the bash expansion method, but
I still think the fish expansion rules are useful more often.


> or
>
> set idx 1 3 7
> set -e foo[$idx]

Again, it seems like this should work since $idx should just be replaced
by the '1 3 7' and then the slicing would be performed.

If $idx is an array, foo[$idx] will be expanded into one element for
each element in $idx. Arrays expand to multiple arguments in fish.
Otherwise things like 'for i in $idx; ...; end' wouldn't work.


> [snip]
> There are still a few gotchas left, though:
>
> * Some people might expect e.g. 'set foo[1 (seq 4 6)] a b c d' to work
> and use the slice indexes '1 4 5 6', but it won't, since it will
> result in the slice indexes '1 4 1 5 1 6'. This is the right thing in
> my opinion, but it is a bit confusing at first.

I'd like to hear an explanation as to why that is correct as it makes no
sense to me.  I have no problem with expecting the user to use

Think about it from the point of view of parameter expansion. No
specuial casing, nothing. What happens when we execute 'set foo[1 (seq
4 6)] a b c d'?

Well, first the subshell 'seq 4 6' is executed. It results in a list
of three elements, '4', '5', and '6'. Fish will now copy the original
argument once for each element in the list, and splice in that
element. So we get the transformation

foo[1 (seq 4 6)] -> foo[1 4] foo[1 5] foo[1 6]

There are no other parameter expansion, so the list of arguments shown
to 'set' is:

argv = set foo[1 4] foo[1 5] foo[1 6] a b c d

And then the headaches begin.

If we where to remove the part where sommand substitutions are turned
into lists, we would get a much less useful syntax, we couldn't do
things like:

for i in (cat /etc/passwd); ...; end

in order to loop over all users.


  set foo[1 (seq -s" " 4 6)] a b c d

though since that would properly replicate manually typing the indices.

Absolutley, that works now, and it should _definitley_ keep working.


What it seems to come down to is that you 'just' need to change the
parsing algorithm so that operations are performed from the inner-most
'scope' outwards.  I think this would also behave more like users tend
to expect.

I'm not following you here. Could you rephrase?


James

P.S. Sorry if I repeated some ideas from the other replies in the
thread, but I decided this one email would be easier than replying to
the various different emails I wanted to in the thread.

--
Axel


-------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid0709&bid&3057&dat1642
_______________________________________________
Fish-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/fish-users

Reply via email to