Hi Rob,
I hope you don't mind I used your example apply code in the module I'm working on. I've adapted it a bit as well (including code reformatting so you may not even recognize it ;-) and left it as an attachment to https://www.w3.org/Bugs/Public/show_bug.cgi?id=26585
It currently does the trick for me, so thanks.
--Marc
On Thu, Aug 14, 2014 at 10:23 AM, Rob Stapper r.stapper@lijbrandt.nl wrote:
Dirk, Marc,
True enough. If it's the concat with variable arg-list you want, do use the string-join:
let $args := ('a', 'b', 'd') return string-join( $args)
if the concat is an example of a more general case then you probably will end up with the folds, including the impact on the performance ;-)
Enjoy,
Rob -----Oorspronkelijk bericht----- Van: basex-talk-bounces@mailman.uni-konstanz.de [mailto:basex-talk-bounces@mailman.uni-konstanz.de] Namens Dirk Kirsten Verzonden: donderdag 14 augustus 2014 8:49 Aan: basex-talk@mailman.uni-konstanz.de Onderwerp: Re: [basex-talk] Apply variable argument list to anonymous function
Hi Rob, Hi Marc,
As Rob showed, HOF functions are a possible (and I think actually the only way, although I am not sure) way to deal with functions like concat, which do expect a variable number of arguments. This is very valid and might be a valid solution. I would just like to add that you should keep the performance in mind. fold-left() of course comes to a price. A simple comparison using fold vs. using string-join
declare variable $args := let $a := ('a', 'b', 'c') for $i in 1 to 50000 return $a[random:integer(3) + 1];
declare function local:apply($fn, $args) { $fn($args) };
declare function local:apply2($fn, $args) { fold-left($args, '', $fn) };
( prof:time(local:apply2(concat#2, $args)), prof:time(local:apply(fn:string-join#1, $args)) )
shows a huge performance impact (around 500ms for fold, 0.01ms for string-join).
This is not me saying you should not use fold (in fact it is a very nice and elegant function), but that you might want to consider the performance impact.
Cheers, Dirk
On 14/08/14 08:15, Rob Stapper wrote:
Par example:
declare variable $args := ('a', 'b', 'c');
declare function local:apply
( $fn , $args ) { fold-left( $args , '' , $fn ) } ;
local:apply( concat#2, $args)
Van: basex-talk-bounces@mailman.uni-konstanz.de [mailto:basex-talk-bounces@mailman.uni-konstanz.de] Namens Marc van Grootel Verzonden: woensdag 13 augustus 2014 22:16 Aan: BaseX Onderwerp: [basex-talk] Apply variable argument list to anonymous function
Hi,
I am trying to call an anonymous function with a variable argument list.
Maybe I'm overlooking something within XQuery but I cannot figure out how to do this.
This is the code I would like to get working.
declare function local:apply($fn, $args) {
$fn($args)
};
declare variable $concat := fn:concat#3;
declare variable $args := ('a', 'b', 'c'); (: needs to handle any list of strings :)
local:apply($concat, $args)
(: => 'abc' :)
What I want local:apply to do is similar to apply in some function languages such as Clojure (http://clojuredocs.org/clojure_core/clojure.core/apply)
In the code above I have two problems. a) how to bind the fn:concat function to a variable. Arity? #1, #2 ... ? b) how to "apply" a variable argument list to the function passed in to local:apply.
I figure I could do something maybe with some other higher order functions but I cannot see the solution. I don't mind rtfm responses, I may have missed it.
I keep bombarding the list with questions so it is only fair to give a bit of context. I am porting parts of a few small Clojure libraries to XQuery, most important libraries are Ring and Compojure which are libraries for use in web frameworks. My implementation currently builds on top of RESTXQ but eventually can provide an alternative way of handling HTTP routing requests through function handlers (without function annotations). This is similar to WSGI in Python and Rack in Ruby. I would've liked to release this sooner but it is more work than anticipated and I want to provide something that does these ideas justice. So it's ready when it's ready ;-) but I'm pretty close. I'm currently finalizing the routing part and need to work some more on middleware handlers. Until then go look at https://github.com/ring-clojure to see what this is about.
--Marc
Dit e-mailbericht bevat geen virussen en malware omdat avast! Antivirus-bescherming actief is. http://www.avast.com
-- Dirk Kirsten, BaseX GmbH, http://basex.org |-- Firmensitz: Blarerstrasse 56, 78462 Konstanz |-- Registergericht Freiburg, HRB: 708285, Geschäftsführer: | Dr. Christian Grün, Dr. Alexander Holupirek, Michael Seiferle `-- Phone: 0049 7531 28 28 676, Fax: 0049 7531 20 05 22
Dit e-mailbericht bevat geen virussen en malware omdat avast! Antivirus-bescherming actief is. http://www.avast.com