Short version: When I call prof:track(...) with an expression as argument, I get the results I would expect. When I assign prof:track#1 to a variable and then call it with an expression by referring to that variable, the time shown is always 0. Is this the expected behavior?
Details: Consider the following XQuery module: let $f := function($s as xs:string) { trace('hi'), prof:sleep(2000), trace($s) }, $pt := (function-lookup( QName('http://basex.org/modules/prof', 'track'), 1), function($item) { map {'time':'?', 'value': $item} } )[1] return (prof:track($f('world')), $pt($f('friends!')) ) It defines two variables: - $f, a function that produces output (so I can see that it ran) and calls prof:sleep (so it takes more than a couple of ms), and - $pt, which will be the prof:track() function if it exists (as it will in BaseX) or a substitute function which just evaluates the expression but does not provide any timing information. It then calls function $f twice, once wrapped in prof:track() and once wrapped in $pt(). The output follows: map { "memory": 0, "time": 2.00069e3, "value": ("hi", "world") } map { "memory": 0, "time": 0.0e0, "value": ("hi", "friends!") } As may be seen, the 'time' value in the map is 0. Conjecture: I suspect that this has to do with the fact that prof:track() is not a normal function -- in Lisp or Scheme, it would have to be implemented as a macro or 'special form', meaning that the arguments to the call are not evaluated before calling the function. I wonder whether what is happening here is that when the call to $pt($f('friends')) is handled, the argument is being evaluated (producing the sequence ('hi', 'friends!')) and then prof:track() is being called. Since it has no work to do, prof:track() then just returns the result, accurately showing a time cost of 0. Background: In a test harness I use to run tests for an XQuery program I am writing, I initially used prof:track() to keep track of how long each test takes to run. Recently, as part of an effort to ensure that the program is implementation-neutral, I rewrote the test harness so that it could run under other XQuery engines as well -- hence the indirection and the definition of $pt. I realize that I could get the BaseX version to work by saying something like let $prof-track := function-lookup(...) let $fall-back := function(...) if (exists($prof-track)) then prof:track(...) else $fall-back(...) but my recollection is that I tried this first and it provoked fatal errors in other engines, since prof:track() is not available in the static context in those engines. Is there any way to write a single module so that prof:track() is used (and produces useful information) if available, and the fallback function is used otherwise? I would really like to avoid generating different versions of the test harness for different XQuery engines. Many thanks for any thoughts or advice anyone on this list can provide. Michael Sperberg-McQueen -- C. M. Sperberg-McQueen Black Mesa Technologies LLC http://blackmesatech.com