Hacker News new | past | comments | ask | show | jobs | submit | page 2 login
Why Isn't Functional Programming the Norm? [video] (youtube.com)
296 points by gyre007 on Oct 17, 2019 | hide | past | favorite | 404 comments



OOP was designed to prioritize encapsulation at the expense of referential transparency. Functional programming was designed to prioritize referential transparency at the expense of encapsulation.

You cannot have referential transparency and encapsulation at the same time.

In order to prevent mutations (which is a requirement of FP), a module cannot hold any state internally; this necessarily means that the state must be passed to each module action from the outside. If state has to be passed to each module action from the outside, then this necessarily means that the outside logic needs to be aware of which state is associated with which action of which child module. If higher level modules need to be aware of all the relationships between the logic and state of all lower level (child) modules, that is called 'leaky abstraction' and is a clear violation of encapsulation.

Encapsulation (AKA 'blackboxing') is a very important concept in software development. Large complex programs need to have replaceable parts and this requires encapsulation. The goal is to minimize the complexity of the contact areas between different components; the simpler the contact areas, the more interchangeable the components will be. It's like Lego blocks; all the different shapes connect to each other using the same simple interface; this gives you maximum composability.

Real world software applications need to manage and process complex state and the best way to achieve this is by dividing the state into simple fragments and allowing each fragment to be collocated with the logic that is responsible for mutating it.

If you design your programs such that your modules have clear separation of concerns, then figuring out which module is responsible for which state should be a trivial matter.


Encapsulation is desirable because it limits the possibility space of what can operate on a set of data. Referential transparency is desirable because pure programs are much easier to reason about. If I understand what youre saying, it seems youre saying referential transparency and encapsulation are at odds and encapsulation is more valuable, but I disagree. Hiding state maybe keeps things tidy and enforces that you need to use the API, but its not really the point IMO. The point of encapsulation is managing state mutations. Hiding state is only a small part. You dont need to hide state as much when its immutable because then you don’t need to care what other code is doing with your emitted data structures because it doesn’t effect you.


Encapsulation doesn't necessarily mean hiding state. It means hiding the implementation details of how actions mutate the state. The same action called on a different kind of module instance can end up mutating the instance's internal state in a completely different way. The higher level logic should not be concerned with how a module performs an action.


I don't quite follow this. You can create (very complicated) immutable objects that encapsulate their state, and provide methods that return new immutable objects with different - and still fully encapsulated - state. Vavr is a good example.


Yes you can reduce and map a large state object into a smaller and simpler object before you pass it down to a child component but the encapsulation is still leaky because the parent component needs to know the implementation details of each action of a child component in order to use them correctly (for example, the parent component needs to know how the different actions of the child relate to each other in terms of how they affect the state); it creates a large contact area between components which creates tight coupling.

The idea of blackboxing/encapsulation is that the parent component should know as little as possible about the implementation of its child components.


Do you have a more concrete example? So far as I can see there is no reason why functional programming would require a parent component to know anything about how its child components interact with the state. The tight coupling you are describing sounds completely foreign to me as a Haskell programmer.


I think some of the spirit of encapsulation (i.e., decoupling from implementation) is achieved by polymorphic functional interfaces, e.g. type classes in Haskell.


" the more interchangeable the components will be. It's like Lego blocks; "

This is precisely the reason why pure FP is prioritizing referential transparency. Even if objects are perfectly encapsulated, with enough complexity, because other objects will depend on that information, and because that information mutates and changes over time, this is bound to cause some errors.

Compilers can't check program correctness because of the halting problem, so FP aims to give the programmer some patterns + laws to help better reason across this "higher" dimension of moving parts.


>> Even if objects are perfectly encapsulated, with enough complexity, because other objects will depend on that information, ...

I would argue that when other objects from different parts of the code depend on the same state and there is no clear hierarchy or data flow direction between those objects, then that is going to cause problems regardless of whether the language is OOP or FP. The problems will manifest themselves in different ways but it will be messy and difficult to debug in either case (FP or OOP) because this is an architectural problem and not a programming problem. It will require a refactoring.

OOP helps to reduce architectural problems like this because it encourages developers to break logic up into modules which have distinct, non-overlapping concerns.


In my view, the new hooks paradigm in React combines the best of both worlds in FP and OOP.


Encapsulation is trivial in FP tho.


I think we need to get past the point of believing in some FP revolution in which enlightenment happens and people suddenly switch to Haskell, OCaml, Clojure, etc. FP is happening in a more evolutionary way with newer languages like Kotlin, Scala, F#, etc. taking ideas from Haskell, SML, and Lisp.

I'm not pretending to be the first to state this observation but I feel like it needs reinforcement here.


