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

Reply via email to