Discussion:
[xquery-talk] Empty or Null Array?
Eliot Kimber
2015-07-16 14:11:31 UTC
Permalink
I'm using an array to pass values down a recursive function call chain.

I noticed that, at least with BaseX but also based on my reading of the
3.1 spec, that you cannot construct an empty array.

Is this correct?

If so, how can one have a function where the array is effectively empty?
E.g., given this function declaration:

declare ns:myFunc($arg1 as xs:string+, $arg2 as array(*)?, $arg3 as
xs:string) {};

How can I satisfy the second argument when in fact I have no items for the
array?

I tried passing in () but BaseX says "Cannot cast empty-sequence() to
array(*)", which makes sense.

I would expect array{} to be a valid constructor, such that

array:size(array{}) = 0 is true but that does not appear to be allowed for
in the 3.1 spec.

What have I missed?

Thanks,

Eliot

----
Eliot Kimber, Owner
Contrext, LLC
http://contrext.com



_______________________________________________
***@x-query.com
http://x-query.com/mailman/listinfo/talk
Eliot Kimber
2015-07-16 14:29:26 UTC
Permalink
I do see that I can do:

let $array := [()]

To create an array with one member that is an empty sequence.

My business problem is I need to pass an array of sequences to a recursive
function, where each recursion takes the cadr of the array. When the array
is empty, recursion stops. So the question is, how to determine that an
array is "empty" given that an array must have at least one member.

It looks like the answer is "an array is empty when the only member is an
empty sequence".

Is my analysis correct?

Cheers,

E.
----
Eliot Kimber, Owner
Contrext, LLC
http://contrext.com
Post by Eliot Kimber
I'm using an array to pass values down a recursive function call chain.
I noticed that, at least with BaseX but also based on my reading of the
3.1 spec, that you cannot construct an empty array.
Is this correct?
If so, how can one have a function where the array is effectively empty?
declare ns:myFunc($arg1 as xs:string+, $arg2 as array(*)?, $arg3 as
xs:string) {};
How can I satisfy the second argument when in fact I have no items for the
array?
I tried passing in () but BaseX says "Cannot cast empty-sequence() to
array(*)", which makes sense.
I would expect array{} to be a valid constructor, such that
array:size(array{}) = 0 is true but that does not appear to be allowed for
in the 3.1 spec.
What have I missed?
Thanks,
Eliot
----
Eliot Kimber, Owner
Contrext, LLC
http://contrext.com
_______________________________________________
http://x-query.com/mailman/listinfo/talk
_______________________________________________
***@x-query.com
http://x-query.com/mailman/listinfo/talk
John Snelson
2015-07-16 14:43:59 UTC
Permalink
On 16/07/2015 10:29, Eliot Kimber wrote:

I do see that I can do:

let $array := [()]

To create an array with one member that is an empty sequence.

My business problem is I need to pass an array of sequences to a recursive
function, where each recursion takes the cadr of the array. When the array
is empty, recursion stops. So the question is, how to determine that an
array is "empty" given that an array must have at least one member.

It looks like the answer is "an array is empty when the only member is an
empty sequence".

Is my analysis correct?



No. The grammar is this:

[73] ArrayConstructor<http://www.w3.org/TR/xpath-31/#prod-xpath31-ArrayConstructor> ::= SquareArrayConstructor<http://www.w3.org/TR/xpath-31/#doc-xpath31-SquareArrayConstructor> | CurlyArrayConstructor<http://www.w3.org/TR/xpath-31/#doc-xpath31-CurlyArrayConstructor>
[74] SquareArrayConstructor<http://www.w3.org/TR/xpath-31/#prod-xpath31-SquareArrayConstructor> ::= "[" (ExprSingle<http://www.w3.org/TR/xpath-31/#doc-xpath31-ExprSingle> ("," ExprSingle<http://www.w3.org/TR/xpath-31/#doc-xpath31-ExprSingle>)*)? "]"
[75] CurlyArrayConstructor<http://www.w3.org/TR/xpath-31/#prod-xpath31-CurlyArrayConstructor> ::= "array" "{" Expr<http://www.w3.org/TR/xpath-31/#doc-xpath31-Expr>? "}"

The SquareArrayConstructor has parentheses and a "?" operator around the exprSingles inside it, so they are optional and can be left out. Thus you can use "[]" for an empty array.

Similarly the CurlyArrayConstructor for a "?" on it's Expr so it can be left out. Thus you can also use "array{}" for an empty array.

John


--
John Snelson, Lead Engineer http://twitter.com/jpcs
MarkLogic Corporation http://www.marklogic.com
John Snelson
2015-07-16 14:31:15 UTC
Permalink
Hi Eliot,

The grammar allows you to use both "[]" and "array{}" to create an empty
array:

http://www.w3.org/TR/xpath-31/#id-arrays

