Hacker News new | ask | show | jobs
by dpatru 2352 days ago
> Why is typed functional programming measurably better than procedural? Why is it better than OOP? Definitive answers are in demand not exploratory experiences.

Functional code tends to be shorter than procedural code. This allows you to think in bigger steps. For example, to read whitespace-separated numbers from stdin and print out their sum, in haskell you could write:

    main = interact $ show . sum . map read . words
This uses very generic haskell functions to put the input into a list of strings, read each string as a number, sum the numbers and show the sum as a string.

It seems to me that the equivalent procedural code would be much longer.

Haskell's type system keeps track of what's going on and alerts you when you try to do something that doesn't make sense. For example, if you leave out the "read" function above, you would be trying to sum strings instead of numbers. Haskell's type checker would complain at compile time. This enables you to program at a high level without having to debug run-time errors because of type mistakes.

3 comments

>Functional code tends to be shorter than procedural code

Shorter is one metric that FP "tends" to be better at. But it's not definitive. Who says procedural programs can't be shorter? And also is shorter necessarily better? Also does it come at the cost of readability? Actually let's not get into readability as it's not exactly measure-able.

>Haskell's type system keeps track of what's going on and alerts you when you try to do something that doesn't make sense.

Algebraic Type systems are indeed a measure-able metric when you measure correctness, amount of errors or total possible programs you can write. It restricts the code you can compile to be correct from a typed perspective. Meaning that out of all the possible programs you can write, Haskell allows you to write less programs in the sense that it stops you from writing certain incorrect programs.

However, ADT's can be used in procedural programs or OOP programs as well. See Rust.

What I want to know is specifically about the functional programs. In the functional programming paradigm what is the quantify-able metric that makes it definitively better?

> However, ADT's can be used in procedural programs or OOP programs as well. See Rust.

Rust isn't OOP. Funnily, it's type system is pretty much the same as Haskell's but stops just before higher kinded types.

Ignoring type systems and just looking at functional vs imperative, the advantage for functional is immutability making functions easier to reason about. Haskell in particular is also lazy, and therefore enables you to not be concerned with evaluation order.

Thanks for letting me know rust isn't OOP. I never said it was. Funnily.

>Ignoring type systems and just looking at functional vs imperative, the advantage for functional is immutability making functions easier to reason about. Haskell in particular is also lazy, and therefore enables you to not be concerned with evaluation order.

Sans the part about laziness, for which the formal term is "normal order evaluation" FYI, OOP guys say the exact same thing about objects word for word.

I don't see how that could be true, as OOP is inherently about encapsulating mutation not preventing it. The problem with OOP is you're also free to alias mutable objects.

> Sans the part about laziness, for which the formal term is "normal order evaluation"

If you want to be pedantic, Haskell is 'call by need', not 'normal order'.

Sure but this is what they say and what they believe. Literally. Armies of programmers believe this and your statement won't convince them.

It always goes into philosophical mumbo jumbo. I'm looking for quantitative and logical proofs that say definitively why functional is better. You do see how your statement will just trigger a vague retort from an OOP guy which will trigger a bunch of other vague retorts and counter examples from you. The end game is it goes nowhere.

If I want to be pedantic, the official term is normal order. You are wrong on this. See SICP chapter 1.

> If I want to be pedantic, the official term is normal order. You are wrong on this. See SICP chapter 1.

SICP isn't going to help you, we're talking about Haskell's 'call by need' evaluation. It's not the same as 'normal order', feel free to look up the definition where ever you like.

I don't think a 'logical proof' is even possible, so I'm not really sure what you're asking for. We could definitely use more research on paradigms and their effects. There are a few studies on types providing benefits, but nothing that I'm aware of about FP. I think the problems stems from the fact that "functional programming" is itself a pretty loose definition.

edit: something you can read about evaluation order,

https://en.wikipedia.org/wiki/Evaluation_strategy#Non-strict...

> In the functional programming paradigm what is the quantify-able metric that makes it definitively better?

It seems extremely unlikely that you'll ever find a satisfactory answer to this, because any advantage a programming language paradigm gives you is either going to be in terms of programming language theory (which you rejected up-thread), or in terms of developer experience and productivity (whatever _that_ means). However, any rigorous study of those latter categories is likely going to be seriously confounded by their variability due to things which are _not_ related to language paradigm, such as organizational concerns, the language's tooling and ecosystem, the problem domain, the skill and experience of individual developers, &c &c. None of these things is straightforward to control for, and I'd be extremely skeptical of any quantifiable metric someone shows me that purports to show clear wins in real-world software development based on language paradigm of all things.

