Re: [basex-talk] Apply variable argument list to anonymous function

2014-08-26 Thread Marc van Grootel
Hi Rob,

I hope you don't mind I used your example apply code in the module I'm
working on. I've adapted it a bit as well (including code reformatting
so you may not even recognize it ;-)
and left it as an attachment to
https://www.w3.org/Bugs/Public/show_bug.cgi?id=26585

It currently does the trick for me, so thanks.

--Marc


On Thu, Aug 14, 2014 at 10:23 AM, Rob Stapper r.stap...@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-boun...@mailman.uni-konstanz.de 
 [mailto:basex-talk-boun...@mailman.uni-konstanz.de] Namens Dirk Kirsten
 Verzonden: donderdag 14 augustus 2014 8:49
 Aan: basex-talk@mailman.uni-konstanz.de
 Onderwerp: Re: [basex-talk] Apply variable argument list to anonymous function

 Hi Rob, Hi Marc,

 As Rob showed, HOF functions are a possible (and I think actually the only 
 way, although I am not sure) way to deal with functions like concat, which do 
 expect a variable number of arguments. This is very valid and might be a 
 valid solution. I would just like to add that you should keep the performance 
 in mind. fold-left() of course comes to a price. A simple comparison using 
 fold vs. using string-join

 declare variable $args :=
   let $a := ('a', 'b', 'c')
   for $i in 1 to 5
   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

Re: [basex-talk] Apply variable argument list to anonymous function

2014-08-14 Thread Rob Stapper
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



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


Re: [basex-talk] Apply variable argument list to anonymous function

2014-08-14 Thread Rob Stapper
And, this one: http://docs.basex.org/wiki/Higher-Order_Functions



Rob



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


Re: [basex-talk] Apply variable argument list to anonymous function

2014-08-14 Thread Rob Stapper
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


Re: [basex-talk] Apply variable argument list to anonymous function

2014-08-14 Thread Dirk Kirsten
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 5
  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


Re: [basex-talk] Apply variable argument list to anonymous function

2014-08-14 Thread Marc van Grootel
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 5
   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 

Re: [basex-talk] Apply variable argument list to anonymous function

2014-08-14 Thread Rob Stapper
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-boun...@mailman.uni-konstanz.de 
[mailto:basex-talk-boun...@mailman.uni-konstanz.de] Namens Dirk Kirsten
Verzonden: donderdag 14 augustus 2014 8:49
Aan: basex-talk@mailman.uni-konstanz.de
Onderwerp: Re: [basex-talk] Apply variable argument list to anonymous function

Hi Rob, Hi Marc,

As Rob showed, HOF functions are a possible (and I think actually the only way, 
although I am not sure) way to deal with functions like concat, which do expect 
a variable number of arguments. This is very valid and might be a valid 
solution. I would just like to add that you should keep the performance in 
mind. fold-left() of course comes to a price. A simple comparison using fold 
vs. using string-join

declare variable $args :=
  let $a := ('a', 'b', 'c')
  for $i in 1 to 5
  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


---
Dit e-mailbericht bevat geen virussen en malware omdat avast! 
Antivirus-bescherming actief is.
http://www.avast.com



Re: [basex-talk] Apply variable argument list to anonymous function

2014-08-14 Thread Rob Stapper
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 5
   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

Re: [basex-talk] Apply variable argument list to anonymous function

2014-08-14 Thread Marc van Grootel
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 5
   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

Re: [basex-talk] Apply variable argument list to anonymous function

2014-08-14 Thread Rob Stapper
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-
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

Re: [basex-talk] Apply variable argument list to anonymous function

2014-08-14 Thread Liam R E Quin
On Thu, 14 Aug 2014 13:42:24 +0200
Marc van Grootel marc.van.groo...@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/


Re: [basex-talk] Apply variable argument list to anonymous function

2014-08-14 Thread Marc van Grootel
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,
--Marc


On Thu, Aug 14, 2014 at 6:10 PM, Liam R E Quin l...@w3.org wrote:
 On Thu, 14 Aug 2014 13:42:24 +0200
 Marc van Grootel marc.van.groo...@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


Re: [basex-talk] Apply variable argument list to anonymous function

2014-08-13 Thread Dirk Kirsten
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,
Dirk

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