Just to recap this thread. Thanks for thinking along. Sorry for the confusion about concat and the variable arguments because it wasn't the main point. I hope that the proposal I issued avoids this.
It is good to see Michael Kay commenting so quickly and admitting it's powerful but a lot of work. Not sure if he meant the impact on the spec or the implementers. I would still be chuffed if it would make it into 3.2 or 4 even :) because I believe that having a real fn:apply is the way forward and would bring XQuery further in the functional programming arena. After re-reading my proposal and weighing workarounds for my routing lib I still haven't found one that pleases me. The best I could come up with is to add annotations to the handler functions that do something similar as what RESTXQ is doing and this was exactly the thing I liked to avoid because it ties the handler function to the routing logic and I wanted a pure XQuery solution. If there are listeners that have a chance to lobby for this, please do ;) I am rooting for ya --Marc > On 14 aug. 2014, at 16:03, Christian Grün <christian.gr...@gmail.com> wrote: > > Hi Marc, hi Rob, > > thanks for your feedback. > >> PS it sure would be nice if such a construction were embedded in xquery. > > XQuery 3.1 is currently in the working draft stage. You can suggest > new features in the W3 issue tracker: > > https://www.w3.org/Bugs/Public > > Best, > Christian > > >> -----Oorspronkelijk bericht----- >> Van: Marc van Grootel [mailto:marc.van.groo...@gmail.com] >> Verzonden: donderdag 14 augustus 2014 13:42 >> Aan: Rob Stapper >> CC: BaseX >> Onderwerp: Re: [basex-talk] Apply variable argument list to anonymous >> function >> >> Maybe too much context? Sorry for that. I do sometimes get confused by this >> functions in functions inception stuff. Maybe it helps looking at the >> Clojure apply function examples by mentally translating syntax from XQuery >> str => concat and function application f(a,b) => (f a b) It's a function >> that is already available since 1.0 as it's very commonly used. >> >> I will try to come up with a simple but representative example this evening. >> >> Sorry for not being clearer. >> >> --Marc >> >>> On Thu, Aug 14, 2014 at 1:16 PM, Rob Stapper <r.stap...@lijbrandt.nl> wrote: >>> Marc, >>> >>> It's very hard to understand ( for me ;-) what you exactly want. >>> Maybe a solution for the downside of your solution is to make a >>> constructor-function for the construction of the $request ( map(*)) >>> available for your users over the internet: f.e: >>> >>> Import module namespace Marc = "www.marc.org/requestConstructor" >>> >>> $greeting, >>> Rob >>> >>> -----Oorspronkelijk bericht----- >>> Van: basex-talk-boun...@mailman.uni-konstanz.de >>> [mailto:basex-talk-boun...@mailman.uni-konstanz.de] Namens Marc van >>> Grootel >>> Verzonden: donderdag 14 augustus 2014 10:13 >>> Aan: Dirk Kirsten >>> CC: BaseX >>> Onderwerp: Re: [basex-talk] Apply variable argument list to anonymous >>> function >>> >>> Hi Dirk, Rob, >>> >>> I realize now that the example I gave the wrong impression. I am looking >>> for something general. That's why I added the link to the Clojure apply >>> function which has a couple of examples which show what it should do. >>> >>> Glossing over the hof functions in XQuery 3 and the hof module again I >>> realize that this is a function that really seems to be lacking and which >>> plays a very important role in functional languages, or at least in Lispy >>> languages and to my knowledge. >>> >>> Say you have this pseudocode: >>> >>> $fn = foo(a,b,c) >>> $args = (1,2,3) >>> >>> $fn($args) obviously doesn't work as it's interpreted as $fn((1,2,3)). >>> What apply does is to apply the function as in $fn(1,2,3). Fold doesn't get >>> me there because it does an application for each argument. >>> >>> Currently I can do this with one argument functions $fn($args[1]) and if >>> I'm not mistaken soon we can do $args[1] => $fn with the arrow operator. I >>> was thinking, hoping, that the semantics of the arrow operator would allow >>> this but apparently it won't. But just by looking at the following code: >>> >>> (1,2,3) => $fn >>> >>> My mind goes $fn(1,2,3). But to XQuery it means $fn((1,2,3)) probably due >>> to the flattening of nested sequences cannot do this as you would loose the >>> ability to provide a sequence as a single argument. >>> >>> Now some more context as the example I gave was misleading and conflated >>> two different issues. >>> >>> In my code I first compile a sequence of routes into handler functions. >>> Then when a request comes in I pass it as a map ($request) to this handler >>> function. >>> >>> Until now my code looks somewhat like this. >>> >>> declare function handler($request as map(*)) { ... }; >>> >>> $route-handler = def-route('GET', '/hello/{name}', handler#1) >>> >>> This way I can apply a request to this handler: >>> >>> $route-handler($request) >>> >>> This is all working fine. >>> >>> The downside is that all the handlers that a user writes must always have >>> the same signature: $request as map(*). I want to de-couple this so that a >>> user can write a handler function like: >>> >>> function greet($name as xs:string, $greeting as xs:string) { >>> fn:content('Hello ', $name, ' ', $greeting) >>> } >>> >>> Then in def-route: >>> >>> $route-handler = def-route('GET', '/hello/{name}/{greeting}', >>> ('name', 'greeting'), greet#2) >>> >>> This keeps the handler function free of having to deal with the request map >>> directly and also have the usual signature checking on request handling. >>> def-route will ensure that the handler knows how to take the 'name' and >>> 'greeting' params from the request map and to apply this two string >>> sequence to the function. >>> >>> There are probably other ways of getting around this if it turns out not to >>> be possible but they would be less elegant. >>> >>> >>> Cheers, >>> --Marc >>> >>>> On Thu, Aug 14, 2014 at 8:49 AM, Dirk Kirsten <d...@basex.org> wrote: >>>> 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 >>> >>> >>> >>> -- >>> --Marc >>> >>> >>> --- >>> Dit e-mailbericht bevat geen virussen en malware omdat avast! >>> Antivirus-bescherming actief is. >>> http://www.avast.com >> >> >> >> -- >> --Marc >> >> >> --- >> Dit e-mailbericht bevat geen virussen en malware omdat avast! >> Antivirus-bescherming actief is. >> http://www.avast.com