On 5/14/06, Beni Cherniavsky <[EMAIL PROTECTED]> wrote:
On 5/14/06, Axel Liljencrantz <[EMAIL PROTECTED]> wrote:
> On 5/12/06, Beni Cherniavsky <[EMAIL PROTECTED]> wrote:
> >
> > Now, later in this thread you explain that all expansion in fish works as
> > outer products.  For example::
> >
> >     echo %.(echo a\nb).(echo 1\n2)
> >     echo {%,(echo a\nb),(echo 1\n2)},
> >
> > prints::
> >
> >     %.a.1 %.a.2 %.b.1 %.b.2
> >     %, a, 1, %, a, 2, %, b, 1, %, b, 2,
> >
> > The first is obviously useful, for some of the examples you gave.  The
> > second is questionable.

But sometimes useful: ``fgrep {-f,(ls *.words)}`` expands to ``fgrep
-f some.words -f more.words``

> > I agree brace/command/variable expansions written side-by-side
> > (``%.$v.(seq 2)``)
> > should form an outer product, but inside braces, I think they should be 
joined,
> > just like ``{%,{a,b},{1,2}}`` produces ``% a b 1 2``.
> >
> > What I'm driving at is that braces, not brackets, should be the
> > joining operator
> > that I talked about.

Thinking some more, I would like to consider the operators that are
frequently useful in a shell:

word_concat(a, 1) -> a1
list_concat([a b], [1 2]) -> [a b 1 2]
word_product([a b], [1 2]) -> [a1 a2 b1 b2]
list_product([a b], [1 2]) -> [a 1 a 2 b 1 b 2]
word_parallel([a b], [1 2]) -> [a1 b2]
list_parallel([a b], [1 2]) -> [a 1 b 2]

What we have now:

word_concat() doesn't really exist because words are built from items
like variable expansion that produce lists. In fish, it's a special
case of word_product().  [In bash, it's a special case of something
useless ;-).  In rc, it's a special case of word_parallel().]
The top level of a command line is list_concat() but it's not
availiable otherwise.
list_product() is availiable through braces but in a surprising way.
word_parallel() and list_parallel() are not availiable.

You can implement word_parallel() as::

    (paste -d "" (echo a\nb | psub) (echo 1\n2 | psub))

and list_parallel() as::

    (paste -d \n (echo a\nb | psub) (echo 1\n2 | psub))

Both are rarely needed, so I think this is good enough.

In this thread we want list_concat() inside array indexing.  Since
``$a[1 2]`` already expands into two words, it's not baseless.  It can
be implemented as::

    (printf '%s\n' 1 (seq 4 7))

but perhaps some direct syntax (not necessarily limited to indexing)
would be useful.

word_product() is extremely useful in simple cases like ``img(seq
5).png`` and it should remain availiable for such uses.

list_product() is sometimes useful (see fgrep example above).  You
could implement it with::

    (printf '%s' (echo a\nb)\n(echo 1\n2))\n

----

Note that all implementations using external commands suffer from
false splitting if any word contains newlines.  It's not a critical
usability bug like space-splitting was in bash but it still might be a
security bug in some situations.  Let's try reliable implementation
with arrays:

function vsub
    # should check that it's unused and register deletion
    # when calling job exits (see psub implementation)
    set -l name _vsub_(random)
    set -g $name $argv
    echo $name
end

# Such functions that return variable names could
# be used like ``$(vsub ...)`` if fish didn't catch it.
# This is useful for testing
function deref
    echo $$argv
end

function concat_arrays
    # variable indirection is also a product!
    vsub $$argv
end

function list_parallel
    concat_arrays (
        for i in (seq (count $$argv[1]))  # should take max or min or what?
            for v in $argv
                echo $$v[1][$i]
            end
        end)
end

function word_parallel
    concat_arrays (
        for i in (seq (count $$argv[1]))
            eval vsub (
                for v in $argv
                    echo -n \${$v}\[$i\]
                end)
        end)
end

So I hacked perlish references int the flat data structures of fish.
May God forgive me ;-\.
No, I do NOT think this is the right way.  But I do want robust
operations on word lists.
Ideas?

If we extend what you are saying here, we come to the conclusion that
no matter what parameter expansion model we choose, se can implement a
few functions which let's us use all other models. I think this is
very important to note. No matter what model we choose, all other
behaviours can be had by writing a simple shellscript function to do a
little transforming.

So the main problem is what should be the standard behaviour. Here, we
have to take into account what is most often what you want, what
concept is easiest to explain and what concept most users would
expect.

My opinion:

Outer product seems to be what you want a large part of the time, it
is also very easy to explain, but users coming from another shell will
definitely not expect it.

Plain concatenation (Never tokenize command substitutions) seems to
rarely be what you want, it is very easy to explain, newbies would
expect it, but people coming from other shells would be surprised.

The Posix way (Tokenize command substitutions, prepend previous things
to the first element, append following things to the last element)
seems to rarely be what you want, it is hard to explain, newbies would
be surprised, but people coming from other shells would expect it.

--
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&kid=120709&bid=263057&dat=121642
_______________________________________________
Fish-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/fish-users

Reply via email to