4 ms·
I agree with everything you wrote. There’s an element in this that gets at why V8’s omission of TCO feels to me like suppression of functional programming. Jav
by odyssey7 3y ago
I agree with everything you wrote.
There’s an element in this that gets at why V8’s omission of TCO feels to me like suppression of functional programming. JavaScript is an incredible widely used multi-paradigm language, to the point that I would recommend for universities to replace Python and Java with JavaScript in their curriculums. It’s just so practical for building software systems, has amazing tooling, connects you to a rich community, and allows you to cover so much academic ground. JavaScript has been a rocket fuel for promoting a vibrant, diverse software engineering ecosystem.
Although you can choose to write a loop and do things imperatively in JavaScript, you don’t have to. The ECMAScript spec is inclusive toward the functional programming paradigm by requiring that engines provide for proper tail calls. Functional programmers should be allowed to have their cake and eat it too! But TCO isn’t implemented in V8, and the workaround is to just switch from functional to imperative programming.
- MrJohz 3y agoI don't think it's the lack of TCO that's the thing holding JS back from getting the next great functional language. There's no structural pattern matching, there's no immutable data structures, there's nothing in the way of convenient syntax sugar like currying. You can mimic all of that, but it's painful, it's not something that Javascript is that great at. Which is fair enough, it doesn't need to be perfect at everything, that's why there's different languages. If you want functional programming in the browser, try using Elm or ReasonML. Both of those are fairly easy to use, I think there are even online playgrounds for both to get started.
- odyssey7 3y agoI think it’s not as widely recognized as it could be just how forward-looking ECMAScript was in introducing language updates in the mid 2010s. For instance, arrow functions make it natural to work with partial application, a currying-adjacent technique. const times = a => b => a * b const double = times(2) const twiceFour = double(4) As a language feature, a function to curry a given function is different from proper tail calls in that it can be implemented as a JavaScript function rather than needing to be built into the JavaScript engine. Similarly, Haskell’s own curry function is imported from its standard prelude. Leaving this detail up to language users allows a diversity of approaches and vibrancy in the community. Lodash has had an implementation for a while: https://github.com/lodash/lodash/blob/0843bd46ef805dd03c0c8d804630804f3ba0ca3c/lodash.js#L10200 https://github.com/lodash/lodash/blob/0843bd46ef805dd03c0c8d.... (Edit, found better example.) Structural pattern matching can be very elegant and it would be nice if ECMAScript offered it. Object destructuring has been added to the language, and that feature could be seen as a stepping stone for adding structural pattern matching in a later version. Proper tail calls however are more fundamental to the paradigm of functional programming, since they are necessary for iterative algorithms to work as well functionally as they do imperatively.
- deleted 3y ago[deleted]
- MrJohz 3y agoIn Haskell, all functions are syntactically and semantically curried. That is, a function that takes two arguments is essentially identical to a function that takes one argument, and returns a new function that returns a second argument. (In fairness, part of this is the laziness of Haskell, and a language like OCaml which also uses currying behaves slightly differently, but still similarly enough.) The `curry` function is not a library implementation of currying, it's a way of unpacking tuples into arguments. In Javascript, a function that accepts two arguments is meaningfully different from a function that accepts one argument and returns a new function that accepts a second argument. Both semantically, but more importantly syntactically. It's possible to overcome this at the library level as you say, but it usually has performance and usability issues - error messages start looking very funky! It also often doesn't play well with other Javascript features, such as the famous `map(parseInt)` issue. That's not to say that currying isn't possible in Javascript, just that it's a feature that doesn't play well with the rest of Javascript. If you really want currying when you're coding, you're probably better off choosing another language - currying will work so much better, and you will have so many more advantages. What I've said is specific to currying, but in my experience, this is generally true. You can use certain functional idioms in Javascript (particularly higher order functions), but it isn't really a functional programming language. Adding features to make Javascript more functional makes the language a lot more complex, but it won't magically turn Javascript into a good functional language. Therefore, it doesn't make sense to include things in Javascript just because they're useful in a functional context, it's first important to validate that these features are useful in a standard Javascript context.
- hajile 3y agoJS works alright with currying, but I think manual currying is the best way to do it with the language (and it's not that inconvenient).
- Rapzid 3y agoShout out to F# in the browser via Fable too.
- miloandmilk 3y agoI was looking for an alternative to rescript and literally just started looking at Fable this week - and absolutely love it in conjunction with Elmish.
- hajile 3y agoTC39 hates FP. They have a stage 2 record/tuple proposal. Records are far more optimizable than JS classes since they enforce concrete types and can’t add/remove fields. Instead, they spent massive amounts of time on private fields which most devs didn’t want (most pushback any JS feature has ever received by a large margin) AND one that completely breaks proxies which are used by all kinds of libraries. Even Java is getting pattern matching before JS. They’ve decided pipe operators are either going to be an abomination or they will be cancelled entirely. So of this completely disregards the opinions and use cases of the FO devs that will be using them. This applies to all the FP proposals on their list. They get delayed, canceled, and neutered while niche or even bad features get implemented instead.
- wk_end 3y agoIt’s a shame, because records and tuples are enormously helpful when trying to optimize React, given how it uses reference equality on objects to bust memoization.