Or you know, stick to JS, because it's of course adorable that you can do functional programming in a functional language (we could do that since the 60s), but having access to the most prevalent language in the web and being employable is even better.
Learn Haskell/OCaml and you'll see how to really take this kind of reasoning many, many orders of magnitude upward. Learn Coq/Agda to see yet another meteoric jump.
* In a large corporate office with heterogeneous skill-sets among developers, but where almost all had some experience with Javascript.
* Javascript Users Groups
In each case, the idea was to make the case that FP could offer them practical advantages. The goal was definitely not to teach them FP or to suggest the best FP tool.
There are definitely better languages in which to do FP. But if for whatever reasons you're working in Javascript, I would suggest that a functional style could be useful.
Most FP paradigms are natural and quite easy in JS.
And learning Haskell can also be described as an "uphill battle".
I, for one, don't know if I would have ever tried to start learning Haskell if I didn't discover some of the benefits of FP first hand through a familiar language.
I'm very serious about this, because as far as I can tell, the next best aspect of FP might be first class functions, but those are starting to be used more in mainstream languages (at least the technique of applying transformations on generic data rather than writing special classes everywhere or using templates).
I'm beginning to feel that the real advantages of FP are being obfuscated by unusual syntax. There should be no reason why we can't go from some of the FP notations to the plain old algebra style (x=y) of C-style languages like Javascript. With better references and immutable variables, we should be able to split calculations up over several lines and have the compiler figure out how to optimize it into basically FP code.
P.S. I do know lisp, so I'm asking for a rather more enlightened answer than just to research it further.
This actually sounds pretty nice to write as a shell pipeline (and that's a really good way to do it), but really, it's likely that you'd end up writing some code like
main() {
q = queue(5);
avg = 0;
while(!eof) {
r, eof = get_record();
t = transform(r);
if(q.size() >= 5){
avg -= q.pop();
}
avg += t;
q.push(t);
print avg/q.size();
}
}
or something, but it'd actually be annoying to extract out the logic for handling the rolling average and split it out from the looping code, at least if you want to maintain constant memory use, and if you had to do something similar in a few places, you'd end up duplicating code.I claim that it's possible to factor that code nicely out in Haskell, and still get the compiler to generate the same machine code as the C loop. This doesn't particularly use first class functions, and more relies on the combo of sufficiently smart compiler and sufficiently strong guarantees about what code will do.
I also take slight offense at calling C-style languages "plain old algebraic style", since it'd be really strange in algebra to say both x=5 and x=6. I would not hesitate to call FP languages where you can substitute equals for equals and such the algebraic languages.
That said, FP often involves the introduction of monads which restore sequencing (along with many other beneficial effects). A monadic FP computation is very similar to a plain imperative computation... just with all of the arbitrary details automatically selected to be coherent and optimal.
You can even pretty easily embed OO in FP languages (though it gets a little hairy sometimes) since as soon as you can simulate open recursion somehow you can get late-binding as you like. See Oleg's O'Haskell papers for this kind of nonsense.
[0] In this regard, even Haskell is impure since it allows for non-terminating computation which can be seen as an impurity since you cannot expect to just evaluate `let x = x in x` repeatedly and get anywhere meaningful. Other languages like Coq, Agda, Idris are terminating (thus not Turing Complete) and therefore truly pure.
Seeing how monads reintroduce temporal dependence is also an astounding insight, and I can't believe that I've never seen them described that way. That means that the monad has more in common with, say, the mutex, than it does with I/O. I've always tried to approach them with metaphors like sockets and utterly failed to grok anything for more than a couple of days.
I'm thinking that if Haskell is an "impure" functional language, then I would like to see a "pure" imperative language. I envision it as similar to Go but multithreaded and basically every function in the language would be its own process, communicating with sockets (so basically a shell with C-style syntax). The overhead could be largely eliminated with a stackless context switcher. It wouldn't be able to achieve the optimization of FP but it might be more approachable to the mainstream and by extension maybe iterate faster and lead to higher productivity. I’d like to see it take the place of OpenCL/CUDA and SIMD because I find them tedious compared to more elegant languages like MATLAB/Octave.
http://adam.chlipala.net/cpdt/
True purity actually doesn't look much like Go at all. Instead, it means that every expression literally can be evaluated and replaced with its value in a completely arbitrary order. This massively simplifies the meaning of a language and opens it up to bear much more structure (such as that of a mathematical proof).
So, maybe I'm just using the power of wishful thinking with my characterization above.
Functional javascript, or python, is not awesome because the default datastructures are mutable, and the ecosystem of libraries are written in an OOP style using mutable data structures. There is some small value in writing the code you control in as FP a way as possible, but you aren't going to have a ton of success in that unless you are willing to rewrite your dependencies to also be more functional.
ReactJS may be a killer app that can influence javascript's "opinions" at the ecosystem scale, but that is going to take more time. I've been using ReactJS since it came out as tech lead on small teams, and it was not without challenges to get an OOP trained team to use React well, and to avoid the OO parts of React.
Edit: In theory, yes, if you could somehow statically enforce that your C code (and dependencies, including the OS) have no side effects, then some hypothetical compiler could combine your imperative C statements into functional expressions, though I don't know what advantage that would give you. Maybe I have misunderstood your post.
Or that unusual syntax is precisely motivated by trying to seamlessly and naturally express FP code.
Either that or they were just being intentionally obtuse... come on, man. Which sounds more likely of these two? I'd personally never want to program in a language with the semantics of Haskell, and the syntax of a C-like language.
> With better references and immutable variables, we should be able to split calculations up over several lines and have the compiler figure out how to optimize it into basically FP code.
Or just dive the code up into whatever temporary and intermediate steps that you need with let-in expressions and where-declarations? I mean, why not? If what you want the compiler to process is FP code, then just divide it up like you would divide up FP code. FP /= one liners.
Even if the only reason (hint: it's not) were that Purescript uses familiar tooling such as NPM, node, CommonJS modules, bower, etc and would allow users to focus on learning functional programming faster.
For those that wasn't more than the examples, there is the wonderfully comprehensive, practical, and just plain fun Purescript book[1].