I think most of the growth of FP is coming from libraries and hybrid languages. Things like React and Redux and streams/linq style operations on data structures, or default immutability. I don’t think “pure” languages will ever really become dominant but a lot of the best ideas are being borrowed.


Don't forget JavaScript! ES6 did wonders for functional programming in JS.


I do not pretend to be a particularly skilled programmer, but in my not so long career I have picked up a bunch of tools: a few algorithms here and there, some data structures, some programming techniques like encapsulation, late binding, higher order functions, pipelines, various form of polymorphism (dynamic, static, ad hoc, inheritance based, structural or whatever), some concurrency patterns (message passing, shared memory, whatever). I end up using whatever seems more appropriate to me for a specific problem depending on intuition, personal preference and experience.

Now, various subsets of the items above have been labeled with different names (functional, procedural, OOO, generic, whatever), but of course most of the time no two people can agree on which subset deserves which label.

I must not be the only one, because a lot (but not all) of very successful languages are not very opinionated and let people mix and match bits as needed.


I didn't listen to the video, but the title raises questions. What is functional programming? Nowadays, most languages are multi-paradigm, it's not so clear what is functional programming (or a functional programming language).

For instance, it's very common to have data types with mutable state in OCaml, or to use non-mutable data-structures, closures, higher-order functions in let say Python. I don't see such a clear dichotomy between functional/non-functional programming languages anymore.

Besides, there are other language "features" that I feel have more impact on the code I write. For instance, static/dynamic typing, asynchronous I/O vs actors vs threads, module systems.

I see functional programming more as a tool and a programming discipline, well-suited to solve some problems, rather than a paradigm that one should adhere no matter what.


The talk actually takes time to answer these questions.

The title is also a bit clickbaity because the talk acknowledges that fp as a style is becoming common.


JavaScript isn't a functional language itself, but you can use a functional library like lodash/fp (https://github.com/lodash/lodash/wiki/FP-Guide) on top of it to get all that lovely functional goodness in your frontend and node code. Using lodash/fp has made my frontend state management code a lot nicer, and I'm really only just starting out with it.


You may want to consider Ramda.js instead: https://ramdajs.com/

IMHO does a better job than Lodash, because:

1. All functions are automatically curried.

2. The order of parameters lends itself to composition.

EDIT: 3. Transducers.


This. (No pun intended.) Lodash had its FP features bolted on as an afterthought, whereas Ramda was designed for it from the start.


I never understood the point of Ramda. It's like it's trying to replace the core functionality of JS with something that's completely orthogonal to what the language actually is, but it's just a bolted on library.

I've worked on codebases where people ignore all built-in JS functions (like Array.map/filter) and write Ramda spaghetti instead with multiple nested pipes and lens and what not to show off their FP purism.

Most of the time, you don't need any of this, it just makes the codebase unreadable, and hard for new people to join the project and be productive in a timely fashion.


Most of the time, you don't need any of this, it just makes the codebase unreadable, and hard for new people to join the project and be productive in a timely fashion.

This is exactly how I felt when I inherited a big project that uses lodash/fp. Having spent ~6 months with the code now I prefer having a functional layer on top of JS. It does make sense.


I only reach for Ramda when the built in Js functions can not accomplish what I want to do, or it would be very messy/hard to reason about. Now that’s very subjective, but I hate when I see people using lodash/ramda map to just map over an array. There’s a lot you can do with the built in methods and they will probably be the superior option


Maybe to avoid questionable behaviors, like in the article posted 3 months ago "Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript" [0]

[0] - https://news.ycombinator.com/item?id=20242852


Things like Ramda and jquery help avoid fighting against IE and other browser nuances, as well.

Even when there seem to be native functions/ methods to do something. That’s where the monster lives.


You stick with your “polyfill”, I’ll stick with mine , so to speak.

It’s nice to be able to make a function as concisely as something like:

Const foo_finder = R.find( R.propEq( ‘prop’, ‘foo’ ) )

...

Const a_foo = foo_finder( a_list )


See this is one of the things I personally hate, accessing or evaluating properties on objects using a string.

We have code so use code which can be parsed, evaluated by the type checker, and so on. What if you mistype 'fop' instead of 'foo'?


3. transducers


Personally, I think JS is a fine functional language. Like you say, it doesn't have a good FP style system library, but it doesn't have a good anything style system library ;-) My main complaint is that currying is awkward. One thing I have discovered, though, is that closures are relatively slow (that is, unoptimised) in most implementations. In several implementations, they can also leak memory in certain circumstances. There is a very old outstanding bug in V8 that gives a lot of details about this... unfortunately I'm not in a position at the moment to go spelunking for it (I wish I'd saved a link...)

