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.gruen@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