> is either going to be in terms of programming language theory

Programming language theory does not study "advantages;" it's simply not a question it asks, let alone answers. The theory is concerned with what properties certain formal systems have. It cannot, nor does it attempt, to assign those properties a value, just as mathematics does not ask or answer whether prime numbers are better than composite numbers.

> None of these things is straightforward to control for, and I'd be extremely skeptical of any quantifiable metric someone shows me that purports to show clear wins in real-world software development based on language paradigm of all things.

Maybe, but that doesn't matter. You cannot claim that you're providing a significant benefit and in the same breath say that it isn't measurable. An advantage is either big or not measurable; it can't be both. If you say that the benefit of the language is offset by the bad tooling, then you're not really providing a big benefit. If and when the tooling catches up, then it's time to evaluate.

But maybe not. I find it very dubious that significant differences are not measurable in an environment with such strong selective pressures for two reasons: 1. it doesn't make sense from a theoretical perspective -- adaptive traits should be detected in a selective environment, and 2. it doesn't fit with observed reality. We observe that technologies that truly provide an adaptive benefit are adopted at a pace commensurate with their relative adaptability; often practically overnight. The simplest explanation from both theory and practice to why a technology does not show a high adoption rate is that its adaptive benefit is small at best.

>Programming language theory does not study "advantages;" it's simply not a question it asks, let alone answers. The theory is concerned with what properties certain formal systems have. It cannot, nor does it attempt, to assign those properties a value, just as mathematics does not ask or answer whether prime numbers are better than composite numbers.

I think we can go deeper than this. There are properties of well designed programs that can be measured to be numerically higher or lower than poorly designed programs. Under this mentality "better" is simply a word with no meaning that is describing a number. It is the human that has the opinion that the higher (or lower) number is a "good design."

The question is what is that number and how do you measure it? For example one number off the top of my head: lines of text. Another better number is the amount of functions. Both of these numbers have flaws so maybe a better number is given a (high level language) and a (program written in assembly language); what is the largest number of high level language primitives you can use to recompose an identical program?

(high level language primitives)/(low level language primitives)

As the ratio approaches 1 we are achieving maximum flexibility as the high level language is injective to the low level primitives. As the ratio approaches zero we are reducing complexity at the cost of flexibility (we reason about less primitives). If the ratio exceeds one then we are creating excess primitives.

Maybe the better designed language/paradigm can has primitives that can used to drive that ratio back and forth from 0 to 1. A poorly designed language is one with a ratio of 4.5 or 0.0001.

So something more advanced but along the lines of this rudimentary and rough outline is certainly possible in my mind.

>But maybe not. I find it very dubious that significant differences are not measurable in an environment with such strong selective pressures for two reasons: 1. it doesn't make sense from a theoretical perspective -- adaptive traits should be detected in a selective environment, and 2. it doesn't fit with observed reality. We observe that technologies that truly provide an adaptive benefit are adopted at a pace commensurate with their relative adaptability; often practically overnight. The simplest explanation from both theory and practice to why a technology does not show a high adoption rate is that its adaptive benefit is small at best.

Yeah I agree. Additionally we're not dealing with the real world here with billions of variables. This isn't a computer vision problem. Assembly language, FP and OOP have a countable amount of primitives. It is amenable to theory and measurement.

>(which you rejected up-thread)

Where did I reject programming language theory? You mean type theory? I didn't reject it. I said it doesn't apply to functional because ADT's can be used on most programming styles outside of FP.

>None of these things is straightforward to control for, and I'd be extremely skeptical of any quantifiable metric someone shows me that purports to show clear wins in real-world software development based on language paradigm of all things.

Don't account for those things. Account for what can be measured. Cut through all the frosting and get to the main point. What is the exact definition of a well designed program when we don't factor in opinionated things like readability? At it's core their must be fundamental properties of a shitty program and a well designed one that exist outside of opinion and is pretty much universally agreed upon.

I feel to be realistic you have to show a program with failure scenarios. That is at least where i struggle with FP. Like what happens if a user enters a non-numeric value and i want to echo back a warning and get a correction, before continuing?
It's shorter in Python:

  sum(int(n) for n in input().split())
I'd argue it's an awful lot clearer, too.

Edit: A more functional version is shorter still, but I think not worth the readability cost:

  sum(map(int, input().split()))