If functional programming is so great, it should be able to stand on its own merits without the constant insults thrown at other programming paradigms.
I lean more towards FP than OOP but there are times when each paradigm makes sense in a specific situation (especially because we rely on a lot of third party code we can’t control).
> Who on earth would craft such a ghastly abomination?
> It may come as a surprise to hear that we can write full, everyday applications along the lines of the functional analog above.
> It is obnoxiously verbose and, as it happens, bad practice
> I avoid using this like a dirty nappy. There's really no need when writing functional code.
> If you are the micro-optimization sort, please close this book. If you cannot get your money back, perhaps you can exchange it for something more fiddly.
To be fair, the later chapters are much more focused solely on FP without the disparaging comments toward OOP.
There is no shortage of drier materials on the subject!
So how does this come across in my tutorial writing?
Not at all. That part of my personality is completely absent (I hope) from anything I create that is intended to teach people. Because the people I want to teach programming to could be anybody. They could be someone who can barely speak English and will just be totally confused by snark. They could be a precocious ten year old whom I would rather not expose to my adult cynicism. They'll get enough of it in life anyway.
Teaching materials should be clear, cynicism and snark free, and should never be condescending to either the reader or any alternative technology or point of view. That doesn't mean criticism free. But the criticism should feel balanced. Does comparing the alternative with a dirty nappy feel balanced to you?
A summary is available in: https://www.info.ucl.ac.be/~pvr/VanRoyChapter.pdf
One of the running themes is the paradigm paradox: "More is not better (or worse) than less, just different".
In other words, each paradigm has its own distinct advantages, which are discussed both in practical terms and using formal semantics.
I don't. There are lots of good functional programming resources where the author is polite and civil. Being condescendent is not an attribute of functional programming.
Example: https://fsharpforfunandprofit.com/
I've written Node for a living. Mostly Typescript in recent years. I've encountered multiple codebases where previous developers have used all kinds of novel constructs to make Javascript codebases resemble a purely functional language. I've never seen an example of this where the developer has actually managed to make their codebase more concise, understandable, testable, extensible, or more robust. The usual outcome is a complete birds-nest of spaghetti code that only the original developer could ever understand. These codebases usually never outlive the tenure of the original developer: They're usually thrown out the second another dev even lays eyes on it.
Reading through this article, I don't really see anything that would make my real-world coding job easier. I don't see any constructs that would actually make my code less complicated. Not to mention the elephant in the room that adding thousands of lines of scaffolding code (that only the author understands) so that Javascript supports monads (that the developers asked to maintain the code won't understand) adds so much more surface area for bugs. If you want to write an application in Haskell, just do that instead. At least then the company knows to look for a Haskell developer to maintain the mess you've made.
I've really enjoyed creating functional pipelines with Ramda in the past for professional projects. I liked how I could use the Ramda functions to explicitly state in my code what the flow of data was with functions like pipe and converge. It seemed to me that being able to understand the dataflow was easier with this paradigm. I could even create pipelines that would automate away dealing with promises in my pipelines with pipeWith. I would implement the same bits of code in "vanilla" js and with Ramda and Ramda was more concise and easier to read (if you understood how Ramda worked...).
You can see an example of the style that I like here: https://github.com/chughes87/calendarbot. I definitely was more "clever" in parts of that codebase than I let myself be in a professional setting heh.
I successfully onboarded a different team onto one of my projects when I was being switched to a different product at my company. An engineer who later did some maintenance work on it told me that the codebase was simple and easy to work with. I did get complaints about a later project that I implemented with Ramda from a person who was totally uninitiated and didn't bother to ask me for help..
I made a lil presentation about Ramda that explains some of this with some graphics that I think are helpful: https://docs.google.com/presentation/d/1tmre_8qJP-QhakXbiBpZ...
And, if the author is successful, then the chances that you could one day be able to write JavaScript code in this fashion and expect it to be maintainable would increase!
This is almost purely functional but makes no attempt to look like anything other than JavaScript and just about everything is identifiable to profilers and covered by some form of test automation.
There's a lot more to developing large projects than your own code. What about the ecosystem? What about everyone else's code? JS IMHO is just a complete mess. That's not at all to belittle the size of the problems it is tasked with solving, which are hard and complex. The difficulty is precisely why the right tool for the job is something that really insists on some level of correctness, in the vein of what rust tries to do at the systems level.
This is all IMHO and there's a lot of room for different opinions here, but I'm guessing we have a consensus, even among JS's biggest advocates, that it can't be described as "insisting on correctness".
Unfortunately the more relevant follow-up question might be: okay it's the wrong tool for the job, so what? It's what we have.
It's far from being "the standard language for the browser", but the browser doesn't know that.
what I really detest about javascript is its inability to say no to the programmer (most dominantly typing woes), and how incredibly late it got some super basic features for code organization. private class members (in a way that isn't syntactically insane) got added to the language figuratively two days ago. what the hell?
this was pretty much the result of the XHTML debacle as well, and I know the reasons why that went down the way it did, but it's kind of weird to me that We Just Can't Have Enforced Correctness In The Browser.
Is it crazy? yeah. But it’s not quasi functional.
It's easy to understand Lists, Options, Eithers and all the other classic monads and what they do. It's harder to understand other forms this can take.
At work I had to build something that ended up leading to creating a new monad type[0]. That process crystalized why we ended up with these ideas and structures much more clearly.
I also highly recommend any of Scott Wlaschin's videos[1]. He does a great job conveying FP ideas, and his videos introduced me to F# which is a really fun language with a very clean syntax.
Another great blog is by James Sinclair [2] who similarly has several articles on using FP in a practical way though some of the code can get a little deep but in an interesting way.
Loosely coupled but cohesive is a very useful mantra when integrating FP ideas along with keeping everything very simple - avoid crazy compositions, deeply nested types, etc. Just cause something can be abstracted due to FP (composing a bunch of function calls, looping once instead of 3 times etc) doesn't mean you should. There is value in breaking pieces up.
[0] https://sambernheim.com/blog/building-a-monad
[1] https://www.google.com/search?client=safari&rls=en&q=scott+w...
Allowing a chain of fat arrows and parentheses-free parameters was one of the nicer choices they made for ergonomic functional programming — being able to concisely write:
const add = x => y => x + y;
Ends up looking similar to Haskell type signatures.
I know there are proposals but neither seems to be making much progress.
I like FP but shoehorning it in with libraries is ugly compared to having native syntax.
https://github.com/tc39/proposal-pipeline-operator - Stage 2
https://github.com/tc39/proposal-pattern-matching - Stage 1
Hopefully we get both in the next couple of years.
Multiple colleagues swear by this book in particular, but I don't know if it needs to be read cover to cover. Reassuringly enough, much of the foundational content regarding immutability and higher order functions seems like it is already common knowledge to younger devs.
I think the biggest conceptual leap from the FP lite that is already practiced in modern JS to the "hard FP" of Haskell and Scala is the generalized approach to contexts via functors/monads. Luckily one such context already exists in JS in the form of the list. Implementing Option/Maybe using a single item list, and composing operations using the existing map and flatMap methods is a nice exercise that paves the way to the happy path only style of programming of the more advanced langs.
Javascript can do some functional programming, but it's not Haskell or OCaml. If you try to use it like that it quickly becomes a big mess and one that is not performant at all. You want to do pure, functional programming? Then write Haskell, or Elm, or Purescript.
I'm saying this as someone that loves fp, but is trying to get rid of a considerable chunk of fp-ts on a big codebase at work.
As a wise man once said, don't fight the language. Doing this deviates from Javascript semantics. It's a hack that is not actually helping people learn fp.
Also, please, don't do monads in Javascript! Monads are a solution for pure languages to deal with effects. Javascript can just do effects as it is!
I haven't had occasion to use wasm but it seems that it provides the ability to run most (all?) languages in the browser.
Here, for example, is f# wasm.
The only way I can see the problem (assuming someone agrees it is) of JS getting solved is if something comes along that's so amazing and blows it out of the water so hard that adoption explodes and browsers start natively migrating to it, along the lines of what we've seen with TypeScript, but instead of a bandaid a full replacement.
Are there any wasm demos (not necessarily source code) to try that would blow my mind? Genuinely interested. Maybe I have seen dozens and it's not obvious.
Enjoy:
- record and array literals
- arrow syntax for lambdas
- spread operator
- map, reduce, forEach
- string template literals
- default values with ||
- single thread memory model
- all the pretty colours
Avoid:
- Formal OO constructs, i.e. 'class' and whatever goes on inside it. They feel out of place, and e.g. the this.function() syntax is clanky. Special hate reserved for those magic proxy getters - breaks the simple record model.
- Formal typing, i.e. Typescript. Becomes unnecessarily verbose and boilerplated, tooling is not quite there, and you almost always need to poke holes in the type system to do anything interesting anyway.
- Lodash and friends. Not needed now the core language has so much out the box.
Where Javascript seems to shine is in being a simple, functional language, with concise syntax, and without heavy OO or type formalisms.
At least to me, Lodash is absolutely necessary even in new projects — such a wealth of functionality and most of it isn’t available OOB in the standard library. It’s easily tree shakable as well.
As for formal typing, TypeScript was a boon for my productivity. Curious about any examples of use where it’s been inadequate?
TS is helping somewhat but it compiles down to JS, and well, almost anything can happen at runtime.
“Compiles to JS” doesn’t imply anything about what a language has to look like; see PureScript for example.
Many of them seem to be about what I, the developer, can use.
Let me reframe it — what if you thought of FP techniques as something you could expose to a user of your API?
What if you viewed all your work in a language as a language. Borrowing concepts like affine types (aha, rust!), dependent types (hello, Agda!), composition (from pipes to combinators, this one is everywhere!) is important.
Strictly procedural or OO concepts might be useful in an implementation, but it rarely helps the user.
Some people writing security vulnerabilities in C are feeling put off by a programming language with sanity checks.
One's toolbelt doesn't ever have enough tools.