Number of arguments of a function and currying

47 views
Skip to first unread message

Yann Le Du

unread,
Apr 27, 2012, 3:14:58 PM4/27/12
to pure...@googlegroups.com
Hi,

I've discovered Pure recently (I was looking for some info on q from kx systems, and stumbled upon your q, instantly found the "equational" adjective exciting and from there continued to Pure)  and I commonly develop scientific apps in Octave, Python, C and Julia. This means I'm not a functional person... but Pure should help me improve.

Now, in Julia I can define a function with different number of arguments, and from there choose different paths. This means that for julia, like in maths, f : R -> R is not the same as f: RxR->R, but this also means that both function can coexist and one or the other will be called upon depending on the number of arguments.

Amazed by the exhibits in Pure's manual and wiki primers, I thought "hey, let's make sure max works also for lists or whatever". And there I discovered that once max is defined with two arguments, as in the prelude, then I can't define it for a single one like a list -- it felt like superman can't button his shirt. I tried to google my way to an answer, and it seems that q authorized such arity variation, but that Pure's compiler now explicitly forbade that. Apparently, it's because of currying. An advised way out is with tuples, but it feels clumsy and doesn't work nicely right out of the box.

Am I right then to conclude that I need to define and name differently as many max as I expect the number of arguments to be ? If so, is there some reference I could look up to see why variable arity is bad, and thus feel better choosing n different names?

Or is there a Pure switch to unleash arity variability? Ok, such a switch would suppose the user knows what he does; I can imagine that max a::array = ... would still permit currying of max a b = ..., as long as the 2-arguments definition comes after the first. I miss this, but perhaps I miss something important here.

And, more importantly, thanks for the very happy hacking time Pure already provides.

Yann


Albert Graef

unread,
Apr 27, 2012, 10:05:30 PM4/27/12
to pure...@googlegroups.com
Hi Yann, and welcome to the list! :)

On 04/27/2012 09:14 PM, Yann Le Du wrote:
> I tried to google my way to an
> answer, and it seems that q authorized such arity variation, but that
> Pure's compiler now explicitly forbade that.

Yes, in difference to Q, once you decide the number of parameters for a
given function in Pure, it's fixed, and the compiler will then complain
if you add an equation which defines the function with a different
number of arguments. I decided to do it that way mainly because it
catches a common type of errors. Also, currying and variadic really
don't go that well together, so while it's possible to do that kind of
thing in Q, it's not really that straightforward to get it right and
such use cases are often somewhat obscure.

NB: Another technical reason for doing it that way is that it makes it
much easier to compile a Pure function to efficient LLVM IR code. While
LLVM IR allows variadic functions, last I checked they weren't available
with the fastcc calling convention, which Pure uses internally, e.g., to
optimize tail calls.

> Am I right then to conclude that I need to define and name differently
> as many max as I expect the number of arguments to be ?

No, you'd define a variadic function in exactly the same way as in Q
using tuple arguments (or using any other aggregate that you find
convenient, such as lists or vectors). E.g.:

namespace my;
max (x,y) = if x<y then y else x when y = max y end;
max x = x otherwise;

Note that I defined this in a separate namespace so that it doesn't
collide with the max function in the standard library.

Albert

--
Dr. Albert Gr"af
Dept. of Music-Informatics, University of Mainz, Germany
Email: Dr.G...@t-online.de, a...@muwiinfa.geschichte.uni-mainz.de
WWW: http://www.musikinformatik.uni-mainz.de/ag

Albert Graef

unread,
Apr 27, 2012, 10:13:53 PM4/27/12
to pure...@googlegroups.com
On 04/27/2012 09:14 PM, Yann Le Du wrote:
> I've discovered Pure recently (I was looking for some info on q from kx
> systems, and stumbled upon your q, instantly found the "equational"
> adjective exciting and from there continued to Pure) and I commonly
> develop scientific apps in Octave, Python, C and Julia. This means I'm
> not a functional person... but Pure should help me improve.

At least Pure will provide you with an easy way to call your existing C
and Octave code. ;-) I'm pondering the idea to interface to Julia as
well. It's a very interesting new language, and as it's LLVM-based,
interfacing to it from Pure should be rather easy. But I guess that this
will have to wait a bit until the Julia ABI settles and the Julia
compiler supports dumping compiled code to LLVM bitcode files.

Yann Le Du

unread,
Apr 29, 2012, 8:01:21 PM4/29/12
to pure...@googlegroups.com

Ok, and I also understood that we may reproduce this Julia's multiple dispatch by using lists:

f [x::int] = 2*x;
f [x::double] = 3*x;
f [x,y] = x-y;

etc.

Now, I have a related question. I was trying to concatenate all the arguments given to a function. The best I can come up with is:

concat x y = concat (x,y);

so that I get

concat 1 0 3 6 7;
>concat (1,0,3,6,7)

Now I'd like to retrieve only the tuple...

