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-boun...@mailman.uni-konstanz.de 
> [mailto:basex-talk-boun...@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

Reply via email to