Hacker News new | past | comments | ask | show | jobs | submit login

The second link. It's not strictly defined. You can piece together the definition from your intuition as a programmer and english speaker and also by what I write. If you have trouble doing this, let me know I can clarify.



My whole point - the one I've been trying to make in every comment in this thread - is that if you want to talk about "FP" as a whole (or "OOP" as a whole), you have to explicitly define it. Relying on intuition or culture is not enough.

Like, I use what I think of as FP features much more than I do what I think of as OOP features. In languages commonly thought of as multi-paradigm, say python, I have lots of higher-order functions, and lots of functions which are just compositions of others (I don't write point-free style though). I try hard to avoid implementation inheritance ("OOP inheritance") if possible. I know people who do the exact opposite thing in python.

But if I write down the definition of "FP" for me and you write down your definition, I 99% guarantee you they'll be different in a substantive way.

So I agree with many of the points you make in the links about how composition works in (what you think of as) FP vs OOP. But I view that as claims about individual design patterns or language features (and very big, fundamental design patterns / language features), not as things called "FP" and "OOP".


>My whole point - the one I've been trying to make in every comment in this thread - is that if you want to talk about "FP" as a whole (or "OOP" as a whole), you have to explicitly define it. Relying on intuition or culture is not enough.

I am aware this is your point. I understand your point. I don't know about you, but I find a conversation of your definition of a term vs. my definition of a term to be uninteresting. Arguing about semantics doesn't matter in my opinion.

>You define "FP" to be (what I claim is) a way that's too narrow. Your splitting the design space into different paradigms is (I claim) not substantiated.

>So I agree with many of the points you make in the links about how composition works in (what you think of as) FP vs OOP. But I view that as claims about individual design patterns or language features (and very big, fundamental design patterns / language features), not as things called "FP" and "OOP".

Your own statements show that you have already derived from my writing what you think I define as FP and OOP. You also implied something about what you believe I defined as "design" saying that I splitted it into "spaces" of different paradigms.

So why is there a need for me to explicitly define a definition for you when you already derived it from my writing? Is this your whole point? That your definition of OOP, FP and design is different from my definition but you understand what I'm talking about? Or is there another point you're trying to make?

Just to refocus: The topic of our thread is basically the rationale behind why I draw the line at function composition as the main point of FP. Given my definitions of OOP, FP and Design, do you understand why I have this rationale? And if you understand my rationale do you agree with it or disagree?


> Is this your whole point? That your definition of OOP, FP and design is different from my definition but you understand what I'm talking about? Or is there another point you're trying to make?

Let C1 be the following claim: "function composition is better behaved than object composition and procedure composition".

Let C2 be the following claim: "the most important part of FP is function composition".

I'm saying that you've provided arguments for C1 (that I mostly agree with). So let's say that I agree with C1. However, you haven't shown why C1 => C2, and I disagree with C2.

So to answer your question, I understand your rationale for C1 (and I agree with it), but I don't understand your rationale for C2, or for why C1 => C2.


>Let C1 be the following claim: "function composition is better behaved than object composition and procedure composition".

>Let C2 be the following claim: "the most important part of FP is function composition".

C9 = functional programming is better designed than OOP and procedural programming.

  I claim C1 to be true (you agree.)
  I claim C2 to be true.
  I claim C9 to be true.
  I do not claim C1 => C2

  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Reasoning for C2:

C3 = The primary task of High level programming languages is to simplify assembly instructions.

C4 = The simplification of assembly instructions is done through Composition.

C5 = Different High level programming languages/paradigms simplify assembly primitives in different ways.

C6 = High level programming languages/paradigms are, in essence just different ways of composing assembly primitives.

(C3, C4, C5) => C6

C7 = If programming languages are all just different ways of composing assembly primitives than how they compose assembly primitives is the most important part of the language and the main differentiator between one high level language and another high level language.

C8 = function composition is the primary form of composition for functional programming.

(C6, C7, C8) => C2

  ---------------------------------------
In short:

- High level programming languages/paradigms are, in essence just different ways of composing assembly primitives.

- If programming languages are all just different ways of composing assembly primitives than how they compose assembly primitives is the most important part of the language and the main differentiator between one high level language and another high level language.

- function composition is the primary form of composition for functional programming.

Therefore: the most important part of FP is function composition.

  -------------------------------------------

  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Reasoning for C9:

C8 = "A Design for a programming language" is just another phrase for "a method of composition for a programming language".

(C1, C8) => C9

  -----------------------------------------------
In short:

- function composition is better behaved than object composition and procedure composition

- "A Design for a programming language" is just another word for "a method of composition for a programming language"

Therefore: functional programming is better designed than OOP and procedural programming.

  ------------------------------------------------

I like this format, thanks for introducing it. I think it allows us to clearly see which axioms we disagree with and need to think about.


I guess the claim I disagree with is C8:

C8 = function composition is the primary form of composition for functional programming.

Most people consider Haskell to be a language that heavily encourages a "functional programming" style. If you take a look at idiomatic Haskell code, yes, you see a lot of function composition. But I think you also see a lot of composition that are distinct from "simple" function composition:

- Parametric polymorphism

- 'Monadic' composition (i.e. `>=>`)

- Applying higher-order functions


- Parametric Polymorphism is a way to define types or functions that are generic over other types. There is no composition going on here. So I disagree with you here.

- You bring up a good point about monadic composition and other forms of more advanced function composition. Although I don't explicitly mention these types of compositions my words encompass these forms of compositions as well. Additionally, technically the >=> is still "function composition" and "point free programming" as the operands and resulting composition are all still functions getting composed.

- Applying higher order functions? Do you mean function factories that take a function and return a new function?

So like C = A(B) where A, B, C are all functions and C is the "composition" of A and B?

The above shares an isomorphism with dependency injection. If A B and C were objects the syntax is exactly the same.

So I mention this in my second link as one of the caveats of OOP. This type of composition is equivalent to dependency injection or object composition. "A" cannot exist on it's own without "B." This is a bad form of composition. as "A" is dependent on "B".

If you do too much of this in your programs, then, like doing an excessive amount of dependency injection or object composition in OOP, your program will lose flexibility as it becomes a network of dependent primitives. Qualitatively, it also makes your code look like a giant mess if you do this everywhere.

That is why the above form of composition is not primary. If used at all it is only used sparingly and usually only on well known higher order functions like map, reduce or compose.

Caveat: It does get blurry here as the composition operator is in itself a function that takes in functions and produces a new function. This is where the isomorphisms between OOP, FP and procedural programming I talk about in the comments on that Quora post begins to meld the paradigms together.


You will note that you and many other FP programmers have gotten away with FP programming without doing a single line of actual function composition yet still yielding much of the same design benefits from the point free style.

This happens because the isomorphism between applicative and composition is really really close. I advocate the point free style for educational purposes, but for practical purposes either style is fine.

I get into the isomorphism briefly here: https://news.ycombinator.com/item?id=22299297

Where |> is the application operator. x |> f = f(x)




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

Search: