Live data from Hacker News

What's functional programming all about? (2017)

lihaoyi.com

101–110 of 158 posts

Re: What's functional programming all about? (2017)

#101
post #47

Earlier quoted context omitted.

Consider async-await a syntactic sugar over Promises (from JavaScript). Then, Promises constitute an instance of the Monad typeclass where monadic `bind` or (>>=) is `Promise.then()`, and `return` is `Promise::resolve()`. Here is a translation of a modification of the example given in [1]: const promise1 = Promise.resolve(123); promise1.then(v => v * 2).then((value) => { console.log(value); // Expected output: 246 })…

Maybe I’m confused, but I dont see how Promise.then() corresponds to bind? If I understand correctly, the point of the bind function is you pass a callback which itself return the monad type. But the Promise.then() callback should not return a monad but just the regular result value of invoking the callback. So in essence Promise.then() is like Array.map() while bind is like Array.flatMap() Edit: It seems you are cor…

I had a caveat in my original post re. the implicit wrapping of the `Promise.then()` callback's (pure) return value in a new Promise, and how this differs from Haskell's monadic bind; I had hoped to make a loose analogy while pointing out the differences for the sake of illustration. However it is indeed also possible to return a Promise from `.then()`'s callback, which is closer to Haskell's bind: [0]

    The behavior of the returned promise (call it p) depends on the handler's
    execution result, following a specific set of rules. If the handler function:

    * returns a value: p gets fulfilled with the returned value as its value.

    [...]

    * returns an already fulfilled promise: p gets fulfilled with that promise's value as its value.
... then you can obtain a solution closer to the Haskell translation by using the behaviour of the second cited bullet point from the MDN article:

    const promise1 = Promise.resolve(123);

    promise1.then(v => Promise.resolve(v * 2)).then((value) => {
      console.log(value);
      // Expected output: 246
    });
[0] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Re: What's functional programming all about? (2017)

#102
post #68

As a programmer, I don't know if it's still relevant to make a strict separation between programming paradigms. You can use immutable types, pure functions, closures and so on in most languages. Conversely, you can define mutable types and imperative code in most functional programming languages. I'm always surprised reading comments on these topics, people saying they don't grasp FP. But don't we use higher-order fu…

There is an interesting trend where things with a strong mathematical definition tend to have the advantage. "Functional Programming" doesn't have a precise definition at all as far as I know, so it is likely it doesn't refer to a real thing. Most of the paradigms are similar as they don't seem to actually mean anything. People seem to want to describe something (in today's article, data flow) but they don't quite ha…

> Functional Programming” doesn't have a precise definition at all

It may be that different people mean different things when they talk about FP. I come from the Haskell corner and from my point of view that's a completely insane claim, at least when it comes to pure FP.

[ ] Are you writing a procedure that just processes its arguments into a return value? [ ] Does the procedure also operate on a non-static context? [ ] Does the procedure generate additional side effects?

If you answer yes|no|no, you are programming purely functionally.

The formal litmus test is the question of whether your procedure actually fulfills the definition of a mathematical function with regard to the relationship between the arguments and the return value. If it also does not generate any side effects, it is a purely functional procedure!

Then you can apply the principles of mathematical composition of functions to the construction of programs. Purely functional languages force you to program this way by default and to use special constructs for everything that has to do with side effects: IO monad, algebraic effects, The Elm Architecture.

How are you supposed to program like this? This is where (in addition to the concepts mentioned above) the higher-order functions that everyone knows come into play: map, fold, filter, flatMap, ... If you only know these and their use in impure languages, as if this were nothing formally thought through, but just a programming style for hipsters, then I can understand how the impression arises that there are no precise definitions here.

In practice, the concepts are often very distorted or not understood at all. For many programmers, OOP mainly seems to mean that you get the drop-down list with completions in Rider when you press “.”.

Re: What's functional programming all about? (2017)

#103
post #101

Earlier quoted context omitted.

Maybe I’m confused, but I dont see how Promise.then() corresponds to bind? If I understand correctly, the point of the bind function is you pass a callback which itself return the monad type. But the Promise.then() callback should not return a monad but just the regular result value of invoking the callback. So in essence Promise.then() is like Array.map() while bind is like Array.flatMap() Edit: It seems you are cor…

I had a caveat in my original post re. the implicit wrapping of the `Promise.then()` callback's (pure) return value in a new Promise, and how this differs from Haskell's monadic bind; I had hoped to make a loose analogy while pointing out the differences for the sake of illustration. However it is indeed also possible to return a Promise from `.then()`'s callback, which is closer to Haskell's bind: [0] The behavior o…

This article argues that while promises support the required operations for monad, they do not support the monad laws:

https://www.siawyoung.com/promises-are-almost-monads/

Re: What's functional programming all about? (2017)

#104
It might look like a bit of a mess, but if you look carefully, you will see

I “grasp” FP, but that pretty much sums up my experience with it. Half of its promises it delivers in the form of “you got used to read a multi-faceted inside-out mess”. I think FP is actually harmful, because it masks the fact we don’t properly teach regular programming.

Re: What's functional programming all about? (2017)

#105
post #101

Earlier quoted context omitted.

I had a caveat in my original post re. the implicit wrapping of the `Promise.then()` callback's (pure) return value in a new Promise, and how this differs from Haskell's monadic bind; I had hoped to make a loose analogy while pointing out the differences for the sake of illustration. However it is indeed also possible to return a Promise from `.then()`'s callback, which is closer to Haskell's bind: [0] The behavior o…

This article argues that while promises support the required operations for monad, they do not support the monad laws: https://www.siawyoung.com/promises-are-almost-monads/

It's a good point. `Promise::resolve()` "flattens nested layers of promise-like objects (e.g. a promise that fulfills to a promise that fulfills to something) into a single layer." [0]

The example was meant to be more of an illustrative analogy than an exact correspondence.

[0] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Re: What's functional programming all about? (2017)

#106
post #79
post #64

Earlier quoted context omitted.

I think I find a lot of FP code harder to both write and read (even code I've written myself), but when the FP code is written and compiles, it is much more likely to be correct. It's an annoying trade off, to be sure. With a language that makes writing FP code ergonomic and idiomatic, though, I'm usually going to choose to write that way. But even in languages where writing in an FP style is a chore (if it's even po…

>it is much more likely to be correct It is not. FP programs measurably have at least as many defects as non-FP programs. There is literally no reason to subject yourself and, worse, your users, to the garbage of FP.

I even know where this comes from. Some very popular circa 2000 book on programming that coined this dogma without a proof, based on the fact that writing a type-correct program in haskell isn’t trivial.

Re: What's functional programming all about? (2017)

#107
post #9

Interesting how the post doesn't mention the word "side effect" once. To me, all of this could be summarized by "no side effect".

No, as in zero, (side) effects means no program for most domains.

For me, the essence of FP is the minimization of global state

Re: What's functional programming all about? (2017)

#108

Earlier quoted context omitted.

> The genuine core feature of FP is the separation of data and methods Couldn't disagree more. Based on this definition C language would be the epitome of functional programming... but it is not.

That's exactly what the parent comment said, since C is an imperative programming language: > The genuine core feature of FP is the separation of data and methods, that stands in contrast not to imperative programming but object oriented programming, whose core feature is fusion of data and methods

Yes, the original comment posits that functional programming and imperative programming are the same thing, but that does not address the practical concerns of the parent. The harsh reality is that we have both "functional programming" and "imperative programming" terms with an intent for them to have different meanings.

Let's accept temporarily that functional programming and imperative programming are, indeed, the same thing. But now you have two terms with the same meaning still wanting to mean something different. A conflict in need of resolve. So, from this point forward what can we say that makes them different?

A trait I often see in languages that are considered functional, and not found in C, is the closure. Its purpose is to bind data with functions. That suggests to me that, as we seek a division in meaning, separation of data and functions is better left for the imperative definition rather than the functional definition.

Perhaps functional programming is best described as the intersection of imperative programming with "OO" programming? That seems to be the view the original commenter ends up taking in subsequent comments.

Re: What's functional programming all about? (2017)

#109
post #68

Earlier quoted context omitted.

There is an interesting trend where things with a strong mathematical definition tend to have the advantage. "Functional Programming" doesn't have a precise definition at all as far as I know, so it is likely it doesn't refer to a real thing. Most of the paradigms are similar as they don't seem to actually mean anything. People seem to want to describe something (in today's article, data flow) but they don't quite ha…

> Functional Programming” doesn't have a precise definition at all It may be that different people mean different things when they talk about FP. I come from the Haskell corner and from my point of view that's a completely insane claim, at least when it comes to pure FP. [ ] Are you writing a procedure that just processes its arguments into a return value? [ ] Does the procedure also operate on a non-static context?…

I also come from the Haskell corner and I agree with roenxi. I don't think that FP is a well-defined concept, nor do I understand your characterization of pure FP. Let's take a simple program

    main = do
      v 
and have a look at the conditions you laid out

* Are you writing a procedure that just processes its arguments into a return value?

  No, it has no arguments and its return value is just (), but it does more besides.
* Does the procedure also operate on a non-static context?

  Yes, it operates v
* Does the procedure generate additional side effects?

  Yes, it prints to the terminal.
So I have answered no | yes | yes, the exact opposite of what I should have to be classed as doing pure functional programming.

You might say "Ah, but the return value of `procedure` is not (), it's IO ()", but I don't see that that changes anything. I can write my entire program in IO if I want, in a way that's hard to distinguish from having written it in, say, Python. Is that not pure functional programming, despite the fact that it's being carried out in Haskell? Then you might say "Ah, but the difference is that you could have written your program purely, without IO". But again I fail to see how that differs from Python. I can write programs that don't do any IO in Python too.

So what is it that makes Haskell a pure functional language and Python not?

My response to all this is that the notion of "pure" is very unhelpful and the correct way to describe this property that Haskell has is "referential transparency", that is

    let x = rhs in ... x ... x ...
has the same result as

    ... rhs ... rhs ...
regardless of how many times (or zero) x occurs.

Re: What's functional programming all about? (2017)

#110
post #104

It might look like a bit of a mess, but if you look carefully, you will see I “grasp” FP, but that pretty much sums up my experience with it. Half of its promises it delivers in the form of “you got used to read a multi-faceted inside-out mess”. I think FP is actually harmful, because it masks the fact we don’t properly teach regular programming.

While I agree that that's the case for the promises in many such tutorials, I think this article explicitly shows that that isn't inherent to the thing that FP is about.

Your quote is specifically about the code formatted in such a way, with arrows drawn all over it, to match the box diagram. But if you look at the code as it would actually be written, in a functional style:

        def make_tiramisu(eggs, sugar1, wine, cheese, cream, fingers, espresso, sugar2, cocoa):
            beat_eggs = beat(eggs)
            mixture = beat(beat_eggs, sugar1, wine)
            whisked = whisk(mixture)
            beat_cheese = beat(cheese)
            cheese_mixture = beat(whisked, beat_cheese)
            whipped_cream = whip(cream)
            folded_mixture = fold(cheese_mixture, whipped_cream)
            sweet_espresso = dissolve(sugar2, espresso)
            wet_fingers = soak2seconds(fingers, sweet_espresso)
            assembled = assemble(folded_mixture, wet_fingers)
            complete = sift(assembled, cocoa)
            ready_tiramisu = refrigerate(complete)
            return ready_tiramisu
...then surely you would agree that that doesn't look like a mess at all, compared to the imperative version a couple of lines below it? And yet, it brings all the benefits described in the following paragraphs!
Post reply on HN