> 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

Reply via email to