Anyway, I've done quite a few fairly large katas in JS using only an FP style of coding without any dependencies and I really enjoyed it.


Personally I find functional style awkward in js. Mostly because data is not immutable, there are no functional operators (composition, application etc.) and no algebraic data types + pattern matching.

But most importantly, prototypal inheritance, in other words invoking the object's own methods as if they were pure functions is what really puts me off.


A lot of that stuff is pretty modern in terms of FP, though. It's definitely not a pure functional language, though quite a lot of the data is actually immutable. It was really surprising to me that strings are immutable (but as the other commenter pointed out, they don't throw if you try to mutate them, so it's not that convenient). "Objects" and arrays are mutable, but it's pretty easy to avoid mutating them if you want to.

It probably wasn't clear, but the reason I didn't use any dependencies is because I was avoiding JS's built in inheritance mechanism, which I don't think is very compatible with FP. You can build objects out of closures and build your own object oriented mechanisms if you want. Unfortunately you run into the limitations of the implementations I mentioned.

I always hesitate to link to my own "fun" code, but just so you understand that I was not looking for code quality in this: https://gitlab.com/mikekchar/testy But it shows how I was using an FP style in JS to implement an alternative OO system. I really had fun writing this code and would have continued if there weren't problems with using closures in JS.

Edit: If you look at this, it's probably best to start here: https://gitlab.com/mikekchar/testy/blob/master/design.md

I really should link that in the README...


Look into Ramda.js if you haven’t yet. It adds partial function application / currying capabilities, as well as composition support.

E.g.

https://ramdajs.com/docs/#partial

https://ramdajs.com/docs/#pipe


Object.freeze does give you shallow immutability in javascript, though it makes setters fail without throwing.


The video explains how JavaScript started out as a Scheme-dialect (Lisp) but for marketing reasons they chose a more Java-like syntax and adopted Java into the name.


An historical mistake that humanity is paying (and will pay) for a long time.

Scheme 'cloths' was a viable option. Lisp remains the most popular scripting language among Autocad users despite Autodesk pushing other languages (.NET and JS). So popular that Autocad clones use it also as a scripting language[1].

Edited [1] https://www.zwsoft.com/zwcad/features#Dynamic-Block


Was it a mistake, though? Languages have to be accessible to their audience, and Javascript caught on because of its relatively gentle learning curve.

If SchemeScript hadn't caught on, it might have been that VBScript took over the web.


Insufficiently C-like languages get ignored, according to: http://james-iry.blogspot.com/2009/05/brief-incomplete-and-m...


Language designers and enthusiats will forever be disappointed at how many social and human factors are at play, which coincidentally, is a large part of the motivation for programming languages


I was working for bigest Autocad competitor for more than 10 years and never had to touch anything similar to lisp :)


If my guess is right, that's because your company's product had their own proprietary language (MDL).

But, that was OK too, because if my guess is right, your company's product also had FAR FAR FAR better COM bindings than Autocad did for 99% of what you'd want to automate.


Javascript falls short of scheme in ways more substantial than java-like vs s-expression syntax. It also has one of the worst numerical towers ever put into a language (that being: "lmao everything is a float".) Also, "function-scope" is an abomination compared to proper lexical scoping.

Edit: I forgot to also mention: weak typing was an awful idea.


There is excellent TypeScript lib called fp-ts


I love everything except the docs. The docs rarely show practical usage. Most functions are just type definitions. This is a MAJOR blocker to anyone that might not have a mathematical background. I find this issue quite a bit with the FP world though. The old joke, "as soon as you understand monads, you instantly become unable to explain them" sort of holds true here. How would I know what I should use? You just have to know.

Just this morning, I had to resort to Stack Overflow for using an Either... a concept I thought I well understood. Turns out, the way I've done it in Scala might not be the norm.

Many programmers coming to this library are coming from JavaScript, so expecting them to understand some (or many) of these things, might not be the right approach. The author has gone to some great lengths to blog about the foundations of FP... so this might help a bit. I just wish the docs were fleshed out with more examples. (the repo is open sources.... I could put up or shut up here)


Because it's not that useful.

There is an contest organized by the International Conference on Functional Programming: https://en.wikipedia.org/wiki/ICFP_Programming_Contest

It was more or less designed to show the superiority of functional programming languages. Yet in that contest C++ has done better than OCaml or Haskell...

The FP crowd seems to be more active doing advocacy than writing code. Yes, we know, there is that one trading company using OCaml. It's such a niche language that they have to pretty much maintain the toolchain and standard library themselves. Meanwhile, plenty of more successful companies use C++, C# or Java with no problem.

