In JavaScript, every function is varadic. The problem is one of contract, not language. Passing varadic functions to higher-order functions without checking whether the types are compatible will cause a problem in every such language.
The problem is parseInt, not map. Consider:
// using lodash.js (http://lodash.com/)
_.mixin({ args: function () { return _.toArray(arguments); } })
['10','10','10','10'].map(_.compose(parseInt, _.first, _.args)); // #=> [10,10,10,10]
Yes, you can use anonymous functions, and you probably would want to do that in practice. However, I was trying to illustrate the point that JavaScript functions are varadic and function composition was an easy way to drive that point home.
EDIT: Also, you raise a really good point in your example which is that when using parseInt you should always specify the base. If I were to modify my example to take that into account it'd get more messy.
The signature is [context, fn, args, slice] where `slice` is the length of arguments to keep from invocation. It's very rare that something warrants using it vs an anonymous function though.
That's interesting, I like how `slice` lets you concat sequences of arguments, but worry about building functions which have too many convenience features. Thought experiment: what if I wanted to pass every other argument?
Comments
In JavaScript, every function is varadic. The problem is one of contract, not language. Passing varadic functions to higher-order functions without checking whether the types are compatible will cause a problem in every such language.
The problem is parseInt, not map. Consider:
It's nice to use functional concepts and all, but in practice a simple anonymous function to trim the arguments is clearer and close to zero overhead:
That's one reason to like the conciseness of CoffeeScript, takes the urge to build compositional towers away: Which one would you rather find in your codebase?Yes, you can use anonymous functions, and you probably would want to do that in practice. However, I was trying to illustrate the point that JavaScript functions are varadic and function composition was an easy way to drive that point home.
EDIT: Also, you raise a really good point in your example which is that when using parseInt you should always specify the base. If I were to modify my example to take that into account it'd get more messy.
I've been using a pair of functions applyRight/Left that fit this case nicely:
The signature is [context, fn, args, slice] where `slice` is the length of arguments to keep from invocation. It's very rare that something warrants using it vs an anonymous function though.That's interesting, I like how `slice` lets you concat sequences of arguments, but worry about building functions which have too many convenience features. Thought experiment: what if I wanted to pass every other argument?
Here's what I use:
For example, do `parseInt10 = F.partial(parseInt, undefined, 10)`, then `[].map(parseInt10)` does the right thing.I imagine you could pass a function
as the `slice` parameter, but that's going into crazy territory.Neither.
But for the sake of argument, I'd rather see
['10','10','10','10'].map(Number);
this is one is correct
['10','10','10','10'].map(String);
this one makes sense
['10','10','10','10'].map(Object);
i'd like somebody to explain me this one ?????????
Javascript is really difficult as soon as one try to do non trivial stuffs.
Object('abc') is the same as new String('abc'), Object(1) the same as new Number(1) - it just calls the .constructor
but "new Number(x)" is not equal to "Number(x)". So, it's tricky, I guess?
Number(x) performs a type conversion to number, new Number(x) constructs a primitive wrapper object Number:
The same applies to other wrapper objects, that is, Boolean and String.This is a problem with javascript, functions shouldn't be variadic by default.
The way in which contracts are enforced or not enforced is a language issue though.