[HN Gopher] Functional programming should be the future of software
       ___________________________________________________________________
        
       Functional programming should be the future of software
        
       Author : g4k
       Score  : 281 points
       Date   : 2022-11-02 10:49 UTC (12 hours ago)
        
 (HTM) web link (spectrum.ieee.org)
 (TXT) w3m dump (spectrum.ieee.org)
        
       | shubhamjain wrote:
       | Functional programming proponents like the blog's author remind
       | of Linux users who sweared by it as a user-friendly OS, thought
       | of everyone else as idiots, and refused to admit its serious
       | flaws as a general-purpose OS. I am not criticizing FP. It has
       | great ideas and many of them have been actively borrowed into
       | other languages. But it's just annoying to see bad analogies that
       | get repeated again and again, like these:
       | 
       | > Now, imagine that every time you ran your microwave, your
       | dishwasher's settings changed from Normal Cycle to Pots and Pans.
       | That, of course, doesn't happen in the real world, but in
       | software, this kind of thing goes on all the time.
       | 
       | > Let me share an example of how programming is sloppy compared
       | with mathematics. We typically teach new programmers to forget
       | what they learned in math class when they first encounter the
       | statement x = x + 1. In math, this equation has zero solutions.
       | But in most of today's programming languages, x = x + 1 is not an
       | equation. It is a statement that commands the computer to take
       | the value of x, add one to it, and put it back into a variable
       | called x.
       | 
       | Deja vu! I read exact same arguments 10 years ago. Maybe if FP
       | did reduce the bugs, you'd have some stats and successful
       | projects to back them up.
       | 
       | I worked at a company where FP was heavily used. It didn't
       | magically reduce the number of issues we had to fix. Possibly
       | increased them because of number of things we had to build from
       | scratch. The company is default dead[1], now. Maybe bugs are not
       | a symptom of the paradigm, but how strongly the systems and teams
       | are architectured to prevent them.
       | 
       | [1]: http://www.paulgraham.com/aord.html
        
         | pessimizer wrote:
         | Did you mean to comment on the analogies you quoted other than
         | to say that they are often used? Is being useful a problem for
         | an analogy?
         | 
         | > But in most of today's programming languages, x = x + 1 is
         | not an equation. It is a statement that commands the computer
         | to take the value of x, add one to it, and put it back into a
         | variable called x.
         | 
         | This is on page 1 of every basic programming book when it's
         | explaining how "variable" differs between math class and
         | programming class. I can't for the life of me see what upsets
         | you about it.
        
           | shubhamjain wrote:
           | They are stupid because they don't address the fact that most
           | procedural languages themselves have features to prevent re-
           | assignments and mutable states (like, const). Also, variables
           | reflect the state of the program, while microwave settings
           | are inputs. The switching of settings doesn't make a whole
           | lot of sense.
           | 
           | > This is on page 1 of every basic programming book when it's
           | explaining how "variable" differs between math class and
           | programming class. I can't for the life of me see what upsets
           | you about it.
           | 
           | I never had a problem grasping the concept. I never equated
           | "=" in programming to "=" in Math. It's just a symbol.
           | Replacing "=" with "<-" would mean the same thing.
        
       | jokoon wrote:
       | As long as I can avoid the mess of oop and inheritance, I'm
       | happy.
       | 
       | Good oop is only found in a very small amount of libraries.
       | 
       | In don't want "reusable oop code", i want fonctions that returns
       | data. Side effects are impossible to keep track.
       | 
       | Of course you can't use fp everywhere, but oop should not be the
       | default.
        
       | VBprogrammer wrote:
       | One could almost say that functional programming will always be
       | the future of software.
        
         | JoachimS wrote:
         | Linux on the desktop - written in a functional programming
         | language. Executed on the Mill CPU. Powered by a fusion
         | reactor.
        
       | insane_dreamer wrote:
       | Arguably the single most determining factor in using a language
       | is the size of the ecosystem relative to the use case. If I'm
       | writing a data science app I'll probably use Python because I can
       | access a large number of well-tested libraries in the space, not
       | because Python is a superior language itself. Same argument for
       | Java (come on, who _actually_ enjoys Java?) Whether it 's OO or
       | FP isn't going to be a major consideration. I enjoy Ruby over any
       | other language, but don't use it much at work because ...
       | ecosystem.
        
       | zamalek wrote:
       | Functional programming won't succeed until the tooling problem is
       | fixed. 'Tsoding' said it best: "developers are great at making
       | tooling, but suck at making programming languages. Mathematicians
       | are great at making programming languages, but suck at making
       | tooling." This is why Rust is such a success story in my opinion:
       | it is heavily influenced by FP, but developers are responsible
       | for the tooling.
       | 
       | Anecdotally, the tooling is why I gave up on Ocaml (given Rust's
       | ML roots, I was seriously interested) and Haskell. I _seriously_
       | couldn 't figure out the idiomatic Ocaml workflow/developer inner
       | loop after more than a day of struggling. As for Haskell, I gave
       | up maybe 20min in of waiting for deps to come down for a Dhall
       | contribution I wanted to make.
       | 
       | Institutionally, it's a hard sell if you need to train the whole
       | team to just compile a project, vs. `make` or `cargo build` or
       | `npm install && npm build`.
        
         | capableweb wrote:
         | > it is heavily influenced by FP
         | 
         | Is it really? I agree with the rest of your post, that Rust
         | provides great tooling, but not sure it's "heavily influenced
         | by FP", at least that's not obvious even though I've been
         | mainly writing Rust for the last year or so (together with
         | Clojure).
         | 
         | I mean, go through the "book" again (https://doc.rust-
         | lang.org/book/) and tell me those samples would give you the
         | idea that Rust is a functional language. Even the first "real"
         | example have you mutating a String. Referential transparency
         | would be one of the main point of functional programming in my
         | opinion, and Rust lacks that in most places.
        
           | TheCoelacanth wrote:
           | It's not a FP language, but it's clearly heavily influenced
           | by FP.
           | 
           | Mutability is a significant part of Rust, but it's much more
           | sharply curtailed than any non-FP language I've ever seen. To
           | be allowed to mutate something, you have to prove that
           | nothing else holds a reference to it. That means that any
           | code that doesn't use mutability itself can pretend that
           | mutability doesn't exist.
        
           | __jem wrote:
           | The entire "idea" of Rust is the ability to achieve memory
           | safety by mutation XOR multiple references, which is a
           | different way to achieve the benefits of referential
           | transparency/immutable data structures without the loss of
           | performance.
           | 
           | Rust is not a "functional language" in that sense, but that
           | was not the claim made, which is that Rust is heavily
           | influenced by FP. This is most clearly seen in the trait
           | system (typeclasses) and iterator patterns.
           | 
           | Influence doesn't mean you're doing exactly the same thing.
           | If I make a rock band influenced by classical music, that
           | doesn't mean I'm doing classical music, but I'm still very
           | obviously influenced by it.
        
           | brmgb wrote:
           | Considering Rust pretty much started as a way to have a ML
           | for system programming and was written in Ocaml, yes, I think
           | it's fair to say it was heavily influenced by FP.
           | 
           | It became less and less ML-like as time went on but it still
           | as a ton of features it inherited from Ocaml and Haskell:
           | variant types, pattern matching, modules, traits come
           | directly from type classes, etc.
        
             | nequo wrote:
             | I think Rust is not particularly FP because it encourages
             | using loops instead of recursion and "let mut" is quite
             | idiomatic in my understanding. Those two characteristics
             | are more relevant than the type system. For example, Scheme
             | and Clojure don't have type classes but are clearly FP
             | because recursion and immutability are idiomatic.
             | 
             | In Rust, even though it is true that .map, .fold, .filter,
             | and .zip exist, first of all they also exist in Python, and
             | second, they need to be sandwiched between .iter and
             | .collect unless one is working with iterators which makes
             | the code noisier and pushes the needle toward loops.
             | 
             | The influence of OCaml and Haskell is clear though, and it
             | makes the language more pleasant to use.
        
         | kitd wrote:
         | Tooling is why Go gets its foot in the door much quicker than
         | other languages IMHO. A single binary with no dependencies that
         | does pretty much everything.
        
           | bombolo wrote:
           | I've seen go programs fail to start because they were
           | dynamically linked to some .so file I happened to not have.
        
             | anotherhue wrote:
             | Yeah 'Fully static' requires some extra linker flags.
        
             | layer8 wrote:
             | They mean the `go` binary, not Go programs in general.
        
           | jonahx wrote:
           | Indeed. Also formatting decided at the language level (gofmt)
           | and a standard library powerful enough to accomplish most
           | business tasks, so you can avoid 3rd party dependencies
           | entirely if you want, while still being productive.
        
         | mrkeen wrote:
         | > Functional programming won't succeed until the tooling
         | problem is fixed.
         | 
         | I think different people have different wants and needs with
         | tooling. I make (and use) binaries with Haskell. I wish more
         | mainstream languages could make binaries.
        
         | sandruso wrote:
         | The npm install experience should be baseline for newer
         | languages. Simply let me get into hacking fast. This is one of
         | the top reason I like tinkering with JS because it just works.
         | (Yes, I know all weaknesses of JS ecosystem, but getting is
         | really easy)
        
           | intrasight wrote:
           | I do agree.
           | 
           | I think .Net has got it right. And dotnet-script
           | [https://github.com/dotnet-script/dotnet-script] has been a
           | game-changer for me with a REPL-like experience for unit
           | testing and writing command-line utilities.
        
         | dist1ll wrote:
         | Not only tooling is a problem. Name one FP language that I can
         | use for high-performance and systems programming. Is there any
         | one except ATS?
         | 
         | And ATS is pretty hard (unlike C, C++ and Rust). I think it
         | will take a while until linear & dependent type languages will
         | hit mainstream. Rust already succeeded in that regard, so it's
         | a great stepping stone.
        
           | skydhash wrote:
           | Most computers follows the Von Neumann architecture. Any
           | imperative languages with no GC would do great because of the
           | small number of abstractions needed to make a program run.
           | AFAIK, C only requires to set up a stack with the registers.
           | 
           | When we build something with lambda calculus as its core, you
           | might want to revise that opinion.
        
             | docandrew wrote:
             | There's some truth to this - imperative languages with
             | state make sense because the underlying hardware is a
             | series of imperative instructions and a large amount of
             | state. What does lambda calculus hardware look like?
        
               | AndrewKemendo wrote:
               | Apparently it's called the "reduceron"
               | 
               | https://www.cs.york.ac.uk/fp/reduceron/
               | https://www.cs.york.ac.uk/fp/reduceron/jfp-reduceron.pdf
        
         | munchler wrote:
         | I think F# has a good tooling story, since it's part of .NET
         | and a first-class citizen in Visual Studio. It doesn't get as
         | much love from Microsoft as C#, but it's still quite nice to
         | use.
        
           | stiiv wrote:
           | After learning a bunch of programming languages and their
           | corresponding ecosystems (incl. Rust, Lisps, Scala), F# is
           | still my favorite by a long shot. Its only serious
           | shortcoming, imo, is the tooling.
           | 
           | Visual Studio is great, but if you're not on Windows, your
           | only practical choices are VS Code + Ionide (I was a sponsor
           | for a while; ultimately lost hope), or JetBrains Rider, which
           | is powerful, but heavy.
           | 
           | Comparing my 10+ years focused on C# with ~5 years focused on
           | F#, I was ultimately more productive in F#. But:
           | 
           | 1. Tools for refactoring and code navigation were better for
           | C# 2. Testing was more predictable with C#; I often just
           | tested from the CLI with F# (so much love for Expecto,
           | though) 3. Paket and dependency management between projects
           | caused days of pain, especially during onboarding
        
             | munchler wrote:
             | Microsoft has come a long way in supporting .NET on non-
             | Windows boxes, but I agree that it's still not as good as
             | it could be.
             | 
             | C# certainly has better tooling, but C# has possibly the
             | best tooling of any programming language on the planet, so
             | that's a high bar to meet.
        
             | karmakaze wrote:
             | I used Visual Studio on macOS for some small F# projects
             | and it worked fine. The only trouble I had was with some
             | setup instructions being spotty because there was a shift
             | in how things were done in recent versions at the time a
             | few years back.
        
           | christophilus wrote:
           | Last time I used F# on Linux, the REPL was a mess and mostly
           | unusable. Compilation takes forever. You have to edit an
           | fsproj rather than inferring modules from the file system
           | structure like most modern languages.
           | 
           | It's a great language-- maybe my favorite, but the tooling
           | stinks if you're not using VS. I'm not switching to Windows,
           | so that leaves me in limbo.
        
             | runevault wrote:
             | I'd argue Rider from Jetbrains is better than VS for F#,
             | though that is a subscription based IDE (though you can
             | stop paying and keep the version you originally "bought"
             | after)
        
             | int_19h wrote:
             | The part about fsproj is due to module order being
             | significant, which I don't think they can change without
             | breaking existing code.
        
             | karmakaze wrote:
             | PSA: Visual Studio for Mac[0]. I know you're on Linux but
             | for others.
             | 
             | [0] https://visualstudio.microsoft.com/vs/mac
        
               | sk0g wrote:
               | And just for clarity, it's not proper Visual Studio, but
               | rather an updated MonoDevelop. Was missing quite a lot of
               | functionality (for Unity/C#) compared to VS, so I used
               | Rider instead.
        
         | Shorel wrote:
         | As someone who likes both mathematics and programming, I find
         | this comment and the article too divisive for divisiveness'
         | sake.
         | 
         | Programming is applied mathematics. An assignment is not
         | 'sloppy' like the article posts, it is just another kind of
         | operation that can be done.
         | 
         | A proof is very much like programming, except you are also the
         | parser, the compiler, and the (comparatively slow) computer.
         | Learning to write proofs helps immensely with learning how to
         | program.
         | 
         | We should strive to make our proofs and programs easier to
         | understand, no matter the paradigm.
        
         | [deleted]
        
         | agentultra wrote:
         | I think tsoding has the wrong idea here. Most mathematicians
         | are not working on GHC or Haskell standards or even using
         | Haskell. Most are still doing mathematics on pen and paper.
         | Many use packages like Sage or Wolfram alpha. Few are using
         | interactive theorem provers like Lean.
         | 
         | Haskell is a poor language to be doing mathematics in.
         | 
         | I'd say the majority of people working GHC are software
         | developers and CS researchers. They're a friendly bunch.
         | 
         | What's holding back tooling is that the developers of the de-
         | facto compiler for Haskell are spread out amongst several
         | organizations and there isn't tens of millions of dollars
         | funding their efforts. It's mostly run by volunteers. And not
         | the volume of "volunteers" you get on GCC or the like either.
         | 
         | That makes GHC and Haskell quite impressive in my books.
         | 
         | There are other factors of course but the tooling is improving
         | bit by bit.
         | 
         | The whole "Haskell is for research" meme needs to go into the
         | dustbin.
        
           | yu3zhou4 wrote:
           | A URL's domain on your profile seem to be expired and hosts
           | some random stuff
        
           | exyi wrote:
           | I think he counts academic computer scientists more as
           | mathematicians than developers.
        
             | agentultra wrote:
             | C++ and Java wouldn't be where they are without CS
             | researchers, so I think the point still stands. These
             | people aren't doing _useless_ work. They 're the ones
             | making sure Concepts won't break the entire ecosystem and
             | that have made the JVM the beast it is.
             | 
             | Grit and determination will get you far but like it or not
             | there is a ton of work that requires knowledge of
             | mathematics and theory that you can't avoid if you want to
             | make good things.
             | 
             | What's kind of neat about Haskell is how closely
             | researchers can work with users and collaborate on
             | solutions.
             | 
             | Remember, the GHC team is pretty small. Their IRC channel
             | isn't huge. Releases still get made fairly regularly and
             | GHC is running one of the most advanced industrial strength
             | programming languages out there with a large ecosystem.
        
               | zamalek wrote:
               | > C++ and Java wouldn't be where they are without CS
               | researchers, so I think the point still stands
               | 
               | I'm not sure how you gleamed that they aren't
               | important/haven't made important contributions/aren't
               | doing useful work from that comment. Tsoding specifically
               | said that they don't make good tooling, _but make great
               | languages._ It 's not memeing about "Haskell for
               | research," it's talking about things it needs to improve
               | (potentially to break free of that meme).
               | 
               | For what it's worth, C++ tooling also sucks. We've just
               | layered tons of kludges on top of it that make the
               | ecosystem somewhat bearable. It's not ideal, contributing
               | to a project for the first time usually requires some
               | troubleshooting to get a working build.
        
               | agentultra wrote:
               | > Tsoding specifically said that they don't make good
               | tooling
               | 
               | And I disagree.
               | 
               | Mathematicians aren't building Haskell.
               | 
               | CS Researchers aren't noodling around either. I know a
               | few of the people working on GHC who are researchers and
               | are doing the hard work of improving error messages and
               | reporting because they care deeply about tooling. They
               | are also users after all!
               | 
               | > For what it's worth, C++ tooling also sucks.
               | 
               | Yeah, so does Haskell's. I think it's just an unfortunate
               | fact of life that nothing's going to be perfect.
               | 
               | My point is that the reason for Haskell's situation is
               | less to do with researchers and more to do with funding
               | and organization.
               | 
               | To that effect, the Haskell Foundation is relatively new
               | and gaining steam. It might change. But it's nowhere near
               | the funding levels that get poured into TypeScript and C#
               | or even Java, gcc, etc.
               | 
               |  _Update_ : Put it this way, the set of people building
               | Python packaging is probably mostly developers and very
               | few, if any, researchers. The tooling isn't great either.
               | I don't think researchers make bad tooling and
               | programmers make good tooling. I think programmers make
               | stinking bad tooling all the darn time. Programming is
               | hard. Tooling is hard. And programmers are a fickle bunch
               | that are really hard to please.
        
           | jasonwatkinspdx wrote:
           | He's talking about Programming Language Theory, which
           | includes various type theories and such. It's where math and
           | logic meet programming languages. In other words, the math of
           | analyzing programing languages, not using programing
           | languages to implement applied math.
        
         | initplus wrote:
         | Honestly Haskell's tooling is really surprisingly good these
         | days. It works fine cross platform, there is a single "blessed"
         | path without too many options to spend time agonizing over.
         | 
         | Today the Haskell example is just `cabal install --only-
         | dependencies && cabal build`.
        
         | zelphirkalt wrote:
         | You gave up using a programming language after a day? And
         | Haskell after installing/building some dependencies for 20mins?
         | Tbh, this sounds like you were not really trying. What kind of
         | experience with a programming language do you expect to have
         | after a mere day? Learning takes time. Anyone might spew some
         | not idiomatic code within a day, but really becoming proficient
         | usually takes longer.
         | 
         | Do you have any references for the "Rust is heavily influenced
         | by FP" thing? To me it does not feel that much FP. I have (for
         | now) given up writing FP like code in Rust. ML-influence --
         | Yeah maybe, if I squint a bit.
        
           | DonaldPShimoda wrote:
           | > Do you have any references for the "Rust is heavily
           | influenced by FP" thing? To me it does not feel that much FP.
           | 
           | The original implementation of Rust was in an ML dialect (I
           | think OCaml?), so from that we know immediately that the
           | original authors were familiar with FP and used it for their
           | own purposes. It seems odd, then, to assume that there would
           | be no influence of their own language.
           | 
           | But if we look at the actual feature set, we find a lot of
           | things that previously belonged almost entirely to the realm
           | of FP. The type system as a whole has a fairly FP feel, plus
           | algebraic data types, exhaustive structural pattern matching,
           | maps and folds, anonymous functions, the use of the unit
           | value for side-effecting work, the functioning of the
           | semicolon operator (which is identical to the OCaml usage)...
           | there's quite a lot, and those were just the examples off the
           | top of my head!
        
             | steveklabnik wrote:
             | (It was OCaml, yes)
        
             | momentoftop wrote:
             | Yep, though it's got type-classes specifically from
             | Haskell.
        
           | orf wrote:
           | > What kind of experience with a programming language do you
           | expect to have after a mere day? Learning takes time.
           | 
           | It does, which is why you need tooling to get out of the way
           | and let you actually learn. Working out obscure tooling
           | commands to build a hello world app then having to grok the
           | error messages absolutely destroys the learning loop.
           | 
           | For rust it took me approximately 3 minutes from scratch to
           | install, bootstrap a project and run the hello world CLI. The
           | rest of the day was spent purely, 100% learning _rust_. Not
           | Cargo.
           | 
           | 20 minutes to install some beginner level dependencies,
           | presumably with little feedback as to what is going in? Dead.
        
             | hither_shores wrote:
             | You shouldn't need to install any dependencies beyond
             | `base` for hello world in Haskell:
             | 
             | ```
             | 
             | module Main where
             | 
             | main :: IO ()
             | 
             | main = putStrLn "Hello, world!"
             | 
             | ```
             | 
             | If you mean installing Dhall's dependencies
             | (https://github.com/dhall-lang/dhall-
             | haskell/blob/master/dhal...), those aren't _too_ crazy, but
             | they 're definitely not all "beginner level". Template
             | Haskell in particular is quite heavyweight.
        
             | wuschel wrote:
             | As I see it, this is a completely legit beginner level
             | perspective. When I first touched a programming language
             | (C, Borland compiler) I was able to run a first program
             | within minutes. I completely understand the frustration
             | with development environments that frustrate an aspiring
             | user unnecessarily - I had this experience with F#, VSCode
             | an Ionide, which is a very ugly case. Haskell was not that
             | bad, but it it certainly is not for the faint of heart.
        
           | BobbyJo wrote:
           | > You gave up using a programming language after a day? And
           | Haskell after installing/building some dependencies for
           | 20mins...
           | 
           | I'd do the same. It's 2022. There are so many options without
           | this friction, why would you fight your way through it?
           | 
           | If either language had some magic power or library, that'd be
           | one thing, but their only selling point is the FP paradigm,
           | which is only _arguably_ _somewhat_ better than what other
           | languages do. Not only that, but most other languages let you
           | do FP to varying degrees anyway.
        
             | zelphirkalt wrote:
             | Haskell's promise is not only FP. That's part of it though,
             | of course, to have an ecosystem, which encourages to
             | continue in an FP style. Haskell's promise is also strong
             | type safety and, as a distinguisher to many langauges,
             | lazyness by default. Aside from that, its implementation is
             | quite performant, if one needs to worry about such things.
             | 
             | I will take a 20min build process for dependencies
             | (probably a few commands, which hopefully are documented in
             | the project's readme and probably only once for most of the
             | lifetime of a project on your personal machine) over a
             | language, that is quickly up and running, but breaks any
             | number of basic principles (for example looking at JS) and
             | lets me shoot myself in the foot. Some languages and the
             | lessons we take from learning them are worth some initial
             | effort. Of course it is not great, that things are not as
             | easy, as they maybe could be, but if the language has other
             | perks making up for that, it might still be worthwhile.
        
               | BobbyJo wrote:
               | > but if the language has other perks making up for that,
               | it might still be worthwhile.
               | 
               | Totally agree, I just think for the vast majority of
               | developers, the trade off here isn't worthwhile. This is
               | reflected in Haskell's stagnant growth despite it's model
               | being better for a lot of things.
        
             | bee_rider wrote:
             | Sure -- people have the right not to try things, which is
             | basically what messing around with a programming language
             | in a new language paradigm for 1 day is. That's fine,
             | although it should also be expected that their opinions on
             | things they haven't tried won't be given much weight.
        
               | BobbyJo wrote:
               | Day one experience matters a lot to most people. For
               | better or worse, your community won't grow if newcomers
               | have to spend a day hating things first.
               | 
               | It won't matter if you're looking for a language to make
               | your baby for the next 5+ years, but most people are
               | trying to solve small problems on an incremental basis.
        
           | yamtaddle wrote:
           | IME learning the (usually shitty) tools and the
           | culture/ecosystem eat up _way_ more time when starting with a
           | new language than learning the language itself does.
           | 
           | I can absolutely understand abandoning such an effort if
           | one's earliest interactions with the tools and/or ecosystem
           | are very unpleasant.
        
           | jackosdev wrote:
           | Immutability, most things are expressions, no nulls. I think
           | this is what they mean, it's a good experience if you want to
           | go purely functional, they took influences from everything
           | though.
        
           | mewmew07 wrote:
           | other things require my attention and there are so many hours
           | in a day
           | 
           | either get those initial minutes right or lose me
        
           | zamalek wrote:
           | My job/hobby is to produce code. It is not fighting a
           | toolchain. It does not bode well for long-term efficient use
           | of my [limited] time if I'm spending a whole day fighting
           | toolchains from the outset.
           | 
           | User experience matters, and developers are ultimately users.
        
         | hamandcheese wrote:
         | There are plenty of non-academic languages with tooling issues
         | as well. I think the larger issue is simply if the language has
         | significant usage in a large corporation who can sponsor
         | tooling development, or not.
         | 
         | Most tooling issues are pretty minor for small apps, it's once
         | one employs scores of developers that the lack of tooling
         | begins to hurt (and by hurt, I mean cost money).
        
         | thejosh wrote:
         | I'm really happy with Meson, as a lot of Wayland (the new
         | display protocol for Linux, the "successor" of X11) apps seem
         | to be built in C, so using meson is super simple and I don't
         | have to worry about tooling (I don't deal much with C/C++, so
         | let me make my change and run away please).
         | 
         | Rust is the same, you can even define a nightly version if you
         | want, so even the correct version is ran with rustup. It's
         | fantastic, and I can contribute much easier to projects without
         | worrying about tooling.
        
           | languageserver wrote:
           | > I don't deal much with C/C++
           | 
           | that is because there is no such thing.
        
             | bee_rider wrote:
             | C/C++ is just 1 in the limit, right?
        
               | xdavidliu wrote:
               | two things wrong with your statement:
               | 
               | - the ++ operator only acts on integer types, not floats
               | or doubles, so there is no limit to speak of here
               | 
               | - the expression "C++" has value equal to C _before_
               | incrementing, hence the expression  "C/C++" is just one
               | for positive C, even when C is small
        
               | bee_rider wrote:
               | So, luckily my mistakes cancel out -- C/C++ = 1 always,
               | so it must also in the limit. Once we figure out how to
               | define limit.
        
             | xdavidliu wrote:
             | the slash symbol is often used to denote multiple entities.
             | For example, "I don't deal with foo / bar" usually means
             | that the commenter doesn't deal with either foo or bar. The
             | commenter is not claiming that foo and bar together
             | constitute a single entity.
        
         | yodsanklai wrote:
         | > I seriously couldn't figure out the idiomatic Ocaml
         | workflow/developer inner loop after more than a day of
         | struggling.
         | 
         | I tend to agree but, compiling C++ isn't just about typing
         | "make". And it did take me more than one day to figure out
         | python/js workflow.
        
         | pera wrote:
         | That's interesting, I often find the tooling one of the best
         | things that FP languages offer. In OCaml for instance I found
         | Dune to be fantastic and extremely intuitive. Another very good
         | experience I had was with Elixir and Hex. In Haskell I
         | personally think that there are indeed quite a few things that
         | could be improved around build system and packaging, but
         | overall it's not really that bad once you learn the quirks.
        
           | zamalek wrote:
           | It would the OCaml community a great service if you wrote up
           | a beginner's tutorial on working with Dune.
        
       | AtNightWeCode wrote:
       | To have a program crash on null is a feature. There was a trend
       | in OO caused by you know who that made people always initiate
       | variables and return stupid things like empty lists instead of
       | null. Among the worst APIs to work with are the ones where you
       | never can tell when you get an empty list if something went south
       | or if it is a correct state.
        
       | rcarr wrote:
       | Functional programming people are the vegans of coding, change my
       | mind
        
       | revskill wrote:
       | Yes, in my production code, the real work is implemented by
       | functions. Class method is just a proxy to the external world
       | only.
        
       | UltraViolence wrote:
       | Can I state for the record that almost every C compiler still
       | supports GOTO?
       | 
       | Rust supports the best traits of both Functional and Imperative
       | languages.
       | 
       | Ergo: The future is Rust. Rust is the future.
        
       | aryehof wrote:
       | I'm reminded of the following quote by the co-author of SICP -
       | Gerry Sussman...
       | 
       | "Remember a real engineer doesn't want just a religion about how
       | to solve a problem, like object-oriented or functional or
       | imperative or logic programming. This piece of the problem wants
       | to be a functional program, this piece of the program wants to be
       | imperative, this piece wants to be object-oriented, and guess
       | what, this piece wants to be logic feed based and they all want
       | to work together usefully. And not because of the way the problem
       | is structured, whatever it is. I don't want to think that there's
       | any correct answer to any of those questions. It would be awful
       | bad writing a device driver in a functional language. It would be
       | awfully bad writing anything like a symbolic manipulator in a
       | thing with complicated syntax."
        
         | NaturalPhallacy wrote:
         | Basically the antithesis of the "silver bullet". That is, there
         | is no silver bullet.
        
           | moffkalast wrote:
           | A silver bullet may be able to elegantly kill the werewolf,
           | but throw enough depleted uranium his way and the problem
           | should go away soon enough.
           | 
           | I suppose that's an analogy for object oriented design or
           | something.
        
         | OkayPhysicist wrote:
         | The problem is sometimes you lose a lot of functionality when
         | you allow for that flexibility. For example, let's say you want
         | your functional language to allow for side effects. Immediately
         | you've lost locality: the explicit arguments of a function no
         | longer guarantee their results. Or maybe you want to allow
         | mutability: there goes thread safety. The fewer hard restraints
         | a language can impose, the less lifting the language can do on
         | your behalf. Give up on Lisp's S-expressions, and the macro
         | system becomes vastly more complicated.
         | 
         | Likewise, a language has a limited amount of space for syntax
         | before you end up a mess. So languages adopt a paradigm, and
         | optimize the language for that paradigm. Functional-style Java
         | is bloated to hell, because Java is built for Object Oriented
         | programming.
         | 
         | Frankly, I'm of the opposite mind of the quote: the middle
         | ground is often worse than either extreme. I'll happily write
         | Object Oriented C#, or Functional Haskell, over a tepid mess of
         | C++.
        
         | Rochus wrote:
         | A refreshingly pragmatic position for an academic. Where did
         | you get that quote?
        
           | DonaldPShimoda wrote:
           | > A refreshingly pragmatic position for an academic.
           | 
           | There are plenty of pragmatic academics. It just happens that
           | academia is about the only place that the non-pragmatic
           | people can find long-term career success, but that doesn't
           | mean there aren't many pragmatic people in the same space.
        
             | Rochus wrote:
             | > There are plenty of pragmatic academics
             | 
             | Sure, just as there are dogmatists in the industry, as the
             | article shows.
        
           | sk0g wrote:
           | From a quick google, likely from a talk on Youtube. Matching
           | section timestamped - https://youtu.be/O3tVctB_VSU?t=2346
        
             | Rochus wrote:
             | Thanks. Very impressive to hear this from the Scheme pope
             | himself. This should make all dogmatists think.
        
             | swyx wrote:
             | isn't it amazing in this day and age we can just google a 7
             | year old quote and basically pull up the actual video of it
             | instantly and send it around timestamped?
             | 
             | some days technology sucks, but other days its a wonder it
             | works as well as it does
        
       | jll29 wrote:
       | > The first purely functional language to become popular, called
       | Haskell, was created in 1990.
       | 
       | Nope: LISP - 1958.
       | 
       | Stopped reading there.
        
         | shepherdjerred wrote:
         | LISP is not purely functional
        
       | agentultra wrote:
       | Maybe it ought to be but it definitely isn't if you look at
       | success as industry adoption.
       | 
       | The author seems to have good intentions and covers all the
       | talking points a new convert will discover on their own.
       | 
       | However I'm afraid an article like this will do more harm than
       | good in the end. There are too many network effects in play that
       | go against a new paradigm supplanting the mainstream as it is.
       | And the benefits of functional programming pointed out in this
       | article haven't been convincing over the last... many decades.
       | Without large, industry success stories to back it up I'm afraid
       | any amount of evangelism, however good the intention of the
       | author, is going to fall before skeptical minds.
       | 
       | It doesn't help that of the few empirical studies done none have
       | shown any impressive results that hold up these claims. Granted
       | those studies are few and far between and inconclusive at best
       | but that won't stop skeptics from using them as ammunition.
       | 
       | For me the real power of functional programming is that I can use
       | mathematical reasoning on my programs and get results. It's just
       | the way my brain works. I don't think it's superior or better
       | than procedural, imperative programming. And heck there are some
       | problem domains where I can't get away from thinking in a non-
       | functional programming way.
       | 
       | I think the leap to structured programming was an event that is
       | probably only going to happen once in our industry. Aside from
       | advances in multi-core programming, which we've barely seen in
       | the last couple of decades, I wouldn't hold out for functional
       | programming to be the future of the mainstream. What does seem to
       | be happening is that developments in pure functional programming
       | are making their way to the entrenched, imperative, procedural
       | programming languages of the world.
       | 
       | A good talk, _Why Isn 't Functional Programming the Norm?_
       | 
       | https://www.youtube.com/watch?v=QyJZzq0v7Z4
        
       | agomez314 wrote:
       | It's not just about FP, it's about creating a language that will
       | allow you to think more clearly about the problem. If we cannot
       | graduate our primitives to the level of abstraction that's
       | required for the problem then codebases will be fragile, projects
       | will run over-budget and complexity will forever increase.
        
       | unnouinceput wrote:
       | Me to Charles Scalfani (article's author): "Who's an edgy boy?
       | Who's an edgy boy! Oh, you're such an edgy boy today. Good boy!"
       | /s
        
       | znafelrif wrote:
       | The properties mentioned in the article are not really tied to
       | functional programming.
       | 
       | - Not allowing null-references can be done with any paradigm. For
       | example with object-oriented programming there really is no
       | reason why it wouldn't work to not allow null references.
       | 
       | - Immutability can also be done with every paradigm. The Java
       | String for example is both object-oriented and immutable.
       | 
       | I think the paradigm is actually irrelevant. The real advantage
       | is not gained by using a functional programming language. It is
       | gained by using a language that prevents null-references and
       | makes it easy to write and use immutable data structures.
        
         | ParetoOptimal wrote:
         | Tis doesn't give you 1) ease of use and 2) composability.
        
       | victorvosk wrote:
       | Love the dubious github repo chart.
        
       | azangru wrote:
       | Oh! From Hacker News trends, I thought the future of programming
       | was going to be Rust...
        
         | gpderetta wrote:
         | wrong week.
        
       | aappleby wrote:
       | Naah. ;)
        
       | munchler wrote:
       | Good article, but the chart of FP languages is way off. There are
       | only 8,752 public Haskell repositories in GitHub (not 126,990, as
       | claimed). Numerous other popular FP languages aren't even listed
       | (e.g. Scala: 13,224, F#: 1,960).
        
       | kstenerud wrote:
       | I immediately distrust any article that makes sweeping claims
       | about one-paradigm-to-rule-them-all.
       | 
       | The reason why multiple paradigms exist is because here in the
       | real world, the competing issues and constraints are never equal,
       | and never the same.
       | 
       | A big part of engineering is navigating all of the offerings,
       | examining their trade-offs, and figuring out which ones fit best
       | to the system being built in terms of constraints, requirements,
       | interfaces, maintenance, expansion, manpower, etc. You won't get
       | a very optimal solution by sticking to one paradigm at the
       | expense of others.
       | 
       | One of the big reasons why FP languages have so little
       | penetration is because the advocacy usually feels like someone
       | trying to talk you into a religion. (The other major impediment
       | is gatekeeping)
        
         | packetlost wrote:
         | > One of the big reasons why FP languages have so little
         | penetration is because the advocacy usually feels like someone
         | trying to talk you into a religion.
         | 
         | Eh, I doubt it. I've encountered a few Haskell snobs in my
         | time, but most people that I know who use FP do so completely
         | silently and will discuss the merits and (and challenges) with
         | you freely. I think the _real_ issues with FP are lack of good
         | tooling, package management, and being a major shift in
         | thinking for most developers. It 's a common theme for someone
         | to say that learning FP (seriously) was the most impactful
         | thing they've done to improve their software chops.
         | 
         | > The other major impediment is gatekeeping
         | 
         | ??? what? I guess you could argue that pure vs non-pure
         | functions are gatekeeping, but there are absolutely legitimate
         | benefits to pure functions that basically everyone can agree
         | on.
        
           | AnimalMuppet wrote:
           | "A monad is just a monoid in the category of endofunctors".
           | Anyone who says that - or anything anywhere close to it - is
           | gatekeeping, no matter how true the statement is.
           | 
           | And it's not just the statement. It seems to me (from my
           | outside perspective) that category theory is often used in a
           | gatekeeping way.
           | 
           | In contrast, take SQL. How much of the mathematical theory of
           | relations do you need to know to be able to write SQL
           | queries? Yes, it might help, but the SQL gurus don't try to
           | drag you into it every time you get close to a database.
        
             | packetlost wrote:
             | SQL is intrinsically tied to set theory and borrows a ton
             | of terminology and logic from set theory. Whether you
             | understand that it's from mathematics or not doesn't really
             | matter. _You are using set theory and it 's terminology
             | regardless._
             | 
             | I've only really ever seen monoids referred to in Haskell.
             | If you actually read my comment, Haskell is not all FP (no
             | PL is). It's not even a significant portion of FP. So just
             | _don 't use Haskell_, it's hardly the first FP language I
             | would reach for and it's probably not the one you should
             | either.
             | 
             | Also, any person willing to learn would be _intrigued_ by
             | the terminology, not reject it as something that 's
             | "gatekeeping". Such a defeatist attitude will not get you
             | very far in a field as complex as this.
        
               | tsimionescu wrote:
               | SQL was explicitly designed to appeal to business people,
               | and uses strictly familiar words and phrases. It was very
               | explicitly designed (though I would say it has mostly
               | failed) to read like pseudo-natural language.
               | 
               | SQL DBs and the precise semantics of SQL are somewhat
               | based on relational algebra, but SQL syntax is definitely
               | not. It's also not using set theoretic terms in general,
               | with the exception of UNION and INTERSECT.
        
             | DonaldPShimoda wrote:
             | > "A monad is just a monoid in the category of
             | endofunctors". Anyone who says that - or anything anywhere
             | close to it - is gatekeeping, no matter how true the
             | statement is.
             | 
             | The original attribution of this line about monads comes
             | from the (intentionally) comedic article "A Brief,
             | Incomplete, and Mostly Wrong History of Programming
             | Languages", published by James Iry in 2009: http://james-
             | iry.blogspot.com/2009/05/brief-incomplete-and-m...
             | 
             | It is not a stance I have ever seen taken up in a serious
             | manner by anybody in the FP community, and I work in PL
             | academia (the region of the community from which I would
             | expect to see the most snobbery). Please stop
             | misrepresenting people based on a misunderstood joke.
             | 
             | There _are_ people in the FP community who gatekeep and
             | take on a snobbish tone -- with that I do not disagree.
             | However, their prevalence is generally overstated; it 's a
             | vocal minority situation. Most people I know or have talked
             | to are very welcoming.
        
               | momentoftop wrote:
               | That article went round the Edinburgh mailing list when
               | it was published, and Phil Wadler, who got monads into
               | Haskell, replied saying something like "I didn't know
               | this. Does anyone have the proof?"
               | 
               | The actual quote that monads are monoids in the category
               | of endofunctors comes from MacLane, and is intended for
               | mathematicians.
        
             | lliamander wrote:
             | > "A monad is just a monoid in the category of
             | endofunctors". Anyone who says that - or anything anywhere
             | close to it - is gatekeeping, no matter how true the
             | statement is.
             | 
             | Quite frankly, if you don't understand that sentence then
             | you are in no position to judge whether the concepts could
             | be made more accessible. Sometimes the important question
             | is not "could this be easier to learn?" but "is learning it
             | worth the effort?".
        
             | the_af wrote:
             | Nobody claims you have to understand category theory to
             | write Haskell. In fact, most will tell you it's not needed.
             | 
             | The saying "a monad is just a monoid..." is a cliche and an
             | in-joke, not gatekeeping. It's the community having a laugh
             | at itself.
        
               | AnimalMuppet wrote:
               | But why is it funny? Isn't it funny because the community
               | knows it comes off that way, at least some of the time
               | (and/or some of the people)?
               | 
               | > Nobody claims you have to understand category theory to
               | write Haskell.
               | 
               | I've seem the claim that you can't _really_ use Haskell
               | without it, here on HN, more than once. (Or at least
               | something that I interpreted as being that claim...)
        
               | the_af wrote:
               | It's funny because the community knows some people too
               | deep in the rabbit hole come across that way, but because
               | the community acknowledges this is a hilarious assertion
               | that would alienate newcomers -- if said with a straight
               | face -- then it cannot be gatekeeping.
               | 
               | Gatekeeping would be if the community said this with a
               | straight face and everyone got impatient when you just
               | "don't get it".
               | 
               | > _I 've seem the claim that you can't really use Haskell
               | without [knowing category theory], here on HN, more than
               | once_
               | 
               | I've almost never come across this assertion; it's
               | certainly not common in the community (or wasn't when I
               | was learning Haskell). I can tell you it's certainly
               | false: you can very well write Haskell without knowing or
               | studying category theory.
        
               | tsimionescu wrote:
               | Well, try understanding the Haskell docs around
               | Applicative, Functor or Monad without understanding at
               | least basic category theory - not to mention the heavy
               | use of notation/operators in place of traditional
               | programming idioms (named functions).
               | 
               | Here [0] is an example:
               | 
               | > This module describes a structure intermediate between
               | a functor and a monad (technically, a strong lax monoidal
               | functor). Compared with monads, this interface lacks the
               | full power of the binding operation >>= [...]
               | 
               | [0] https://hackage.haskell.org/package/base-4.17.0.0/doc
               | s/Contr...
        
               | the_af wrote:
               | Counterpoint: I learned about Applicative, Functor and
               | Monad by reading docs and tutorials, and I haven't the
               | faintest idea about category theory.
               | 
               | These are the building blocks of Haskell. You learn them
               | as you go, just as you learn what a "method" is when
               | learning OOP. You don't need to know category theory.
        
               | tsimionescu wrote:
               | Learning what Applicative, Functor and Monad are _is_
               | category theory. It 's like saying "you can learn how to
               | do unions, intersections, and differences on collections
               | of unique objects without understanding set theory".
        
               | cole-k wrote:
               | That seems a little silly to me and I think we're
               | splitting hairs with what it means to do category/set
               | theory. I don't know category or set theory, so I hope
               | you will forgive me for using yet another allegory.
               | 
               | Let's say I make a type class for Groups (in the abstract
               | algebra sense). The rationale behind this is that there's
               | an algorithm for exponentiation which is O(log(n)) versus
               | the naive O(n) algorithm. So if you make an instance
               | that's a Group, you get to use this fast exponentiation.
               | 
               | Sure, to understand and use this type class you have to
               | understand what a Group is. However, I think it's a bit
               | of a stretch to tell someone "in order to use Group you
               | must first learn abstract algebra" because they'll think
               | you're telling them to take a university level course. In
               | actuality, they don't have to know much at all (they
               | don't even need to understand _why_ the exponentiation
               | algorithm works) - they just need to know what is a
               | lawful Group.
               | 
               | The first day of the intro to abstract algebra course I
               | took introduced much more information than you'd need to
               | use this made up type class, and I expect the same of the
               | others.
               | 
               | Like this is my understanding of
               | Functors/Applicatives/Monads. I kind of know their shape
               | and how to use them. If you asked me about any of the
               | underlying math I would shrug and maybe draw a pig
               | (https://bartoszmilewski.com/2014/10/28/category-theory-
               | for-p...).
        
               | jimbob45 wrote:
               | I've had someone do that on this very website. I was
               | assured that affine types in Rust are too difficult to
               | understand without a solid grounding in Category Theory.
               | 
               | The years have proven that ease of programming and the
               | burden of knowledge are the two most important elements
               | of a programming language. FP zealots simply won't accept
               | that their chosen paradigm is opaque to most for benefits
               | that can't seem to be written out in human language.
        
               | the_af wrote:
               | > _I 've had someone do that on this very website_
               | 
               | On this website you will hear anyone say the wildest
               | assertions. There's the whole human range of expression
               | here. But what makes you think actual FP practitioners
               | (and Haskelers) really believe this?
               | 
               | The proof wouldn't be what some random person here on HN
               | tells you. The proof would be you getting involved in an
               | actual FP community trying to write an actual FP project
               | and being told that you just cannot do this unless you
               | understand category theory. Which, as I said, is not
               | something that happens... at least not in my (limited)
               | experience.
               | 
               | Never confuse what people tell you here on HN, random
               | forums or even throwaway StackOverflow comments with what
               | actually happens in the actual communities when trying to
               | achieve real goals and not just chat about stuff.
        
             | marcosdumay wrote:
             | Nobody says that seriously.
             | 
             | It tells a lot how people go for common jokes to complain
             | about a community. It's easy to fall for that if you never
             | actually interacted with the people.
        
             | wiseowise wrote:
             | > "A monad is just a monoid in the category of
             | endofunctors". Anyone who says that - or anything anywhere
             | close to it - is gatekeeping, no matter how true the
             | statement is.
             | 
             | You just tried to badmouth whole community of FP
             | programmers by taking serious a running gag, wow.
        
         | darksaints wrote:
         | Thank you. I learned functional programming first, and I do
         | think there is a lot of merit to it in a large proportion of
         | software development tasks. But there are far too many people
         | trying to fit square pegs in round holes with it. Pure
         | functional applications which manage large amounts of complex
         | and messy state are a nightmare to work with. There is a reason
         | why game developers and simulation developers have almost
         | defaulted to object oriented programming. There is a reason why
         | cryptography developers have defaulted to procedural
         | programming. There really should be a No Free Lunch theorem for
         | programming methodologies.
        
           | hajile wrote:
           | I believe game developers aren't against functional
           | programming (John Carmack has great things to say about
           | Haskell for example).
           | 
           | Pure functions excel at state management and reducing bugs.
           | If there were a reason to make games with a functional
           | language, this is the reason.
           | 
           | The big issues seem to be deterministic performance and
           | resource usage. Garbage collection, lazy evaluation, etc all
           | result in bubbles of weird performance. That doesn't matter
           | for the overwhelming majority of programs where the human
           | limits in responsiveness is hundreds of milliseconds, but
           | does matter it must scale into single digit milliseconds.
           | 
           | There are functional languages that have this capability, but
           | outside of the partially functional Rust, they are basically
           | unknown.
        
         | grumpyprole wrote:
         | FP has one distinct advantage over many other paradigms, it has
         | very sound and well understood theoretical foundations, being
         | essentially based on the formal mathematical logics (e.g.
         | System F and its derivatives). This has huge implications for
         | correctness and reasoning.
        
           | sli wrote:
           | I'll get made to take shortcuts to get the product out before
           | I'll be allowed to be strict on correctness if it means
           | pushing a deadline back even a single day. I love
           | correctness, but it's just not often important to people who
           | aren't me and for reasons completely outside of my control.
        
         | pessimizer wrote:
         | This is just an appeal to the law of averages. I don't believe
         | that you're actually considering ada, cobol and forth for new
         | projects.
         | 
         | > One of the big reasons why FP languages have so little
         | penetration is because the advocacy usually feels like someone
         | trying to talk you into a religion.
         | 
         | This is never really a reason for anything, it's a personal
         | attack on people who advocate the thing that you don't want to
         | do. FP people are not bullying you, or shoving anything down
         | your throat.
        
           | galangalalgol wrote:
           | People do still consider ada. I wouldn't, but I don't need
           | that tool. I feel like you are creating a strawman. The gp
           | wasn't talking about languages but about paradigms. OO was
           | overused but it has its place, and both imperative and
           | functional programming have strengths. There are some
           | languages that can do everything, or almost everything, but
           | multitools are never quite as good at being pliers as pliers
           | are. And they are pretty bad at being a hammer. There is
           | nothing quite like having exactly the right tool for the job,
           | to the point that I would rather have a poorly made version
           | of the exact right tool than a well made version of almost
           | the right tool.
        
           | [deleted]
        
           | a_wild_dandan wrote:
           | To be charitable to kstenerud, FP advocacy does often sound
           | like proselytizing. When promoting FP to folks, I think we
           | can mitigate that issue by communicating a couple points:
           | 
           | 1. There's no dichotomy between FP and OOP. Sprinkle it into
           | places where it makes sense to you. Adoption can come by
           | degrees.
           | 
           | 2. Just thinking in composable, pure functions on projects
           | buys you serious mileage. You don't have to wrangle monads
           | (or worse, victimize team members with advanced FP ideas).
           | Just KISS.
           | 
           | FP often feels to non-practitioners like a pretentious and
           | byzantine fad. We'll have better luck with widespread
           | adoption if we can be inviting and dispel those negative
           | associations. We'll seem less zealous if we can frame FP as a
           | practice to dip one's toes into, rather than a religion to be
           | submerged & baptized into.
        
             | pdimitar wrote:
             | > _Just thinking in composable, pure functions on projects
             | buys you serious mileage_
             | 
             | This is exactly where I was a called a zealot and gave up
             | because it was obvious the other person felt attacked, as
             | if I told them "you are an idiot for using procedural and
             | imperative style all your career" -- which I absolutely
             | didn't say or even imply.
             | 
             | Ultimately, selling someone on FP is selling them a new
             | mental model and I think a lot of us how hard that is.
             | People by default don't want to change the way think, it's
             | a fact of life.
        
             | skierguy wrote:
             | I think a lot of the "religious" feeling I get from FP
             | advocates is the constant focus on purity and the "No, you
             | AREN'T DOING IT RIGHT!!!" kinds of tantrums. You HAVE to
             | understand the nuance. You HAVE to participate in these
             | strange little paradigms that esoteric thinkers have come
             | up with. Ultimately, I think of FP languages like Haskell
             | as playgrounds to pilot bleeding-edge ideas before the best
             | ideas get incorporated into languages that are widely used
             | in production.
             | 
             | Ultimately, some real-world processes are just procedural,
             | and procedural languages are easier to apply to them. When
             | it comes to callbacks, mapping functions to a list, etc.,
             | it's pretty clear to me that FP paradigms are superior.
             | 
             | In other words, I think it's part fad/religion, but as with
             | anything, you can learn from it and take the good parts.
        
               | leidenfrost wrote:
               | Problem is, it's hard to distinguish the chaff from the
               | wheat. A lot of practices that advertised themselves as
               | "the way of the future" and most of them faded into
               | nothingness.
               | 
               | At some point people try to save time and stick with
               | practices that stand the test of time.
        
               | blep_ wrote:
               | Most languages _have_ already taken the good parts. We
               | barely even consider them a  "FP thing" anymore.
               | Callbacks and map() are just things you can do in most
               | languages.
               | 
               | What remains when people advocate for more FP _is_ the
               | more esoteric stuff. (And non-nullability, which
               | inexplicably gets associated with FP surprisingly often
               | despite being orthogonal to everything else in the
               | paradigm.)
        
           | sidlls wrote:
           | > FP people are not bullying you, or shoving anything down
           | your throat.
           | 
           | Have you ever worked with a FP evangelist? Every single
           | experience I've had has been with a person who simply won't
           | take "no" for an answer. The impatience, ego, and pettiness
           | is bar none, really.
           | 
           | Aside from that, there are objective reasons to be skeptical:
           | it's inefficient when it comes down to actual implementations
           | that have to work on actual computers and solve actual
           | problems ("but but tail recursion and copy optimizations
           | lolol you moron you just don't understand it"). Also, _most_
           | FP tends to become much more complex than an equivalent
           | imperative program solving the same problem, usually through
           | a terrible confluence of code density and mazes of type
           | definitions.
        
             | agentultra wrote:
             | ... there are lots of optimizations available when you have
             | immutable types and no assignment operator if you're
             | curious.
             | 
             | Pure, immutable data structures might not be the right
             | choice if you don't have the right language/tooling/runtime
             | to take advantage of the benefits but they're there.
        
             | jerf wrote:
             | I have spent the time with Haskell to learn how to not just
             | use it a bit, but program it idiomatically and with some
             | fluidity. I think there is a very interesting point you can
             | reach if you go 100% all the way in. There are some types
             | of programs that you can write, like compilers, that are
             | kinda painful and dangerous and quirky in imperative or OO
             | programming and are just beautiful in full on, no
             | compromises functional programming.
             | 
             | I am _waaaaay_ less impressed by the half-assed  "I
             | borrowed a few paradigms and bashed them into an OO or
             | multi-paradigm language but it's still fundamentally
             | imperative" approach.
             | 
             | Reconceptualizing your _entire program_ as consisting of
             | recursion schemes and operations that use those recursion
             | schemes, what I think the deep, true essence of functional
             | programming as a paradigm is, is a very interesting and has
             | a lot of interesting benefits hard to obtain any other way,
             | along with some costs you might never otherwise think about
             | if your mindset is too deeply into one particular world.
             | 
             | Rewriting a _single for loop_ with five maps, reduces, or
             | filters is nothing. It 's a parlor trick. It buys you
             | nothing of consequence. For avoiding bugs I almost never
             | have, this requires a lot of extra syntax and costs huge
             | runtime performance unless the compiler is smart enough to
             | optimize it away.
             | 
             | That doesn't mean it's bad, per se. I use maps and filters
             | as appropriate. In some languages, they're syntactically
             | convenient, and if I'm mapping or filtering with something
             | that is already a function anyhow, the performance issue is
             | moot. I'm not saying this is bad and you should never use
             | those things.
             | 
             | What I _am_ saying is that is completely uninteresting as a
             | "paradigm shift". Writing architecturally imperative
             | programs with a light sprinkling of map and filter is
             | nothing. Come back to me when your program is no longer
             | architecturally imperative, and the top level of your
             | program is now a two-line expression of a chain of mapMs
             | and <*>s that represents your entire program. _Now_ you
             | have something fundamentally different.
             | 
             | Frankly, I think those who bang on about how vital it is to
             | replace for loops with maps and filter chains have actually
             | managed to miss _the entire interesting point about FP_.
             | One could perhaps blame FP advocates for not explaining it
             | very well with some justification. But it still is what it
             | is. These people are banging on about how square a brick
             | is, and how hard it is, and how nicely you can use one to
             | bash things open, and how nicely you can polish up a brick
             | if you want, but the point of bricks is that you can put
             | them together to build walls. Sticking a couple of bricks
             | in the middle of a mud hut leaves you with a weird looking
             | mud hut.
             | 
             | The point of functional programming isn't map and filter;
             | it is taking the class of things for which those are only
             | two easy examples (and not even necessarily the most useful
             | in general), and then building your entire program out of
             | that class of things. You end up with something very
             | different if you do that.
             | 
             | The linked article also bangs on about not having null
             | references. Nothing stops you from having an imperative
             | programming language that lacks null references. It is not
             | a good or interesting example of why FP is interesting.
             | 
             | Anyways, upon re-reading, I lost a bit of focus on my
             | original point, which is that you do need to watch out for
             | which of the types of FP are being advocated. I have very
             | different reactions between the two of "consider rewriting
             | your fundamental view of the world to be composing
             | recursion schemes instead of as the stringing together of
             | imperative operations in various fancy ways" and "you
             | shouldn't use for loops". You may not love the first; it is
             | certainly a trip and not necessarily for everyone and
             | everything, but it will at the very least expand your mind.
             | The second is, well, mostly annoying to me because of the
             | vigor of its advocates far out of proportion to either its
             | programming utility or its mind expansion characteristics.
        
               | p0nce wrote:
               | Where are all the FP software products I can use? It
               | doesn't seem to dominate a lot of software niches, no?
        
               | jancsika wrote:
               | > The second is, well, mostly annoying to me because of
               | the vigor of its advocates far out of proportion to
               | either its programming utility or its mind expansion
               | characteristics.
               | 
               |  _Thanks to closures, map /reduce function callbacks in
               | Javascript are extremely handy._
               | 
               | Please link me to something like a stackoverflow answer
               | with "vigor" greater than this, I'd love to read it.
        
               | monkpit wrote:
               | If you were to write a post about taking an example
               | imperative program and showing the conversion to FP, I'd
               | be very interested to read it. Or if you have a link
               | handy to someone else's post?
               | 
               | For me it's difficult to immediately understand what you
               | mean about the top level program, mapM, etc. I guess what
               | you mean is that they entire program can be expressed as
               | 1 call with some args? I feel like there is probably more
               | nuance that I am not grasping.
               | 
               | I am curious to add this way of thinking to my toolbox,
               | and I learn best by examples.
               | 
               | I have read things like Mostly adequate guide to FP and
               | whatnot. They always get stuck on side effects and
               | containers, which is fine, but doesn't really address the
               | larger scope of program design.
        
             | yonaguska wrote:
             | As someone that's left scala and come back to dotnet
             | land... depending on the domain, functional programming
             | results in much cleaner solutions. A lot of the code messes
             | in functional paradigms that I dealt with and also created
             | were mostly due to people that didn't understand how to
             | _think_ functionally. It took a long time for me to figure
             | it out. I find myself missing features all the time now,
             | and spending a whole lot more time fixing bugs that simply
             | wouldn 't exist had people just applied more functional
             | principles in their code. I understand where you're coming
             | from with your frustrations, but I would personally
             | attribute that to the LISP culture problem that I also saw
             | with the hardcore functional programmers. Everyone would
             | just nerd snipe themselves into re-inventing the wheel.
             | 
             | Also, my dotnet contemporaries on average do not care as
             | much about code quality as people did when I was in scala
             | land. But this might just be a company culture thing.
        
               | silversmith wrote:
               | This rings true - experiencing different paradigms opens
               | you up to more elegant solutions. That's why years later
               | I now see the value of the "Programming languages" course
               | I had in university - every lecture covered a new
               | language and had homework to implement a program in it. I
               | haven't touched LISP or Prolog since, but just being
               | exposed to them made me write better code in
               | "traditional" languages.
        
               | jjav wrote:
               | Agreed. I took a year (long ago) to learn lisp just to be
               | exposed to a different way. And it has paid dividends in
               | terms of providing alternate ways of thinking about code
               | in other languages.
               | 
               | That said, I'd never want to use lisp in a real
               | production project. Same for FP. Get exposed to these
               | things, take the learnings and bring them into KISS
               | boring production code that is fast and maintainable.
        
               | bbarn wrote:
               | .net, and C# especially are absolutely fantastic tools
               | for programming. The problem is just that they are
               | embraced by large companies and that is where crappy
               | engineers tend to congregate, in my experience. The
               | bigger the company the easier it is to get lost in the
               | crowd.
               | 
               | I enjoy functional programming, but I'm a wizard with C#
               | and .net, and I can pull a much higher salary continuing
               | to focus there. I can write my own fun stuff in Haskell
               | for myself and will continue to enjoy corporate money.
        
               | BlargMcLarg wrote:
               | It's also laziness and controversy. Unit testing is
               | something aggressively pushed in many of these places,
               | but then they continue to litter side effects, long
               | flows, loads of complex objects, void methods, and more
               | which inherently make it more difficult to test. FP
               | guidelines help a lot of these cases, and you don't need
               | to understand monoids, monads or any of that to grasp the
               | concept of simple functions with clear output.
               | 
               | Meanwhile, FP is kind of a pain to connect things in, for
               | most people.
        
               | yonaguska wrote:
               | I'm trying to push unit testing, as a means to get rid of
               | some of those negatives you pointed out. But it's not a
               | panacea. And obviously, I don't want to test for the sake
               | of it either.
        
               | leidenfrost wrote:
               | Before learning FP I used to ask myself: "Assuming that
               | by tomorrow my memory gets erased and my IQ diminishes by
               | 50 points, will I understand this code?".
               | 
               | That's why I try to juggle the least amount of variables
               | as possible at the same time, while trying to have my
               | code to read like a cooking recipe or a very simple
               | literature. From that, FP feels almost natural.
               | 
               | Even more so, I think that most software bugs and
               | spaghetti code is made by people that were too confident
               | on themselves. They thought they could handle a lot of
               | random unrelated variables floating around all the time,
               | while having their functions do a lot of random
               | algorithms at the same time.
               | 
               | And yes, they could handle it. The first time. But, in
               | the long run, most people forget, or they leave and
               | another person ends up having to maintain it, and that
               | super brief-and-clever code became an unmaintainable
               | mess.
        
             | [deleted]
        
             | knaekhoved wrote:
             | How do you distinguish between people who are in a
             | religious fervor and people who have figured out that
             | something is obviously beneficial?
        
               | jjav wrote:
               | > How do you distinguish between people who are in a
               | religious fervor and people who have figured out that
               | something is obviously beneficial?
               | 
               | Seems easy to me.
               | 
               | If it's obviously benefitial, show me:
               | 
               | - Performance benchmarks showing how much faster the
               | compiled code runs
               | 
               | - Case studies demonstrating faster development and/or
               | fewer time spent debugging
               | 
               | - Studies showing consistently better maintainability
               | 
               | If it is lacking this data, it comes across as religious
               | fervor.
        
               | fsdjkflsjfsoij wrote:
               | > people who have figured out that something is obviously
               | beneficial?
               | 
               | If it's so beneficial then those people can prove it by
               | building something exceptional. I worked with Haskell and
               | Scala for almost a decade and libraries were full of bugs
               | and performance problems. A lot of bugs just hadn't been
               | reported because so few people were using them. FP
               | certainly has its strengths but so far there's very
               | little evidence that it produces better software in the
               | long term.
        
               | knaekhoved wrote:
               | > there's very little evidence that it produces better
               | software in the long term.
               | 
               | Have you used other software? 99% of it is dogshit.
               | 
               | > libraries were full of bugs and performance problems
               | 
               | This is a really wild claim to me. IDK about Scala, but
               | libraries in Haskell, Ocaml, and Elixir are all vastly
               | better than libraries in C++, Java, Python, _despite_ a
               | smaller userbase.
        
               | epgui wrote:
               | In life, there are a lot of obvious things that are very
               | difficult to teach.
               | 
               | For example, I'm a biochemist with 12 years of education,
               | and I can't seem to be able to convince anyone that
               | vaccines are safer than no vaccines.
               | 
               | Humans just don't like new things or changing their mind,
               | and that's a very generalizable fact, even among very
               | smart groups of intelligent engineers.
        
               | blep_ wrote:
               | The typical argument for vaccines is much less shaky than
               | the typical argument for pure FP. For one, vaccine people
               | can actually explain _why_ vaccines are good. FP people
               | seem to mostly just repeat variations on  "it's easier to
               | reason about" and showing trivial functions that are
               | generally not easier to reason about.
               | 
               | Imagine trying to get people to accept vaccines, but in a
               | world where we have other types of medicine that usually
               | works well enough for all the things you've developed
               | vaccines for, and the only argument you're allowed to
               | make is "it's obviously better, look at how amazingly
               | _liquid_ the stuff in this syringe is ".
               | 
               | You'll still get some resistance, but in our current
               | world, pure FP is much more of a niche thing than pro-
               | vaccine stances. There's a reason for that.
        
               | goostavos wrote:
               | >figured out that something is obviously beneficial?
               | 
               | Case in point for the problem with FP communication. When
               | you speak in smug absolutes, it comes off as religion.
               | 
               | I'm pretty big into the FP world. I love Purescript. I
               | dig Idris and exploring dependent types. I spend a lot of
               | time at work teaching "functional" thinking. And yet, I
               | still find most "hard core" FP evangelists insufferable
               | for smugly explaining things as "obviously beneficial."
               | ugh.
               | 
               | That is a lots that sucks about pure FP. It's not all
               | upsides. The FP community can do a _lot_ better at
               | "evangelizing" by talking like engineers rather than
               | sales people.
        
               | knaekhoved wrote:
               | Where did I say that FP was obviously beneficial? You're
               | reading too much into my question. I was questioning the
               | GP's epistemology.
               | 
               | > talking like engineers rather than sales people.
               | 
               | They do talk like this - go to any Haskell conference and
               | it's 90% engineering papers - much better than e.g. a JS
               | conference. It's just that most people don't even know
               | what PL engineering even _looks like_ , let alone how to
               | interpret it.
        
               | _dain_ wrote:
               | > Where did I say that FP was obviously beneficial?
               | You're reading too much into my question. I was
               | questioning the GP's epistemology.
               | 
               | cmon fuckin guy
        
           | pfraze wrote:
           | I was once at a distributed systems meetup where a member of
           | the audience interrupted the talk to give an extemporaneous
           | presentation on why we should all be using Haskell.
           | 
           | FP advocates have a reputation for being zealous and
           | pretentious. The only question is whether they're right to
           | be.
        
             | SkyMarshal wrote:
             | An anecdote of one person with bad manners shouldn't be
             | representative of the whole.
             | 
             | I'd estimate there are three kinds of FP advocates:
             | 
             | 1) People (like me) who have experienced personal pain in
             | building or maintaining complex systems in imperative or
             | other paradigms, and are genuinely astounded and relieved
             | when we learn how Haskell and other FP languages can
             | mitigate or eliminate that pain. They tend to advocate FP
             | as a solution to specific problems they've personally
             | encountered.
             | 
             | 2) PLT academics who are just generally fascinated with
             | building a mathematical programming language that can
             | elegantly express the most advanced notions in math and
             | logic.
             | 
             | 3) People who like to feel superior and rudely interrupt
             | presentations to expound on monads and endofunctors and the
             | like.
             | 
             | Try to focus on and/or associate with #1 and #2 and ignore
             | #3.
        
               | mpweiher wrote:
               | > An anecdote of one person with bad manners shouldn't be
               | representative of the whole.
               | 
               | It is so incredibly widespread, it's not just "an
               | anecdote of one person".
               | 
               | The entry-level courses at TU-Berlin where I studied had
               | just been taken over by FP disciples when I started
               | studying, and it was crazy. "Let me tell you about our
               | Lord and Saviour Functional Programming, Hallelujah".
               | 
               | And of course the reality didn't come close to matching
               | the advertising.
               | 
               | And it never does.
               | 
               | Another nice example was in a lecture by SPJ on parallel
               | Haskell, where he says "This can only be done in a
               | functional language.". Audience member: "We've been doing
               | exactly this in HPC for decades. In FORTRAN". Instead of
               | conceding or apologising for the gaffe, SPJ doubles down
               | with something along the lines of "well, then what you
               | are using _is_ an FPL ". Jeez. Oh, and when it comes to
               | the results he reveals that the overhead is so high that
               | you need 7-8 cores running full tilt to be equivalent to
               | a single core C program. Jeez.
               | 
               | In general, there is also the widespread phenomenon I
               | call "functional appropriation", where a similarity is
               | noted between some aspect of FP and some other mechanism
               | or paradigm or some such, and then the claim is made that
               | this obviously means that the other mechanism/paradigm is
               | just thinly veiled FP.
               | 
               | Newsflash: let me tell you about Turing machines. Or NAND
               | gates...
               | 
               | For example FRP, "Functional Reactive Programming". Which
               | is really just dataflow, and badly packaged dataflow at
               | that. Or the React people's claim that the core concept
               | or React is that the UI is a "pure function" of the
               | model. Well, it turns out it is not. Not a pure function
               | at all. And not really a function either. Just a mapping.
               | And _any_ UI had better be some sort of mapping of the
               | model, or it 's hard to see how it would qualify as a UI.
               | 
               | I could go on (and on, and on, and on...) but I'll stop
               | now.
        
               | leidenfrost wrote:
               | imho the whole thing about FP it's not about a
               | objectively superior way of coding, but a way of coding
               | that's better suited to the current high level, highly
               | distributed world.
               | 
               | There are A LOT of developers, a lot of custom made
               | software and a lot of web applications. And unless you
               | really need performance, most web services are an ideal
               | use case for FP practices. Even if you do it in plain
               | Javascript.
               | 
               | Some people are zealots about it, yes. But imho FP is a
               | better way to trickle down those concepts instead of
               | telling people to spend decades to become imperative code
               | masters.
        
               | SkyMarshal wrote:
               | _> current high level, highly distributed world_
               | 
               | That's one area it's well-suited for. Also in error-
               | handling and prevention, and in refactoring, and
               | configuration management. All personal pain points for me
               | previously.
        
               | mpweiher wrote:
               | > imho the whole thing about FP it's not about a
               | objectively superior way of coding,
               | 
               | OK.
               | 
               | > a way of coding that's better suited to the current
               | high level, highly distributed world.
               | 
               | But is it objectively better suited? One might even say
               | "superior"? ;-)
               | 
               | Also, I actually believe FP is actually quite ill-suited
               | to the high-level and particularly the highly distributed
               | world.
        
               | leidenfrost wrote:
               | > Try to focus on and/or associate with #1 and #2 and
               | ignore #3.
               | 
               | I disagree. We are too tolerant with the zealots.
               | 
               | They are an obstacle to the exchange of knowledge. They
               | don't want people to learn and get better at programming.
               | They want to live in their own Mr Robot personal fiction.
               | 
               | FP is a tool. A great tool, yes. But a tool in the end.
               | And we should promote it as such.
        
             | toomanydoubts wrote:
             | I understand that it looks like that, but I believe most of
             | the FP evangelists are just too excited about the cool tech
             | and want to share it with everybody so everybody else can
             | feel the joys of functional programming. At least that's
             | why I often mention and talk about FP to other devs.
        
               | jjuel wrote:
               | So like a Christian who just wants you to share the same
               | joys of Jesus Christ that they do correct?
        
               | ryanwaggoner wrote:
               | In my experience growing up as an evangelical Christian,
               | the proselytizing has very little to do with wanting
               | strangers to "share the same joys of Jesus Christ".
        
               | dmitriid wrote:
               | I used to program in Erlang. The joy of it doesn't lie in
               | FP. Not even closely.
               | 
               | It's in the runtime, effortless processes etc.
               | 
               | If all you can offer is "joy of programming in FP",
               | you're in a cult.
        
               | andsoitis wrote:
               | > so everybody else can feel the joys of functional
               | programming
               | 
               | That is the kind of knowing-better-than-thou that
               | undermines the evangelism.
        
               | [deleted]
        
             | psychoslave wrote:
             | If there is a way to do it that you feel more
             | efficient/enjoyable than an other more widespread one, just
             | show other people. If they don't look interested, changing
             | communication style next time might help. Become more
             | proselyte will almost neither pay positively.
        
           | psychoslave wrote:
           | > This is just an appeal to the law of averages. I don't
           | believe that you're actually considering ada, cobol and forth
           | for new projects.
           | 
           | First it greatly depends on what "new project" mean here.
           | There myriad of new projects within existing code base for
           | which the existing used technologies are the major factor.
           | 
           | When it's about creating a brand new product out of a blank
           | slake, sure Cobol won't be your first idea for a startup.
           | Maybe Ada might come to mind if some high level of
           | reliability is required, like in aeronautics and the like.
           | 
           | It also depends on the team skills. If you have team mates
           | which are all Haskell advanced practioners, surely imposing
           | J2EE for the next big thing might not be brightest move in
           | term of crew motivation.
        
           | moffkalast wrote:
           | > I don't believe that you're actually considering ada, cobol
           | and forth for new projects.
           | 
           | I'm not considering Erlang either.
        
         | rosenjcb wrote:
         | We use Clojure at my work and it's basically functional Java
         | with parens. No snottiness or evangelism needed. The fact that
         | I don't have to write Java OOP boilerplate is a big enough
         | advantage to me. Even if you just write it like Python or JS,
         | it's still leagues better.
        
         | thosakwe wrote:
         | Another reason is that imperative languages have a lot of
         | business inertia around them. It's expensive to rewrite
         | existing code or switch to a new language, and most businesses
         | can't justify this cost.
         | 
         | I love functional programming, but I doubt most companies that
         | sell CRUD apps care about it.
        
           | softwarebeware wrote:
           | Another reason is that imperative languages are all that's
           | necessary for many (maybe even the majority) of business use
           | cases.
           | 
           | Really a lot of it boils down to if this else that, and
           | little more.
        
             | OkayPhysicist wrote:
             | "all that's necessary" implies there's something
             | fundamental about imperative languages that's intrinsically
             | more basic. In fact, the opposite is true. If you're
             | problem statement is "in response to event X, transform Y
             | into Z, stick it in a database, then take A from the
             | database, reshape it into B, and send it back to the user"
             | then weak functional approaches are the natural solution.
             | (languages like Elixir or idiomatic JavaScript).
        
         | kstenerud wrote:
         | Addendum after watching this thread blow up:
         | 
         | What's interesting to notice about this thread is how many
         | messages are just oozing with smug superiority and disdain for
         | anyone who doesn't share their knowledge. Yes, some are from
         | genuinely humble and even-handed FP practicioners, but when we
         | look at people who are vocal about FP, this small example shows
         | around 90% of them in the gatekeeper camp. And the punchline is
         | I don't think they can even see what they've become. This is
         | what adds to the insidiousness of it all: They genuinely
         | believe themselves to be helpful and positive.
         | 
         | This is a huge cultural problem, and one that I've seen many
         | times in other communities over the years.
         | 
         | Take Linux, for example. Nowadays, it's trivial to get up and
         | running with Linux, but it wasn't always so. Back in the 90s
         | the installation was tricky, to say the least. The end user
         | tooling was iffy at best and buggy as hell, there were tons of
         | sharp edges, but most frustrating of all were the gatekeepers.
         | People can handle challenges and pitfalls, but nothing quite
         | takes the wind out of their sails like a smug asshole
         | belittling them when they ask for help or express frustration.
         | 
         | Similarly with video codecs. In the 2000s when video codecs
         | were a new thing, they had so many obscure options that almost
         | nobody knew what would produce a good result, and so the
         | gatekeepers came out of the woodwork to hold the sacred
         | knowledge prisoner. They brought us byzantine software like the
         | appropriately named Gordian Knot, and once again the forums
         | were full of smugness, arrogance, and abuse as people despaired
         | over how the hell to rip their DVDs into something viewable.
         | 
         | And it's similar in the Nix community, and countless others
         | I've observed over the years.
         | 
         | In my experience, gatekeeping goes hand-in-hand with poor
         | tooling and educational resources. The worse the UX, the more
         | gatekeepers it attracts (because gatekeeping fulfills a need
         | they have, so they flock to gatekeeping opportunities). Linux
         | used to require an understanding of init scripts and
         | environment variables and bash and crontabs and kernel
         | recompiling and all sorts of esoteric knowledge just to get
         | started. But now with mature tooling, it's easy to get started
         | and then dig deeper at your leisure via the wealth of newbie
         | friendly articles littering the internet.
        
           | rowanG077 wrote:
           | Do you have actual, recent, examples of this? I keep reading
           | the same attitude you have here, but I have never seen it
           | first hand.
        
             | BlargMcLarg wrote:
             | Git, Vim and general GUI come to mind, specifically on this
             | site. There is always _someone_ berating individuals for
             | not using shortcuts, not using the console instead of a
             | visual tool, using an IDE, etc. Specifically using Git with
             | a GUI primarily is a great way to get flak from several
             | subreddits, too.
             | 
             | NB: This is not an invitation for discussion on the pros
             | and cons, to berate either preference, or gatekeep.
        
           | weatherlight wrote:
           | I think It's funny. the blog is literally the opposite of
           | gate keeping, trying to get non FP people into FP. Even
           | provides a book, a course, doesn't throw around Math terms
           | and yet your argument is "Well, some FP practitioners are
           | smug and suck, so why bother?"
           | 
           | Elixir is a functional programing language (It's not pure
           | like Haskell or PureScript, but thats besides the point.)
           | 
           | The Elixir community is absolutely awesome! All or welcome.
           | 
           | There are soooo many resources for people to learn FP, the
           | gate keeping thing may have been true ten years ago but I
           | certainly don't think that the case today.
        
           | leidenfrost wrote:
           | On the other hand, it's really frustrating to explain this
           | kind of things to the most Juniors. Many of them were too
           | confident on their code because "they had everything in their
           | heads" and anything else was like an incoherent and
           | overcomplicated ceremony. "Why do all that when I can do a
           | simple index.js file and add a simple if and that's it?"
           | 
           | There's a catch with FP, where many of their implications
           | impose you to write better code. But it's not mandatory to go
           | the functional way to do that, and I always try to explain
           | the importance of those fundamental principles to other
           | people, and they can try to implement it in whatever style
           | they desire.
           | 
           | But when someone just doesn't want to learn, they always see
           | me with a smug and gatekeeping attitude and I can't help but
           | see them as people that just don't care at all.
        
         | inimino wrote:
         | It _is_ similar to a religion, because if everyone agrees to
         | adopt the same reality, then there 's easy communication and a
         | shared background understanding that makes it easy for everyone
         | to work together. Picking a religion is a society-wide
         | coordination problem, and strategies of shaming and in-
         | group/out-group exclusion make sense in this context, where
         | they wouldn't about flavors of ice cream, for example. We see
         | the same thing happening in tech all the time. I don't want to
         | learn a new technology, which means I don't want _you_ to learn
         | it, because I don 't want it to become something that engineers
         | are expected to know. And so on.
         | 
         | The point is to understand that "right tool for the job" and
         | "C++ for everything" are religious positions, too. There might
         | even be a dominant religious position, which likes to style
         | itself as just the disinterested rational viewpoint.
         | 
         | The FP folks might be a somewhat more fervent (crazy
         | mathematical) sect, but there's no getting away from religion,
         | though we can call it by other names (fashion, "best
         | practices", ...).
        
         | gjulianm wrote:
         | > One of the big reasons why FP languages have so little
         | penetration is because the advocacy usually feels like someone
         | trying to talk you into a religion. (The other major impediment
         | is gatekeeping)
         | 
         | I think one of the major reasons is because IO doesn't really
         | fit well into the FP paradigm. All the theory and niceties take
         | a second place when you find out that something as simple as
         | "print a line here to console" isn't as simple as you thought
         | it should be.
        
           | valenterry wrote:
           | I think the context here is pure functional programming. So
           | not just replacing e.g. loops with mapping and such things,
           | but actually making effect-handling explicit. The IO type (or
           | otherwise deferred-type) is essentially for that. Saying it
           | doesn't fit into the FP paradigm doesn't make sense. Without
           | IO, FP is useless because you simply cannot "do" anything at
           | all.
        
           | kaba0 wrote:
           | Isn't this IO thing a bit overused? There are more FP
           | languages that are not as pure as Haskell, but even if we
           | only do IO through a special monad it is not too bad at all.
           | 
           | And I say that as someone who is very much fore "practical
           | FP" -- I do think that local mutability is sometimes simply
           | the better fit for a problem.
        
             | gjulianm wrote:
             | > there are more FP languages that are not as pure as
             | Haskell
             | 
             | I mean, that's precisely the point I'm making, that IO
             | doesn't fit into the FP paradigm and that languages that
             | make IO easier necessarily deviate from it. And once you
             | bring non-FP concepts into an FP language, most people will
             | reasonably question why do that instead of the easier way,
             | which is bringing FP concepts into imperative languages.
        
               | throwawaymaths wrote:
               | Arguably the best platform for the general io use case is
               | functional.
               | 
               | From how when you console in to a cluster and run a
               | command on another node, the standard io is redirected to
               | you, to how tcp/up and up sockets are managed by the
               | stdlib, it's really hard to beat Erlang.
        
               | aranchelk wrote:
               | Pure functional languages model IO with monads, which are
               | very much functional (function composition within a
               | context) and IMO easy to use. This ease of use is
               | probably why JS adopted the pattern with native promises
               | -- async/await. They fit well into otherwise imperative
               | code and people seem to to like them.
        
               | tsimionescu wrote:
               | Pure functional languages can very well have normal IO.
               | It's Haskell's lazyness that mostly forced it to use
               | monads for IO, for better or for worse. In a pure FP
               | language with strict evaluation semantics, IO can easily
               | be implemented as a pure function foo -> (World, Input)
               | -> (World, Output).
        
           | HideousKojima wrote:
           | Another problem is that as nice as avoiding state and side
           | effects is, for any decently complex application there's a
           | minimum amount of state that you simply have to handle, and
           | as a general rule OOP languages seem to make dealing with
           | state much easier. Mind you there are plenty of good ideas in
           | FP, and discriminated unions is the feature I want added most
           | to C#.
        
         | jrm4 wrote:
         | 100%.
         | 
         | IMHO, the ideal "future of programming" is like how a lot of
         | game dev has C on the "back-end," and Lua "in-front."
         | 
         | Why one language or paradigm? Mix it up.
        
         | TheCondor wrote:
         | Discussing FP without mentioning induction and proofs always
         | makes me wonder.
        
           | JoelMcCracken wrote:
           | why?
        
         | tylerdinner wrote:
         | Totally agree. As a Javascript dev I got functional code pushed
         | on me in 2016.
         | 
         | It's definitely good practice for devs to learn some of the
         | pitfalls that FP prevents and solves, but implementing it on a
         | massive scale front-end application just seems impractical.
         | 
         | Having worked on a large streaming service and considering the
         | author's 3 MONTH struggle after his 40 YEARS experience, I'd
         | estimate that a re-write of our codebase there would have taken
         | our 20 devs over a decade.
        
           | hajile wrote:
           | Anything beats the hundreds of incompatible classical
           | inheritance models rammed on top of proptypes.
           | 
           | Today, functional has won so completely that devs don't even
           | notice. Using classes is almost entirely antipattern.
           | Factories with object literals and Claire's reign supreme.
           | Everyone prefers map, filter, reduce, etc over manual
           | looping. Const and copying as a default immutability is
           | preferred to mutation. Nobody thinks twice about higher order
           | functions everywhere.
        
           | tasuki wrote:
           | > As a Javascript dev I got functional code pushed on me in
           | 2016.
           | 
           | What do you mean?
        
           | trgn wrote:
           | Functional programming, and it's degenerate cousin, cramming
           | random functional constructs (array comprehension methods,
           | willy-nilly currying, ...) in Javascript has been the worst
           | thing to happen to web programming.
           | 
           | What that has done is made a whole generation of developers
           | completely detached of the impact on heap allocation and GC.
           | If web programs are slow and bloated, it's partly because of
           | using nuggets from functional programming just for the sake
           | of it.
        
           | karmakaze wrote:
           | > implementing it on a massive scale front-end application
           | just seems impractical.
           | 
           | That's true if a team was trying to do so from scratch in js
           | or ts. However React borrows a lot from FP and works at
           | scale. A better example would be Elm.
        
           | eyelidlessness wrote:
           | > implementing it on a massive scale front-end application
           | just seems impractical.
           | 
           | I was using Clojure/ClojureScript around the same time. I've
           | since worked primarily in TypeScript/JavaScript. I'm sure the
           | FP experience influenced my opinion, but it seems impractical
           | to me _not_ to use FP techniques for a large scale frontend
           | application. The applications I inherited and maintain now,
           | which were certainly not originally implemented with FP
           | techniques, have been gradually becoming much more
           | maintainable as I'm able to eliminate or at least ruthlessly
           | isolate mutations. Not only because the code itself is easier
           | to reason about, but also because it's easier to reason about
           | dependencies between different parts of the systems--even
           | parts which haven't changed.
        
           | kstenerud wrote:
           | I'm actually all for the FP things that have been added to
           | imperative languages, which increase their power tremendously
           | and make a lot of tasks a helluva lot easier. But like any
           | tool, it has its place. I'd be equally leery of a pure
           | imperative solution as I would be a pure FP solution.
        
         | hresvelgr wrote:
         | > One of the big reasons why FP languages have so little
         | penetration is because the advocacy usually feels like someone
         | trying to talk you into a religion.
         | 
         | This is a part of it. The other part is FP's a bit of a mind
         | fuck if you're used to procedural programming. Take a classic
         | example: Haskell. To do anything remotely productive it's
         | advisable to understand how monads and the various monad design
         | patterns fit together. This difficulty is further compounded by
         | monads having it's foundation in category theory, a branch of
         | mathematics. But hey, they're just monoids in the category of
         | endofunctors, it can't be that hard ;) You can rely on `do`
         | syntax a lot but it really helps to learn how they work.
         | 
         | > I immediately distrust any article that makes sweeping claims
         | about one-paradigm-to-rule-them-all.
         | 
         | I get where you're coming from but this is the end state as far
         | as I'm concerned. Pure FP is where we're all headed. I am
         | convinced the more we try to make mutable state, and
         | concurrency safe and correct, the more FP concepts will leech
         | into future languages.
         | 
         | Rust was one of the first steps toward this. The language is
         | procedural but a lot of the idiomatic methods of doing things
         | are functional at heart. Not to mention most of it's syntax
         | constructs return values. You can still mutate state, but it's
         | regulated through the type system and you can avoid it if you
         | really want to.
         | 
         | Rust's enums, arguably one of it's killer features are
         | algebraic data types and they're combined together the way you
         | would use monads in Haskell. This not only avoids null typing
         | (if you ignore ffi), but also provides a bullet-proof framework
         | for handling side-effects in programs.
         | 
         | I could be totally crazy, but I reckon many years from now,
         | we'll joke about mutating state the same way we joke about de-
         | referencing raw pointers.
        
           | Test0129 wrote:
           | I'm not sure why you're getting downvoted.
           | 
           | > I get where you're coming from but this is the end state as
           | far as I'm concerned. Pure FP is where we're all headed. I am
           | convinced the more we try to make mutable state, and
           | concurrency safe and correct, the more FP concepts will leech
           | into future languages.
           | 
           | Having been around the block to catch a couple "FP will rule
           | the world" cycles I can say this is likely untrue. While FP
           | is useful and I personally enjoy it, it is not always the
           | most efficient, nor is it the most clear. This is true in
           | your example of Rust as well. Functional constructs are often
           | slower than their procedural counterparts. For example,
           | having to pass around immutable data structures becomes
           | pretty memory intense even with a highly developed GC.
           | 
           | > I could be totally crazy, but I reckon many years from now,
           | we'll joke about mutating state the same way we joke about
           | de-referencing raw pointers.
           | 
           | Dereferencing raw pointers has been joked about as long as
           | I've been in the industry, and probably even joked about in
           | the 70s. We still dereference pointers today. Similar,
           | _state_ is a very natural thing to reason about. Sure, you
           | can argue as many FP fans do that stateful programs can be
           | rewritten with pure functions. I have yet to see FP code that
           | does this that doesn 't negatively effect readability. Even
           | something as simple as large map/reduce/filter chains can
           | quickly become _extremely_ difficult to debug when compared
           | to a very simple loop.
           | 
           | All this to be said there's a lot of benefit many languages
           | can take from FP paradigms. Map, reduce, etc are great
           | examples. Offering immutable state, and algebraic data types
           | could also be beneficial especially in the areas of
           | concurrent and parallel programming. In my professional
           | experience the problems usually start when you begin talking
           | about pure functions which in theory are _awesome_ but
           | sometimes don 't map to a problem domain well, or become
           | extremely hard for Joe Developer to get used to. Often times
           | I will think in a functional way, but rewrite things into a
           | procedural way, because communicating your idea is often just
           | as important as the code you write.
        
             | hresvelgr wrote:
             | > In my professional experience the problems usually start
             | when you begin talking about pure functions which in theory
             | are awesome but sometimes don't map to a problem domain
             | well, or become extremely hard for Joe Developer to get
             | used to.
             | 
             | It's a ripe field for research. I do wonder if there is a
             | better way to program in a pure functional way that
             | conforms to the impurity of the real world. I agree with
             | you though, I think while pure FP is a tantalising
             | abstraction, it must obey the the whims of the hardware.
             | The only way you're getting pure FP to the absolute bottom
             | is if you can monadically formalise the hardware you're
             | running on, which has been attempted [1].
             | 
             | > Often times I will think in a functional way, but rewrite
             | things into a procedural way, because communicating your
             | idea is often just as important as the code you write.
             | 
             | I think this is perhaps the common benefit that is cited
             | from learning FP. It provides an alternate way of
             | expressing the same solution, but maybe in a simpler
             | fashion. The reverse is also true, what is not straight
             | forward in FP may be expressed simpler, procedurally.
             | 
             | [1] https://www.cl.cam.ac.uk/~mom22/itp10-armv7.pdf
        
           | innocentoldguy wrote:
           | I've used Erlang, Elixir, and Elm and found them all quite
           | easy to learn. There are different coding strategies, sure,
           | but for me FP is much less frustrating than OOP.
        
           | bcrosby95 wrote:
           | Using Haskell as the classical example of FP is a bit like
           | using Rust as the classical example of imperative
           | programming.
           | 
           | You can do it but they're much harder than most other
           | languages in the class and not anywhere near representative
           | of the whole class.
           | 
           | My FP journey was: Scheme (different but okay) -> Haskell
           | (wtf) -> Erlang -> Clojure -> Elixir. Nowadays when I reach
           | for an FP it's Clojure or Elixir, mostly based upon the
           | problem at hand.
        
           | tsimionescu wrote:
           | > The other part is FP's a bit of a mind fuck if you're used
           | to procedural programming
           | 
           | It's not "if you're used to procedural programming" - FP is
           | simply hard for people to reason about. You can often very
           | intuitively reason about imperative programs, while FP always
           | requires putting your abstract thinker cap on. Look at any
           | non-software person describing describing how to do something
           | and see how often that sounds like an imperative program vs
           | an FP one. Hell, most algorithms papers are themselves using
           | imperative pseudo-code, not FP pseudo-code (unless they're
           | specifically describing novel algorithms important for FP of
           | course).
           | 
           | > I am convinced the more we try to make mutable state, and
           | concurrency safe and correct, the more FP concepts will leech
           | into future languages.
           | 
           | Concurrent mutation is fundamentally hard regardless of what
           | paradigm you chose to implement it in. Parallelism can be
           | made safer by FP, but parallelism is actually pretty easy in
           | every paradigm, with even a little bit of care. And
           | concurrent updates of mutable state are just a fundamental
           | requirement of many computer programs - you can try to wrap
           | them in monads to make them more explicit, but you can't
           | eliminate them from the business requirements. The real world
           | is fundamentally stateful*, and much of our software has to
           | interact with that statefullness.
           | 
           | * well, at least it appear so classically - apparently QM is
           | essentially stateless outside its interactions with classical
           | objects (the Born rule), but that's a different discussion.
        
             | BlargMcLarg wrote:
             | Eh, it really depends. Some people find trees easier to
             | navigate through recursion than iteration, same for lists
             | and graphs. Some do better using decomposition on a list to
             | get a combined value or create permutations than doing it
             | through iteration and indexing. FP commonly becomes
             | problematic when things are far more trivial to do stateful
             | than stateless, with side-effects than without, and more.
             | 
             | FP usually shines in small sections of easily isolated
             | code, where it is still trivial to grasp for most and its
             | strengths show more than its weaknesses. Given that code
             | isn't more easily expressed using iteration, anyway. The
             | moment things have to be woven together and not leave any
             | side-effects is when the difficulty jumps to 11.
        
               | tsimionescu wrote:
               | Sure, there are contexts where the functional approach is
               | actually more natural - especially already highly
               | abstract contexts. I actually like to use certain
               | functional paradigms in my day to day programming (or
               | did, before switching to Go). I just dislike the claim
               | that imperative code is simply more familiar and not more
               | natural/intuitive (in general).
        
         | tikhonj wrote:
         | > One of the big reasons why FP languages have so little
         | penetration is because the advocacy usually feels like someone
         | trying to talk you into a religion.
         | 
         | That's exactly what worked for OOP--have we collectively
         | forgotten just how hard OOP was pushed _everywhere_ 15-20 years
         | ago? Way more aggressive than any FP advocacy I 've seen, and
         | I've seen a lot. When I was learning to program every single
         | book and tutorial pushed OOP as the _right_ way to program;
         | procedural programming was outmoded and functional programming
         | was either not mentioned or confused with procedural
         | programming.
         | 
         | I still have to deal with the fallout from OOP evangalism; I've
         | had colleagues who unironically use "object-oriented" as a
         | synonym for "good programming" and managers who believe design
         | patterns _are_ software engineering.
        
           | softwarebeware wrote:
           | And yet today we only have partially-OOP languages being
           | mostly used in procedural ways.
        
         | thrown_22 wrote:
         | Tooling. Tooling is the major reason why no one uses functional
         | programming languages in industry. I was very into Haskell a
         | decade ago. Today I don't even know where to start when it
         | comes to installing a new package. If Debian doesn't have it in
         | their repos I usually just try building it from source and hope
         | make all works. If it doesn't. Well I probably didn't need that
         | package anyway.
        
           | innocentoldguy wrote:
           | My company does FP and I think the tooling in Elixir is
           | pretty great.
        
         | knaekhoved wrote:
         | The popularity of various programming paradigms is mostly
         | historically contingent and driven by social/business dynamics,
         | not because of any reasonable constrained optimization.
        
         | alanwreath wrote:
         | >> navigating all of the offerings, examining their trade-offs
         | 
         | the amount of time you're afforded for that exercise better fit
         | neatly inside a very small window of implementation (in other
         | words you're probably not going to do it, or at least do it
         | justice)
         | 
         | >> figuring out which ones fit best to the system being built
         | in terms of constraints
         | 
         | constraints will always get ya. It always ends up to being what
         | is the tool/paradigm that you (and your project manager) are
         | most comfortable with because you'll most likely use it in leu
         | of anything else (especially given you are not the only one
         | that has to be convinced -- engineers don't operate in a
         | vacuum, and they love predictability, ie what they already
         | know)
         | 
         | >> You won't get a very optimal solution by ...
         | 
         | YAGNI. Premature Optimization. KISS.
         | 
         | I am not saying that ^^^ is true, I'm just introducing you to
         | your new conversation buddies for the foreseeable future.
         | People always bring'em along for the conversation.
         | 
         | >>> trying to talk you into a religion
         | 
         | advocacy among unbelievers is always gonna come off like this,
         | especially when the evangelists have dealt with so many
         | naysayers and the apathetic majority. And this is probably the
         | crux of the entire issue. Students' first languages in school
         | are generally imperative languages. They are taught in their
         | youth a path away from functional programming. Which is funny
         | to me because my school was always promoting that their studies
         | were there to help you grow one's intellect and not necessarily
         | fit into some cog of the industry. But, I don't recall much
         | playtime given to functional languages (not as much as they
         | deserved at least).
         | 
         | My point is that it would be nice if FP was the first tool that
         | was given to students that pour out of universities into
         | developer teams. It would be nice if the easy button for a
         | group was FP, not the other way around. Then it would be much
         | easier to beat the other drums (like the testing drum).
        
           | ptero wrote:
           | >> the advocacy usually feels like someone trying to talk you
           | into a religion
           | 
           | > advocacy among unbelievers is always gonna come off like
           | this, especially when the evangelists have dealt with so many
           | naysayers and the apathetic majority.
           | 
           | If an advocate sees unbelievers and naysayers around it is
           | more a reflection of the advocate tactics. No offense
           | intended. Most developers will gladly hear an overview of how
           | a new technology can make doing X easier, better or faster.
           | Even when there is a steep learning curve. They may not
           | switch to it quickly or at all, but they are likely to form
           | positive impression of it.
           | 
           | But if an advocate starts with "your tools are bad", "stop
           | doing Y", "you need to unlearn Z" he is usually digging a
           | hole for his technology, not advancing its adoption. If an
           | advocate cannot produce powerful, convincing examples showing
           | the goodness of his technology (without bashing existing
           | tech) he should stop advocating and start learning. My 2c.
        
             | alanwreath wrote:
             | For the most part, agreed. But the arguments for FP are old
             | and like you're mentioning could be sold easily by the
             | right orator (those teachers/evangelists exist btw in
             | droves on YouTube and elsewhere). I'm only saying that
             | given what academia and collective professional experience
             | has proven around FP, it would be nice if FP or FP patterns
             | were the first option(s) most stressed to budding
             | SWEngineers/Developers and that imperative architecture was
             | the afterthought (not the other way around as _probably_ it
             | is in our current state).
             | 
             | In other words, there would be little need to evangelize
             | for FP if it was the base of understanding.
             | 
             | And while there are a lot that want to improve the field,
             | I'd wager that most 9-5's are tired, wanna finish a good
             | days work and rest.
        
               | AnimalMuppet wrote:
               | But why _should_ FP be the basis for understanding?
               | 
               | Let's say I run a CS department. And let's say that I've
               | accepted that what my department is really doing is jobs
               | training for software engineers. Well, what are their
               | jobs going to be, imperative or functional? For most of
               | them, for most of their careers, the jobs are going to be
               | imperative. Why should we start with FP?
               | 
               | You could say "FP is better", but then we're back at the
               | OP's point. FP is better _for some things_ , and worse
               | for others.
               | 
               | For you to say that FP should be the starting point, you
               | need to show that FP is better for the majority of
               | programming situations, or else to show that FP is the
               | better way to learn programming for the majority of
               | students. I have never seen anyone seriously attempt to
               | show either one. (Some argue "it fits how we think
               | better", but what they mean is that it better fits how
               | _they_ personally think, ignoring that different people
               | think differently.)
        
               | alanwreath wrote:
               | It's about rope. Imperative languages generally give you
               | a lot of flexibility (for x or y) and, therefore, rope to
               | hang yourself. I don't believe that starting students
               | here, from a pedagogical perspective, is a good strategy.
               | FP languages/paradigms, on the other hand, are all about
               | restrictions(immutability, side effects, etc), and thus
               | less rope. Less places to hang yourself, so to speak.
               | 
               | Also, even though, as you've stated sw engineers tend to
               | work in an imperative environment (which I'm arguing is
               | an artifact of their formative years), junior sw
               | engineers should at least start with a bit of trepidation
               | to use that rope (if only in their heads).
               | 
               | Plus, utilizing a functional style (and understanding the
               | _whys_ of functional style, where pragmatic) would
               | improve many aspects of industry (e.g reducing the
               | friction of adding tests - did I mention that I love
               | tests??)
        
           | torginus wrote:
           | I am sorry, but you sound like you know for a fact that
           | functional programming is better, but you have trouble making
           | others recognize that fact.
           | 
           | Imho, FP has many tangible weaknesses, just a few off the top
           | of my head:
           | 
           | - Immutability is non-intuitive: If I were to ask someone to
           | make an algorithm that lists all the occurrences of a word on
           | a page, they wouldn't intuitively come up with an algorithm
           | that takes a slice of text and a list of occurrences, then
           | returns an extended list, and an linked list with one more
           | occurrence.
           | 
           | - Immutability can cause more problems than solve: If I were
           | to create a graph of friendships between people, chances are
           | that if I were to add a link between A and B, then not only A
           | and B would need to be updated, but everyone who transitively
           | knows A and B (which, since no man is an island would
           | probably mean, everyone). This is highly complex, and
           | probably just as bad as living with mutability.
           | 
           | - FP is not performant: FP code tends to be full of pointers
           | and non-performant data structures like linked lists that
           | have very little memory locality. It also makes optimizations
           | such as updating things in a certain order to avoid
           | recalculation impossible.
           | 
           | - FP has to deal with side effects: The real world has side
           | effects, and your FP code is probably a bit of business logic
           | that responds to a HTTP request, and fires of some other
           | request in turn. These things have unavoidable side effects.
        
             | initplus wrote:
             | On this friendship example, I think already FP is showing
             | you something useful about the way you are designing your
             | model.
             | 
             | A friendship is really an edge in a graph. if you manage
             | friendships by recording a collection of friend PersonId's
             | on each person, you are modelling a graph by recording the
             | same edge in two different places, and then hoping the
             | programmer is diligent enough to never make a mistake and
             | update the edge in one place but not the other. If you
             | model the friendship graph as a collection of id pairs, not
             | encapsulated inside a specific person structure, this
             | invalid state is no longer possible.
             | 
             | I'm not sure what you are on about regarding making
             | transitive updates - that idea is obviously not going to
             | work on any moderately sized network. Imagine if Facebook
             | tried to record all your transitive friendships on your
             | account!
             | 
             | Sure immutability is non-intuitive, but it's really
             | helpful! Like borrow checking in Rust, immutability helps
             | eliminate an entire class of bugs. And immutable code is
             | often much easier to reason about, you need to keep
             | significantly less of the context in your head.
        
             | throwawaymaths wrote:
             | I think you're completely missing an entire world of FP
             | languages which are not pure like Haskell, ocaml, elm,
             | etc... There are languages with side effects as an easily
             | accessible escape hatch but don't do things which make
             | debugging a pain like data encapsulation and inheritance.
             | 
             | Also, there are FP langs out there that have _better_ data
             | /heap locality with indirected pointer data structures,
             | because they don't share memory and so the pointers aren't
             | tied to anywhere except where they are directly running.
             | 
             | I completely disagree with immutability being non-
             | intuitive. Try explaining to a junior/bootcamp JavaScript
             | or python developer why when you pass an integer into a
             | function it doesn't reflect changes you made in the called
             | function when you jump back into your calling frame... But
             | if you do the same with a object/dictionary...
             | 
             | For junior programmers immutable passing is absolutely the
             | default assumption and so I think it's reasonable to claim
             | it's the intuitive choice.
             | 
             | There's even crazymaking shit where in python if you have a
             | default array parameter you can seriously fuck up your
             | model of what's going on if you mutate that array anywhere.
        
             | alanwreath wrote:
             | >> I am sorry, but you sound like you know for a fact that
             | functional programming is better
             | 
             | I can see the room for misunderstanding. My only argument
             | is that FP is worthy of more playtime than it currently
             | enjoys in undergraduate academia. I'd wager that the
             | current percentage of FP/Imperative playtime is 95/5.
        
               | torginus wrote:
               | Ah I see. I've been out of school for a while so I don't
               | know how students are taught - but if you take a modern
               | language such as Kotlin, you'll see it's a mishmash of
               | concepts from various paradigms, including FP.
        
             | naasking wrote:
             | > - Immutability is non-intuitive: If I were to ask someone
             | to make an algorithm that lists all the occurrences of a
             | word on a page, they wouldn't intuitively come up with an
             | algorithm that takes a slice of text and a list of
             | occurrences, then returns an extended list, and an linked
             | list with one more occurrence.
             | 
             | What do you base this on? Did you run a study of people who
             | had never programmed before and then asked them to invent a
             | pseudo-programming language to solve this problem? Or are
             | you talking about the "intuition" of people that have
             | already learned to program, mostly likely in an imperative
             | programming language, in which case your claims to
             | "intuition" don't mean anything.
             | 
             | > - Immutability can cause more problems than solve: If I
             | were to create a graph of friendships between people,
             | chances are that if I were to add a link between A and B,
             | then not only A and B would need to be updated, but
             | everyone who transitively knows A and B (which, since no
             | man is an island would probably mean, everyone). This is
             | highly complex, and probably just as bad as living with
             | mutability.
             | 
             | Firstly, that's not true, it depends entirely on what sort
             | of data structure is used. For instance, a trivial model is
             | a simple list of graph modifications, ie. type Action =
             | AddFriend(a,b) | RemoveFriend(a,b), type FriendGraph =
             | List(Action). Any change to the graph thus requires
             | allocating only a single node.
             | 
             | Secondly, if you were to model this mutably, a node removal
             | means you would lose information about the fact that two
             | people were friends at one time.
             | 
             | > - FP is not performant: FP code tends to be full of
             | pointers and non-performant data structures like linked
             | lists that have very little memory locality. It also makes
             | optimizations such as updating things in a certain order to
             | avoid recalculation impossible.
             | 
             | This argument is based on assumptions about the functional
             | programming idioms, the compiler, the machine it's running
             | on and more. I could just as easily say that imperative
             | programming doesn't scale because you can't easily
             | parallelize it across cores, and since single-core
             | performance is now a dead end, even if everything you just
             | said were true it's basically irrelevant for the question
             | of performance.
             | 
             | > - FP has to deal with side effects: The real world has
             | side effects, and your FP code is probably a bit of
             | business logic that responds to a HTTP request, and fires
             | of some other request in turn. These things have
             | unavoidable side effects.
             | 
             | I'm not sure who denies this. The question is not whether
             | useful software has side-effects, it's what sort of side-
             | effects you actually need for any given program and how
             | those side-effects should be modeled so you can properly
             | reason about them and achieve the program properties you
             | need.
             | 
             | If your programming language has pervasive side-effects
             | then you have to deal with them everywhere, and the failure
             | modes multiply. If your programming language does not
             | support pervasive side-effects, then the side-effects are
             | pushed to the edges of your program where they are more
             | amenable to reasoning. Questions like "how did we get into
             | this state?" are considerably simpler to backtrace as a
             | result.
        
               | torginus wrote:
               | 1. Immutability _is_ non-intuitive. If I were to hand a
               | regular person a book, and ask him how he would list all
               | the page 's numbers where the word cheese appears, he
               | would probably say something like this: 'I would read
               | through the book, keeping a scrap of paper at hand.
               | Whenever I saw the word cheese, I would write down the
               | page number' This is an imperative algorithm. I could
               | give more examples, but I hope you get the point.
               | 
               | 2. I just wrote the 'friends' example to make a point -
               | common, complex programs often have huge graphs of
               | interconnected objects, whether one would like it or not.
               | Your solution is to build a journal of friendships and
               | breakups - it's not a typical solution for object
               | relations - seeing if 2 people are friends is a linear
               | operation. Keeping the history around might not be
               | necessary or useful.
               | 
               | 3. Your FP code runs on a modern OoO CPU whether you like
               | it or not - so it's safe to make that assumption. And
               | multithreading might not be a silver bullet. FP does
               | nothing to break long dependency chains. As for sharing
               | values between CPU cores, considering the latencies
               | involved, it might be cheaper to compute the value
               | locally, but multithreaded optimization is a black art -
               | it's not always obvious if sharing is better.
               | 
               | Another example is when I made a small toy Excel-like
               | spreadsheet that supported formulas - while Excel itself
               | is FP, I realized that the best way to update cell
               | values, is to topologically sort all dependent
               | expressions, and evaluate them one after the other - an
               | imperative concept.
               | 
               | 4. I was just making the point is it's easy to write a
               | function in e.g. Java that is imperative on the inside,
               | but is pure when called from the outside. Other languages
               | will even allow the compiler to enforce this, while still
               | being imperative. So both 'regular' and FP languages can
               | avoid some side effects to some extent, but have to deal
               | with others.
        
               | naasking wrote:
               | > 1. Immutability is non-intuitive. If I were to hand a
               | regular person a book, and ask him how he would list all
               | the page's numbers where the word cheese appears, he
               | would probably say something like this: 'I would read
               | through the book, keeping a scrap of paper at hand.
               | Whenever I saw the word cheese, I would write down the
               | page number' This is an imperative algorithm.
               | 
               | No, that's a purely functional algorithm. Note how he's
               | just _adding numbers to the end of a list_ and
               | emphatically _not_ mutating the existing items in any
               | way. Tell me what you see as the functional real-world
               | solution to this problem. Do you consider an accounting
               | general ledger to also be imperative? Because it clearly
               | isn 't, it's an append-only log where all previous
               | entries are immutable, which is exactly the same thing as
               | the list noting the pages containing the word "cheese".
               | 
               | > 2. I just wrote the 'friends' example to make a point -
               | common, complex programs often have huge graphs of
               | interconnected objects, whether one would like it or not.
               | Your solution is to build a journal of friendships and
               | breakups - it's not a typical solution for object
               | relations - seeing if 2 people are friends is a linear
               | operation. Keeping the history around might not be
               | necessary or useful.
               | 
               | The example doesn't make a point. In either imperative or
               | functional programming, the operations you need and their
               | time and space complexity will dictate the data
               | structures and algorithms to use. Saying that programs
               | have "huge graphs of interconnected objects" is not
               | evidence of anything specific.
               | 
               | > 3. Your FP code runs on a modern OoO CPU whether you
               | like it or not - so it's safe to make that assumption.
               | 
               | Make what assumption exactly? Microcontrollers are in-
               | order. GPUs are in-order. You also made claims that FP
               | programs are full of pointers and non-performant data
               | structures. I have no idea what out of order execution
               | has to do with this claim. Certainly early FP languages
               | were pointer heavy, but early imperative programs were
               | goto heavy, so I'm not sure what exactly you think this
               | says about FP in general.
               | 
               | > And multithreading might not be a silver bullet. FP
               | does nothing to break long dependency chains.
               | 
               | FP encourages and often forces immutability which _does_
               | help significantly with parallelism and concurrency.
               | 
               | > Another example is when I made a small toy Excel-like
               | spreadsheet that supported formulas - while Excel itself
               | is FP, I realized that the best way to update cell
               | values, is to topologically sort all dependent
               | expressions, and evaluate them one after the other - an
               | imperative concept.
               | 
               | Prove that that's _the best_ way, and not merely the best
               | way you know of, or the best way available to your
               | programming language of choice.
        
               | tsimionescu wrote:
               | > No, that's a purely functional algorithm. Note how he's
               | just adding numbers to the end of a list and emphatically
               | not mutating the existing items in any way.
               | 
               | They are clearly mutating the piece of paper to add new
               | numbers to it. There is no linked list in sight. They are
               | also flipping the pages of the book in order, another
               | imperative paradigm.
               | 
               | The closest you could come to a pure FP algorithm
               | expressed in physical terms would have been "Say there
               | are still pages I haven't looked at, and say I have a
               | stack of post-it notes on the current page; then, I would
               | check if the word cheese appears on this page, and if it
               | does, I would produce a post-it note with the page number
               | on it, adding it over the stack of post-it notes; I would
               | then flip one page; on the other hand, if I am looking at
               | the last page of the book, I would add another post-it
               | note to the stack if needed, and return the whole stack
               | of post-it notes to you otherwise".
               | 
               | Imperative:                 foreach page in book
               | if 'cheese' in page           write(paper, page.number)
               | 
               | Functional:                 search page:rest_of_book
               | post-it-stack =          search rest_of_book
               | (if ('cheese' `on page)                    then
               | number(page):post-it-stack                    else post-
               | it-stack)       search [] post-it-stack = post-it-stack
               | 
               | Of course, we could write this easier with a map and
               | filter, but I don't think there is any good way to
               | express those in physical terms (not with a book -
               | filters have nice physical interpretations in other
               | domains though).
               | 
               | Later edit:
               | 
               | A version of the imperative algorithm closer to what was
               | described in prose:                 repeat:         word
               | = read_word(book)         if word == 'cheese':
               | write(paper, current_page_number(book))         if
               | no_more_words(book):           return paper
        
               | naasking wrote:
               | > They are clearly mutating the piece of paper to add new
               | numbers to it.
               | 
               | No, they are simply adding a new record for the word
               | occurrence. If the paper runs out, they grab another
               | sheet and continue. This is clearly an append-only
               | ledger, just like that used in accounting. These are both
               | immutable abstractions.
               | 
               | The fact that this is happening on a single sheet of
               | paper is merely an _optimization_ , it's not a property
               | of the underlying algorithm they're employing. The post-
               | it equivalent you describe is simply a less space
               | efficient version of exactly the same algorithm. You're
               | basically saying that tail call elimination makes FP no
               | longer FP.
               | 
               | > There is no linked list in sight.
               | 
               | What do linked lists have to do with anything? You don't
               | think that FP or immutable programming have to use lists
               | do you?
               | 
               | > They are also flipping the pages of the book in order,
               | another imperative paradigm.
               | 
               | Traversing an immutable sequence in order is now an
               | imperative algorithm? Since when?
               | 
               | What's really happening here is that you've already
               | assumed that physical reality and people's intuitions are
               | imperative, regardless of the contortions required.
               | 
               | This example of counting words and the general ledger are
               | perfect examples: it's absolutely crystal clear that all
               | of the recorded entries are immutable and that this log
               | of entries is append-only, which is a characteristic
               | property of FP and immutable abstractions, and yet you
               | have to contort your thinking into looking at the paper
               | itself as some mutable state that's essential to the
               | process in order to call this an imperative process.
        
               | tsimionescu wrote:
               | > The fact that this is happening on a single sheet of
               | paper is merely an optimization, it's not a property of
               | the underlying algorithm they're employing.
               | 
               | The person is describing the abstraction, not any
               | optimization. If you were to translate their words
               | directly into code, you would have to write code that
               | modifies the piece of paper, because this is what they
               | described.
               | 
               | In contrast, when using a persistent data structure, the
               | abstraction says that I create a new structure that is
               | the old one + some change, but, as an optimization, the
               | computer actually modifies it in place. The
               | implementation is imperative, but the abstraction is
               | functional.
               | 
               | > You're basically saying that tail call elimination
               | makes FP no longer FP.
               | 
               | No, I'm saying that there is a difference between writing
               | an algorithm using tail-call recursion, and writing it
               | using iteration; even if the compiler produces the same
               | code. The tail-call recursive version is FP. The
               | iterative version is imperative. How they actually get
               | executed is irrelevant to whether the algorithm as
               | described is FP or imperative.
               | 
               | In contrast, you're basically claiming that any algorithm
               | that could be abstracted as FP is in fact FP. So, `for
               | (int i = 0; i < n; i++) { sum += arr[i]; }` is an FP
               | algorithm, as it is merely the optimized form of `sum
               | x:xs total = sum xs x+current; sum [] current = total`
               | after tail-call elimination.
               | 
               | > Traversing an immutable sequence in order is now an
               | imperative algorithm? Since when?
               | 
               | Immutability and FP are orthogonal. Append-only ledgers
               | are a data structure, not an algorithm; and it's
               | algorithms that can be functional or imperative.
               | 
               | On the other hand, yes - traversing a data structure in
               | order is an imperative idiom. In pure FP, the basic
               | operation is recursive function application, not
               | traversal. For loops and tail-call recursion obtain the
               | same thing in different ways.
               | 
               | > This counting words and the general ledger are perfect
               | examples: it's absolutely crystal clear that all of the
               | recorded entries are immutable and that this log of
               | entries is append-only, which is a characteristic
               | property of FP and immutable abstractions, and yet you
               | have to contort your thinking into looking at the paper
               | itself as some mutable state in order to call this an
               | imperative process.
               | 
               | By your definition, I understand this is an FP algorithm
               | for producing a list of the first 100 natural numbers,
               | since it's append-only:                 xs := []int{}
               | for (i := 0; i < 100; i++) {         xs = append(xs, i)
               | }
               | 
               | You can certainly define FP = append-only, but that is
               | emphatically not what others mean by the term. Instead,
               | most people take FP to mean "expressing the problem in
               | terms of function applications (and abstractions based on
               | them), where function == pure function in the
               | mathematical sense".
               | 
               | > What's really happening here is that you've already
               | assumed that physical reality and people's intuitions are
               | imperative
               | 
               | I've actually shown what I think is actually an FP
               | algorithm represented in physical terms, and how that
               | translates 1:1 to FP code (and the alternative imperative
               | algorithm). I don't think it's fair to accuse me of
               | assuming that physical reality is imperative - at least
               | not without showing your 1:1 mapping of the description
               | to FP pseudo-code.
               | 
               | Edit to ads:
               | 
               | Perhaps a fairer representation of the imperative
               | algorithm should have been:                 repeat:
               | word = read_word(book)         if word == 'cheese':
               | write(paper, current_page_number(book))         if
               | no_more_words(book):           return paper
               | 
               | This is even closer to the prose version, and makes it
               | clearer that it was describing an imperative traversal.
        
             | agentultra wrote:
             | I think you haven't read much of the literature and don't
             | have any real experience with it on a real project.
             | 
             | There is no intuition when it comes to programming.
             | Everyone has to learn it. You're appealing to familiarity
             | of concepts you've already learned and assume everyone else
             | thinks the same way.
             | 
             | There are highly efficient graph algorithms using pure
             | immutable data structures. You don't seem to be aware of
             | how much sharing is enabled by immutability nor the
             | algorithms for efficiently updating graphs in a pure
             | functional way. Try reading this book [0].
             | 
             | Again there is a whole zoo of optimizations available
             | exclusively to pure functional languages that you don't
             | seem to be aware of. Try reading _Counting Immutable
             | Beans_. Some of the optimizations GHC can do are
             | impressive. It's not all bad performance.
             | 
             | Want to talk about cache misses? Check out an average C++
             | code base. It has a dedicated cache-miss operator.
             | 
             | Side effects are everywhere. And yes, in a purely
             | reverentially transparent language, it becomes a pain being
             | forced to be explicit about every mutation, network call,
             | and file handle operation when you're used to throwing
             | caution to the wind and flying free with them. Improper
             | handling of side effects include common use-after-free
             | errors, etc. After years of dealing with this mud all of
             | software, at least for me, explicit handling of effects
             | becomes exactly what you want in order to keep your sanity
             | intact.
             | 
             | [0] https://books.google.ca/books/about/Purely_Functional_D
             | ata_S...
        
               | badsectoracula wrote:
               | > There is no intuition when it comes to programming.
               | Everyone has to learn it.
               | 
               | There is no intuition in anything aside from the very few
               | things we are born with. Everything else is learned from
               | experiences.
               | 
               | And to that end, chances are someone has learned to
               | follow procedure-like steps like a recipe at a very early
               | age - indeed, in some schoolbooks recipes and other
               | "procedural" works are among the first things someone
               | does.
               | 
               | Children learn things like "to do X, first do Y and then
               | Z" from a much earlier age, often before even learning
               | how to read and write (e.g. via simple papercrafting in
               | kindergarden) than something like "X = Y*Z". Giving and
               | taking commands (i.e. "imperative" programming) as a
               | concept is something people meet in their lives much
               | sooner and are more exposed to than abstract problems.
        
               | agentultra wrote:
               | I think the jury is out on which programming paradigm is
               | easier to teach to kindergarten aged children.
               | 
               | Let alone adults with no prior training with programming.
               | 
               | I don't believe it's as natural as you seem to think.
        
             | hajile wrote:
             | FP isn't just limited to Haskell while your criticisms seem
             | aimed only at that one language.
             | 
             | Immutability may not be intuitive, but neither are
             | pointers, hash tables, structured loops, OOP, etc. In any
             | case, maintaining immutable code is certainly more humane
             | than trying to reason about 10th order side effects.
             | Finally, the majority of functional languages are immutable
             | by default with optional mutation when needed.
             | 
             | Your immutable argument is a red herring. It's the wrong
             | algorithm. Bubble sort is much more intuitive than heap or
             | quick sort, but you certainly wouldn't recommend it.
             | 
             | You are flatly wrong about performance. Ocaml and
             | StandardML are just as fast as languages like Go or Java.
             | This is incredible when you realize These FP languages are
             | maintained by a handful of people with basically no budget
             | and are keeping pace with languages that have tens out
             | hundreds of millions of dollars pushed into them.
             | 
             | FP doesn't mean no side effects (though it does tend to
             | encourage limiting and separating them). Outside of Haskell
             | and Miranda, basically all the other FP languages have side
             | effects and even Haskell has an escape hatch available.
        
           | Communitivity wrote:
           | To any leads reading this,
           | 
           | >>> navigating all of the offerings, examining their trade-
           | offs
           | 
           | >> the amount of time you're afforded for that exercise
           | better fit neatly inside a very small window of
           | implementation (in other words you're probably not going to
           | do it, or at least do it justice)
           | 
           | Every project I have worked that has done a gap analysis has
           | executed faster and smoother than those that didn't. A gap
           | analysis being a more rigorous approach to an analysis of
           | tradeoffs, solution capabilities vs requirements/existing
           | software, and sometimes scoring/ranking (often with three
           | recommended options depending on client's choices in
           | tradeoffs).
        
         | bennysonething wrote:
         | What does gatekeeping mean in this context? Genuine question.
        
           | tsimionescu wrote:
           | Something like "oh, you're using map() and filter() in your
           | C++ program? you're not doing actually doing FP unless
           | [...]".
           | 
           | See https://news.ycombinator.com/item?id=33438320 for an
           | example of this exact attitude.
        
       | misja111 wrote:
       | Very odd that this article states that functional programming is
       | the solution to the null reference problem. Yes as far as I know
       | all functional languages have some kind of Optional or Maybe type
       | as a solution, but there are non-functional languages with this
       | solution as well.
        
         | munchler wrote:
         | Perhaps, but those are still FP solutions that have been added
         | to non-FP languages.
        
         | chriswarbo wrote:
         | > Yes as far as I know all functional languages have some kind
         | of Optional or Maybe type as a solution, but there are non-
         | functional languages with this solution as well.
         | 
         | Optional/Maybe values are tedious if we don't have
         | functions/methods like map, flatMap, etc. which take functions
         | as arguments. That requires first-class functions, which pushes
         | things further in the direction of FP.
         | 
         | I think of things on a spectrum, e.g. more-functional/less-
         | functional, rather than having a hard cutoff of "this is FP" or
         | "this isn't FP".
        
       | cafard wrote:
       | Functional programming: the future of computing since 1977.
       | (Dating it from John Backus's Turing Award lecture.)
        
         | throwaway17_17 wrote:
         | Is that really a fair date to use? The functional programming
         | Backus is talking about bears little resemblance to the
         | functional programming which is being discussed now(and in the
         | article). I think an interesting discussion can be had about
         | what defines functional programming (and I'm not really trying
         | to argue with you), but Backus's FP doesn't fit the definition
         | the article or other posters are using (or implying).
        
       | jmull wrote:
       | Functional programming fixes what ails you!
       | 
       | How do I know? A thought leader told me so!
       | 
       | Nothing against functional programming, which certainly has its
       | uses and advantages, but this article is basically substance-
       | free.
       | 
       | I guess it's really an ad for the author's company and book?
       | Considering the shear number of things conflated with functional
       | programming here, I'm not sure it would be worth the time.
        
       | anfelor wrote:
       | Even though this article comes from a reputable source, it should
       | be pointed out that the author is not a researcher in the area --
       | and the decision not to include various MLs, OCaml, Scala, or F#
       | in the chart of functional languages seems controversial. So this
       | article does not speak for the community. If you want to read
       | more about using Functional Programming in Industry, I would
       | recommend Yaron Minsky's
       | https://queue.acm.org/detail.cfm?id=2038036 instead.
       | 
       | Why did the GOTO statement fall out of favor with programmers? If
       | you look at Knuth's famous article weighting the importance of
       | GOTO (https://pic.plover.com/knuth-GOTO.pdf) you can see many
       | calculations where the GOTO statement can save you a tiny bit of
       | runtime. Today, these matter far less than all of the other
       | optimizations that your compiler can do (e.g. loop unrolling,
       | inserting SIMD instructions etc). Similarly, in some domains the
       | optimizations that functional compilers can do matter more than
       | the memory savings mutation could bring.
       | 
       | Personally, I believe that with in the next decades memory usage
       | will matter more, but even then functional programming languages
       | can do well if they can mutate values that only they
       | reference(https://www.microsoft.com/en-
       | us/research/uploads/prod/2020/1...). This does not break the
       | benefits of immutability, as other program parts can not observe
       | this mutation.
       | 
       | I disagree with the articles premise that it is "hard to learn"..
       | it might be today but it doesn't have to be. Monads are usually
       | difficult for beginners, but algebraic effects are almost as
       | powerful while being much simpler. They have slowly become
       | mainstream (and might even make it into WASM!). It is an exciting
       | time for functional languages and many people are working to make
       | them even better!
        
         | thoradam wrote:
         | > the decision not to include various MLs, OCaml, Scala, or F#
         | in the chart of functional languages seems controversial
         | 
         | I don't know why that would be controversial. There's a very
         | clear distinction between (MLs, OCaml, Scala, F#) and (Haskell,
         | Elm, PureScript, etc.).
        
           | anfelor wrote:
           | Sure, they are in different language families. But a chart
           | showing the "top dozen functional-programming languages"
           | should include all languages that were given a separate
           | workshop at the International Conference on Functional
           | Programming (https://icfp22.sigplan.org/): Haskell, ML,
           | OCaml, Scheme, Erlang, miniKanren (the last two are arguably
           | specialised enough that they could be excluded to put more
           | focus on general-purpose languages).
        
       | photochemsyn wrote:
       | Hybridization of object-oriented and functional approaches seems
       | like a decent approach to theses problems.
       | 
       | > "Nearly all modern programming languages have some form of null
       | references, shared global state, and functions with side
       | effects..."
       | 
       | Which is to say, code is organized into discrete classes,
       | instantiated as objects, but those objects only use the
       | functional paradigm with respect to their bound functions, i.e.
       | no side effects, no shared global state. Some sort of input
       | validation and screening can be used with each to sanitize values
       | and avoid null references. Then you have a collection of discrete
       | modular elements which can be reasoned about or debugged
       | independently.
       | 
       | Such classes would be essentially 'stateless' but you could have
       | other classes that stored mutable state and were queried by the
       | functional types, much like the application-database model:
       | 
       | > "The trend has been to keep stateless application logic
       | separate from state management (databases): not putting
       | application logic in the database and not putting persistent
       | state in the application. As people in the functional programming
       | community like to joke, "We believe in the separation of Church
       | and state""
       | 
       | https://ebrary.net/65011/computer_science/separation_applica...
        
         | brmgb wrote:
         | Someone should bolt object-oriented features on top a
         | functional programming language to see what it would look like.
         | That would be an interesting research project. They could call
         | it O- _something_ and do a pun with an animal name.
        
           | metaltyphoon wrote:
           | Don't need to, look at F#. Its functional first and OO is
           | bolted on.
        
             | brmgb wrote:
             | Now I'm stuck wondering if you missed the joke or are one
             | upping me. Well done if it's the case.
        
         | ParetoOptimal wrote:
         | > Hybridization of object-oriented and functional approaches
         | seems like a decent approach to theses problems.
         | 
         | It's too complex and loses a lot:
         | 
         | > Contemporary imperative languages could continue the ongoing
         | trend, embrace closures, and try to limit mutation and other
         | side effects. Unfortunately, just as "mostly secure" does not
         | work, "mostly functional" does not work either. Instead,
         | developers should seriously consider a completely
         | fundamentalist option as well: embrace pure lazy functional
         | programming with all effects explicitly surfaced in the type
         | system using monads.
         | 
         | https://m-cacm.acm.org/magazines/2014/6/175179-the-curse-of-...
        
       | loonginthetooth wrote:
       | Gonna be honest, this guy lost me at 'I decided to learn Haskell
       | --and needed to do that on a business timeline. This was the most
       | difficult learning experience of my 40-year career...'
       | 
       | like, really?
        
       | begueradj wrote:
       | Quoted: "OOP has, however, been wildly successful. It may be that
       | this success is a consequence of a massive industry that supports
       | and is supported by OOP."
       | 
       | Link: https://stackoverflow.blog/2020/09/02/if-everyone-hates-
       | it-w...
        
       | dukeofdoom wrote:
       | Would be nice to have a functional language to construct images
       | for something like midjourney
        
       | markdog12 wrote:
       | Tangent: article has a useless 13.2MB gif at the top, with a
       | "high" fetch priority.
        
       | agumonkey wrote:
       | Oh, scalfani, he was quite invested in FP talks too.
       | 
       | It's funny, I'm calling cover effect (forgot the idiom, but
       | basically when big medias put you up, your uptick is over) on
       | simple FP. I think mainstream absorbed most of the idioms (map
       | filter reduce, decorators, composability, lazy streams etc) and
       | there's nothing else in that bag to push.
       | 
       | That said, I do believe that FP as an abstract multi stage
       | modeling language is still gonna help in the future because it
       | raises provability which is something that I personally miss
       | every day in most mainstream languages. You're never too sure
       | about anything and it's tiresome.
        
       | [deleted]
        
       | water8 wrote:
        
       | fedeb95 wrote:
       | Software should be the future of functional programming.
        
       | halfmatthalfcat wrote:
       | The article picks on Javascript (of course) however you can write
       | almost exclusively functional code in Javascript with the help of
       | Rambda, fp-ts or the like. Yes, there is no "compiler" (outside
       | of tsc) that will help you (yet) but stylistically, it's
       | possible.
        
         | jvanderbot wrote:
         | There is nothing magical about functional programming, it is
         | the elimination of non functional programming features that is
         | important.
         | 
         | A language that can do either is exactly the wrong thing, from
         | the perspective of TFA
        
           | jve wrote:
           | > There is nothing magical about functional programming
           | 
           | How come not? I read that F# gives you compiler exception
           | when you didn't match all possible values. Or when you didn't
           | handle __maybe__ cases. JS even doesn't mind comparing
           | strings with ints and incorrectly summing them together and
           | not throwing a runtime exception less alone a compiler
           | complaint.                 "1" == 1       true       "1" + 1
           | '11'
        
             | innocentoldguy wrote:
             | I view this as one of JavaScript's myriad flaws. Adding "1"
             | to 1 is nonsensical and the result of "11" is even more so.
        
             | dmitriid wrote:
             | These are peculiarities of type systems, not of functional
             | or non-functional programming.
        
             | jvanderbot wrote:
             | You can add error checking (e.g., compiler exceptions), but
             | you cannot remove the parts of JS/other languages that
             | cause that error checking to be important in the first
             | place, not without fundamentally breaking the
             | language/existing libraries.
             | 
             | TFA describes a paradigm where those features don't exist,
             | and so the error checking is not important. That's a truly
             | safe language. It's also hypothetical at this point, IMHO.
        
         | chrisseaton wrote:
         | You can write exclusively functional code in pretty much any
         | language can't you?
        
           | spion wrote:
           | Go is probably one popular exception.
        
             | dottedmag wrote:
             | You still can if you wish to. First-class functions are
             | there.
        
               | spion wrote:
               | I wish that were true. Unfortunately, functional
               | composition breaks down when functions have multiple
               | return values, as is the case for everything that returns
               | an `err, res` pair. So even with generics added, Go is
               | still hostile to functional programming.
               | 
               | If Go gets a Result<T> generic type similar to the one in
               | Rust to replace (err, res) that would work. That seems
               | highly unlikely, however. The node.js community went
               | through a similar migration from (err, res) callbacks to
               | promises and it was quite painful, I think its highly
               | unlikely this will happen in Go.
        
               | dottedmag wrote:
               | (res, err) is Either monad, isn't it?
        
               | brabel wrote:
               | It used to be impossible to do anything remotely like FP
               | in Go before generics, but now I believe it's indeed
               | quite possible.
        
               | chrisseaton wrote:
               | But everything you can do with generics you can do
               | manually by copying and pasting code?
        
               | brabel wrote:
               | Oh that's true. But you're a terrible masochist if you
               | consider that an option.
        
               | spion wrote:
               | Or lets look at persistent data structures, a staple of
               | functional programming:
               | 
               | https://github.com/tobgu/peds
               | 
               | Notice how you'd need to generate the DS for every type
               | you'd like to use it with, which is not the case with
               | built in mutable maps and slices.
               | 
               | To make them type-safe, you need to generate them for
               | every type you use. While this is technically possible,
               | it does make the language quite hostile towards
               | functional programming. With generics, this is rectified
               | but the problem with non-composable multi-return-value
               | functions still remains
        
               | spion wrote:
               | Lets take `map` for example. Before generics, you would
               | have to reimplement map for every type combination. Each
               | implementation would be done with a for loop. Now, while
               | I'm willing to look over having one `map` implementation
               | being done in imperative code and then everything else
               | using that, I'm not exactly comfortable calling
               | reimplementing map with imperative code for every type
               | combination functional programming.
        
           | nuclearnice1 wrote:
           | Reminds of
           | 
           | https://en.m.wikipedia.org/wiki/Greenspun%27s_tenth_rule
           | 
           | > Any sufficiently complicated C or Fortran program contains
           | an ad hoc, informally-specified, bug-ridden, slow
           | implementation of half of Common Lisp.
        
         | ramesh31 wrote:
         | You don't need any libraries to write functional JS. Modern
         | React development is almost entirely purely functional.
        
         | dmitriid wrote:
         | Javascript is already functional enough without these
         | libraries. Rambda et al make simple code unnecessarily complex
         | or verbose, and complex code unreadable
        
       | skohan wrote:
       | Imo functional programming is one of those things that makes
       | sense from a theoretical perspective, but comes with compromises
       | when it comes to reality.
       | 
       | The thing about functional programming is that the confidence you
       | get from immutability comes at the cost of increased memory usage
       | thanks to data duplication. It's probably going to create a
       | ceiling in terms of the absolute performance which can be
       | reached.
       | 
       | There are just other ways to solve the problems like NPE's and
       | memory safety, like ADT's and ownership rules, which don't come
       | at the same costs as FP.
        
         | colonwqbang wrote:
         | Why do you think that functional programming results in data
         | duplication? I would think it's rather the opposite.
         | 
         | With strong immutability like in Haskell, you can share values
         | even between threads and can avoid defensive copying. Two
         | versions of the same immutable tree-like data structure can
         | also share part of their representation in memory.
         | 
         | (Haskell has other problems causing increased memory usage, but
         | not related to data duplication in my mind)
        
           | Widdershin wrote:
           | Not the poster you're responding to but I think they're
           | referring to the current need to allocate more memory when
           | updating immutable data structures.
           | 
           | Not that there aren't ways to represent mutability in
           | Haskell, just that the de facto use of immutability causes
           | excess allocation.
        
             | colonwqbang wrote:
             | Efficient functional programming often uses tree-like data
             | structures. These can be immutable but still avoid
             | duplication.
             | 
             | Consider if you "duplicate" a Data.Sequence Seq (finger
             | tree) for modification. You're not actually copying the
             | whole structure, you are creating a new root node and re-
             | using as much as possible of the common structure.
             | 
             | The end result is that a bit more memory is used in the
             | simplest case, but not due to duplication I think.
             | 
             | The benefit is that a thread can make a modified value at
             | cheaper cost without affecting another thread that is still
             | using the original value. I also think it's easier for the
             | programmer to understand the code.
        
               | AnimalMuppet wrote:
               | That's duplicating _part_ of the structure. That uses
               | more memory than just modifying a value in-place, but
               | less than duplicating the whole tree.
        
               | skohan wrote:
               | Won't this still result in a lot of fragmentation? I.e.
               | won't you have disjoint allocations for those new
               | branches of the tree? Sounds pretty cache-unfriendly.
        
               | hither_shores wrote:
               | In a strict language or with poorly optimized lazy code,
               | yes. If you can get good stream fusion, not really. If
               | your code fuses _really_ well (common for lists, harder
               | elsewhere) the whole thing will happen on the stack.
        
           | bmj wrote:
           | _Why do you think that functional programming results in data
           | duplication? I would think it 's rather the opposite._
           | 
           | I suspect it has something to do with the perceptions around
           | always returning a new thing from a function rather than the
           | mutated input to the function. For example, if you need to
           | mutate the property of an object based on other inputs, the
           | perception is you would clone that object, modify the
           | property appropriately, and then return the cloned object.
           | 
           | [Edit: formatting]
        
             | AnimalMuppet wrote:
             | So, ELI5: What do you do instead, where you return a
             | modified object, but still have immutability? Or do you
             | avoid the problem by not trying to do that?
        
               | hither_shores wrote:
               | In most situations, you use persistent data structures
               | where you only have to copy the modified leaves.
               | 
               | If you really need your type to be backed by a contiguous
               | block of memory, you batch updates (stencils, SIMD, etc.)
        
               | AnimalMuppet wrote:
               | But if you modify the leaf, don't you also have to modify
               | the branch node that points to the leaf, so that it
               | points to the new one? And every node from there to the
               | root?
        
               | hither_shores wrote:
               | Yes, you (or rather, core library developers) need to
               | pick a data structure appropriate to your access
               | patterns: linked lists for iteration, search trees for
               | concatenation, finger trees for random access, and so on.
               | But you should be doing this anyway for clarity, even if
               | you face no performance constraints.
        
         | louthy wrote:
         | If the first thing you talk about is performance and not
         | quality and maintainability, then you're already missing the
         | point. Most software just isn't in some super high-perf
         | environment - what matters is fewer bugs, easier
         | maintainability, better communication with other engineers
         | (through declarative code).
         | 
         | The code we work on in the 2020s is much, much more complex
         | than code written 20 years ago. We need better primitives to
         | help our weak and feeble brains deal with this complexity. FP
         | (particularly pure FP) gives us that. It isn't a panacea, but
         | it's a major step in the right direction.
        
           | skohan wrote:
           | I just disagree that performance isn't a concern in almost
           | every context. There's a hierarchy of concerns, to be sure,
           | and if you haven't written reliable code which solves the
           | problem yet you shouldn't be worried about performance, but
           | if your PL itself imposes a performance tax, that's something
           | which has to be paid every time your program gets executed,
           | by every user.
           | 
           | As programmers, our job is to not to play with abstractions,
           | it's to move electrons and make hardware do things. We can't
           | afford to abstract away the complexity of the hardware
           | completely. Indeed the trends in PL popularity of the past 20
           | years have been to move back closer to the hardware, and away
           | from highly abstracted environments, like scripting languages
           | and JVM.
        
             | tluyben2 wrote:
             | But Python/Ruby (and JS? Not sure how far they are with
             | optimising that or what the comparison would be) are very
             | slow compared to Haskell. So people are paying that price
             | all the time without getting any benefits that Haskell
             | (etc) can over next to it. I agree with the GP; performance
             | is really not very interesting for most projects and most
             | (Py/JS are the top dev languages by far I think)
             | programmers/companies are agreeing with that by using low
             | performance environments that make them productive. So
             | productivity seems to win out.
             | 
             | For sake of the environment and hardware upgrades, I think
             | we definitely should make an effort and we can see that
             | improvements in compilers and PL theory _do_ help with this
             | when the goal is practical programming languages using
             | these techniques; Rust does, Haskell was meant as academic
             | language for a long time.
             | 
             | I think robustness/security should go first anyway as
             | hierarchy of concerns; that's where things are really
             | breaking now.
        
               | skohan wrote:
               | Python and JS are top programming languages for very
               | specific reasons. Python because:
               | 
               | 1. It has a low barrier of entry for non-programmers,
               | which makes it suited for applications like data science
               | and ML.
               | 
               | 2. There is vast library support for math and science,
               | which makes it basically the only choice for those
               | domains.
               | 
               | But python is basically used as an API for highly
               | optimized C libraries since any kind of a hot loop in
               | python is basically an anti-pattern unless you own stock
               | in energy companies or hate getting results quickly.
               | 
               | JS has its place because because until very recently it
               | had a monopoly on web front end development, which is one
               | of the largest programming domains.
               | 
               | So for both of those examples, it's the use-case
               | determining the PL, not the programmer.
        
           | rileymat2 wrote:
           | Can you give some examples of increased code complexity over
           | the last 20 years? I am blanking on that.
           | 
           | I have noticed a lot more ops complexity and additional
           | library usage, but not complexity in the code I am
           | responsible for.
        
         | yobbo wrote:
         | The extent to which immutability leads to duplication seems a
         | matter of implementation rather than a principle.
         | 
         | The compiler/runtime could optimize such that memory is reused,
         | as long as all other laws are obeyed.
        
           | UncleMeat wrote:
           | To some degree. But it really is the case that a persistent
           | functional data structure is going to have a slower insert
           | operation than a traditional mutable set. There's no getting
           | around that.
        
             | savingsPossible wrote:
             | https://hackage.haskell.org/package/containers-0.6.5.1/docs
             | /...
             | 
             | log(n) slowdown to add in the end
             | 
             | but the cost to add in the middle is cheaper then the
             | trivial array (see insertAt)
        
               | UncleMeat wrote:
               | The asymptotic behavior is not the entire story. Because
               | persistent data structures almost necessarily need to
               | have their data allocated non-contiguously they have
               | terrible cache performance and prefetching/speculation
               | behavior in comparison to data structures that take
               | advantage of contiguous memory locations.
               | 
               | I also mentioned sets, not lists.
        
         | narrator wrote:
         | The other problem with functional programming is it's harder to
         | look at code and figure out the time complexity. At least with
         | non-functional languages I can easily figure out why there are
         | performance problems with it. Stuff like lazy evaluation may
         | seem cool, but it's not when you have to figure out why
         | something's slow.
        
           | brmgb wrote:
           | That's an Haskell issue not a functional programming issue.
           | Haskell is pretty much the only functional programming
           | language which is lazy by default. It's the sole one for the
           | reason you give. Every other ones are eager by default and
           | you can opt in to lazy evaluation when needed.
        
           | tasuki wrote:
           | This is lazy vs strict, not functional vs whatever. I'm a fan
           | of functional programming, not so much a fan of lazy
           | evaluation. Look at PureScript or Idris perhaps?
        
         | ParetoOptimal wrote:
         | > Imo functional programming is one of those things that makes
         | sense from a theoretical perspective, but comes with
         | compromises when it comes to reality.
         | 
         | Ironically whay you say is true in theory, but not true in the
         | real world.
         | 
         | Source: real world Senior Haskell programmer
        
         | sesm wrote:
         | Duplication problem is solved by immutable data structures with
         | structural sharing. They are part of Clojure standard library
         | and exist in some other languages.
        
         | simion314 wrote:
         | From my experience if you are not dogmatic/extremist about it
         | you can gain a lot, so I try to do things in a functional way
         | in my non functional languages.
        
           | skohan wrote:
           | Yeah I totally agree. I think writing code which is
           | "functional where possible" is super powerful and offers a
           | ton of advantages. Trying to cover that last 20% of cases
           | where you have to bend over backwards to create a performant
           | functional solution, to solve a problem which is trivial with
           | a little bit of mutability, doesn't make sense.
        
         | brabel wrote:
         | This article tries to push FP as a solution to NPE??? What
         | the?! NPEs are a problem due to dodgy type systems... it's a
         | type sytem problem, not a language paradigm one... i.e. it has
         | no relation to whether a language is functional or not.
         | 
         | For example, Dart 2 is null-safe! No one in their right mind
         | would claim Dart is a FP language. Even Java can be null-safe
         | if you use some javac plugin like the Checker Framework.
         | 
         | Also, a language can totally be functional and yet suffer from
         | NPE, like Clojure or Common Lisp, but I suppose the author may
         | be forgiven here because they are talking only about "purely
         | functional programming languages"... (they didn't mention
         | "statically typed" though, but that's clearly implied in the
         | content)...
         | 
         | I believe the author is inadvertently pushing for two things
         | that are pretty much unrelated to FP, even if they are a
         | requirement in most purely-functional languages:
         | 
         | * immutability
         | 
         | * strong, static type systems
         | 
         | I would mostly agree with both (except that local mutability is
         | fine and desired, as anyone trying to implement a proper
         | quicksort will tell you - also, see the Roc language[1], which
         | is purely functional but uses local mutability), but I write my
         | Java/Kotlin/Dart just like that and I wouldn't consider that
         | code purely functional. I don't think whether the code is
         | purely functional actually matters much at all compared to
         | these 2 properties, which can be used in any language
         | regardless of their main paradigm.
         | 
         | [1] https://www.roc-lang.org/
        
         | pyrale wrote:
         | Data duplication is coming to all minstream languages these
         | days, whether it's a community best practice or a requirement
         | for some libraries (e.g. streams in Java).
         | 
         | I'm not saying that in-place operations don't have their uses,
         | but to me, these use-cases look more and more like niche cases,
         | as opposed to being the default choice in the past. That is
         | well-reflected in new languages like rust, where a new name is
         | by default immutable, and must specifically be flagged as
         | mutable in order to be variable.
         | 
         | It means that the benefits of immutability and the performance
         | tradeoffs people are willing to take are evolving. I would
         | assume larger codebases and faster hardware means performance
         | is less valuable, and clarity comes at a premium.
         | 
         | I do agree with you that NPEs and memory safety are unrelated
         | problems, though.
        
           | skohan wrote:
           | Data duplication is a tool which can be used to avoid large
           | classes of bugs, but there's no question it comes at a cost
           | to performance.
           | 
           | If anything, I would say explicit mutability allows us to
           | decrease data duplication. By being explicit about what's
           | mutable and what's not we don't have to resort to holding
           | "safe copies" to ensure shared memory is not being mutated
           | unexpectedly.
        
         | dottedmag wrote:
         | Immutability does not even have to be bound to functional
         | programming. One can use persistent (= immutable from the
         | user's perspective) data structures, like immutable.js and get
         | most of the benefits.
         | 
         | Moreover, persistent data structures can be optimized well (see
         | Clojure), so that the performance issues may be relegated to
         | the inner loops, as usual, and the rest of the program may use
         | safe-for-sharing data structures.
        
         | ajuc wrote:
         | My problem with functional programming is refactoring. If you
         | don't have side effects when you want to do 2 things deep into
         | the call tree to something that is in completely different call
         | tree branch - you have to extract it all the way up to the
         | common parent and pass it through all the intermediates just so
         | that one function deep there can access it.
         | 
         | It's incredibly frustrating when you work in a functional
         | language, and yet it's the main benefit (no side effects).
         | 
         | I'd like to have a language that is imperative when written and
         | functional when read :)
        
           | iterati wrote:
           | I've handled this (in Clojure) either by passing a context
           | map through the entire stack or binding some context atom at
           | the top and using it lower down the stack. The binding is
           | less obvious at first glance, so I prefer to pass the
           | context, but both make testing quite easy and reduce the need
           | for heavy refactoring.
        
           | mejutoco wrote:
           | > I'd like to have a language that is imperative when written
           | and functional when read :)
           | 
           | Depending on which language Monads give you exactly that
           | bridge between imperative and functional.
           | 
           | In your example, you can always choose to have side effects
           | in that deep call.
           | 
           | Personally, I like a type-driven approach. Then, I do not
           | care so much where functions are (they will be grouped
           | logically, but could be anywhere), as long as the type in and
           | the type out matches.
        
           | beders wrote:
           | I like that aspect because it gives you a hint that your call
           | tree is not how it should be. Lifting out side-effects and
           | passing the data back in is one approach, but not the only
           | one.
           | 
           | Turning a deep call tree into a flat pipeline is a popular
           | other approach and often leads to less complexity, better
           | compos-ability.
        
             | ajuc wrote:
             | I like it when I'm done. I very much dislike it when I'm
             | not sure yet what my code should do so it changes
             | constantly. And that's most of the time in gamedev for
             | example.
        
         | Widdershin wrote:
         | This is actually an area where there's room to improve FP
         | languages.
         | 
         | If you track ownership in functional languages, you can
         | statically determine if a value is used more than once.
         | 
         | If it's only used once, you can apply any updates to that value
         | in place without allocating more memory.
         | 
         | This gives the performance benefits of mutability with the
         | safety benefits of immutability, in some common cases.
         | 
         | The main trick is adjusting memory layouts accordingly. You can
         | keep it simple by only applying this optimisation for functions
         | of A -> A, or if you're replacing it with a different type you
         | can analyze the transformations applied to a value and pre-
         | emptively expand the memory layout.
         | 
         | If a value is likely to be used only once, but might be used
         | multiple times, you can also apply the same approach at runtime
         | by reference counting and updating inplace when there's only a
         | single reference (for functions of A -> A at least).
         | 
         | I believe the Roc folks are aiming to have aspects of this
         | functionality, and I also believe there's similar stuff
         | becoming available in Haskell under the guise of linear types.
         | 
         | Finally, if you really need a shared mutable value, that can be
         | achieved with mechanisms like the State type in Haskell.
         | 
         | In short, the pieces are there to create a functional
         | programming language that doesn't introduce needless memory
         | usage overhead, but I don't think anyone has put all the pieces
         | together in a convenient and accessible way yet.
        
           | bcrosby95 wrote:
           | I get that not everyone does, but a large part of why I use
           | Clojure is because it makes a whole class of concurrent
           | designs easier. In particular, sharing that immutable data
           | across multiple threads.
           | 
           | As a simplified example: one thread modifies the data, and
           | another thread writes a snapshot of the data.
           | 
           | In the programs I write, it would pretty much never benefit
           | from this optimization.
        
       | jmartin2683 wrote:
       | At the end of the day, functional programming isn't fun (to me).
       | None of the qualities touched on in the article are unique to it,
       | either. So... I'll keep not doing it.
        
       | adamwk wrote:
       | This article reads like something from 2010. Other than Go, new
       | languages no longer have null references and you don't need a
       | purely functional language to do so. I kept waiting for more
       | examples for why we need FP but the article yada-yada-yada'd the
       | rest
       | 
       | I think FP came and showed everyone how to design expressive
       | types, how to define flatMap on more than arrays, and that's it.
       | It turns out you don't need Haskell, you can incorporate those
       | features in imperative languages like Rust and Swift.
        
         | cheriot wrote:
         | The "blue collar" approach to functional programming is a
         | fruitful one.
         | 
         | Written about Scala, but applies to any language:
         | https://www.lihaoyi.com/post/StrategicScalaStylePracticalTyp...
         | 
         | In doing this, program organization starts to change in
         | interesting ways. Modeling error states as regular data cleans
         | up a lot of complexity.
        
         | siknad wrote:
         | > I kept waiting for more examples for why we need FP
         | 
         | Dependent types, allow a lot more type safety (ex. shader
         | program type parametrized by description of its uniform
         | variables, getting rid of `INVALID_OPERATION` on wrong uniform
         | location/type).
         | 
         | > you can incorporate those features in imperative languages
         | like Rust and Swift
         | 
         | Incorporating dependent types into imperative languages with
         | unrestricted effects is hard (impossible?).
        
       | deviantbit wrote:
       | I believe functional programming is interesting, and fun. But it
       | is not going to replace the world. My background has spanned from
       | working on AAA games, to simulations for the DoE, to owning my
       | own business developing embedded products, and graduate school
       | (yes, I went back as a gray haired, and did that late). I fell in
       | love with Lisp many years ago on a TI Explorer.
       | 
       | Functional languages are inherently difficult to develop
       | applications that require state to change in non-deterministic
       | ways. In fact, I challenge you to develop a first-person shooter
       | in Haskell (Have fun).
       | 
       | There are many types of applications where functional languages
       | are perfect, but there are more that it would be a disaster. To
       | make broad sweeping claims, such as this article, just encourages
       | unnecessary discourse, and shows the ignorance of the author, and
       | his limited understanding of the domain of problems that
       | functional languages will benefit from, and the larger domain of
       | problems that will not benefit from them.
       | 
       | As an employer, I don't hire people for their functional
       | programming skills. If they have them, the better, but we have
       | over 3 millions lines of code in C++, and close to a million in
       | Java. We are not starting over, and new projects will leverage
       | existing code.
        
         | ParetoOptimal wrote:
         | > In fact, I challenge you to develop a first-person shooter in
         | Haskell (Have fun).
         | 
         | https://hackage.haskell.org/package/frag
         | 
         | > There are many types of applications where functional
         | languages are perfect, but there are more that it would be a
         | disaster.
         | 
         | Can you give an example or two of an application in a
         | functional language would be a disaster?
         | 
         | > To make broad sweeping claims, such as this article, just
         | encourages unnecessary discourse, and shows the ignorance of
         | the author, and his limited understanding
         | 
         | No, it's an opposing viewpoint to the popular "right tool for
         | the job" and "take the best from functional, best from
         | imperative, and smash them together".
         | 
         | See "The curse of the excluded middle by Erik Meijer".
         | 
         | > As an employer, I don't hire people for their functional
         | programming skills.
         | 
         | I certainly choose my jobs with language and ecosystem in mind.
        
           | deviantbit wrote:
           | frag-1.1.2 failed during the building phase. The exception
           | was: ExitFailure 1
           | 
           | Go fix that for us.
           | 
           | ``Can you give an example or two of an application in a
           | functional language would be a disaster?``
           | 
           | Sure, code that tests its self. Not happening. Which means,
           | most embedded applications where fault tolerance is a must.
           | If you don't know what caused the error, well, lets here your
           | ignorant response. Explain how you trap those problems in a
           | functional language, and do it as simple as you can, say in
           | C, or Pascal.
           | 
           | ``opposing viewpoint to the popular "right tool for the
           | job"``
           | 
           | So you advocate a hammer for screw. Got it. You're exactly
           | the kinda of person I won't hire. You're so bent on proving
           | you're right, you ignore the right tool for the right job.
        
         | thrown_22 wrote:
         | >Functional languages are inherently difficult to develop
         | applications that require state to change in non-deterministic
         | ways. In fact, I challenge you to develop a first-person
         | shooter in Haskell (Have fun).
         | 
         | Don't know about Haskell but it would be very fun to do it in
         | Lisp.
         | 
         | Performance sold separately.
        
           | deviantbit wrote:
           | Then try it.
        
           | mikedelago wrote:
           | Common lisp has a "pretty OK" story for calling C code
           | whenever some speed is needed [0,1]. In my opinion, they
           | suffer from some of the documentation/quick start problems
           | that common lisp has, but they're otherwise usable.
           | 
           | Some of Naughty Dog's late 90's/early 2000's games (Jak and
           | Daxter, Jak II) were written in a lisp called GOAL, Game
           | Oriented Assembly Lisp [2]
           | 
           | [0] https://github.com/rpav/cl-autowrap [1]
           | https://github.com/cffi/cffi#cffic2ffi [2]
           | https://en.wikipedia.org/wiki/Game_Oriented_Assembly_Lisp
        
       | zelphirkalt wrote:
       | Functional programming (FP) is great, no question. However, we
       | who know about FP should not forget, that there are other
       | worthwhile paradigms out there. Just think of Prolog-like things
       | or programming in relations (for example minikanren) for example.
       | The good thing is though, that mostly-FP/FP languages can be used
       | to make DSLs, which in turn enable such kinds of paradigms, so
       | that we are not limited to FP itself.
        
       | scabel wrote:
       | As someone who uses Scala on a daily basis, I might be biased.
       | However, functional programming is truly the future because of
       | its mathematical guarantees. Pure functions give us referential
       | transparency i.e. we can substitute a piece in a large layer and
       | still expect the entire thing to work as long as it has no side-
       | effects. This has so much relevance to software maintainability.
       | The downside is that, to take advantage of this mathematical
       | guarantee the code has to be pure through and through. A single
       | side-effect can spoil everything. Immutability, is another aspect
       | of pure functions i.e. a pure function wouldn't mutate its
       | inputs.
        
       | rcgorton wrote:
        
       | antihipocrat wrote:
       | This article would have benefited a lot by including a few
       | examples of functional expressions and how they compare with
       | other paradigms.
        
       | waselighis wrote:
       | I like the philosophy of Rust (and some other languages) of "safe
       | by default". Rust variables are immutable by default, but can be
       | made mutable using "let mut". Rust is memory safe by default, but
       | can be made unsafe using the _drumroll_ "unsafe" keyword. As for
       | null references, other languages still have them but enforce
       | "strict null checking", such as Kotlin and TypeScript. They force
       | you to verify a reference is not null before using it, but
       | without the verbosity of an Optional or Maybe type.
       | 
       | Functional programming is great, but it's far from optimal in
       | many situations. For example, implement a self-balancing binary
       | search tree using a common imperative language with mutability.
       | Then try implementing it again but using pure functional
       | programming. Certainly very possible but also requires a lot more
       | work when you're not allowed mutability.
        
         | exyi wrote:
         | Actually, implementing AVL tree in purely functional way is
         | easy, I'd say it's easier than doing it in the mutable in-place
         | way. It will allocate more, but will have the optimal
         | O(something) complexity.
         | 
         | Many other algorithms are much harder, though, especially those
         | requiring fast array indexing (graph search, hash tables, ...)
        
         | maweki wrote:
         | > but without the verbosity of an Optional or Maybe type
         | 
         | Without the safety of having that encoded in the type system.
        
           | ackfoobar wrote:
           | `T` and `T?` being different types is encoding in the type
           | system.
           | 
           | It is a _different_ encoding, though.
        
           | wollef wrote:
           | No, Kotlin/TS do the same thing with different syntax.
           | 
           | See https://kotlinlang.org/docs/null-safety.html#safe-calls
           | (TS is basically the same)
        
         | douglasisshiny wrote:
         | You're allowed mutability, even in languages like Haskell.
        
         | poorlyknit wrote:
         | A note regarding your binary tree example:
         | 
         | I'd argue that FP is actually great for working with tree-like
         | data structures. For example, the common implementations for
         | sets and maps are based on balanced trees. IME it's graph-like
         | or array-based stuff where the paradigm struggles.
        
           | savingsPossible wrote:
           | Pay a log(n) slowdown and you have arrays in all their glory
           | (and more!)
           | 
           | https://hackage.haskell.org/package/containers-0.6.5.1/docs/.
           | ..
        
             | poorlyknit wrote:
             | If we really need to we can just actually use arrays tho:
             | 
             | https://hackage.haskell.org/package/primitive-0.7.4.0/docs/
             | D...
             | 
             | That's what I meant: You can mostly use tree-like log(n)
             | data structures rather nicely but you'll have to isolate
             | your mutating code into stuff like PrimMonad, see:
             | 
             | https://hackage.haskell.org/package/primitive-0.7.4.0/docs/
             | D...
             | 
             | I like Haskell because it lets me write clean interfaces at
             | a high level but fall back to byte-level stuff when needed.
        
             | snovv_crash wrote:
             | It isn't just log(n), it's also L1 vs L3 access times and
             | an extra level of pointer chasing.
        
           | xdavidliu wrote:
           | great for reading trees, but not for cases where nodes need
           | to be added or removed. There's a "zipper tree" structure but
           | it's kind of a pain to implement:
           | 
           | https://github.com/xdavidliu/fun-
           | problems/blob/main/zipper-t...
        
           | Nihilartikel wrote:
           | I don't disagree that manipulating deep arrays and graph data
           | can be harder in an immutable functional language, at least
           | with default commands.. however many fp languages have
           | powerful and mature libraries that let you work with deep
           | data structures very gracefully and correctly. Clojure has
           | Specter, Haskell has lenses and stuff.
           | 
           | For me, the FP dream ( and we aren't quite there yet) is that
           | your program is an airtight declaration of the desired
           | functionality, and then we get out of the way and let the
           | compilers and profiling runtimes optimize away.
           | 
           | How cool would it be if the runtime stats could let the jit
           | either unroll and inline a function if it's called on small
           | arrays from network buffers, or push it to gpu if it's
           | frequently called on huge in ram buffers? Not there yet, but
           | as the tower of complex tooling needed to work in a compute
           | parallel world keeps growing, we are going to be relying more
           | and more on the compiler/runtime to optimally use that power.
        
             | poorlyknit wrote:
             | See my cousin comment; I just wanted to make the point that
             | working with tree-like data structures in FP feels rather
             | natural.
        
               | anta40 wrote:
               | Tree data structures are pretty prevalent in compiler.
               | Like that, perhaps?
        
             | thethirdone wrote:
             | > For me, the FP dream ( and we aren't quite there yet) is
             | that your program is an airtight declaration of the desired
             | functionality, and then we get out of the way and let the
             | compilers and profiling runtimes optimize away.
             | 
             | I would guess we are at least 100 years away from this.
             | Current imperative compilers miss obvious optimizations and
             | FP typically needs many layers of optimization before it
             | would be efficient. Any one layer failing to make progress
             | would result in a very slow program.
             | 
             | Currently FP compilers generally don't even use successors
             | for natural numbers because it would be slow. Typical
             | programs use other data structures more complex than
             | numbers that would need to be optimized into a mutable
             | structure. If FP compilers can't do it for integers, they
             | definitely can't for FP programs as a whole.
        
         | misja111 wrote:
         | A better example would be to implement an efficient HashMap in
         | pure FP. This is simply impossible unless you fall back to some
         | tree based solution which is less efficient.
         | 
         | Interested why this is downvoted .. Hashmaps can have O(1) time
         | complexity for lookups and inserts in the imperative world, in
         | pure FP either lookup or insert can be no better than O(log(n))
        
           | hither_shores wrote:
           | > in pure FP either lookup or insert can be no better than
           | O(log(n))
           | 
           | For single operations, yes. But what we really care about is
           | usually the amortized performance over many operations, which
           | can still be constant time.
        
       | pie_flavor wrote:
       | In a world where your two options are object-oriented and
       | functional, functional is naturally superior. But just because
       | the last twenty years have had all the oxygen sucked up by
       | object-oriented does not mean there are no alternatives to it
       | other than functional. Like all good IEEE articles, it's seven
       | years out of date: Rust is one of the most maintainable languages
       | around, simply by embracing good old fashioned procedural
       | programming. And the _only_ practical example they give, null
       | pointers, have been a solved problem outside FP for an even
       | longer time.
        
       | z9znz wrote:
       | At the last two places I worked, I gradually led my teams from
       | traditional OOP Ruby or Python behaviors to at least partially
       | functional (if you'll pardon the pun).
       | 
       | The immediate value I was able to demonstrate was in testing.
       | Three basic (not too scary) principles can get you a long way:
       | 
       | 1. push mutations and side effects as far toward the edges as
       | possible (rather than embedded in every method/procedure)
       | 
       | 2. strive for single responsibility functions
       | 
       | 3. prefer simple built-in data structures (primarily hashes) over
       | custom objects... at least as much as possible in the inner
       | layers of the system
       | 
       | If these steps are taken, then tests become so much simpler. Most
       | mocking and stubbing needs evaporate, and core logic can be well
       | tested without having to touch the database, the api server, etc.
       | Many of the factories and fixtures go away or at least become
       | much simpler. You get to construct the minimal data structure
       | necessary to feed to a test without caring about all the stuff
       | that you normally would have to populate to satisfy your ORM
       | rules (which should be tested in their own specific tests).
       | 
       | Once devs see this, they often warm up quickly to functional
       | programming. Conversely, the quickest way to get an OOPist to
       | double down and reject any FP is to build complex chains of
       | collection operations which build and pass anonymous functions
       | everywhere. Those things can be done where appropriate, but they
       | don't provide as much early bang for the buck... and they likely
       | prevent FP from getting a foot in the door to that team.
       | 
       | The only real downside is that naming things is hard, and good
       | single responsibility practices result in a lot more functions
       | that need good names.
        
         | blep_ wrote:
         | > prefer simple built-in data structures (primarily hashes)
         | over custom objects
         | 
         | I've found this is actually one of my biggest problems with
         | functional code as currently written: people seem afraid to
         | just declare a struct/record, in lots of cases where it's
         | obviously the right thing.
         | 
         | If everything is a hash, you've just made all arguments
         | optional and now you've invented a bad type system inside your
         | good type system.
         | 
         | If everything is a tuple (more common in my experience, from
         | reading Haskell), now you know (int, int) is actually a pair of
         | ints, but you've thrown away variable names and nominal typing:
         | is it a 2D vector, a pair of indices into an array, or
         | something else entirely?
         | 
         | Defining custom types _is_ the elegant solution to this: you
         | have `struct range { start: int, end: int }` and now your
         | functions can take a range and everything is great.
        
           | z9znz wrote:
           | It's not about being afraid to define a struct/record (rigid
           | type). It's about being afraid of being stuck with something
           | that doesn't meet your needs later or elsewhere, if only by a
           | little bit.
           | 
           | That Range type is great until you have cases where you want
           | variations on a Range, such as a MeasuredRange (same start
           | and end, but with a new field called step_cost). Original
           | functions which take a Range can't cope with this new
           | completely different struct called MeasuredRange. So now we
           | have to change them all to accept Range or MeasuredRange, or
           | we need some kind of type heirarchy to relate them in
           | appropriate ways.
           | 
           | The alternative is to accept the runtime risk of receiving a
           | thing which doesn't have the start and end that you needed.
           | Or of course if it were a very important piece of logic where
           | failure was not an option, you just make your
           | do_rangy_thing() require explicit start and end parameters.
           | Then it's up to the caller to call
           | do_rangy_thing(my_range[:start], my_range[:end]). Ultimately
           | that just moves your failure risk up one level, though.
           | 
           | Likewise, you can use hash destructuring in Clojure like
           | (do_rangy_thing [{:keys [start end]}] ... or pattern matching
           | in Elixir like def do_rangy_thing(%{start: s, end: e}) ...,
           | both of which will blow up at runtime if the hash passed in
           | doesn't have the required keys.
           | 
           | Many people accept the runtime risk because it greatly
           | simplifies code at the cost of runtime safety. The worst
           | thing, in my view, is when languages try to bolt on some kind
           | of type strictness later and end up solving the Range vs
           | MeasuredRange problem by listing all possible accepted types
           | or just throwing up their hands and saying Any.
           | 
           | I don't know Haskell, but from what I've heard about it I
           | find it surprising that (int, int) is as common as you say. I
           | thought they were very much about detailed specific types,
           | with the theory "if it compiles, it works". My guess is that
           | generic tuples are just an indication that some of the
           | participants didn't want to deal with the complex type system
           | and have a thousand different narrow case types defined.
        
       | le-mark wrote:
       | It would be helpful if the article started off defining what a
       | functional language is. A lot of languages have functional
       | features but are not "purely" functional. I think most would
       | agree there's a spectrum; dynamic vs static, eager vs lazy,
       | mutable vs immutable.
       | 
       | So what flavor of functional programming one might ask, since
       | javascript is a dynamically typed flavor that is ubiquitous
       | nowadays? The fine article suggests drum roll... Haskell! The
       | author believes a statically typed and lazily evaluated language
       | is what we all should be using. Unlike the various other
       | dynamicaly typed options like small talk or scheme or lisp.
       | Standard ML and Ocaml being statically typed are eagerly
       | evaluated.
       | 
       | Most popular languages have added a lot of functional features in
       | recent years so it's clear the world is moving that way, imo.
        
         | commandlinefan wrote:
         | > A lot of languages have functional features but are not
         | "purely" functional.
         | 
         | That was my first thought. I work mostly in Java because that's
         | what they pay me to do, but I've almost never worked with a
         | Java programmer who could actually write Java code using the OO
         | features that the language is based around. When I see their
         | Scala code... it's mostly var, rarely val, because it's easy to
         | think about.
        
           | wnolens wrote:
           | Whenever I see "interesting" object modeling beyond very
           | basic inheritance, I groan. I've never experienced it being
           | worth the hassle (templates, factories, etc..).
           | 
           | But my code is flush with
           | collection.stream().filter().map().collect() etc. I was
           | initially critical of it in code reviews (coming from C), but
           | have been totally converted.
        
             | feoren wrote:
             | Templates (I assume you mean Generics, if we're talking
             | Java?) aren't worth the hassle, but your code is flush with
             | .filter() and .map()? Which rely entirely on generics to
             | provide any typing support at all? You should learn to
             | embrace generics; they're absolutely critical for the code
             | you just said you write, and more. And they are most
             | certainly not going away.
        
           | feoren wrote:
           | > I've almost never worked with a Java programmer who could
           | actually write Java code using the OO features that the
           | language is based around
           | 
           | I don't understand this. The language is based around
           | primitive, flawed, simplistic OO features, right? Like "class
           | Dog : Animal"? I never write code like that either, because
           | it's _bad practice_. But you 're saying they _can 't_ write
           | code like that? Or that they don't use classes at all? How
           | can you even write any Java that way?
        
             | commandlinefan wrote:
             | > they don't use classes at all
             | 
             | As much as they can avoid it, yes. The only classes I ever
             | see are those that are auto-generated from some JSON or ORM
             | processing tool - everything else is a static function.
        
         | dmitriid wrote:
         | To quote "Stop Writing Dead Programs" [1]: "If what you care
         | about is systems that are highly fault tolerant, you should be
         | using something like Erlang over something like Haskell because
         | the facilities Erlang provides are more likely to give you
         | working programs."
         | 
         | [1] https://www.youtube.com/watch?v=8Ab3ArE8W3s
        
           | throwaway1492 wrote:
           | That quote is absurd because the vast majority of
           | applications on the planet are not written in Erlang and work
           | just fine. Working and fault tolerance are in no way related.
           | Being generous the majority of applications with very high
           | uptime are also not written in Erlang.
        
             | dmitriid wrote:
             | This quote isn't about "vast majority of software".
             | 
             | It's about tools we use and waste our time on.
        
             | throwawaymaths wrote:
             | And also the vast majority of "working" applications have a
             | full devops team, legions of highly paid senior developers,
             | etc. "You" do not.
        
               | throwaway1492 wrote:
               | Ok so we're adding "developer productivity" on to the
               | list. Aside from moving the goal, one does not have faith
               | a lot faith in the knowledge of people making these
               | claims, like where's the proof?
               | 
               | Hint read Joe Armstrong's dissertation.
        
               | fallat wrote:
               | Is this actually true? I feel like the majority that
               | software exists is non-business software simply because
               | there's zero cost...
        
             | feoren wrote:
             | > the vast majority of applications on the planet are not
             | written in Erlang and work just fine
             | 
             | The vast majority of applications on the planet are bug-
             | ridden, fragile, over-budget, under-thought, mark-missing,
             | user-hostile garbage. They most certainly do not "work just
             | fine."
        
       | 60secs wrote:
       | "Kindly let me help you or you will drown said the monkey putting
       | the fish safely up a tree."
       | 
       | -- Alan W. Watts
        
       | wheelerof4te wrote:
       | The programming world peaked with structured and modular styles.
       | Everything else is random noise.
       | 
       | Keep your programs nicely structured and easy to follow. No code
       | "architecture" nonsense, please.
        
       | Ciantic wrote:
       | Lot of the time arguments for Functional Programming seem to
       | describe some form of total programming and avoiding partial
       | functions. Like enforcing null checking or exhaustive matching,
       | avoiding panics etc.
       | 
       | When I was going through Functional Programming classes in
       | Haskell, the teacher tried to separate total programming and
       | functional programming.
       | 
       | For instance Rust programs rarely use function composition
       | compared to Haskell. He didn't consider Rust as very good
       | functional programming language for that very reason. But at the
       | same time Rust has good total programming tools like exhaustive
       | checking, Option, Result etc.
       | 
       | Does anyone else try to separate functional programming and total
       | programming?
        
         | ben7799 wrote:
         | Arguments from academic and mathematicians will/may favor
         | provability.
         | 
         | Pure Functional where everything is function composition have
         | more hope of producing a valid mathematical proof for a block
         | of code. CS/Math will favor this over the aspects that get
         | grouped into total programming, which often don't help
         | provability.
        
         | chriswarbo wrote:
         | Totality can be split into two separate properties:
         | 
         | - All programs are defined for all inputs (exhaustive)
         | 
         | - All programs terminate/coterminate
         | 
         | The former is becoming more common (like your Rust example),
         | but the latter isn't very widespread. For example, most would
         | consider a function like this to be exhaustive, even though it
         | loops forever when both Ints are non-zero:                 foo
         | : (Int, Int) -> Int       foo (0, y) = y       foo (x, y) = foo
         | (y, x)
         | 
         | Proving termination is hard, and often undesirable; e.g. we
         | want servers and operating systems to keep running
         | indefinitely. However, co-termination can be quite easy, e.g.
         | if we define a Delay (co)datatype:                 data Delay t
         | where         Now   : t -> Delay t         Later : Delay t ->
         | Delay t
         | 
         | Wrapping recursive calls in 'Later' allows infinite processes,
         | at the cost of some boilerplate (Delay is a monad, if you know
         | what that is):                 foo : (Int, Int) -> Delay Int
         | foo (0, y) = Now y       foo (x, y) = Later (foo (y, x))
        
       | DeathArrow wrote:
       | Functional or procedural or whatever, it doesn't matter much for
       | me as long as the paradigm is not OOP.
       | 
       | I strongly believe that data should live separate from the
       | actions performed on it. I also believe that inheritance is a bad
       | thing as there are other, better means to achieve polymorphism.
       | 
       | I do believe in a data oriented programming where we waste as
       | little CPU cycles as possible and introduce as little
       | abstractions as possible.
        
         | GaryPalmer wrote:
         | I am working on a java game where I threw all OOP knowledge out
         | the window and use C-style pure data-classes with public fields
         | and no methods.
         | 
         | It's pretty refreshing to work this way compared to the design
         | pattern madness you see in enterprise applications - but I
         | guess it's not very safe if multiple people are working on this
         | and some don't know what they are doing.
         | 
         | There has to be some middle ground, I think people have been
         | going way overboard with OOP in the last two decades.
        
           | DeathArrow wrote:
           | Me too, I use .NET but try to use in the least OOP way as
           | possible. Of course, for interviews I can recite all things
           | about OOP, countless patterns and their "advantages", SOLID,
           | DDD done OOP way and most of the Uncle Bob "wise" teachings.
        
       | caporaltito wrote:
       | No.
        
       | JackFr wrote:
       | > The biggest problem with this hybrid approach is that it still
       | allows developers to ignore the functional aspects of the
       | language. Had we left GOTO as an option 50 years ago, we might
       | still be struggling with spaghetti code today.
       | 
       | This is demonstrably false, as C has always had a goto and its
       | use by custom and in practice is greatly circumscribed.
        
       | KingOfCoders wrote:
       | I wish this all was based on some kind of science.
        
       | Existenceblinks wrote:
       | Just don't include non-sense jargon in languages we are good to
       | go. Elixir | Elm is dead simple FP you barely care about "FP",
       | it's just module and functions. No monad, typeclass, lens(I still
       | don't know this one, what it is).
        
       | ww520 wrote:
       | Functional programming helps because the lack of mechanisms in
       | languages to manage state mutability. FP brings in the big ban,
       | keeping things immutable, to make state management easier. When
       | new languages like Rust that can automatically track state
       | ownership, state management and mutability are much easier. You
       | don't need to enforce immutability all the times, though it still
       | helps. The need for FP's practices is actually lessen.
        
       | AlexanderDhoore wrote:
       | ML language != functional programming. There is more out there
       | than Haskell.
       | 
       | The article doesn't even mention OCaml, the second most popular
       | ML-derived language on Github. Makes me suspect the article is
       | not very well researched.
        
         | cosmic_quanta wrote:
         | While the title doesn't specify this, the article is about
         | _pure_ functional programming. I don 't think OCaml fits this
         | bill exactly.
        
           | xjm wrote:
           | It doesn't fit "pure", but it solves the same problems the
           | article is talking about, as other functional programming
           | languages do.
           | 
           | In fact the article is excluding most functional languages by
           | saying "pure", and then goes on with "Of the top dozen
           | functional-programming languages, Haskell is by far the most
           | popular" under the graph, which is wrong because it's missing
           | "pure", a feature that is _not_ required to solve the
           | problems that are being talked about.
           | 
           | So I agree on the initial point "Makes me suspect the article
           | is not very well researched."
        
       | plgonzalezrx8 wrote:
       | No.
        
       | taeric wrote:
       | I find this an amusing take. I'd more fully accept "declarative
       | should be the future of software." In that, at large, I'd rather
       | larger chunks of the software I am responsible for to be
       | declarations of intent, if at all possible. That said, the rubber
       | still hits the road somewhere, such that the abstraction should
       | be tailored to fit the domain, if you can.
       | 
       | As a fun challenge, look at the definition of pretty much any
       | fractal. It is a mathematical construct that is almost certainly
       | not equivalent to what most "functional programming" environments
       | let you do. Indeed, most definitions are imperative by nature,
       | that I recall, and yet they work remarkably well.
       | 
       | Really, anything from the book Turtle Geometry would have a
       | challenging time in a lot of functional languages. Which is not
       | that most functional languages are bad. Just they don't usually
       | even try to abstract over the graphical. I hate that folks see
       | how well the abstract over functions and assume that is all
       | programming is.
        
         | BoiledCabbage wrote:
         | > Really, anything from the book Turtle Geometry would have a
         | challenging time in a lot of functional languages.
         | 
         | https://github.com/sergv/turtle-geometry
         | 
         | Is an implementation of the book Turtle Geometry in Scheme. A
         | Lisp dialect.
         | 
         | > Which is not that most functional languages are bad. Just
         | they don't usually even try to abstract over the graphical. I
         | hate that folks see how well the abstract over functions and
         | assume that is all programming is.
         | 
         | There is an entire section of SICP dedicated to graphical
         | abstraction using functions and function composition.
        
           | taeric wrote:
           | Yeah, that isn't surprising, in that the book even mentions
           | using LISP. However, this is a touch of a goal post shift
           | with what folks typically mean by modern functional
           | programming. (Which, to be fair, was always far more nebulous
           | than folks admitted.)
           | 
           | Specifically, though, this is my point. The turtle geometry
           | abstraction is very imperative, by nature. It is still
           | declarative, at a high level. But it is not functional.
           | Despite that, it can be implemented in one of the classic
           | functional languages. (Though, lisp's origins are far more
           | imperative than you would think.)
        
       | IceHegel wrote:
       | I have found OOP better for thinking abstractly about complex
       | systems.
        
       | coldacid wrote:
       | The self-righteous attitude of the article is very much
       | offputting. I'd love to have something to wave around at my boss
       | and co-workers to convince them of the usefulness of the FP
       | paradigm (to at least encourage FP-like practices in our heaps
       | and heaps of existing code) but this article is certainly not it.
        
       | ArcMex wrote:
       | All this article has done is reinforce my desire to always
       | consider the best paradigm for my use case.
        
       | nu11ptr wrote:
       | I personally think Rust should be included in this group. It
       | isn't technically a functional language, but it has a "functional
       | flair" with many of the same benefits as functional programming
       | provides, and with some of the features (pattern matching, sum
       | types, etc.). It takes a different approach to mutability, but
       | the net benefit I think is about the same.
        
       | abird198 wrote:
       | I doubt so. Mutation is incredibly powerful. Problem is that we
       | don't understand it.
        
         | exyi wrote:
         | They don't claim that pure FP is the future. Immutable is
         | better default IMHO, make it explicitly mutable if you need it
         | and know what you are doing.
        
       | JoachimS wrote:
       | The article states: "More important, developers need to learn a
       | new way of thinking. At first this will be a burden, because they
       | are not used to it. But with time, this new way of thinking
       | becomes second nature and ends up reducing cognitive overhead
       | compared with the old ways of thinking. The result is a massive
       | gain in efficiency."
       | 
       | In my experience from University CS education and later on in
       | industry, a quite large group of students or engineers,
       | programmers never grasp the functional way of thinking. It don't
       | just take longer time, it doesn't happen. For this reason I'm
       | skeptical that FP will ever be able to replace imperative (and
       | object oriented) programming.
        
       | martin1975 wrote:
       | Hammers ought to be used to solve every problem.
        
       | zzzeek wrote:
       | The first text sums it up:                   It's hard to learn
       | 
       | Which is refreshing to see just stated up front: FP is for smart
       | people who have some motivation to learn something hard, even
       | when there's a whole world of alternatives that are not "hard" to
       | learn. in this writer's case, it appears to be they own a company
       | and they've mandated everything be written in Haskell or
       | PureScript, which will select for employees that are willing /
       | able to do that, etc.
       | 
       | as long as humans are employed to write the code directly, "hard
       | to learn" is a non starter for being the "future".
        
         | ch4s3 wrote:
         | You should give elixir a try. It's easy to learn, the tooling
         | is really good, and the community is super friendly. I've found
         | the mix of immutability and dynamic/structural typing to be
         | great in practice.
        
         | rileyphone wrote:
         | Specifically, FP requires expansive working memory, which is a
         | normally distributed trait across the population. Meanwhile, in
         | OOP one can reason from the perspective of the object and the
         | interfaces it's interacting with, easing the burden on
         | programmers, but there are obviously drawbacks there as well.
        
           | ParetoOptimal wrote:
           | > Specifically, FP requires expansive working memory,
           | 
           | What? FP increases local reasoning!
           | 
           | > in OOP one can reason from the perspective of the object
           | 
           | In FP one can reason from the perspective of the function?
        
       | FpUser wrote:
       | We should have less priests and more practical people. Mine is
       | the only true approach is the shortest path to being told to fuck
       | off.
        
       | bitwize wrote:
       | FP is a thing that's come and gone. All the smart kids have moved
       | on to Rust, where you get to play with types like a Haskell
       | programmer but still have imperative constructs and no GC.
        
       | commandlinefan wrote:
       | Functional programming, as a paradigm, is way better than object-
       | oriented programming, and also equally more complicated than
       | object-oriented programming. My observation, over the past 30
       | years, is that 90+% of programmers aren't even capable of doing
       | object-oriented programming - so getting them to do functional
       | programming is a pipe dream.
        
         | feoren wrote:
         | > 90+% of programmers aren't even capable of doing object-
         | oriented programming
         | 
         | Similar to other takes I've seen in this thread. But isn't it
         | flawed to talk about being "capable of object-oriented
         | programming" when object-oriented programming is itself an ill-
         | defined, flawed idea? (I'm talking C++/Java/C#/textbook OO, not
         | Smalltalk.) I spend a majority of my time in C#, and I'm not
         | really sure I'm doing object-oriented programming either.
         | Learning curves are never linear, but if it were, the curve for
         | OO in C# would look something like:
         | 
         | Level 0: God-classes, god-methods. Puts the entire program in
         | the "Main" method.
         | 
         | Level 1: Most of the logic is in "Main" or other static
         | methods, with some working, mutable data stored in classes. No
         | inheritance.
         | 
         | Level 2: Logic and state are starting to get distributed
         | between classes, but lumpily -- some classes are thousands of
         | lines long and others are anemic. Inheritance is used, badly,
         | as a way to avoid copy/pasting code. Short-sighted inheritance
         | based on superficial similarities, like "Dog : Animal". No
         | clear separation of responsibilities, but "private" is starting
         | to make an appearance. If design patterns are here, they're
         | used arbitrarily. Still lots of mutability around. This is "OO
         | Programming" as taught in early textbooks. It's bad.
         | 
         | Level 3: Methods and classes are starting to ask for
         | contracts/abstractions instead of implementations. Inheritance
         | hierarchies are getting smaller, include abstract classes, and
         | are starting to be organized by need and functionality, rather
         | than by superficial similarity; things like "TextNode : Node".
         | Classes are clearly articulating their public surface vs.
         | private details, with logic behind which is which. Generics are
         | used, but mostly just with the built-in libraries (e.g.
         | IEnumerable<T>). Design patterns are used correctly. Mutability
         | is still everywhere. If interfaces are used, it's in that
         | superficial enterprisey way that makes people hate interfaces:
         | "Foo : IFoo", "Bar : IBar", for no discernable reason. This is
         | "OO Programming" as taught in higher-level textbooks.
         | 
         | Level 4: No more "Dog : Animal". If inheritance is used at all,
         | it's 1 layer deep (not counting Object), and the top layer is
         | abstract. Code de-duplication is done via composition, not
         | inheritance. Fluent/LINQ methods like .Select() [map] and
         | .Where() [filter] have mostly replaced explicit loops. A large
         | percentage of the code is "library" code -- new data structures
         | and services for downstream use. Generics are everywhere, and
         | not just with standard-library classes. Interfaces are defined
         | by the needs of their consumers, not by their implementations
         | -- you may not even see an implementation of an interface in
         | the same project it's defined (this is a code-fragrance; a good
         | smell!). Liberal use of Func<> and Action<> has eliminated
         | almost all of the explicit design patterns and superficial
         | inheritance that used to exist. Mutable state is starting to be
         | contained and managed, perhaps via reactive programming or by
         | limiting the sharing of mutable objects. This doesn't look much
         | like OO as taught in textbooks.
         | 
         | Level 5: Almost all code is library ("upstream") code, with a
         | clear, acyclic dependency graph. Inheritance is virtually
         | absent; an abstract class may show up occasionally, but only
         | because it hasn't been replaced with something better yet. Most
         | code is declarative using fluent/functional-style methods on
         | immutable data structures, like .Select() and .Where(). Where
         | Level 4 may have abandoned that style at the limit of the "out
         | of the box" data structures, Level 5 just writes their own
         | immutable fluent/functional data structures when they need to.
         | This means heavy use of interfaces, Func, and generics,
         | including co- and contra-variance. It also means adapting ideas
         | from the functional world, such as Monoids and the "monadic
         | style" (but not an explicit Monad type, both due to the lack of
         | higher-kinded types and due to the fact that Monad is a red-
         | herring abstraction that is not useful on its own). Most code
         | looks like it's written in a mini domain-specific language,
         | whose output is not a result, but a plan (i.e. lots of lazy
         | evaluation, but with sensible domain-specific data structures,
         | not with raw language elements like LISP). Data is largely
         | organized via relational concepts (see: Out of the Tar Pit),
         | regardless of the underlying storage layer. Identity and state
         | are separated. Data and function blend seamlessly. Mutability
         | is almost exclusively relegated to the internals of an
         | algorithm, mostly in said data structures. Virtually no mutable
         | state is shared unless it's intrinsically necessary. If it is
         | necessary, it's tightly controlled via reactive programming or
         | something similar. A few performance-critical loops look almost
         | like C, with their own memory models, bit twiddling, and other
         | optimizations, but these are completely internal, private
         | details, well commented and thoroughly tested. This looks
         | nothing like OO Programming as taught in textbooks. It looks a
         | lot more like functional programming (with some procedural
         | sprinkled in) than OO.
         | 
         | If there's a Level 6, I'm not there yet, nor have I seen it (or
         | known what I was looking at if I did).
         | 
         | So when I see someone say "programmers aren't doing OO
         | programming", I don't know what that means. Only Levels 2 and 3
         | above look much like "object-oriented programming". If nobody
         | told you C# was supposedly an "object-oriented language", and
         | all you saw was Level 5 code, would you know OO was supposed to
         | be the overriding paradigm?
         | 
         | Are people avoiding OO programming because they can't do it, or
         | because they evolved past it? To someone stuck at Level 3,
         | Level 5 code might look unnecessary, overly complicated,
         | whatever. It might look like code written by someone who
         | doesn't know how to do OO.
        
         | kleene_op wrote:
         | > getting them to do functional programming is a pipe dream
         | 
         | I don't know if that was intentional but I'm upvoting!
        
       | nayroclade wrote:
       | It's strange to me that this article focusses so much on
       | nullability, which seems like a tangental issue. There's nothing
       | stopping an imperative language from enforcing nullability
       | checks. Indeed, with full strictness enabled TypeScript will do
       | just that, including requiring you check every indexed access to
       | an array.
        
         | yxhuvud wrote:
         | Yes, enforced nullability checks is just a type system feature.
         | Another example that has it is Crystal, which is an OOP
         | language.
        
         | discreteevent wrote:
         | Not only that but directly under the heading "Nullifying
         | problems with null references" they start to describe problems
         | with global variables. The article is all over the place. There
         | may be arguments for functional programming but I wouldn't
         | trust this writer because their thinking is so sloppy.
         | 
         | Also: "But many functions have side effects that change the
         | shared global state, giving rise to unexpected consequences. In
         | hardware, that doesn't happen because the laws of physics
         | curtail what's possible."
         | 
         | The laws of physics? That's complete waffle. What happens when
         | one device trips a circuit breaker that disables all other
         | devices? What happens when you open the door to let the cat out
         | but the dog gets out as well?
        
         | klysm wrote:
         | This is a good point and I agree it buys you similar safety.
         | The annoying part is it isn't a monadic data structure. You
         | usually get some syntactic sugar for a limited subset of
         | mapping (optional chaining), but a lot of the time that's
         | insufficient and you get imperative code.
        
           | stiiv wrote:
           | Speaking as someone who recently switched from F# to
           | TypeScript: yes, "annoying" is just what it is.
           | 
           | Until TypeScript at least has pattern matching you'll be
           | writing at least 50% more code, maybe more.
           | 
           | Chaining would be a godsend, but without auto-currying, it's
           | unsightly. Computation expressions would be better, and would
           | probably be easier to implement if, say, TypeScript included
           | a "native" `Option`, `Result`, or `Async`.
        
         | AtNightWeCode wrote:
         | And you will end up with monads anyway in FP which probably are
         | about as error prone as missing null checks.
         | 
         | Many compilers warn about potential null problems as well.
        
       | dec0dedab0de wrote:
       | I don't know any purely functional languages[], so my viewpoint
       | is skewed here. Whenever I have seen a python developer drink the
       | functional kool-aid they end up either storing state in global
       | variables, environment variables or in a dictionary they end up
       | passing to every function. I then have to explain to them that
       | passing a dictionary around and expecting variables to be in it
       | is just half-assed OOP.
       | 
       | My rule of thumb is anything that needs state should be in a
       | class, and anything that can be run without state or side effects
       | should be a function. It is even good to have functions that use
       | your classes, as long as there is a way to write them with a
       | reasonable set of arguments. This can let you use those functions
       | to do specific tasks in a functional way, while still internally
       | organizing things reasonably for the problem at hand.
       | 
       | The minute people start trying to force things to be all
       | functional or all OOP, then you know they've lost the plot.
       | 
       | [] I have been wanting to learn lisp for over a decade, I just
       | never get around to it.
        
         | ahartmetz wrote:
         | I strongly agree. Rule one: avoid and simplify state (e.g.
         | recalculate data if it's cheap instead of updating it when any
         | of its inputs change). Rule two: if you need state, keep it
         | coherent by tightly managing it (go through functions that
         | maintain the invariants) and exposing as little as possible.
         | That is where classes come in.
        
           | valenterry wrote:
           | Pure functional programming is orthogonal to that. In other
           | words: you can have your class that contains a maximum
           | simplified state, no problem. Extending this to be pure
           | functional means that in addition to everything else that you
           | said, the calls to the class that manages the state are now
           | considered as needing "special treatment" in the sense that
           | you can't merely call them, you have to also explain what
           | should happen if there are multiple calls. I.e. the order of
           | execution is not depending on the order of lines of code
           | anymore, but it is defined through the means/syntax that the
           | programming language gives you.
        
       | paradite wrote:
       | JavaScript is functional if you write in functional.
       | 
       | There's nothing stopping you from writing pure functional code in
       | JavaScript or TypeScript.
        
         | mikedelago wrote:
         | I think this is something a lot of people overlook too quickly,
         | too. It's pretty easy to get some of the benefits of FP without
         | using Haskell/Scheme/ML/whatever in a lot of languages:
         | 
         | - Write pure functions
         | 
         | - Postpone side effects until necessary (as in, set up the side
         | effect in a way that the side effects inputs are testable)
         | 
         | - Return things when possible, in order to increase the
         | expressiveness of your code
         | 
         | It's also important to not fight the language you're working
         | in. If you're constantly breaking idioms and your teammates
         | can't read your code, FP isn't providing any benefit.
        
         | ParetoOptimal wrote:
         | > Contemporary imperative languages could continue the ongoing
         | trend, embrace closures, and try to limit mutation and other
         | side effects. Unfortunately, just as "mostly secure" does not
         | work, "mostly functional" does not work either.
         | 
         | https://m-cacm.acm.org/magazines/2014/6/175179-the-curse-of-...
        
       | mmargerum wrote:
       | Doesn't include Clojure in GitHub repo count.
       | 
       | "Functional programming also requires that data be immutable" Not
       | true
        
         | victorvosk wrote:
         | Not to mention you can use just about any language provided you
         | adhere to FP standards. It doesn't need to be forcibly "baked
         | in".
        
         | munchler wrote:
         | Pure functional programming does require immutable data. There
         | are lots of FP languages that aren't pure, though.
        
         | waselighis wrote:
         | The D programming language is a good example which defines pure
         | functions, not as strictly operating on immutable data, but
         | simply as functions without side effects. So pure functions can
         | still have local mutable variables, but cannot mutate any
         | shared or global state. It goes further with "weakly pure"
         | functions which can have mutable parameters/arguments, but
         | still cannot mutate any global variables.
        
       | ChrisMarshallNY wrote:
       | I like and agree with much of the advantages of FP, but I've
       | never used it exclusively.
       | 
       | A number of years ago, we worked with a startup that was based
       | around a new FP language, focused on image processing
       | pipelines[0]. It's actually quite cool. We came from a C++
       | background.
       | 
       | Learning the language was difficult, but our team was very
       | capable, and very experienced. We did it.
       | 
       | But it was just too limited, and the advantages never appeared
       | for us. We were doing it for an embedded implementation.
       | 
       | It was a really neat experience, but ended up as a failure. I am
       | sorry for that, as I actually thought they had the right idea,
       | and I think that management failure was as much to blame as
       | technical hurdles. The language had many limitations, but we were
       | still able to work with it. That's what you get, with a highly
       | capable team. The startup we worked with, had some real
       | rockstars.
       | 
       | These days, I program in Swift, which has many FP features. I
       | enjoy it.
       | 
       | Nonetheless, I think that many of these "new paradigms" are built
       | around the premise that most programmers suck, and need to be
       | forced to write good code, which never seems to work.
       | 
       | Companies seem to be desperate to hire crappy engineers, and get
       | them to write good code, as opposed to hiring decent engineers,
       | in the first place, who can write good code, regardless of the
       | tools.
       | 
       | [0] https://halide-lang.org/
        
       ___________________________________________________________________
       (page generated 2022-11-02 23:02 UTC)