As it says on the site, Fogus is "a core contributor to Clojure and ClojureScript". I wonder why he didn't just write a book on ClojureScript instead. Isn't ClojureScript already a way to write functional javascript?
Nice! I hope "Thinking code" and "Data-orientation" parts will get more attention (and space), versus ClojureScript and "weby" stuff, in case there will be a trade-off.
Javascript is inherently functional on its own! I can't speak for the author, but I suspect he titled it this way because of how few javascript users there are that actually understand this fact.
Javascript is inherently dis-functional (hehe) as it relies heavily on mutation and side-effects, rather than immutability and functional purity. First-class functions do not mean the language is functional.
I disagree with this statement. Arrays are mutable, it's easy to make global mutable state, for the longest time for loops required a mutating index, etc.
That's true, and may be reinforced somewhat by the fact that JavaScript doesn't eliminiate tail calls. In other words, there are situations where a recursive algorithm would be clean and compact, but might result in the call stack being blown inadvertently.
I ran into this recently while building a "practical" monads library for JavaScript. Each monad and transformer has sync and async variants. The sync variants can't use straight recursion because "deep" monadic binds will result in a blown call stack. The solution was/is to allocate on the heap in terms of an array that acts as a manually operated call stack (I think I essentially implemented a "trampoline" but I'm not 100% certain).
> for the longest time for loops required a mutating index
Well, at least one mutating index is convenient:
function forEach (a,f) {
for(var i=0;i<a.length;i++) f(a[i],i,a);
}
After that, you generally wouldn't need more indexes.
But does it really require a mutating index?
function forEach (a,f,i) {
var n = i || 0;
f(a[0],n,a);
if(a.length > 1)
forEach(a.slice(1),f,n+1);
}
Array copies aren't particularly efficient, of course, and there are languages with data structures backing arrays for which some similar approach might be efficient, but there it is.
I guess the thing I'm harping on is shawnz saying that javascript is INHERENTLY functional. I think it's possible to write javascript in a functional way: Underscore.js is a perfect example of that. But I wouldn't say it's INHERENT of javascript.
I think javascript is INHERENTLY object oriented/imperative but can be functional if you put some effort into it.
Yes, but JavaScript is flexible enough to allow persistent data structures, and a value-semantics API for working with them, to be implemented in terms of a library:
Just to avoid confusion: mori the library, as distributed by npm, is already compiled. Building the library itself requires a compile step, but an end-user just needs to load it with a script tag or require("mori").
It is, but pre-distribution it is compiled down to 100% JavaScript as a stand-alone JS lib that you can load with a script tag or NodeJS require(...).
The ClojureScript compiler only gets involved if you want to hack on mori yourself, as opposed to consuming it as a library.
If the point you're making is that it's implemented with ClojureScript as opposed to JavaScript, the fact is that everything that ClojureScript "does" you can do with hand-written JavaScript, but your hand-rolled solution might not be as generic or efficient (depending on your JS chops).
Javascript, like other scripting languages (Ruby comes to mind), is both functional, imperative and OO. It has mutable state, imperative loops, first class functions, closures, etc...
I did the same thing. I have been waiting for this book. For a variety of reasons, I have been spending more time coding in Javascript and a little less in Clojure, and I hope this book helps make that a happier experience.
The otherwise beautiful 'official site' has a very curious 'feature' right at the bottom: a glossary of choice words which, on click, pop open a window alert with their 'definition'. It gets even more bizarre: at least two of those items return "glossary entry for [xyz] not yet available".
So far I've been disappointed by the "functional X" books.. Probably because I've read SICP and much of the "functional" books just repeat the same patterns over and over.. i.e. memoization, closures, map, reduce, etc. Still, I'm a sucker for these books and I'll gladly buy it. Hopefully I'll learn a thing or two.. and if I do so, I'll be more then happy to share the word about it! : )
35 comments
[ 4.8 ms ] story [ 72.6 ms ] threadThanks for the new book fogus, love TJoC 1 and am eagerly awaiting the sequel.
I ran into this recently while building a "practical" monads library for JavaScript. Each monad and transformer has sync and async variants. The sync variants can't use straight recursion because "deep" monadic binds will result in a blown call stack. The solution was/is to allocate on the heap in terms of an array that acts as a manually operated call stack (I think I essentially implemented a "trampoline" but I'm not 100% certain).
Well, at least one mutating index is convenient:
After that, you generally wouldn't need more indexes.But does it really require a mutating index?
Array copies aren't particularly efficient, of course, and there are languages with data structures backing arrays for which some similar approach might be efficient, but there it is.I think javascript is INHERENTLY object oriented/imperative but can be functional if you put some effort into it.
JavaScript is inherently a blurry mess, and intentional but hacky hybrid of Scheme and C-style.
http://swannodette.github.io/mori/
Just to avoid confusion: mori the library, as distributed by npm, is already compiled. Building the library itself requires a compile step, but an end-user just needs to load it with a script tag or require("mori").
The ClojureScript compiler only gets involved if you want to hack on mori yourself, as opposed to consuming it as a library.
If the point you're making is that it's implemented with ClojureScript as opposed to JavaScript, the fact is that everything that ClojureScript "does" you can do with hand-written JavaScript, but your hand-rolled solution might not be as generic or efficient (depending on your JS chops).