If you want to convince someone of the superiority of FP, write a real killer application. A new browser to compete with Chrome, a video game that can dethrone Skyrim or the Witcher 3. Maybe a DBMS that's even better than PostgreSQL? Basically: show, don't talk.


Just because you don't see it, doesn't mean it's not happening.

- Have you ever heard about how Walmart handles Black Fridays?

- Do you even know what's behind Apple's payment system?

- You ever used Pandoc, Couchbase, Grammarly, CircleCI, Clubhouse.io, Pandora, Soundcloud, Spotify?

- Have you ever asked a question - what is an app like WhatsApp that was sold for $19 Billion runs on?

- or How Facebook fights spam, Cisco does malware detection or AT&T deals with abuse complains?

- How Clojure is used at NASA or how Microsoft uses Haskell?

Frankly, I don't even know what's there to debate about. Functional programming is already here and it's been used in the industry for quite awhile already and its usage growing in a quite steady pace. Almost every single programming language today has certain amount of FP idioms, either built-in or via libraries. So yeah, while you're sitting there, contemplating about if FP useful or not, people been building hundreds of awesome products.


I said: it's not _that_ useful. I did not say it's completely useless.

Every large (or even small) company has people writing stuff in Perl, Bash, Haskell, Ruby, Rust, VBA, Scala, Lua or what not. I've been that guy, too.

More often than not it is a distraction more than anything, and it ultimately ends up being rewritten in C++, Java or Python. I think there are some niches where it helps; OCaml has had some success with static analysis and proof assistants, or even with code generation projects like FFTW.


Honestly, do you really think a company with only 35 engineers could build, scale and sell a product like WhatsUp for even a fraction of that amount but using C++, Java or Python? I seriously doubt that.

Look, I've seen both sides and I know this for sure (this isn't a mere opinion, this is a certain fact) - FP allows to build and maintain products using smaller teams.

You don't have to trust my word, do your research, google "companies using Clojure" (or Haskell, OCaml, Erlang, etc). You will see that either those companies are not too big, or the FP teams in large companies not very large. Skeptics often cite this fact, claiming it to be the proof that FP codebases don't scale to large teams. The truth is - you don't need a big team to build a successful product with FP language. And the number of startups using FP langs is steadily growing.


> A new browser to compete with Chrome

Firefox is written in Rust

> a video game that can dethrone Skyrim or the Witcher 3.

afaik latest "God Of War" is written in Rust

> Maybe a DBMS that's even better than PostgreSQL?

Datomic - Clojure, Mnesia, Riak, CouchDB - Erlang

Yeah, I know that Rust is not FP lang, it's imperative, but it does adhere to FP principles.

"it's not that useful"? Heh.


Because it is not the best solution for most computer problems.

Simple as that.

I am a functional and OOP programmer myself. I find functional way more elegant for modeling most mathematical problems, but OOP way better at modeling real life things with states.

OOP and states introduce lots of problems and complexity, but the solution is not removing states, or a series of complex mathematical entelechies.

In fact "removing states" is not really removing them. It is creating new objects with static states on it. It makes it super hard to model real life.

(dynamic)States exist in real life. Temperature, pressure, height, volume, brightness, weight...

There are programmers that understand programs as a religion, they only program in one system ans believe it is the best thing in the world and everybody should be forced to use it. I feels sorry for them and the people that depend on them.

The solution will be new paradigms that are neither OOP nor FP.


>(dynamic)States exist in real life. Temperature, pressure, height, volume, brightness, weight...

It's more like, states better match our more common way to model our sense-data. It's easier to grasp for us, but it doesn't mean it's the way that will cause provide the best desirable results.

If you take the example of mass in physic, most of the time it's perfectly fine to deal with it as an first class attribute of an object. But it's not how Higgs mechanism aboard the notion.


Having used FP for the past decades in many different domains that's huge news to me.


One thing I haven't seen brought up in this thread yet is support for foreign language embeddability. For example, Python code is technically quite slow, but that often doesn't matter much because it is easy to write external functions in C or C++ that behave like normal Python functions. I imagine that it would be more difficult to embed C++ code into a language with strong functional gauruntees. In that sense, the performance of Python is close to the performance of the fastest language with the same paradigm, which is (with current compilers) better for imperative programs that are structurally more similar to how the CPU operates.


Good ideas take a long time to catch on in tech, regardless of how much anyone believes its a fast moving industry.


Functional programming? absolutely 100% yes.

Functional programming languages? well, it depends on the problem.

If performance is an important issue, most of the time functional programming languages are a big 'no'.


