Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > Curried functions in JavaScript (how to employ genericly, and invisibly)?

Reply
Thread Tools

Curried functions in JavaScript (how to employ genericly, and invisibly)?

 
 
svend
Guest
Posts: n/a
 
      07-22-2003
Hey there,

I was thinking about some curried functions in JavaScript, and I made
this:

<script>
function add(a, b, c) {
if (arguments.length == 1) {
return function (d,e) {return a + d + e}
}
if (arguments.length == 2) {
return function (d) {return a + b + d}
}
return a + b + c;
}

t = add(1,2);
alert(t(3));

alert(add(1,2,3));
</script>

Which works, but it's ugly, to say the least. So I was wondering, if
there's a way, to create this, in a more generic way? I'm aware, that
it probably wont be SML like curried, which is totally transparent,
but is there anyway at all?

In a way, so that it works, as close to SML as possible, though I'm
willing to accept, some code will be needed?

Regards,
Svend
 
Reply With Quote
 
 
 
 
Douglas Crockford
Guest
Posts: n/a
 
      07-22-2003
> I was thinking about some curried functions in JavaScript, and I made
> this:
>
> <script>
> function add(a, b, c) {
> if (arguments.length == 1) {
> return function (d,e) {return a + d + e}
> }
> if (arguments.length == 2) {
> return function (d) {return a + b + d}
> }
> return a + b + c;
> }
>
> t = add(1,2);
> alert(t(3));
>
> alert(add(1,2,3));
> </script>
>
> Which works, but it's ugly, to say the least. So I was wondering, if
> there's a way, to create this, in a more generic way? I'm aware, that
> it probably wont be SML like curried, which is totally transparent,
> but is there anyway at all?
>
> In a way, so that it works, as close to SML as possible, though I'm
> willing to accept, some code will be needed?


You could write an array method sum() that would take an array and return its
sum. Then you can capture arguments as an array and apply sum to it to get a
value. That might be a little bit prettier.

http://www.crockford.com/javascript/little.html

 
Reply With Quote
 
 
 
 
Dom Leonard
Guest
Posts: n/a
 
      07-23-2003
Svend Tofte wrote:
<snip> I ...
was actually
> thinking of something even more generic. Something, like an array, and
> could return a new function, which would call the original function..
>
> ala:
>
> function x() {
> return new function() {x(argumentsArray)}
> }
> Returning a function, that would call "x", with the arguments, passed
> to the first call of "x", in the right order, and then apply the new
> arguments, afterwards.
>


Function .length property and .apply method might be useful, ala

function makeCurry(func,oldArgs)
{
var length=func.length;
var oldLength = oldArgs ? oldArgs.length : 0;
function curry()
{
var i;
var myLength=arguments.length;
var newArgs;
if((oldLength==0) && (myLength >= length))
return func.apply(this,arguments);
if(myLength==0)
return curry; // no change
newArgs = new Array();
for(i=0; i < oldLength; ++i)
newArgs.push(oldArgs[i]);
for(i=0; i < myLength; ++i)
newArgs.push(arguments[i]);
return (newArgs.length >= length) ?
func.apply(this,newArgs) :
makeCurry(func,newArgs) ;
};
return length ? curry : func;
}

// as tested in Mozilla

