I rely heavily on function mapping, but I wasn't aware of the behavior for the
null case, so I had a real head scratcher of a bug - my function was more like
func($s as xs:string, $b as xs:boolean){...}. It was receiving
func("something",()), so I incorrectly assumed that the function wasn't getting
nulled out.
Thanks for all of the clarifications.
-Will
-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Ron Hitchens
Sent: Saturday, June 18, 2011 6:13 AM
To: General MarkLogic Developer Discussion
Subject: Re: [MarkLogic Dev General] Why does xs:boolean(())=()?
> Passing a () value to any function with function mapping turned on doesn't
> call the function at all.
That's overstating it a bit. Function mapping comes
into play when you pass a sequence (possibly empty) for
a parameter that is declared as a singleton (one and only
one allowed). In that case, an implicit FLWOR is created
to iterate over the sequence and call the function once
for each value.
For example:
declare function local:myfunc ($param as xs:string) {
fn:concat ("Hello ", $param)
};
Calling this function like this: local:myfunc ("Fred")
produces the single string:
"Hello Fred"
Calling it like: local:myfunc (("Fred", "Sally"), produces:
("Hello Fred", "Hello Sally")
Because it's the equivalent of:
for $i in ("Fred", "Sally")
return local:myfunc ($i)
Calling it like this: local:myfunc (()), either
on purpose or because a variable you pass in is an empty
sequence, produces an empty sequence because the implicit
FLWOR iterates zero times.
If the function looked like this, adding "*" to the
parameter definition:
declare function local:myfunc ($param as xs:string*) {
fn:concat ("Hello ", $param)
};
Then calling it as: local:myfunc (("Fred", "Sally"),
invokes the function only once and sends the sequence
as the value of $param. That would cause fn:concat to
blowup because it doesn't like sequences.
Note also that this applies to ALL the singleton
parameters. A function like this:
declare function local:myfunc ($p1 as xs:string, $p2 as xs:string) {
fn:concat ("Good ", $p1, " ", $p2)
};
If called like this:
local:myfunc (("morning", "evening"), ("Fred", "Sally"))
Will be called four times and produce this sequence:
("Good morning Fred", "Good evening Fred",
"Good morning Sally", "Good evening Sally")
Function mapping is slick and powerful, but can lead
to a lot of head scratching.
If you're sending XPath expressions to a function, it
may be less confusing to apply the function in the XPath
itself. Like this:
/some/path/name/first-name/local:myfunc(.)
It's a little more obvious here that the function
applies to each item matched by the XPath (which may
be none at all).
Hope that helps.
On Jun 17, 2011, at 8:00 PM, Keith L. Breinholt wrote:
> Your function was never called. You have been bitten by function mapping.
> Passing a () value to any function with function mapping turned on doesn't
> call the function at all.
>
> Function mapping is turned on by default. If you want it off put this at the
> top of your code.
>
> declare option xdmp:mapping "false";
>
> Hope that helps.
>
> - Keith
>
>
> -----Original Message-----
> From: [email protected]
> [mailto:[email protected]] On Behalf Of G. Ken Holman
> Sent: Friday, June 17, 2011 12:38 PM
> To: General MarkLogic Developer Discussion
> Subject: Re: [MarkLogic Dev General] Why does xs:boolean(())=()?
>
> At 2011-06-17 17:58 +0000, Will Thompson wrote:
>> Can someone explain why passing this function () returns (), instead of
>> an element or throwing an exception?
>>
>> declare function local:do-stuff(
>> $bool as xs:boolean
>> ) as element() {
>> if ($bool)
>> then <x/>
>> else <y/>
>> };
>
> I would expect passing the function an argument value of () would return a
> runtime error because there is no optionality allowed on the datatype of the
> argument. An argument of xs:boolean* would allow the empty set to be passed
> as an argument and <y/> would be returned.
>
>> I see that xs:boolean(())=(),
>
> Correct if you are expressing a comparison operator there. Both sides
> evaluate to false(), but for slightly different reasons ... or rather, the
> same reason but different mechanisms.
>
> The left-hand side is explicitly computing the effective-boolean-value of the
> empty set and the right-hand side implicitly (because it is an operand of the
> operator) expresses the effective-boolean-value of an empty set.
>
> The two false() values equate as true().
>
> If you are using "=" in your statement as a notation for "returns", then the
> statement is not correct ... xs:boolean(()) returns false().
>
>> but it seems like this should either eval to false(), or the function
>> should throw an exception since () isn't a boolean (or is it?).
>
> xs:boolean does a cast of the argument. The first bullet of the
> documentation cites what is returned when the argument is an empty set:
>
> http://www.w3.org/TR/2007/REC-xpath-functions-20070123/#func-boolean
>
> The implicit cast for the equality operator is defined here:
>
> http://www.w3.org/TR/2007/REC-xpath-functions-20070123/#func-boolean-equal
>
> I hope this helps.
>
> . . . . . . . . . . . Ken
>
> --
> Contact us for world-wide XML consulting & instructor-led training
> Crane Softwrights Ltd. http://www.CraneSoftwrights.com/q/
> G. Ken Holman mailto:[email protected]
> Legal business disclaimers: http://www.CraneSoftwrights.com/legal
>
> _______________________________________________
> General mailing list
> [email protected]
> http://developer.marklogic.com/mailman/listinfo/general
>
>
> NOTICE: This email message is for the sole use of the intended recipient(s)
> and may contain confidential and privileged information. Any unauthorized
> review, use, disclosure or distribution is prohibited. If you are not the
> intended recipient, please contact the sender by reply email and destroy all
> copies of the original message.
>
>
> _______________________________________________
> General mailing list
> [email protected]
> http://developer.marklogic.com/mailman/listinfo/general
---
Ron Hitchens {mailto:[email protected]} Ronsoft Technologies
+44 7879 358 212 (voice) http://www.ronsoft.com
+1 707 924 3878 (fax) Bit Twiddling At Its Finest
"No amount of belief establishes any fact." -Unknown
_______________________________________________
General mailing list
[email protected]
http://developer.marklogic.com/mailman/listinfo/general
_______________________________________________
General mailing list
[email protected]
http://developer.marklogic.com/mailman/listinfo/general