6 ms·
How to stop functional programming (2016)
- skybrian 1y agoApparently, someone doesn’t really get what makes functional programming hard to understand? It’s not writing the occasional pure function. Code review or pair programming might help here, to learn the team’s common idioms.
- IshKebab 1y agoYeah this 100%. FP isn't hard because of FP - it's all the other things that popular FP languages come with that makes them hard to understand. Arguably most of them are not related to FP; they're just style choices: 1. Global type inference. 2. Implicit syntax (no brackets for function calls, commas to separate arguments, semicolons to end statements/expressions, etc.) 3. Currying & point free style. 4. Tendency to have very deep nested expressions. The gap between `let foo =` and it's actual value can often be hundreds of lines. I'm sure you can write FP code that avoids these issues and is easy to follow but it doesn't seem like people do that in practice. Rust avoided all of these issues fortunately. (Oh I forgot about monads.)
- amluto 1y agoAlso: avoidance of mutable state, even locally. A lot of functions can be more straightforwardly expressed using mutable variables and data structures, and most functional languages can handle local mutable state, but a lot of code in functional languages avoids it. Conversely, a lot of code written in imperative languages would be clearer and/or less bug-prone if it avoided mutable state and used persistent data structures. I wish there was a mainstream, high performance language that made both styles equally ergonomic.
- deleted 1y ago[deleted]
- delta_p_delta_x 1y ago> I wish there was a mainstream, high performance language that made both styles equally ergonomic. Unironically, C++.
- ndriscoll 1y agoOr depending on what "high performance" means (e.g. if Java or Go would be considered acceptable), Scala.
- Mond_ 1y ago> > I wish there was a mainstream, high performance language that made both styles equally ergonomic. > Unironically, C++. At best C++ falls under "equally unergonomic".
- Philpax 1y agoDoes Rust not meet that description?
- amluto 1y agoRust is very good at making things immutable. But that doesn't mean it's particularly fun to, for example, append or prepend something to a list and retain a reference to both the old and the new list. Compare to most "functional" languages, in which prepending an item to a list and ending up with immutable references to the old and new lists is almost the defining feature of the language.
- IshKebab 1y agoYeah although I find FP languages' obsession with singly linked lists to be a real flaw because they have such awful performance characteristics. And also pretty bad ergonomics often. The number of times stuff comes out backwards...
- Mond_ 1y agoConsidering the performance implications of a full commitment to immutable data structures, I think Rust does a pretty good job here. Dynamic arrays / vectors / slices or whatever you want to call them are probably the most important or fundamental non-plain-old-data data structure, and in a purely immutable environment these are essentially impossible (or have awful performance characteristics).
- calebh 1y agoIn my experience the main benefit of functional programming is function purity. I am completely fine with mutation inside of a function since the all of the mutation logic is self-contained in a single small block of text. I think everyone should take a shot at writing a non-trivial functional program to see the benefit. Once you understand what makes it great, you can apply what you've learned to the majority of OOP/impure languages.
- brabel 1y agoFlix has "regions", which are a way to allow mutation locally while keeping the language purely functional otherwise: See Region-based Local Mutation in https://flix.dev/ https://flix.dev/
- jen20 1y agoAlso the unwillingness of so many enterprise developers to learn anything that wasn't commonplace in 2001, regardless of whether they were in the workforce by then.
- elevation 1y ago> I forgot about monads I've been solving business problems with code for decades. I love pure, composable functions, they make my job easier. So do list comprehensions, and sometimes, map and filter. Currying makes sense. But for the life of me, no forum post or FP tutorial that I could find explained monads in clear language. I've googled "what is a monad" once a year, only to get the vague idea that you need monads to handle IO. I wondered if my brain was broken, but now I'm wondering if most FP adherents are simply ineffective communicators: they've got an idea in their head but can't/won't express it in a way that others after them can understand. In other words, the exact same reason why TFAuthor was corrected by his employer.
- OhMeadhbh 1y agohttps://www.bi6.us/CO/N/20250330.HTML#/033002 https://www.bi6.us/CO/N/20250330.HTML#/033002
- vjerancrnjak 1y agoI felt similar with lenses. The problem lens solve is horrible. You don’t even want that problem. FP can be the pragmatic as well. You’re going to glue up monad transformers, use lenses like there’s no runtime cost, and compute whatever you need in days but at least you know it works. Maybe there’s accidentally quadratic behavior in lifting or lenses but that’s by design. The goal is to just throw software at things as fast as possible as correctly as possible.
- AdieuToLogic 1y ago> I felt similar with lenses. The problem lens solve is horrible. You don’t even want that problem. Lenses abstract properties in a composable manner. How is this problem horrible? > FP can be the pragmatic as well. You’re going to glue up monad transformers, use lenses like there’s no runtime cost, and compute whatever you need in days but at least you know it works. Maybe there’s accidentally quadratic behavior in lifting or lenses but that’s by design. The goal is to just throw software at things as fast as possible as correctly as possible. Any abstraction can be used inappropriately. Slavish adherence to an approach in spite of empirical evidence is a statement about those making decisions, not the approach itself. In other words: A poor craftsman blames his tools.
- mrkeen 1y ago> (Oh I forgot about monads.) This demands an equivalent article which takes the same form as TFA. A coworker complains about monads, so the manager insists all monads be taken out. So Brian gets to work on the codebase, removing all Lists, Optionals, Streams, Functions, Parsers, Transactions, ...
- jazzypants 1y agoThis is written by the same guy who made a big stink about how JS promises weren't pure monads and somehow that was a problem-- a zealot, in other words.
- frozenlettuce 1y agowell, promises' computations start as soon as they are created, so they are not composable. and there' no cancellation/resource control as well. so I guess that the criticism is valid
- macintux 1y ago(2016)
- seanhunter 1y agoBy the looks of the code snippets he should have explained that he’s not doing functional programming, he’s just writing unnecessarily non-idiomatic python code. I’m sure his manager would have understood.
- ndriscoll 1y agoThe code snippets are Scala. The first snippet is idiomatic. I can't imagine a team adopting Scala and complaining about functional programming though.
- tengbretson 1y agoI thought "idiomatic Scala" was an oxymoron.
- cyberpunk 1y agoDoes it still generate 17 page long stacktraces of nothing but $anon$fun? Good times.
- mrkeen 1y agoI've been there. One of the more functionally-minded devs wrote something to do with putting Keys and Values into some kind of json store, and a less functionally-minded dev complained about all the type variables - Ks and Vs I guess.
- tiew9Vii 1y agoThe article date appears to be around the time the company the author was working at got a new CTO who effectively said functional programming was banned. The Scala teams got broken up and some pro Scala staff managed out… Maybe it’s related, maybe it’s not.
- flohofwoe 1y agoWhen did method chaining become 'functional programming'? It's not 'functional programming' that makes the code unreadable, but overly long chains of array-processing functions. Sometimes a simple for-loop which puts all operations that need to happen on an array item into the loop-body is indeed much more readable.
- jolux 1y ago> When did method chaining become 'functional programming'? It's very similar to applicative style in FP. Conceptually, method chaining is equivalent to nested function application, it just comes with syntax sugar for specifying the `self` parameter.
- Jaxan 1y agoA big difference is that it must include the thing the functions act upon (self). In functional programming you often leave that out. In FP you can also refactor little pieces of the chain into its own separate name (eg: smallest = sort >> head). This avoids long chains.
- fuzztester 1y agoInteresting. In which functional programming languages (that you know), can this be done? That refactoring little pieces, I mean. Looks like it would help with code readability.
- mrkeen 1y ago> When did method chaining become 'functional programming'? As soon as you stop calling it "method chaining" and start calling it "function composition". If you chain together a bunch of methods ('.' operator) in an OO setting, that's called a "fluent interface". It's a sign of good design and is to be commended. If you compose a bunch of functions ('.' operator) in an FP setting, it's an unreadable mess, and you will receive requests to break it into separate assignment statements and create named variables for all the intermediate states.
- 1y ago
- busterarm 1y agoThere's only one universal lesson that I've learned over my 25+ year career so far and it's that software engineering types are fragile creatures whose egos must be tended to. Delicately. This is becoming increasingly true as the years pass and the number of times I've had to drop whole mature architectures and reimplement something worse because some engineer's feefees got hurt can no longer be counted on my fingers & toes.
- jtms 1y agoThis is 180 degrees from teams I have been on some years ago - everyone took pride in being thick skinned and detaching their ego from PR reviews. Seems to be a generational thing
- busterarm 1y agoI 1000% agree with you. I barely recognize this industry from where I started in it. Pretty sure once my mortgage is paid off I'm changing careers.
- imtringued 1y agoUsing Scala and then complaining about unnecessary complexity is a bit much. Like, if you made the technologically brave decision to use a niche language like Scala that isn't just a slightly better Java like Kotlin then you'd better expect to accommodate the inexperienced developers by training them, possibly via pair programming, instead of constricting the experienced developers.
- tsss 1y agoIf this code is too complicated for you then you should reconsider your career.
- frhhfgf 1y ago[dead]
- elevation 1y agoTFA is indignantly reacting to the least charitable interpretation of what his employer has asked him to do. I'd like to know the honest shape of the code his manager rejected before judging the employer over this.
- dismalaf 1y agoAgreed. Especially if they chose to use Scala...
- astrobe_ 1y agoBeyond the satire, one is supposed to write code which is readable, and like often with written works, one has to think about the "audience", the readers. When you write technical documentation, you have to decide ahead of time the expected skill level of the reader - often that decision is written too in the intro as "prerequisite(s)". When writing code you have the motto "don't make me think" in mind, but how to know what's the maximum level of trickiness for readers? There are familiar techniques and idioms when it is your main programming language, but they are not for someone using this language on the side. In any case, neither code nor comments should be tutorials. To a reasonable extent, it is up to the reviewer to do their homework or just ask. Then based on that interaction you can add a comment or a parenthesis, or uncompress a bit the code. But not to the point that it means to "dumb down" things, because it is a downward spiral.
- dimal 1y ago> When writing code you have the motto "don't make me think" in mind I disagree with this phrasing. We’re engineering after all. The entire job is thinking. If someone doesn’t want to think, then they shouldn’t be a programmer. Readability matters, though. I try to have a narrative structure in my code, so it leads the reader along. Formatting matters. And documentation helps. If you want to introduce an unfamiliar idiom that might be more functional, good, but document it. Share it with the team and talk about it. I know that writing and reading documentation is usually seen as a waste of time unless you’re doing it for AI, but I’ve seen it work well in multiple teams. In my experience, the teams with poor docs have the worst code.
- odyssey7 1y ago"I didn’t have time to write you a short letter, so I wrote you a long one." -- Mark Twain It's difficult to explain how to write well, but bad writing and bad computing systems typically impose far greater cognitive burden on readers than might have been necessary. There is an art to software engineering. Functional programming does involve idioms, though I would say no more than imperative programming, or OOP, or some other paradigm. One of the overarching themes of FP is to reduce the cognitive footprint to only the essential properties of the problem to be solved. A novice artist can produce a recognizable figure using many pencil strokes. It takes a master to produce a compelling likeness with only the lines that are necessary.
- _aleph2c_ 1y agoThe manager solved the wrong problem. People should be sharing their tricks with each other. This was a perfect time to set up some peer-to-peer training.
- jen20 1y agoOr in the age of AI, "have you asked Claude to explain what the code does so you can learn something?"
- jmmv 1y agoMissed chance to do something like: class User: def calculateCoworkers() = { this.coworkers.clear() for { d <- this.departments } this.coworkers ++ d.employees } and then, somewhere else... user.calculateCoworkers() ... many lines after ... for { c <- user.coworkers } ... do something ... Yes, I've seen code like this many, many, many times where class members are used as "global variables" to pass state across functions. And I've noticed AI likes to generate code like this too (possibly because of the former (large presence of this "pattern" in the training data), which means I'm encountering this now in pull requests...
- sevensor 1y agoBonus points if you do half the calculation in the parent class and the other half in a child class. Double bonus points if one or both of them also hits a database.
- cies 1y agoFP code is often easier to read (the article provides a case to that point). What gave FP a bad rep is, i guess, Haskell (and the "pure functional approach w/ monad transformer stacks"). Every shop I worked at the devs were already at a level that they'd appreciate FP code: easier to read, refactor and test. The tendency is also towards FP: see the features in recent Java/C# version. Or languages that gain popularity recently (Kotlin, Rust) are more FP'ish than their predecessors (respectively Java and C++).
- OhMeadhbh 1y agoThe way I tell it is FP gives you more options for where to put the state and how to denote it. There are plenty of environments that let you mix OOP and FP and they're all a little bit funky, but not unworkable. I think the key thing here is the learning curve is a little steeper than OOP-ish languages. And since our universities are now really just trade schools, teaching kids which python libraries to use to feed data into a ML model someone else has built, there's little chance we'll see junior software developers who have been exposed to idomatic functional programming.
- deleted 1y ago[deleted]
- apalmer 1y agoUltimately the important thing is that the development team align on the style of programming that they will use at least per project. And the larger the codebase and more developers working on it the more important the consistency in implementing the style guide is. Imperative programming style has many advantages over functional for some problems. Functional programming style has many advantages over imperative for some problems. The only clearly 'wrong' approach is codebases where you can look at the code and determine a specific developer on the team wrote feature x because it fundamentally looks completely different from the other sections.
- ChrisMarshallNY 1y agoWell, this is one of the reasons that I like coding for myself. The pay sucks, but I don't have to bowdlerize my work. When someone pays me to write code for them, they get to call the shots; even if I think their judgement sucks. If they want to hire incompetent programmers, that can't understand even halfway-advanced code, then that's their prerogative, and I need to suck it up, and play by their rules; which may include the need for me to write code as if I just started yesterday, because it will need to be maintained by folks that, um, just started yesterday.
- nor0x 1y agoWould be interested in an article about stopping OOP. I see myself often drifting towards classes and abstractions once my code grows in complexity
- fainpul 1y agoYou go into work and discover that a coworker isn't happy with some code you wrote because they don't like it. They go to your manager and tell them that you're being a problem by writing code they don't like. Your manager, being very skilled in conflict resolution, makes a technical decision to avoid whatever tool you used which caused the problem. In your case it was OOP. That's it. You've been told. No more OOP. The manager has figured out what's good for the business and you figure that listening is what's good for your job.
- OhMeadhbh 1y agoThough honestly, having a manager that's interested in how software is made is a gift. My managers for the last 20 years have all been like "okay, let's do planning poker and everyone make sure that all the fields in your JIRA tickets are filled out."
- OhMeadhbh 1y agoThis is the video that's been going around. It's a bit long and could have been compacted into a 20 minute video, but if you have the time, it's a good overview for people without a computer science background. "Casey Muratori – The Big OOPs: Anatomy of a Thirty-five-year Mistake – BSC 2025" https://youtu.be/wo84LFzx5nI https://youtu.be/wo84LFzx5nI But if your point is there aren't any written articles about stuff like this, I agree. If they're out there, they're a bit outside the mainstream.
- fuzztester 1y agogoogle richard feldman (roc lang creator) talk about using just functions and data. don't remember exact title, sorry, but description i used above is close, iirc.
- yohbho 1y agowhen I see the word function or someone uses parenthesis to call one, it clearly is fp. Management was clear that this would not be tolerated, this source is too addictet to the good pure shit.
- OhMeadhbh 1y agoI wrote my own Lisp-like language that's a LLVM front end that explicitly uses greater-than / less-than angle brackets instead of parentheses for exactly this reason. When you walk by and don't look closely at it, it sort of looks like HTML so doesn't attract attention. And when a co-worker looked closer I just said it was a legacy templating engine and they really should just stick to python.
- jondwillis 1y agoThis literally happened to me with Functional Reactive Programming, around the same time frame (2016.) I still have to advocate for minimizing mutable state. At least since then, popular languages and frameworks are putting in a ton of work to make functional programming look more like the imperative spaghetti that is still prevalent and taught.
- yakshaving_jgt 1y agoI do love a bit of FP. Here's the canonical Hello, World! program. {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} module Main where import Foreign.C.Types import Language.C.Inline qualified as C C.include "<stdio.h>" C.include "<stdlib.h>" main :: IO () main = [C.block| void { system("python -c 'print \"Hello, World!\"'"); } |]
- OhMeadhbh 1y agoExcept that someone installed a different version of python on the target system that changes the semantics of the print keyword.
- OhMeadhbh 1y agoMy final days at Planet Labs involved me telling people "oh hey, I'm going to do this functional thing" and everyone saying "oh wow! that's great!" And then I went around to key engineers and explained in detail what I was doing in the code and they said "OMG! THAT'S AWESOME!" And then I checked it in and the response was "I HAVE NO IDEA WHAT THE FUCK YOU'RE DOING HERE!?" Yeah. I don't want to work with those people. Did I quit? Was I fired? I can't really remember. But ultimately, I moved on to a better environment.
- notmyjob 1y agoThought the title read, “How to _slop_ functional programming,” and got excited. “It’s happening!!!”