function add(a,b,c)
{
return a+b+c;
}
var cAdd=makeCurry(add);
cAdd(2,4,; //= 14
cAdd(2)(4)( //= 14
cAdd(2,4)( //= 14
cAdd(2)(4, //= 14
cAdd(2)()(4)()( //= 14

=======

When working up the code I ran into problems with the arguments array
not being an instance of javascript's Array constructor (I think), so
simply almalgamated old and new arguments in a loop.

HTH,
Dom


 
Reply With Quote
 
Douglas Crockford
Guest
Posts: n/a
 
      07-24-2003
> When working up the code I ran into problems with the arguments array
> not being an instance of javascript's Array constructor (I think), so
> simply almalgamated old and new arguments in a loop.


That is really annoying, isn't it? A coding mistake in Netscape was reverse
engineered and copied into JScript, and then written into the standard.

This will produce a real array from arguments :

Array.prototype.slice.apply(arguments)

You can also give slice additional parameters for removing some initial
parameters from the array at the same time.

http://www.crockford.com/

 
Reply With Quote
 
Fox
Guest
Posts: n/a
 
      07-24-2003
If I understand the material correctly:

function
Curry()
{
this.accumulator = 0;

function curry(arry)
{
var f = arry[0];
var count = 1;
while(count < arry.length)
{
f(arry[count++]);
}
}

if(arguments.length > 1)
{
curry(arguments);
}

return this.accumulator;
}

// test:

function
add(n)
{
this.accumulator += n;
}

function
mult(n)
{
if(this.accumulator == 0)
this.accumulator = 1;
this.accumulator *= n;
}



alert(Curry(add, 1, 2, 3, 4, 5));
alert(Curry(mult, 1, 2, 3, 4, 5));

or you can just inline the functions:

Curry(function(i){ this.accumulator += i; }, 1,2,3,4,5);
etc...


************************************************




svend wrote:
>
> Hey there,
>
> I was thinking about some curried functions in JavaScript, and I made
> this:
>
> <script>
> function add(a, b, c) {
> if (arguments.length == 1) {
> return function (d,e) {return a + d + e}
> }
> if (arguments.length == 2) {
> return function (d) {return a + b + d}
> }
> return a + b + c;
> }
>
> t = add(1,2);
> alert(t(3));
>
> alert(add(1,2,3));
> </script>
>
> Which works, but it's ugly, to say the least. So I was wondering, if
> there's a way, to create this, in a more generic way? I'm aware, that
> it probably wont be SML like curried, which is totally transparent,
> but is there anyway at all?
>
> In a way, so that it works, as close to SML as possible, though I'm
> willing to accept, some code will be needed?
>
> Regards,
> Svend

 
Reply With Quote
 
Lasse Reichstein Nielsen
Guest
Posts: n/a
 
      07-24-2003
http://www.velocityreviews.com/forums/(E-Mail Removed) (svend) writes:

> In a way, so that it works, as close to SML as possible, though I'm
> willing to accept, some code will be needed?



How about this currying function:
---
function curry(f,n) { // n is number of arguments for f
return function() {
var cnt = n;
var accu = [];
var self=this;
function accumulate(args) {
for(var i=0;i<args.length;i++) {
accu[accu.length]=args[i];
cnt--;
}
if (cnt<=0) {
return (f.apply(self,accu));
} else {
return function(){return accumulate(arguments);};
}
}
return accumulate(arguments);
}
}
---
And even
Function.prototype.curry = function(n){return curry(this,n);};

Then you can write

function f(a,b,c){ return a+b+c; };

and

var g= f.curry(3);
g(1,2,3) + g(1)(2)(3) + g(1,2)(3)

/L 'the wonders of untyped languages!'
--
Lasse Reichstein Nielsen - (E-Mail Removed)
Art D'HTML: <URL:http://www.infimum.dk/HTML/randomArtSplit.html>
'Faith without judgement merely degrades the spirit divine.'
 
Reply With Quote
 
Dom Leonard
Guest
Posts: n/a
 
      07-25-2003
Douglas Crockford wrote:

> This will produce a real array from arguments :
>
> Array.prototype.slice.apply(arguments)
>

Thanks for the thought - whilst not using it exactly, put me on a
suitable track. FWIW, the makeCurry function reduced to

function makeCurry(func,oldArgs)
{ function curry()
{ var newArgs = arguments;
if(newArgs.length ==0)
return curry; // no change
if(oldArgs)
{ newArgs=new Array();
newArgs.push.apply(newArgs,oldArgs);
newArgs.push.apply(newArgs,arguments);
}
return (newArgs.length >= func.length) ?
func.apply(this,newArgs) :
makeCurry(func,newArgs);
}
return func.length ? curry : func;
}

Cheers,
Dom

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
LA cops with nothing better to do employ the easter bunny richard Computer Support 11 04-02-2010 03:32 PM
private virtual functions and pure virtual functions with bodies John Goche C++ 10 12-08-2006 04:00 PM
Curried class methods? Scott Lamb Python 3 08-17-2006 09:15 PM
please help me in distinguish redefining functions, overloading functions and overriding functions. Xiangliang Meng C++ 1 06-21-2004 03:11 AM
Curried functions =?ISO-8859-1?Q?Holger_T=FCrk?= Python 0 06-04-2004 09:44 PM



Advertisments