Apply variable argument list to anonymous function
Wednesday, 13 August 2014 · 16 messages · last reply 26 Aug 2014
MG
Marc van Grootel13 Aug 2014 22:15 #
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.
--MarcDK
Dirk Kirsten13 Aug 2014 23:55 #
Hi Marc,
interesting question! Although I don't actually now the answer, I think there is an easy work-around for this one. Simply use string-join() instead of concat, i.e.
declare variable $concat := fn:string-join#1;It will yield the same result.
I don't actually know how to properly handle the variable number of arguments for
fn:concat to use as function items, so the core of your question is quite interesting. However, I think that concat even has a variable number of arguments is rather strange and impractical (normally simply a sequence of items is used in lots of other function declarations). According to the spec
(http://www.w3.org/TR/xpath-functions/#func-concat) it sounds very much this is due to backwards compatibility. I am sure someone from our team with more function-item knowledge than I am knows the answer how (or if?) this can be done.
By the way, your project sounds quite interesting! I only have a very slight idea what it actually is (because I am not really familiar with the technologies you mentioned and compared it to), but handling HTTP routing sounds and porting from Clojure sounds good to me.
Cheers,
DirkQuoted text · Marc van Grootel · 47 lines
On 13/08/14 22:15, Marc van Grootel wrote: > 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 >
--
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
RS
Hi Marc,
I’m a basex-user but checkout the fold-functions: fold-left(), fold-right. See: http://docs.basex.org/wiki/Higher-Order_Functions_Module
Success,
Rob Stapper
Quoted text · basex-talk-bounces at mailman.uni-konstanz.de · 23 lines
Van: basex-talk-bounces at mailman.uni-konstanz.de [mailto:basex-talk-bounces at 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
RS
And, this one: http://docs.basex.org/wiki/Higher-Order_Functions
Rob
Quoted text · basex-talk-bounces at mailman.uni-konstanz.de · 23 lines
Van: basex-talk-bounces at mailman.uni-konstanz.de [mailto:basex-talk-bounces at 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
RS
Par example:
declare variable $args := ('a', 'b', 'c');
declare function local:apply ( $fn
, $args
)
{ fold-left( $args
, ''
, $fn
)
} ;
local:apply( concat#2, $args)Quoted text · basex-talk-bounces at mailman.uni-konstanz.de · 23 lines
Van: basex-talk-bounces at mailman.uni-konstanz.de [mailto:basex-talk-bounces at 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
DK
Dirk Kirsten14 Aug 2014 08:49 #
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
Quoted text · Rob Stapper · 96 lines
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 at mailman.uni-konstanz.de [mailto:basex-talk-bounces at 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
MG
Marc van Grootel14 Aug 2014 10:12 #
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
Quoted text · Dirk Kirsten · 141 lines
On Thu, Aug 14, 2014 at 8:49 AM, Dirk Kirsten <dk at 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-bounces at mailman.uni-konstanz.de [mailto:basex-talk-bounces at 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
RS
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-----
Quoted text · basex-talk-bounces at mailman.uni-konstanz.de · 135 lines
Van: basex-talk-bounces at mailman.uni-konstanz.de [mailto:basex-talk-bounces at mailman.uni-konstanz.de] Namens Dirk Kirsten Verzonden: donderdag 14 augustus 2014 8:49 Aan: basex-talk at 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 at mailman.uni-konstanz.de > [mailto:basex-talk-bounces at 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
RS
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-----
Quoted text · basex-talk-bounces at mailman.uni-konstanz.de · 186 lines
Van: basex-talk-bounces at mailman.uni-konstanz.de [mailto:basex-talk-bounces at 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 <dk at 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-bounces at mailman.uni-konstanz.de >> [mailto:basex-talk-bounces at 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
MG
Marc van Grootel14 Aug 2014 13:42 #
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
Quoted text · Rob Stapper · 230 lines
On Thu, Aug 14, 2014 at 1:16 PM, Rob Stapper <r.stapper at 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-bounces at mailman.uni-konstanz.de [mailto:basex-talk-bounces at 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 <dk at 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-bounces at mailman.uni-konstanz.de >>> [mailto:basex-talk-bounces at 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
RS
Rob Stapper14 Aug 2014 15:48 #
Marc,
Maybe the attached example helps. Instead of putting the arguments in an sequence they are put in a function-header. The "userFunction" now returns a function-header to be used as argument-list by the foo-function.
PS it sure would be nice if such a construction were embedded in xquery.
Success,
Rob
-----Oorspronkelijk bericht-----
Quoted text · Marc van Grootel · 248 lines
Van: Marc van Grootel [mailto:marc.van.grootel at 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.stapper at 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-bounces at mailman.uni-konstanz.de > [mailto:basex-talk-bounces at 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 <dk at 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-bounces at mailman.uni-konstanz.de >>> [mailto:basex-talk-bounces at 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
CG
Christian Grün14 Aug 2014 16:03 #
Hi Marc, hi Rob,
thanks for your feedback.
Quoted text · Rob Stapper · 1 line
> 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
Quoted text · Rob Stapper · 259 lines
> -----Oorspronkelijk bericht----- > Van: Marc van Grootel [mailto:marc.van.grootel at 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.stapper at 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-bounces at mailman.uni-konstanz.de >> [mailto:basex-talk-bounces at 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 <dk at 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-bounces at mailman.uni-konstanz.de >>>> [mailto:basex-talk-bounces at 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
LQ
Quoted text · Marc van Grootel · 3 lines
On Thu, 14 Aug 2014 13:42:24 +0200 Marc van Grootel <marc.van.grootel at gmail.com> wrote: > I will try to come up with a simple but representative example this evening.
Note, if you are proposing a change to the XQuery languuage itself, the XQuery WG and the XSLT WG are aware of limitations in our syntax and the fact you can't call a function with a signature like
fn:concat() using a function item; a concrete proposal would for sure be discussed by the Working Groups when they next meet jointly in September, although it is almost certainly too late for XQuery 3.1. The way to get it considered is to file a bugillza issue/bug; see www.w3.org/XML/Query for pointers to doing that.
Liam--
Liam Quin - XML Activity Lead, W3C, http://www.w3.org/People/Quin/ W3C staff participant for XQuery
Pictures from old books: http://fromoldbooks.org/
MG
Marc van Grootel14 Aug 2014 21:40 #
Hi all,
I've submitted a proposal to the issue tracker for XQuery 3.1. After thinking about it for a while I realized that to me it appears quite feasible to use the 3.1 array type to have something like
fn:apply and also keep the current semantics with for example the proposed arrow operator. I hope that I could explain myself well enough. Let me know if you think it makes sense.
https://www.w3.org/Bugs/Public/show_bug.cgi?id=26585
Cheers,
--MarcQuoted text · Liam R E Quin · 14 lines
On Thu, Aug 14, 2014 at 6:10 PM, Liam R E Quin <liam at w3.org> wrote: > On Thu, 14 Aug 2014 13:42:24 +0200 > Marc van Grootel <marc.van.grootel at gmail.com> wrote: > >> I will try to come up with a simple but representative example this evening. > > Note, if you are proposing a change to the XQuery languuage itself, the XQuery WG and the XSLT WG are aware of limitations in our syntax and the fact you can't call a function with a signature like fn:concat() using a function item; a concrete proposal would for sure be discussed by the Working Groups when they next meet jointly in September, although it is almost certainly too late for XQuery 3.1. The way to get it considered is to file a bugillza issue/bug; see www.w3.org/XML/Query for pointers to doing that. > > Liam > > -- > Liam Quin - XML Activity Lead, W3C, http://www.w3.org/People/Quin/ > W3C staff participant for XQuery > Pictures from old books: http://fromoldbooks.org/
--
--Marc
MG
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
--MarcQuoted text · Christian Grün · 274 lines
> On 14 aug. 2014, at 16:03, Christian Grün <christian.gruen at 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.grootel at 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.stapper at 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-bounces at mailman.uni-konstanz.de >>> [mailto:basex-talk-bounces at 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 <dk at 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-bounces at mailman.uni-konstanz.de >>>>> [mailto:basex-talk-bounces at 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
MG
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
Quoted text · Rob Stapper · 164 lines
On Thu, Aug 14, 2014 at 10:23 AM, Rob Stapper <r.stapper at 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 at mailman.uni-konstanz.de [mailto:basex-talk-bounces at mailman.uni-konstanz.de] Namens Dirk Kirsten > Verzonden: donderdag 14 augustus 2014 8:49 > Aan: basex-talk at 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 at mailman.uni-konstanz.de >> [mailto:basex-talk-bounces at 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 >
--
--Marc
Written for BaseX 7.9. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery