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?
> But it can do things the other maps can't easily, like create an array of differences between elements, or a running total, and so on. Other languages have other solutions to those problems.
Lisp has some rather elegant solutions to both of those use cases. It's misleading to say that Javascript's 'map' is more powerful just because it tries to cram two or three distinct use cases into one.
It's not like Javascript even uses the Lisp definition of 'map' (which is not what most languages use for map - they use Lisp's 'mapcar').
Seems like they included extra parameters in map since they forgot to include a fold! Running totals are perfect for fold, for differences, use zipWith.
But, JavaScript is rather functional. I've heard it described as "lisp in C's clothing". Douglas Crockford uses monads in JS (intentionally) and gave an interesting yet hard to follow introduction to JS monads not too long ago. I'd like to see the functional side of JS emphasized in the next iteration.
It's fine to say that Javascript is functional, but:
>I've heard it described as "lisp in C's clothing"
I hear this line all the time, and it always irritates me. Saying that Javascript is Lisp-like just because it's somewhat functional is like saying that it's like Java because it's "object-oriented", even though there are a number of key differences (the use of "this", the prototypical inheritance model, runtime checks vs. static checks with late binding, etc.) It's worse, because it's rather trivial to force Javascript to behave somewhat like Java, but there's no way to force Javascript to exemplify the defining characteristics of a Lisp[0].
The nature of Lisp has nothing to do with lambdas and closures, mapcars and reduces - the phrase 'Lisp in C's clothing' doesn't even make sense, because the nature of Lisp cannot exist without an s-expression-based grammar[1]. Even though Lisp is known as a functional language, the defining characteristics of Lisp have nothing to do with it being functional.
[0] Perhaps a better analogy would be comparing it to JVM languages on the basis of the grammar, even though the two are completely orthogonal - Javascript isn't intended to run on the JVM, and while you can cross-translate code between Javascript and JVM languages and fake compatibility this way, that ability has very little do do with the defining characteristics of Javascript as a language.
[1] That doesn't mean you need to have parentheses; the grammar simply needs to be homomorphic with s-expressions, which leaves a great deal of flexibility. Javascript, however, does not make the cut.
Why do people keep incorrectly insisting that JavaScript is "functional" or "Scheme-like"? It is neither.
Merely having anonymous functions does not make a language "functional". JavaScript does not encourage the use of pure functions. It does not encourage the use of recursion. It does not encourage immutability. It does not have a robust, sensible type system. It does not encourage currying.
It's pretty clear that JavaScript is inherently not a functional programming language. It goes against functional programming techniques in almost all respects, especially when it comes to JavaScript code that's out in the wild.
Doug’s talk was hard to follow because he didn’t give an adequate explanation. Not because he’s subject to some curse of the monad, but because he evidently did not understand the topic well enough.
Haskell is so different from JS that is impossible to faithfully translate a monad into JS. It is like trying translate a Haiku from Japanese to English.
Maybe if he called his thing a Jonad, and explained how it was inspired by the monad's "executable semicolon" aspect, it would have been better.
This example clearly violates the principle of least surprise, but it doesn't necessarily mean that the language it comes from is bad. Rather, the code it's used in is.
"map" is sufficiently common and standard that it's a bad name for this function, irrespective of whether this is a good or bad function to include in the base language.
with the new ES6 coming , people from python are going to feel a lot of confusion , since some new functionalities are inspired by python but are in reality different from the python implementation,like modules , generators , ... Javascript has always been like that ( thinking of "this" that is totally different from "this" of Java for instance , let's not even talk about the new class keywork which will be very confusing too , for those who believe they can just go the java way with js from now on ). But i'm quite happy with the language ,it feels like self, the revenge ...
This is more of a case of a stupid library than stupid language.
And whether it's a stupid library is even debatable. map() has gained a more popular understanding from functional programming these days but it was probably not so when this Javascript map() function was added.
It is very likely that the person who added map() to JavaScript knew about its meaning in functional languages, otherwise s/he would have called it applyToEach() or something like that.
One important characteristic of the map function is that it can be used reversibly. For example, (partial map inc) is inverted by (partial map dec). If I want to map over a collection by a function that takes the entire collection as an argument I'd rather use some function other then map to avoid confusion.
Hmm? What is the reverse of (partial map constantFunctionReturnsZero)?
A fold/reduce is just as sometimes-reversible, when paired with an appropriate unfold. (example: multiplication and factorization)
I think you mean that map is self-composable, in the sense that the map function distributes over function-composition, in the same way that (in first-order functions) multiplication distributes over addition.
The information lost by calling the constant function is pushed to the end of the list so that it can be called reversibly. This can be applied on an entire list:
Not at all. Some other languages work this way, and in the right context (best-effort systems, not mission critical ones), it can be a boon to backward compatibility and other ease of use factors.
In Python for example you can explicitly declare variadic functions to ignore extra arguments. But when it's the default behavior you can for example change the official signature of a callback interface without breaking compatibility. It can be pretty liberating to work in a best-effort language...though perhaps it makes testing a bit more important.
That's how JS works. You can pass as many extra parameters as you want (they get discarded) and you can also omit as many parameters as you want (it's like passing undefined).
The array-like `arguments` object will always reflect what was actually passed to the function though.
> They want to know if function arguments are call by value or call by reference (neither).
My knowledge of Python is limited, but I was under the impression that it is call by value just like everything else (where Python's notion of value is "pointer to something"). Am I missing something?
You essentially changed the definition of "value" to mean what is just called "name" in Python.
Names refer to objects. Names are introduced by name binding operations such as `=`, `import`, `def`.
def f(a, b): # a, b - local variables
a = [1] # doesn't change x list; a refers to the new list hence forth
b.append(2) # change y list; b refers to the same list as y
x, y = [], []
f(x, y)
print x, y # [], [2]
Note: a "win" doesn't change the truth. It just means that nobody cared enough to participate further in the hostile discussion.
The answer -- regardless of who thinks they can "win" the argument -- is "this is not a useful question to ask, because people will draw incorrect conclusions, based on assumptions from other languages, from whichever answer is given".
Similarly, "pointer to something" is not a useful way to think about Python, because people with a background in C will start making assumptions about what "pointer" means. You might think that assigning to that "pointer" changes what's stored in the memory it points to, but really all it does is re-bind a name within the (local, which does not affect global) scope, leaving the "memory" unchanged.
So rather than ask which misleading-analogy-to-another-language Python uses, just ask how Python works.
I'm not sure I understand. Function calls work the same way in every call by value language: the binding of an argument to a value is the same as the binding of a variable or the assignment of part of a data structure. That's a pretty clear and simple thing to want to say, and "call by value" is the way to say it.
Since this is exactly the behaviour of Python's function calls, how is describing Python as call by value "not useful"? And where's this "misleading analogy to another language", given the concept is clearly explained without reference to any particular language?
I'm prepared to accept that people become confused over this, but I reject the notion that it is not a useful question.
People ask these questions because they're used to the way other languages work, and want to have an analogy to help them understand how Python works.
Except this isn't useful, because Python doesn't work the way those other languages do. They'll run into cases where their mental model of what "pass-by-value" or "pass-by-reference" means does not match up to Python's actual workings, and then they'll spend endless time arguing about which model Python uses when the answer is really "neither, stop trying to shoehorn one of those models onto a language that doesn't fit".
What you've done is define your own number system, I do not believe you are representing what "base 1" might be.
If a base means, you can write numbers of this form:
abc
Where the value is:
aB^2 + bB^1 + cB^0
and you can only have B symbols, then your one symbol for base 1 would need to be 1, still useless, but not completely:
1 = 11^0 = 1
11 = 11^1 + 11^0 = 2
...
Note that you cannot represent 0 in base 1 with this method.
If you choose 0 as your one symbol for base 1, then the only number you can represent is 0. I assert this is even more useless than selecting 1 as the symbol.
0 = 01^0 = 0
00 = 01^1 + 01^0 = 0
...
As far as I can tell, the example was trying to interpret "10" as base 1. 10 has two different symbols which truly does not make sense in base 1.
I assert that base 1 is not a valid base, because you cannot represent all integers in it.
Additionally, the "unary point" or whatever it would be called, would serve no purpose:
1.1 = 11^0 + 1*1^-1 = 2
I'm not sure how that might disqualify something for a "base" but it certainly doesn't help :) Probably the strongest argument is the inability to represent 0.
Of course, this is not a practical notation, since 0 would hard to distinguish from actual absence, but it would be viable in some situations: a table of numbers say, where you know that no cells are empty. So theoretically, it is possible to represent 0 in base 1, regardless of its obvious impracticalities.
That's using a different notation than our more familiar number systems, though.
If we were treating it like base 2 (or 10 or 8 or 16), we would evaluate 0000 as 1^30+1^20+1^10+1^00 = 0. A number system where the only number you can represent is 0 is a bit less useful.
The problem is parseInt, not map. Consider: