Live data from Hacker News

How side effects work in FP

chadnauseam.com

81–90 of 107 posts

Re: How side effects work in FP

#81
post #48

FP explanations like this annoy me: That is, this code: x = foo() y = bar(x) z = bar(x) Should mean the same thing as: y = bar(foo()) z = bar(foo()) Because it's obvious to anyone that has written any sort of complex program that those are not the same thing. foo() can be an expensive operation like an HTTP call. Or it might depend on a database which can change state underneath it. I assume FP has answers for these…

> foo() can be an expensive operation like an HTTP call. Or it might depend on a database which can change state underneath it.

Not in Haskell! I recommend reading the rest of the post.

Re: How side effects work in FP

#82
post #67

Earlier quoted context omitted.

I like to explain functional programs like this. Functional programs don't _do_ anything, they are a list of commands some external interpreter (what you call the runtime, but doesn't have to be a runtime) will execute or compile. Functional programs only contain descriptions of the various commands, but it is an external interpreter executing the commands. Functional programs return "recipes". "recipes" are picked u…

This I can understand. But why would someone want to do this? It feels like mental overhead. So what advantages are there to a system like this?

Referential transparency, as the original post says. For example, in a functional language you're always allowed to transform

  a = f()
  b = f()
  c = g(a, b)
into

  a = f()
  c = g(a, a)
because f() is guaranteed not to have side effects. (If it does return side effects through the IO monad, instead of actually performing the side effects, g receives two data structures that encode what IO operations to perform.) In an imperative/procedural language, f() may have side effects, and if it does the two programs are not equivalent.

This may (not) make programs easier to reason about.

Re: How side effects work in FP

#83

> Equational Reasoning Probably the best reason to use FP imo. It just cuts out so much overhead when trying to read other people’s code.

A related advantage is expression-orientated code. In ML languages, code forms a beautiful tree structure where you can see the binding definition of each binding by looking down and right. let x = something really big and complicated whereas in a language built around statements it will be scattered all over: let x = null; x = something(); x = somethingElse(x); x = anotherThing(x); In the first case the definition o…

You can get something similar via method chaining: x.something().somethingElse().anotherThing()

C# extension methods aren't the perfect solution for this, but I love that they exist to at least make chaining possible without needing to modify the class that I'm applying the function to. D has an even better version of this called UFCS which makes it so `Bar something(Foo f)` can either be called as `something(x)` or `x.something()` without needing any special annotations like C# requires.

Re: How side effects work in FP

#84
post #72

Earlier quoted context omitted.

A related advantage is expression-orientated code. In ML languages, code forms a beautiful tree structure where you can see the binding definition of each binding by looking down and right. let x = something really big and complicated whereas in a language built around statements it will be scattered all over: let x = null; x = something(); x = somethingElse(x); x = anotherThing(x); In the first case the definition o…

You are free to structure it differently: let x = anotherThing( somethingElse( something() ) );

That's worse because now you have to find the innermost function and then walk back outwards. It gets especially ugly when the calls require other parameters

    let x = anotherThing(
      somethingElse(
        something(
         x, y, z
        ), 1, 2, 3
      ), "a", "b", "c"
    );
Or maybe this looks cleaner?

    let x = anotherThing(
      somethingElse(
        something(x, y, z),
        1, 2, 3
      ),
      "a", "b", "c"
    );
Neither is easy to follow.

Re: How side effects work in FP

#85

Oh, haven't seen a monad article in quite some time. > Monads really are just a convenient way to build up action values Except when they aren't, because lists/arrays (with map) and Maybe (with map) and .. are something totally different. And that's the problem with _all_ these monad tutorials/how-tos/...: the problem is, that monads (and functors) are not burritos or elephants but _both_. So they are hard to underst…

Monads are algebraic objects that conform to certain axioms. The same way burritos and elephants can end up being groups, rings, Hilbert spaces or whatever under right conditions and right operations, many things can be monad too, under the right operation. The issue with these monad tutorials are in their very premise. They want to explain what monad is without giving its mathematical definition (and its mathematical context) but this inevitably causes significant amount of nuance to be lost.

Re: How side effects work in FP

#86

> You're viewing my site on the centralized web. Check me out on the dweb ! (Warning: it's slow.) It's really hard to take someone serious when they make big, untrue, statements saying the real web is "centralized" right on every page of their site, to peddle crypto scams. https://chadnauseam.com/reasoning-quiz > Neo-Nazis are holding a demonstration in a small town, waving swastikas around and shouting about Hitler.…

> big, untrue, statements saying the real web is "centralized"

Well, it's not completely centralized, but it's more centralized than using IPFS for the backend and ENS for the namespace. I think that's hard to debate right? If I take down my server right now chadnauseam.com will go down for everyone. But if anyone has my IPFS page pinned, it will stay up for everyone no matter what I do (barring exploits in IPFS I don't know about). So in that sense it really is more decentralized.

> Nazi sympathy under the guise of tolerance.

I don't understand why you see a quiz that gives you the option to pick either way as promoting one option over the other

Re: How side effects work in FP

#87
post #30

One benefit of describing state change as a pure data structure, instead of directly executing it, is that you may now write functions that run these state changes in different ways. E.g. you may have a dry-run function that doesn't actually change the state but only describes what it would do. Or you could have a function that generates a verbose log of all steps executed. Etc. That doesn't necessarily work for IO,…

Yeah! That's why I'm excited for the effect system to land in OCaml. In general I think effect systems are more user friendly than monads and it makes the choice of how to handle the effects more explicit.

Re: How side effects work in FP

#88
post #75
post #69

Earlier quoted context omitted.

> That just raises a different problem: y = bar(generateUUID()) z = bar(generateUUID()) You can't write that in Haskell! Instead you write something like. yuuid

Yeah, I'm not denying that these things are solved in Haskell or other FP languages. People build complex applications in those languages so all things must be possible one way or another. My complaint is that the tutorials never wade into these weeds and show how FP makes real world applications easier to build.

> the tutorials never wade into these weeds and show how FP makes real world applications easier to build

Yes that's true, and it's unfortunate.

Re: How side effects work in FP

#89

I don't speak Rust well, but I can share my perspective from Clojure, where I tend to think in data. A program is a sequence of immutable functions taking input from the world and reducing that to instructions to mutate the world (aka side effects). The world here can also be some place that stores state. Ideally mutation is the last step of the pipeline, which takes the instructions and produces the side effects. Or…

> immutable functions That doesn't sound right.

Oh you're right, having coffee at the terrace while typing on the phone, I meant 'pure' functions which take and return immutable data structures.

Re: How side effects work in FP

#90
post #18

Earlier quoted context omitted.

Somehow there is this school of thought that FP === Mirada/Haskell, go figure.

As someone who is just getting into FP I’d say Haskell was the most famous language I knew of before a month ago. Lisp might count but it isn’t widely known to be a functional language most people just think it’s a weird language.

Since you are only getting into FP, here is a list of languages that aren't FP when Haskell and Miranda are considered the only game in town.

Lisp, Scheme, Common Lisp, Clojure, Raket, Caml Light, OCaml, Standard ML, F#, Scala, MLton, Concurrent ML among other lesser known ones.

Post reply on HN