Sunday, March 7, 2010

When are sequences too much ?

I'm struggling with (one of many) artifacts of allowing expressions (variables, and positional parameters) be XdmValues, which allow sequences.
In generally this is a good, if not necessary thing.
It allows sequences to be stored in variables and produced as expressions and be preserved as sequences. For example

A=<[ 1 , 2 , ]>
xquery -f file.query -v sequence_var $A

Note that you can pass a single XdmValue ($A) as a parameter to Xquery.

The problem comes if you want to 'flatten' the sequence to seperate positional params.


A=$(ls) # produces a single sequence of files

echo $A

This looks right but under the hood echo is getting a single argument (argv[1]) which is a sequence.

Suppose I want to delete all these files

posix:rm $A

Ups ... rm now gets 1 argument ... it has to know that if the argument is sequence to iterate over each item like this
for i in $A ; do posix:rm $i ; done

For many commands getting sequences where they expect items is problematic.
But on the other hand being able to preserve sequences is critical.

So What to do ?
I'm working on (and open to suggestion) a syntax which forcibly flattens sequences into positional parameters.

Something like maybe

although I'd like it to work with inline expressions as well
posix:rm $(ls) # How to get this to flatten ?

Comments welcome on this idea


  1. I'm experimenting with a non-invasive partial solution for this problem. Its not a general solution but might be useful enough to be sufficient.

    I added a -E (or -expand) option to set.
    This tells set that it should expand (flatten) all sequences into individual XdmItme's for each positional parameter.

    set $(ls) # sets $1 to be a sequence of file names

    set -E -- $(ls) # sets $1...$N to be individual file names

  2. I've implemented a more invasive change, checked in but not released yet.
    This reverts the default behaviour for sequences to expand to multiple arguments, but allows direct control of each expression by using {expr}.

    set $(ls) # sets multiple args
    set {$(ls)} # sets 1 arg as a sequence
    set <[1,2,3]> # sets 3 args
    set {<[1,2,3]>} # sets 1 arg as sequence of 3


Due to comment spam, moderation is turned on. I will approve all non-spam comments.