Well, if performance is really an issue, I guess anything that is not C, C++, rust or a thin wrapper over those languages or legacy libs written in the likes of Fortran won't be an option, so yes.

That being said, it seems like performance is not an issue for most of the code written these days, aside from not writing quadratic solutions for problems solvable in linear time.

If you use java, .net, go or the likes, odds are you would be fine with a functional language ; and if you need performance with those languages, odds are that you will need arcane knowledge equivalent to what you would need to know to make performant fp code.


I mean, Jane Street use OCaml for high-frequency trading, where latency can cost significant amounts of money. They seem to be perfectly happy with it.


This video exists in an alternate reality where marketing departments do not. Many of these languages became popular not because of some intrinsic property, but because of a strong marketing push by one or more backing companies. There was a period of time, not so long ago, where "object oriented" was basically a checkbox on language marketing copy, and if your language didn't have it you would get scoffed at.


Did you actually even skimmed the video? It does speak about large cash injection on the marketing side.


Can you give contemporaneous examples? I'm curious if there are companies out there actively pushing their language/framework, as opposed to sort of passively posting/updating without marketing.


The lines between marketing and "passively posting" are very blurry, especially in the tech world. Is Linus T. marketing, when in a technical presentation about git he says "if you like SVN you might wanna leave"? Is Mozilla marketing, when they claim in technical blog posts that rust provides system language level performance while being safe?


MS .Net


OO is merely a style of laying out imperative code for the compiler to put into proper linear order.

End of the day there are instructions emitted in a linear fashion and other instructions running (OS?) can provide an execution context ("Hi process, here's your memory area with pretend addresses do you can think it's all yours, you go over there to Core-2 and run at Z priority.")

OO is not particularly easy to learn WRT FP, but it does have the contextual advantage of having been delivered on the back of FAST compiled languages like C++.

Java runs as fast as the big money thrown into it's VM can make it run. If the JVM were dog-slow, you would see lower adoption of it.

Ocaml as used by corps like Jane Street etc,is not directly for running application code from (or rather, the application in question does code generation.)

High level languages could be expected to adopt either code-generational or Cython-style approaches. (Chicken Scheme, for example)

C++ merely has the historical accident of bridging 2 generational worlds of computing, hence you can find C++ full-stack.

Anyone for doing DSP purely in Ruby with no C-libs?


It´s basically because of marketing, fads, hype but we also have to take into account that FP is probably ok for the Hacker News audience but way too complex for the average developer.

Most code is LOB apps and social media apps churned by software factories and internal IS/IT areas. In these kind of projects coding is a rite of passage before becoming a team leader or a project manager, so most devs won´t invest much in their coding skills. As a result the average code tends to be badly decomposed procedural code over a procedural-like class hierarchy and devs just follow the fads because this is what gets them jobs.

Adding FP to this formula could prove really wrong for those in charge of projects. Better to be conservative and use Java, C#, Python or even nodejs/JavaScript as they allow to churn the same procedural code of ever just in different clothes.


Because simple is better than perfect.


Well, funny you said that. Clojure people put simplicity above everything else https://www.youtube.com/watch?v=34_L7t7fD_U


I got another question. Why don't those prophets leave intelligent people alone and let them use whatever tooling/approach they find appropriate for solving particular problem instead of heating the air trying to propagate/force whatever ideology they carry.


Because those profits don't think your definition of appropriate in this context is correct.


People at the places I work keep memeing links to blog posts along the lines of "OOP is dead. Functional programming is the new king".

Yet to see a single line of a functional language in production.

As other commenters have mentioned most decent modern lanuages are multi-paradigm.


There is lots of functional language code in production.

As a recent example GitHub uses this Haskell application for code analysis: https://github.com/github/semantic

Also, Erlang powers a huge amount of the US’ cellular infrastructure, as well as RabbitMQ, which is used in a ton of production workloads.

There’s actually a pretty decent list on Wikipedia: https://en.m.wikipedia.org/wiki/Functional_programming


might be interesting for you, Lips in production:

https://tech.grammarly.com/blog/running-lisp-in-production


I used to work in a company that had part of the process written in Lisp and it was in true production. Once the (fp) guy left the company everyone else had to support that code. What a nightmare that was. No one wanted to touch it with a ten foot pole. Should we had another FP guru in our midst, that may have turned out differently. But everyone was in agreement that that part needs to be rewritten in a language that everyone else is using. In real life - if most stuff in your company is FP and there is plenty of expertise to go around - do FP. If not - do not. :-)


Arguably, if you knew that A: there was code in Lisp and B: only one person knew how to support it, they should have either rewritten it while the one who understood it was still there, or had more people learn Lisp, or hired more people who knew Lisp. It shouldn't have been allowed to reach the point where someone quit without anyone else having a clue.


