Hi Sebastian, A quick comment for your code : it is better to use it sparsely, because inspect:functions is quite slow. If you want to improve perfs, create first a map. Here is the code that I am using for this kind of "overloading"
declare variable $common:MapIntrospecting := common:map_inspect_functions(); declare function common:name-function($fun as function(*)){fn:data(inspect:function($fun)/@name)}; declare function common:map_inspect_functions() { map:new(for $fun in inspect:functions() return map:entry(common:name-function($fun),$fun)) }; (this one has to be modified accordingly to your %dispatch annotation, i.e. add where exists(inspect:function($f)[annotation[@name='dispatch: default'][literal[1]=$id]])) and the dispatcher becomes simply declare function common:dispatcher(nodes as node()*,$fun as *function(*)*) as item()* { let $disptchedfun := map:get($common:MapIntrospecting, *common:name-function($fun)*) return if (empty($disptchedfun)) then $fun($nodes) else $disptchedfun($nodes) ) }; >By „map of functions“ did you mean what "inspection:functions()“ is doing? No, I am talking about a map that can take any item a keys, and any item as values. For instance, in the code above, I would prefer to write the following dispatcher declare function common:dispatcher(nodes as node()*,$fun as *function(*)*) as item()* { let $disptchedfun := map:get(common:MapIntrospecting(),$fun) return if (empty($disptchedfun)) then $fun($nodes) else $disptchedfun($nodes) ) }; Its is simply a question of performance : in the first mechanism, you have first to "serialize" the function as a string (calling the inspect:function), then to look to a map(string, function), to finally get the correct function call. In the second you directly access to the function, avoiding an expensive call (inspect:function). However, most probably this enhancement would be of less impact in your code, if you don't call this dispatcher trillions of time. >I don’t get it: how would you be able to overload the query eval function? exactly as above. It is something a little bit more elaborate than the following code declare function common:evil_eval($nodes as node()*,$expr as xs:string) as item()* { try { let $fun := map:get($common:MapIntrospecting,$expr) return if (empty($fun)) then xquery:eval('$xml'||$expr,map{'$xml' := $nodes}) else $fun($nodes) } catch *("ouch") }; Hope this helps Cheers, Jean-Marc 2013/12/2 Christian Grün <christian.gr...@gmail.com> > Hi Sebastian, > > > BTW: I unfortunately missed your and Alexanders presentation at the > MarkUp > > Forum: are there any slides available? > > The slides should soon be available here: > http://www.markupforum.de/archiv.html > > > This is similar to imported modules in XSLT: If you import template > rules, > > which are more specific, > > they will be applied first. Could this be applied to XQuery as well? > (But in > > XSLT you would have to > > import the custom code and hence change your code. We can do that in > XQuery > > as well, but it > > is not completely decoupled, is it?) > > As Jean-Marc pointed out, the Inspection Module may help out. The > module is fairly new, so we are interested in your (and everyone’s) > feedback if you would like to have some functions added.. > > Christian > _______________________________________________ > BaseX-Talk mailing list > BaseX-Talk@mailman.uni-konstanz.de > https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk >
_______________________________________________ BaseX-Talk mailing list BaseX-Talk@mailman.uni-konstanz.de https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk