473,411 Members | 2,184 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,411 software developers and data experts.

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

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
Jul 20 '05 #1
6 2479
> 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

Jul 20 '05 #2
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,8); //= 14
cAdd(2)(4)(8) //= 14
cAdd(2,4)(8) //= 14
cAdd(2)(4,8) //= 14
cAdd(2)()(4)()(8) //= 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
Jul 20 '05 #3
> 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/

Jul 20 '05 #4
Fox
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

Jul 20 '05 #5
sv********@svendtofte.com (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 - lr*@hotpop.com
Art D'HTML: <URL:http://www.infimum.dk/HTML/randomArtSplit.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 20 '05 #6
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

Jul 20 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Holger Türk | last post by:
Hello, a common pattern to write curried functions (i.e. without the need for a special partial application syntax, like in PEP 309) is like in this example: def functionLock (lk): def...
13
by: Kai Grossjohann | last post by:
It seems that Ctrl-N in Mozilla opens a new empty browser window. That's fine, I don't need to do anything about it. But Ctrl-N in IE appears to clone the current window. Is there a way to...
2
by: Tinderbox | last post by:
I am working on a piece of code for an academic experiment and it puzzled me for days, any help? I use javascript to sort a table in a html page. bascially, a user can click on any attributes...
136
by: Matt Kruse | last post by:
http://www.JavascriptToolbox.com/bestpractices/ I started writing this up as a guide for some people who were looking for general tips on how to do things the 'right way' with Javascript. Their...
34
by: electrician | last post by:
Perl has it, Basic has it, Fortran has it. What is so difficult about creating a goto command for JavaScript. Just set up a label and say go to it.
21
by: petermichaux | last post by:
Hi, I've been asking questions about library design over the last week and would like to get feedback on my overall idea for a JavaScript GUI library. I need a nice GUI library so there is a...
67
by: Robert | last post by:
Hi, I have been reading the article at http://www.crockford.com/javascript/private.html and I was wondering if there also was some way to be able to have private methods that can be called from...
3
by: Scott Lamb | last post by:
I'm trying to dynamically generate class methods which have access to some state passed in at creation time. (Basically as a workaround to twisted's trial not having a way to dynamically add stuff....
6
by: Aaron Gray | last post by:
Hi, Is there any tool that will concatinate JavaScript files compacting them spacewise and removing comment fields ? I have some sed script that sort of does the job but was wondering if there...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.