John
Post by Eliot Kimber
I'm using an array to pass values down a recursive function call chain.
I noticed that, at least with BaseX but also based on my reading of the
3.1 spec, that you cannot construct an empty array.
Is this correct?
If so, how can one have a function where the array is effectively empty?
declare ns:myFunc($arg1 as xs:string+, $arg2 as array(*)?, $arg3 as
xs:string) {};
How can I satisfy the second argument when in fact I have no items for the
array?
I tried passing in () but BaseX says "Cannot cast empty-sequence() to
array(*)", which makes sense.
I would expect array{} to be a valid constructor, such that
array:size(array{}) = 0 is true but that does not appear to be allowed for
in the 3.1 spec.
What have I missed?
Thanks,
Eliot
----
Eliot Kimber, Owner
Contrext, LLC
http://contrext.com
_______________________________________________
http://x-query.com/mailman/listinfo/talk
--
John Snelson, Lead Engineer http://twitter.com/jpcs
MarkLogic Corporation http://www.marklogic.com

_______________________________________________
***@x-query.com
http://x-query.com/mailman/listinfo/talk
Eliot Kimber
2015-07-16 14:43:19 UTC
Permalink
So it does--I misread the BNF diagram.

The error I'm getting from BaseX appears to be something different than I
thought it was, as this does work:

let $array := []
return <result>{$array}</result>


So it must be something accessing my empty array that is not happy with it
being empty.

Cheers,

E.
----
Eliot Kimber, Owner
Contrext, LLC
http://contrext.com
Post by John Snelson
Hi Eliot,
The grammar allows you to use both "[]" and "array{}" to create an empty
http://www.w3.org/TR/xpath-31/#id-arrays
John
Post by Eliot Kimber
I'm using an array to pass values down a recursive function call chain.
I noticed that, at least with BaseX but also based on my reading of the
3.1 spec, that you cannot construct an empty array.
Is this correct?
If so, how can one have a function where the array is effectively empty?
declare ns:myFunc($arg1 as xs:string+, $arg2 as array(*)?, $arg3 as
xs:string) {};
How can I satisfy the second argument when in fact I have no items for the
array?
I tried passing in () but BaseX says "Cannot cast empty-sequence() to
array(*)", which makes sense.
I would expect array{} to be a valid constructor, such that
array:size(array{}) = 0 is true but that does not appear to be allowed for
in the 3.1 spec.
What have I missed?
Thanks,
Eliot
----
Eliot Kimber, Owner
Contrext, LLC
http://contrext.com
_______________________________________________
http://x-query.com/mailman/listinfo/talk
--
John Snelson, Lead Engineer http://twitter.com/jpcs
MarkLogic Corporation http://www.marklogic.com
_______________________________________________
http://x-query.com/mailman/listinfo/talk
_______________________________________________
***@x-query.com
http://x-query.com/mailman/listinfo/talk
Eliot Kimber
2015-07-16 14:51:47 UTC
Permalink
I see my error: accessing a member that does not exist is a dynamic error,
so:

let $array := []
let $item1 := $array(1)

Throws an error.

I naively expected it to return an empty sequence. But upon reflection the
defined behavior in the spec is correct, otherwise you wouldn't be able to
distinguish the lack of a member and a member whose value is an empty
sequence.

So array:size($array) := 0 is the correct way to test for an empty array.

It would be useful if the 3.1 spec had some examples of these cases--I'm
not seeing any examples of creating an empty array in the Array
Constructors section.

Cheers,

Eliot
----
Eliot Kimber, Owner
Contrext, LLC
http://contrext.com
Post by John Snelson
Hi Eliot,
The grammar allows you to use both "[]" and "array{}" to create an empty
http://www.w3.org/TR/xpath-31/#id-arrays
John
Post by Eliot Kimber
I'm using an array to pass values down a recursive function call chain.
I noticed that, at least with BaseX but also based on my reading of the
3.1 spec, that you cannot construct an empty array.
Is this correct?
If so, how can one have a function where the array is effectively empty?
declare ns:myFunc($arg1 as xs:string+, $arg2 as array(*)?, $arg3 as
xs:string) {};
How can I satisfy the second argument when in fact I have no items for the
array?
I tried passing in () but BaseX says "Cannot cast empty-sequence() to
array(*)", which makes sense.
I would expect array{} to be a valid constructor, such that
array:size(array{}) = 0 is true but that does not appear to be allowed for
in the 3.1 spec.
What have I missed?
Thanks,
Eliot
----
Eliot Kimber, Owner
Contrext, LLC
http://contrext.com
_______________________________________________
http://x-query.com/mailman/listinfo/talk
--
John Snelson, Lead Engineer http://twitter.com/jpcs
MarkLogic Corporation http://www.marklogic.com
_______________________________________________
http://x-query.com/mailman/listinfo/talk
_______________________________________________
***@x-query.com
http://x-query.com/mailman/listinfo/talk

Loading...