1. 10

  2. 7

    I mostly agree with this article, but I’m skeptical that you can do functional programming in a language that doesn’t have first-class functions. I think there’s a minimum bar for supporting FP style, and though you could jump thru hoops to implement first-class functions in a language that doesn’t have them, by that point you’re just creating a new language hosted inside another.

    But I also don’t think “functional programming language” is a great term, except when understood as “language which encourages functional programs to be written”. Like speed, “functionalness” is a property which can only be applied to individual programs, not whole languages. And like speed, a language can shape both the bounds of how functional the programs written in it can be as well as how much effort it takes to achieve a certain level of speed or functionalness.

    1. 3

      I’m skeptical that you can do functional programming in a language that doesn’t have first-class functions.

      Yeah. If I were to rewrite/revise this article, I’d probably mention that. You need lexical closures, or some equivalent. I actually believe even subroutines (code with effects) need to be first class as well.

    2. 3

      You can pretend you can do functional programming in any language, but what use is it if you don’t get any support from the language’s semantics? If “functional programming” is intended to be more than just another buzzword, its technical meaning[0] has to be something along these lines:

      Functional programming is a programming style in which the problem domain is modeled as a collection of values, and the problem’s solution is implemented as a collection of procedures that evaluate functions, i.e., mappings from values to values.

      Hence, the bare minimum one can demand in a language for “doing functional programming” is:

      • The ability to define problem-domain values, abstracting away the details of their physical representation, such as the number of independently allocated memory blocks used to store this representation in memory.
      • A purely syntactic criterion for establishing that a procedure evaluates a function, and a large class of functions that can be efficiently evaluated by procedures that satisfy this criterion.

      If your language gives you less than this, then either “doing functional programming” is bound to be an uphill struggle (in which case you should consider switching to a style that makes life less difficult) or you will have to relax the definition of what “functional programming” means (in which case you need to argue that your revised definition is still meaningful).

      [0] Note that I’m not saying functional programming is unquestionably a good thing. My purpose is just to give a technically precise criterion for when one is “doing functional programming”.

      1. 3

        Of course you can do FP in any language. The real question is can you do it conveniently.

        1. 2

          Maybe another way to think about this is “Can I not do FP in my language?”. Yes for JavaScript and Scala and Rust - you can write procedural code to your heart’s content in these languages, even if JavaScript gives you the tools to use functional abstractions and Scala and Rust actively encourage them. No for Haskell and Elm - there’s no way to write code that looks imperative in these langauges.

          1. 5

            No for Haskell and Elm - there’s no way to write code that looks imperative in these langauges.

            What do you mean by “looks imperative”? Doing everything inside the IO monad is not much different from writing a program in an imperative language.

            1. 2

              You mean StateT and IO. And then learning how to use both.

            2. 3

              Writing Haskell at my day job, I’ve seen my fair share of Fortran written in it. The language is expressive enough to host any design pathology you throw at it. No language will save you from yourself.

            3. 1

              Highlight worth quoting in the future:

              “The value of a language that strongly enforces a paradigm is that it immerses you in that approach to solving problems. The more it enforces the paradigm, the more you are forced to attempt solutions using that paradigm. The more functional your language, the more training you get in approaching problems in a functional way. The same goes for OOP and Procedural. In essence, you get more practice because you can’t rely on the other paradigms you already know.”

              Emphasis added. The precedent for this is immersion training for learning languages versus learning specific features one by one. The latter would be like an English-speaking person learning Spanish who just tries new words or grammar rules on a Spanish-speaking friend who is fluent. Certainly that person could learn more use of Spanish over time. The fluent speaker, though, probably got that way through an immersive learning experience that surrounded them with the language, forced them to use it to get basic things done, and gave many more opportunities for optional use. This gave them a level of understanding and utility that the piecemeal, opportunistic approach could [probably] never match.

              When I last looked, most of the old arguments and newer research suggested our brains handle programming much like they handle language comprehension in general. Combined with positive results from immersion training, that corroborates the author’s claim that immersion in different programming paradigms is the best way to learn to read, write, and speak them. Almost all anecdotal evidence I read from people learning other paradigms confirms this: they say it changed how they thought about solving programming problems regardless of whether they’d adopt the paradigm-focused language in practice. They almost always believed it had value for them with many producing code examples showing how certain problems were expressed in objectively-better ways in some paradigms than others.