8 ms·
Introducing "Functional JavaScript"
- bsimpson 14y agoIs it prudent to utilize the functional style in a language that isn't tail call optimized? Doesn't that create a lot of garbage for the GC?
- johnpmayer 14y agoI think that because TCO is all but inevitable in future engines/standards, starting to use functional patterns now for the programming benefits is worthwhile.
- jcampbell1 14y agoBe my guest. Start using this implementation of each. Let me know if you run into any problems. function each(arr,fn,pos) { pos = pos || 0; fn(arr[pos++]) if(pos < arr.length) each(arr,fn,pos); } Seems like a recipe for a disaster.
- fogus 14y agoI prefer Underscore's implementation of `each`. It doesn't blow the stack. http://underscorejs.org/docs/underscore.html#section-13 http://underscorejs.org/docs/underscore.html#section-13
- k3n 14y agoThat would highly depend on if you're writing performance-sensitive code, and I doubt most JS would be greatly affected by these paradigms.
- MBlume 14y agolack of TCO doesn't mean it's a little slow, lack of TCO means that naive use of classic functional patterns blows the stack for big lists/structures/arguments.
- fogus 14y agoBy "classic functional patterns" you mean recursion. There are other ways to implement functions that are "classically functional" using techniques other than recursion, that do not blow the stack. I'll talk about each and their tradeoffs.
- MBlume 14y agoI did also say "naive use" =) Looking forward to the book.
- gngeal 14y agoIt's not just recursion, it's calls in general, I guess. (There are other ways of being space-inefficient in functional programs, see the odd versus even streams issue in Scheme.) Are you going to mention tail calls in ES6 in your book, BTW?
- fogus 14y agoSorry for the late response. I will not cover ES6 tail calls very much at all except to mention the possibility for inclusion.
- k3n 14y agoRight, but is this a concern for most JS? I realize that JS is becoming more popular for various tasks -- not always relating to the web -- but still, I kind of doubt that 99% of the JS out there is going to run up against these types of problems. Perhaps something like Uglify.js or similar might, but then again, if you're implementing a parser (or any other static code analyzer/tool) then you're probably going to avoid most libs to start with.
- Cushman 14y agoFunctional programming doesn't have to mean deep recursion-- it's not like you can't use functions and loops in the same code.
- gngeal 14y agoTail calls are not as much about "deep recursion" as they are about continuation-passing style, compositionality, and similar things. It's like with lazy evaluation. It allows you to write novel kinds of algorithms and data structures, and you can emulate it with helper objects or structures, but it's tedious, muddles the essence of the code, and the implementation without them (the helper structures) would be simpler if the language provided you with lazy expressions. In other words, repeat with me: loops don't compose. They're not first-class, they're not extensible, they're a syntactic construct.
- munificent 14y ago> In other words, repeat with me: loops don't compose. Iterators do, though. Most of the languages that don't do TCO instead lean on those instead: C++, C#, Python, and eventually JavaScript.
- pjmlp 14y agoFunctional Programming is much more than just recursion. There are lots of concepts that are still applicable even when using imperative loops.
- camus 14y agoWould it allow to avoid stackoverflows with a simple flood fill algorithm if Javascript had tail call optimization ? right now i need to build my own stack, and "unstack" it manually.
- cdumler 14y agoFunctional purity would be nice, but TCO not strictly necessary to be program very functionally. For instance, here TCO would be necessary to prevent the stack from being over-run: function fact(x) { return (function factIter(i, total){ if(i<=1){ return total; } return factIter(i-1, total*i); })(x,1); } However, if you're willing to allow mutation in non-accessible code or closures, there are options: function fact(x) { if(i<=1) { return 1; } return _.range(1,x+1).reduce( function(sum, x) { return sum*x; } ); }
- alexfarran 14y agoYou can use a trampoline like the one the author has written in this library https://github.com/fogus/lemonad/blob/master/lib/lemonad.js#L1089 https://github.com/fogus/lemonad/blob/master/lib/lemonad.js#... Basically you rewrite your recursive functions so that instead of calling another function they return a parameterless closure. Then you can iteratively call your first function, and the function it returns, and the function it returns etc until the return value is not a function.
- knowtheory 14y agoYes, in particular, asking people to think about the input and output to a particular piece of code is really important. Pulling apart the iteration over a collection of elements and behavior performed to each element is one of those insights that a functional style is good at communicating, and leads to better more testable code.
- fogus 14y agoKnowing the limitations of your runtime is important. My book is not a dogmatic application of functional programming in spite of JavaScript, but instead an exploration of the functional techniques that complement JavaScript. Tail calls make an appearance, but they are more broadly applicable than their use in the presence of TCO.
- kaoD 14y agoWho needs loops nowadays? Just map, reduce, filter and imperatively-loop when needed (around 0.1% of cases?).
- k3n 14y agoSeeing as the page's title has "fun.js", I thought this was yet another 'functional JS' lib... but I was pleasantly surprised to see that this is actually a book that covers different aspects of FP within JS. Now I'm looking forward to reading it!
- petercooper 14y agoGive it an hour and this link will be retitled "fun.js" by the mods..
- k3n 14y agoBeen around here awhile, but mostly on the fringes, so I'm not sure what you mean by that...?
- petercooper 14y agoHN policy used to be that you could give items customized/more appropriate titles if the page you were linking to had a bad title. In the last year, this guideline was removed from the guidelines page and mods have been renaming items "back" to the actual title of pages being linked to. So this item should be "fun.js" and now the useful title it is now. I'm surprised it hasn't happened yet because there have been a ton of examples in the past several months. (If you couldn't guess, I think the change in policy is ridiculous.)
- k3n 14y agoI see, thank you for the explanation. I have mixed feelings about it; on one hand, if an author titles a piece of work, then in the interest of honoring their creative expression (e.g. their work) then it'd be best to use their titles. Except, of course, when it's a poor title. On the other hand, authors aren't always the best about naming articles, and/or there's context that's present on their site that might produce a title that's out of context when lifted wholesale for use on another site. For this article, I think "fun.js" is particularly poor, as it implies that it's about some coding project. Of course, the ecosystem has been tacking ".js" onto anything even remotely related to JS, and so it's not all the author's fault, but as a HN title it'd be misleading. IMO the 'best' title here would be akin to a reference, such as: "Functional Javascript: Introducing Functional Programming with Underscore.js" by Michael Fogus (O'Reilly)
- kailuowang 14y agoWhat I really miss when doing "functional JS" is pattern matching. Is there any good solution for that?
- goldfeld 14y agoHave you seen matches.js? https://news.ycombinator.com/item?id=4516576 https://news.ycombinator.com/item?id=4516576
- kailuowang 14y agoIt looks great. Thanks for the link!
- coldtea 14y agoYou might try this one: http://www.bramstein.com/projects/funcy/ http://www.bramstein.com/projects/funcy/ It implements pattern matching in JS, with objects and closures. Not as convenient as first class support, but might be worth it.
- bsimpson 14y agoThat link is overloaded. Try this one: https://github.com/bramstein/funcy https://github.com/bramstein/funcy
- fogus 14y agoI also really miss pattern matching and I think that JavaScript would be well-served by it or even minimally some sort of destructuring.
- GeZe 14y agoFor those who don't want to wait for the book, I've written a brief article covering some concepts of functional programming in JavaScript: http://livescript.net/blog/functional-programming-in-javascript-using-livescript-and-prelude-ls.html http://livescript.net/blog/functional-programming-in-javascr... It covers first class and higher order functions, currying, partial application, composing functions, using operators as functions, comprehensions, and immutability.
- weareconvo 14y agoIn all of this, let us never forget: "Functional Programming" is a great lens through which to look at a large class of problems... but it is never the goal. Code re-use is the goal. FP and OOP are just means to that end.
- cousin_it 14y agoCode reuse also seems like an intermediate goal to me...
- weareconvo 14y agoIf you want to be precise about it, "the goal" is specific to each human being. I would hope it's something like "Make the world a better place" though.
- gngeal 14y ago"Code re-use is the goal. FP and OOP are just means to that end." I think that both of you are right, to some extent. Code reuse is a goal, because it's better than writing everything anew every time you need some functionality. But it's not a long term goal, because sooner or later, it turns out that the code you have is insufficiently abstract, and you have to replace it with something more generic. I don't think that the level of genericity and abstraction available in mainstream languages is up to the task of making long-time code reuse an appropriate goal. VPRI-style "'runnable math' specifications" seem like the way to go, but how many people program that way?
- chc 14y agoCode reuse isn't the point of OOP. It may be a goal you personally have when you're writing code in OOP style, but AFAIK it was not Alan Kay's overriding goal when he coined the term. It was more about promoting clean, well-factored program designs. Reuse just happens to fall out of that more readily than bad program designs.
- gngeal 14y ago
- jimbokun 14y agoI like the idea of separating a programming paradigm from actual programming languages. Obviously, certain languages lend themselves to certain paradigms, but it's nice to see a book explaining the concepts of functional programming in a language that doesn't enforce all of the tenants of that paradigm by default.
- GhotiFish 14y agoI find these topics to be fun, and I want to use them. However, I can't help but feel that if I use these design patterns, they might unintentionally obfuscate my intentions to my peers. I have a code base, and I think my priority should be to remains as consistent with that code base as possible. Am I wrong? Is this book just for entertainment? There's nothing wrong with that of course.
- raganwald 14y agoI ended up writing a blog post to answer your excellent question. Please let me know if you feel I shouldn't have quoted you or if the post could be improved in any way: https://news.ycombinator.com/item?id=5409626 https://news.ycombinator.com/item?id=5409626
- GhotiFish 14y agoThat was a good analysis of the problem. I'll give it some thought.
- benrhughes 14y agoLink seems to go nowhere, unfortunately
- nailer 14y agoFor the second edition, I think focusing on ES5 wherever something is actually included in JavaScript would be a huge improvement. Underscore.JS duplicates huge parts of ES5's own work for the benefit of older ES3 environments like IE8, Firefox 3 etc.
- bsimpson 14y agoThough I agree, there are only a handful of Array.prototype methods, and I believe Underscore falls back to them when they are available. I imagine you could read fogus's work, then substitute where appropriate if you're already well-versed in JS. "I know I can use [].forEach instead of _.each."
- gosukiwi 14y agoWhere can I suscribe so I know when it's released?
- deleted 14y ago[deleted]
- pasbesoin 14y agofogus, This may be too political (as well as OT) a question for you to respond, but I see that this is an O'Reilly book. Does this mean that O'Reilly... um, "has some life left in them"? I guess I'm hoping so, and looking for some encouraging words from your own experience doing this book with them. Or criticism, if it's justified and you are free to say. (There used to be some O'Reilly people on here, I've noticed, so keep that in mind...) I like Tim and like the older books. Some more recent issues have given me pause. P.S. Oh, I see the book isn't out, yet. Maybe I should ask this later. Also, I didn't initially consider that this could start another "O'Reilly" conversation, in depth. Rather, I'm interested in first-hand experience.
- linse 14y agoHey jashkenas / Michael, how funny, we are just in the review process of our book (also at O'Reilly) covering functional programming techniques in JavaScript! It is in German, and with lots of tasty Curry recipes we explore currying in programming and cooking at the same time. :) Our book is called "Das Curry-Buch" (the curry book) and you can find it here: http://is.gd/currybuch http://is.gd/currybuch Check it out, I think there cannot be enough books on functional programming! :)
- pepijndevos 14y agoFor the German speakers amongst you, a friend of mine also just submitted her book about functional Javascript for review at O'Reilly: http://www.amazon.de/Das-Curry-Buch-Funktional-programmieren-JavaScript/dp/386899369X/ http://www.amazon.de/Das-Curry-Buch-Funktional-programmieren...
- hilko 14y agoI've been reading up a lot on functional programming, and by know I think I get most of the principles and techniques. What I'm mostly struggling with is how to structure my code within this paradigm. While this struggle is not limited to FP, I'd be very curious to find resources that don't just show code snippets, but explain the greater architecture of FP implementation.