Notice that they are using Common Lisp, which is a multi-paradigm language, rather than a more functional lisp like Clojure.


They also use Clojure at Grammarly AFAIK.


Common Lisp is a great language for OOP programming though. Almost any serious CL code heavily uses CLOS.


I guess you haven't really looked too hard then https://clojure.org/community/companies


Jane Street is OCaml basically from top to bottom. They seem pretty fast.


The backend for HN is written in a Lisp dialect...



Functional programming at Atlassian: https://youtu.be/HSQ9ET0bOYg



I feel it's because functional programming is not a general application methodology. It excels at several idioms that we use as programmers but I feel it's something more specialized and niche then OO programming. I personally use OO as a base and iterate from there, using Functional idioms where is applicable. Some classes of programs can be described in its entirety in functional terms, but they're a small portion compared to the whole. Everything can be expressed in OO idiom, even if it's not the optimum way; I don't know if the same can be said of Functional. Would like to know more;


I've been working with FP for around a decade now, and anything you can express in OO can be expressed with FP just as easily and often in a much simpler and more easily maintainable fashion. I copresented a talk on how my team uses FP in our platform if you're interested in more details:

https://www.youtube.com/watch?v=IekPZpfbdaI


> Everything can be expressed in OO idiom

You know, at some point in history most scientists in Europe believed that the math can only be done using Roman numerals.


Do not try and make the computer functional. That's impossible. Instead, only realize the truth... THERE IS NO COMPUTER. Then you will see that it not the computer that is functional, it is yourself.


Hm, so, Feldman claims that it wasn't the OO that made C++ popular, but rather the other features added on top of it that C with Classes didn't have. But one of those features that C with Classes didn't have was virtual functions. Without that, it's not clear how OO C with Classes really is. This potentially undermines Feldman's argument, because he hasn't ruled out the possibility that virtual functions were one of the key factors in C++'s success.


These things are not all-or-nothing.

I have one compute device, the GPU, that I program with its language (eg GLSL, OpenCL).

I have another compute device, the CPU, that I program with its language (eg C, C++).

