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

Reply via email to