So I thought I'd convert the output to a string, split it at the space character and retrieve the second element.

So I tried :

c = concat 1 0 3 6 7;
s = str c;

and it worked, I obtain the expected string that  can split. So then I tried:

f = str $ concat;

f 1 0 3 6 7;

and it failed! (gives wrong string)

I thus looked around and understood function composition was more complex than what I had thought.

So here's my question: is there a function composer o similar to pipe such that g o f sends the output of f to g as if I had typed it in the interpreter ? So g should wait for the application of f to have reached normal form before itself being applied.

I somehow feel this quest(ion) stems from my ignorance of the functional way.

Yann

Albert Graef

unread,
Apr 30, 2012, 6:38:46 AM4/30/12
to pure...@googlegroups.com
On 04/30/2012 02:01 AM, Yann Le Du wrote:
> Now, I have a related question. I was trying to concatenate all the
> arguments given to a function. The best I can come up with is:
>
> concat x y = concat (x,y);
>
> so that I get
>
> concat 1 0 3 6 7;
> >concat (1,0,3,6,7)

Ok, so I guess that what you want is a kind of uncurry function which
takes an arbitrary number of curried arguments? I'm afraid that this is
not really possible unless you know in advance how many arguments need
to be uncurried.

If you do know the number of arguments, then you could use something like:

call f n x = call f (n-1) . (\y -> (x,y)) if n>1;
= f x otherwise;

Now you can write:

> f = call g 4;
> f a b c d;
g (a,b,c,d)

But why are you trying so hard to avoid curried functions in the first
place? Can you describe the specific problem you're trying to solve?
Maybe there are other ways to achieve what you want.

Yann Le Du

unread,
May 1, 2012, 8:32:13 AM5/1/12
to pure...@googlegroups.com


On Monday, April 30, 2012 12:38:46 PM UTC+2, ag wrote:
On 04/30/2012 02:01 AM, Yann Le Du wrote:
> Now, I have a related question. I was trying to concatenate all the
> arguments given to a function. The best I can come up with is:
>
> concat x y = concat (x,y);
>
> so that I get
>
> concat 1 0 3 6 7;
>  >concat (1,0,3,6,7)

Ok, so I guess that what you want is a kind of uncurry function which
takes an arbitrary number of curried arguments? I'm afraid that this is
not really possible unless you know in advance how many arguments need
to be uncurried.

If you do know the number of arguments, then you could use something like:

   call f n x = call f (n-1) . (\y -> (x,y)) if n>1;
     = f x otherwise;

Now you can write:

   > f = call g 4;
   > f a b c d;
   g (a,b,c,d)

But why are you trying so hard to avoid curried functions in the first
place? Can you describe the specific problem you're trying to solve?
Maybe there are other ways to achieve what you want.


Thanks, I'm just playing with the language, so it's not something I really want but let me say what I wanted to achieve: make a function that outputs a tuple of the arguments passed to itself, whatever the number of arguments. I understand that it's not possible, and it looks like this impossibility is a feature of the language.

Yann
 

Yann Le Du

unread,
May 1, 2012, 9:11:17 AM5/1/12
to pure...@googlegroups.com


On Saturday, April 28, 2012 4:13:53 AM UTC+2, ag wrote:
On 04/27/2012 09:14 PM, Yann Le Du wrote:
> I've discovered Pure recently (I was looking for some info on q from kx
> systems, and stumbled upon your q, instantly found the "equational"
> adjective exciting and from there continued to Pure)  and I commonly
> develop scientific apps in Octave, Python, C and Julia. This means I'm
> not a functional person... but Pure should help me improve.

At least Pure will provide you with an easy way to call your existing C
and Octave code. ;-) I'm pondering the idea to interface to Julia as
well. It's a very interesting new language, and as it's LLVM-based,
interfacing to it from Pure should be rather easy. But I guess that this
will have to wait a bit until the Julia ABI settles and the Julia
compiler supports dumping compiled code to LLVM bitcode files.


That C et al. connectivity is indeed already amazing, but adding Julia would Lorentz boost Pure to Best.
 
Albert

--
Dr. Albert Gr"af
Dept. of Music-Informatics, University of Mainz, Germany
Email:  Dr.G...@t-online.de, a...@muwiinfa.geschichte.uni-mainz.de
WWW:    http://www.musikinformatik.uni-mainz.de/ag

Johannes Engels

unread,
May 2, 2012, 12:50:20 AM5/2/12
to pure-lang


On 28 Apr., 04:13, Albert Graef <Dr.Gr...@t-online.de> wrote:

> I'm pondering the idea to interface to Julia as
> well. It's a very interesting new language, and as it's LLVM-based,
> interfacing to it from Pure should be rather easy.

This would be great! Julia seems to avoid a lot of Matlab's annoying
drawbacks.

Johannes
Reply all
Reply to author
Forward
0 new messages