And just to underscore a point that Ron made, if you are OK with a function taking and empty sequence as a parameter, it is good practice to type it with a * or ?, and then you will never get function mapping to occur (it requires a singleton). Of course you will have to code your function so it does something reasonable when you pass it an empty sequence, in that case.
-Danny -----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of Will Thompson Sent: Monday, June 20, 2011 9:19 AM To: General MarkLogic Developer Discussion Subject: Re: [MarkLogic Dev General] Why does xs:boolean(())=()? 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 _______________________________________________ General mailing list [email protected] http://developer.marklogic.com/mailman/listinfo/general