I have code to control these devices, that mostly handles scheduling and waiting on the results of these computations (as well as network traffic and user input), and I program that in a language that supports functional style (eg C#, TypeScript).


as someone who made my first SPA, using Elm & met the presenter once in NY. functional programming is elegant and nice. but practicality is another different matter. for it, to be the norm, it has to have 10x advantages over the status quo. on the frontend, part JS already offers some features of functional programming, with some imperative parts. On the backend, none of the functional languages you would want to use such as Ocaml match say the ecosystems of Python, Java, Node.js & .Net world.Hell even F# which is an excellent language, is treated like the bastard step son of Microsoft


Clojure & Clojurescript are very practical and pragmatic. I've been writing Javascript for quite long time, I have tried and used most *script languages: Coffescript, Typescript, Livescript, Gorillascript. I've looked into Elm, ReasonML and Purescript. Clojurescript today has is the most balanced one - it gives you real productivity boost, simple FFI, different bundling options, gradual typing and generative testing, code that is clean, concise and very easy to reason about. It is a shame people dismiss it for some dogmatic reasons even without given it a try.


I mean, on the backend functional programming usually really shines, since you're can implement your APIs using FP without needing to have any state (the FP will just be translating http requests into calls to stateful storage).

E.g. at Facebook, the PHP code I write is usually highly functional.


Functional programming is not new, it has been around for many decades. The reason it didn't catch on is because it doesn't map very well to how our brain works. Human brains are object oriented, so OOP is very easy to grasp.

The real question is, why are people now taking a second look at functional programming. And the answer is Moore's law. Moore's law is coming to and end, and CPUs are not getting faster. Instead they are adding more and more cores. To take advantage of lots of cores you need concurrency. OOP is not very concurrency-friendly because objects have state, and to avoid corrupting state in a multi-threaded environment you need locks, and locks reduce concurrency. Functional programming doesn't have state, so you don't need locks, so you can get better concurrency.


That's utter rubbish. My team has been working with Clojure for close to a decade now. We regularly hire coop students from university, and none of them have ever had problems learning functional programming. It typically takes around a couple of weeks for a student to become productive and start writing useful code. The only people I've ever met who say that FP doesn't map to the way our brains work are people who're deeply invested in imperative style and never tried anything else.

The reasons for the imperative style being dominant are largely historical. Back in the day we had single core machines with limited memory and very slow drives. Imperative style and mutability makes a lot of sense in this scenario. Today, the problem of squeezing out every last bit of performance from a single core is not the most interesting one. And we're naturally seeing more and more FP used in the wild because it's a better fit for modern problems.


I think you can do better than calling something you disagree with “rubbish” because your team didn’t have problems with it.

Here’s an example of people finding functional programming unnatural, maybe you can leverage your experience to explain why he is wrong:

Functional Programming Is Not Popular Because It Is Weird https://probablydance.com/2016/02/27/functional-programming-...


Have you actually tried it? I dunno, after using Clojure for a while I realize now - there's nothing weirder than having to dig into deep, nested hierarchies of Java classes. I simply don't understand anymore people who willingly write that kind of code and even claim to be happy and productive.


I would venture a guess to say that what makes FP or declarative style programming/thinking feel weird is not any great context like the nature of the human brain but rather the lesser one that usually people try to learn it after already having had learned imperative style stuff.

The functionally written recipe from https://probablydance.com/2016/02/27/functional-programming-... may be less helpful if I need to know exactly what steps to take to bake a cake, but it will actually be much more helpful if I want to know what a baked cake is. It isn't quite a fair example because it leverages how humans already know what a baked cake is, what a preheated oven is, etc and the clunkiness of the FP-style recipe is likely more due to that than anything fundamental to FP.

Let's try a different example that better maps to real world application logic. The task is to build a scootybooty.

Imperatively, a scootybooty program is:

- Acquire four wheels and two axels.

- Chop down a tree.

- Plane wood from tree into curved flat shape.

- Attach axels to convex side of planed wood shape.

- Attach wheels to axel.

Declaratively it is:

- A scootybooty is a planed plank of wood with two trucks.

- A planed plank of wood is a flat board.

- A truck is an axel with two wheels.

Now imagine your boss asks you wtf this scootybooty thing is and what it can do. Which program more quickly allows you to answer these questions? My favorite thing about the FP/declarative paradigm is that the mental model first-classes the abstract thing you are implementing above how you implement it. Imperative style encourages you to think about the steps it takes to do something moreso than the thing itself which IMO can lead to cart-before-horse type mistakes in planning. Declarative programming: "the forest is made of many trees", imperative programming: "tree, tree, tree, tree, tree, tree..."


It's not just my team, there are many of people working with Clojure and other functional languages out there, and there are plenty of FP projects in productions in pretty much every domain.

Functional programming is weird in the same way Japanese is weird to an Anglophone. A person who learned Japanese as their mother tongue will find English equally weird. The comments in the link you posted already address the points the author tries to make, which all boil down to FP being different from what they're used to.


> Human brains are object oriented, so OOP is very easy to grasp.

Can I cite you on this? Because I have only ever seen this explained in Programming 101, where Java is the language they teach.

I wonder where this sentiment comes from. I imagine it came from marketing.


Yeah I've gotta be honest the first few times I was taught OOP I couldn't quite grasp the purpose. I like it now for encapsulation of state, but generally I find it much easier to deal with records + pure functions as building blocks.


> Can I cite you on this?

No, you can't. Because like the other commenter noted: "This is utter rubbish." It only looks easy to understand on the surface, but quickly becomes a mess. "spaghetti code" and "lasagna code" are the terms invented in OOP realm. Being said that - some advanced FP concepts can be pretty daunting to grasp as well.

Saying that human brains are OOP or FP oriented is equivalent to saying that human brains wired to recognize patterns in music but not color, or something like that.


Why would you need functional programming for that? Ada has extremely easy-to-use language constructs for concurrency.

Just to dive into Ada/SPARK: https://docs.adacore.com/spark2014-docs/html/ug/en/source/co...


> Functional programming doesn't have state, so you don't need locks, so you can get better concurrency.

This is not true.

Many algorithms are intrinsically imperative (e.g., quicksort). You can represent it using some monads in Haskell to hide this, but in the end your code is still imperative; and if you want to parallelize it, you still have to think about synchronization.


It might be nice to some but man if you are not required to learn a dozen different paradigms to use it. It’s expensive (harder to teach) and not intuitive for a beginner.


Maybe Elm itself is a killer app, but certainly not elm-ui. I don't think Datomic is a killer app too. Its certainly not comparable to Rails/OSes at scale


Sorry, but I think you need to take another look at Datomic


Datomic is really neat but, for any system that operates at significant scale, I think the approximately-10-billion-datom capacity is probably too great a concern.

For example: Stop&Shop has 415 stores, and

  365 days * 415 stores * 100 purchases per day * 50 datoms per purchase
will fill up your system in 14 years without even spending datoms on inventory and the like. And that "100 purchases per day" could be low by a factor of 5 or 10 (I don't know).


Datomic shards naturally though – Datomic queries are functions that take database values as input. You can pass multiple database values as input and join across them. This is a first-class construct. I don't remember if this works in Cloud but it definitely works in onprem.


Part of Python's strength is in its ecosystem related to machine learning. That, and it is a popular language to teach to kids these days.


To this newbie, procedural is ===SO=== much easier to understand.


Actually it's the other way around. For someone who is not exposed to programming at all, it is much easier to pick up a language like Clojure. This is not merely my opinion - I have seen it multiple times, with different people.

Julie Moronuki who never had any exposure to programming at all and has a degree in linguistics decided to learn Haskell as her first programming language, just as an experiment. Not only she did manage to learn Haskell and become an expert, she co-authored one of the best selling Haskell books. I remember her saying that after Haskell other (more traditional) languages looked extremely confusing and weird to her.


I only had experience of coding in Matlab in university, and started learning Clojure in my first job. It was very intuitive.


So, I DO believe that this earnest high-level programmer is very earnest, I just don't think that he is starting with a full deck of cards. The manner in which he quickly brings up "C" and it's "killer app" being systems programming, and then jumps into the Javascript morass, it sort of suggests that he should start with first principles on how computers function.

Computers are imperative devices. I don't think that a for-loop or a map function fundamentally impede understanding of this concept. I DO think that pretending that languages that run on top of Virtual Machines need to aknowledge their dependency heirarchy and stop attempting to "level/equalize" the languages in question. One would use C in order to write a VM like V8 that then could run your scripting language. The core of Autocad is surely C++ with some lower-level C (and possibly assembler) regardless of whichever scripting language has then been implemented inside of this codebase, again, on a virtual machine.

The Operating System is a virtual machine. The memory management subsystem is a virtual machine.

Javascript runs on browsers. (Or V8, but then that was originally the JS engine of a browser) and has inherent flaws (lack of type system, for one) that limit it's use in specifying/driving code generation that could provide lower level functionality. THAT is the essential issue. VHDL and Verilog can specify digital logic up to a certain level of abstraction. C++ and C code generation frameworks can be used to generate HDL code to some degree, to the degree that libraries make them aware of the lower-level constructs such HDL's work in. I have no doubt that Pythons MyHDL presents a very low learning curve in terms of having the Python interface, but then the developer needs to be aware of what sort of HDL MyHDL will output and how it will actually perform in synthesis and on a real FPGA.

We don't need MORE layers of opaque abstraction. People need to learn more about how computers work as abstraction doesn't obviate the need to know how the lower levels work in order to optimize ones higher level code.

I can provide specific examples regarding libraries that purport to provide a somewhat blackbox interface, but upon deeper examination DO, in fact, require intimate knowledge of what is inside.

Abstractions are imperfect human attempts to separate concerns and they are temporary and social membranes.

Now, having said all of this: If a person ran a Symbolics Lisp system, such a system was holistic and the higher-level Lisp programmer could drill down into anything in the system and modify it or see how it was made.

I digress... read the source code for any magical black boxes you are thinking of employing in your work.


Some of those sources are pretty daunting...


indeed... hence the desire for blackboxes.

leaky abstractions require the occasional lid-lifting... and all abstractions have a tendency to leak somewhere or other, especially if they attempt to be all encompassing.

I think FP is certainly a viable high-level specification but ultimately there is lower-level code 'getting stuff done' (lol, "side effects") One has to be at least roughly aware of HOW ones specification is getting implemented in order to solve problems that arise and in order to optimize.

This is all the more compelling reason to cease this relentless push to "cram more stuff down the tubes" or "add more layers to the stack"

I honestly think that we need to return to KIS/KISS (keeping it simple)

SIMPLIFY and remove extraneous stuff that prevents one from having a total mental model of what is happening.


Because it is difficult and funding flows to workflows which treat software like brick laying.


‘cause software development is as far away from math as plumbing. there, don’t need to watch the video anymore.


I cannot watch the video as youtube is blocked at my office. But I can answer the premise.

OO is the norm because it is has immediate business value and is easier to teach to young people. Most programmers in the work place are produced from educational institutions. Educational institutions has competitive quantifiable

FP requires thinking in terms of calculus. This isn't hard, personally I find it much faster and easier. Thinking in calculus does require some maturity, and possibly some analytical experience, young students may not find comfortable.

---

This question can also be answered in terms of scale.

FP reinforces simplicity. Simplicity requires extra effort, often through refactoring, in order to scale or allow extension for future requirements. This is a mature approach that allows a clearer path forward during maintenance and enhancements, but it isn't free.

OO scales immediately with minimal effort. OO, particularly inheritance, strongly reinforces complexity, but scale is easily and immediately available. This is great until it isn't.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: