Live data from Hacker News

How side effects work in FP

chadnauseam.com

101–107 of 107 posts

Re: How side effects work in FP

#101
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?

You can reason and compose pure effectful programs leveraging referential transparency.

Re: How side effects work in FP

#102
post #20

Something that I always found funny is that main clearly has to take something as input (otherwise it would not be able to produce different output between runs). So in GHC the main method (main :: IO()) internally takes a value of type RealWorld (theRealWorld) and returns the new RealWorld produced by running the program. I imagine by the time it's lowered to actual assembly they've dropped that, but I've never deal…

I am not at all an expert on GHC's codegen, but having glanced at that code before (mostly to get an intuition of what IO is under all that sugar), RealWorld doesn't even... exist. Realworld and its close friend, State# are tokens of sort. they're zero-sized and deeply magical (the GHC.Prim is quite enlightening to read). All the primops are defined as infinite loops... it's quite a sight to behold. As something tota…

Oh of course - I only ever worked with the GHC Core language which is completely and explicitly typed so it was especially blatant :D

I do understand that in reality it's simply a tag value to ensure that the compiler correctly orders and threads operations correctly, but I still think it's semantically cute :D

Re: How side effects work in FP

#103

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 mathematica…

A "mathematical object" in this case is a description of how the object is expected to behave.

But even so, I think something is lost in reducing monads to a clump of related behaviors and properties. You still need intuition about what these behaviors actually mean and what kinds of real-world objects actually conform to these properties.

So you are right that monad "is not" a nondeterministic computation or a container or whatever, but a monad "is" a common set of behaviors/properties that we should expect nondeterministic computations and containers to conform to.

Abstraction without intuition is obfuscation!

Re: How side effects work in FP

#104
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?

“Have you tried turning off and on again?” is advice to perform a total state reset, which works because the system’s state is inconsistent but its sources of truth are not.

You never have to reset state if you do not have it in the first place. You get other bugs still, but you don't have the most common class of bugs.

But, you need some state. You just want to discourage it. Some of it can come from laziness, but with difficulty. (Chris Okasaki’s Purely Functional Data Structures uses it to de-amortize the bound on a FIFO queue.) Other things, like ring buffers, are harder to argue.

So you want to be able to express an array of IORefs, say, for your ring buffer. But the people who use it become aware that it is a stateful construct and must be used that way.

Read “what color is your function?” for a counterpoint, of course.

Re: How side effects work in FP

#105

Earlier quoted context omitted.

They probably mean Haskell. Note: I don't know Haskell, so below is speculation. To log you need IO. To get IO you need to provide it to the function that will do logging. And now your function has to be marked as doing IO. So now you need to thread all that IO through all your functions, and "turn you code into monadic code" (I think that's the term). Other languages (like Erlang) don't care, and you can log wheneve…

And here we see the damage caused by the modern OOP. People that complain about that want to replicate in Haskell the lob4j philosophy of adding logging into every interface, because with data and IO chunked everywhere inside object interfaces, you never know if you can ever repeat an execution in a development environment to verify it. The thing is, if for some reason you really think you need to log inside a pure f…

> And here we see the damage caused by the modern OOP. People that complain about that want to replicate in Haskell the lob4j philosophy of adding logging into every interface

And here we see a person slinging unsubstantiated accusations

> if for some reason you really think you need to log inside a pure function, you either need an intermediate variable or your perceived needs are severely misguided.

Clear demonstration of "it looks like hardly anyone is doing any useful logging in Haskell".

Because, as we know, the fact that "you can repeat an execution" immediately makes your need to log anything in that execution as "misguided".

Re: How side effects work in FP

#106
post #84
post #72

Earlier quoted context omitted.

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.

I take you are no big fan of Lisp? /s

Well, actually I agree with you - sometimes. I have actually written helper functions to get similar pipeline processing capabilities in js.

    function pipe(...args) {
      return args.reduce((x, fn) => fn(x), null);
    }

    pipe(
      () => 2,
      (x) => 7*x,
      console.log
    )

Re: How side effects work in FP

#107

Earlier quoted context omitted.

And here we see the damage caused by the modern OOP. People that complain about that want to replicate in Haskell the lob4j philosophy of adding logging into every interface, because with data and IO chunked everywhere inside object interfaces, you never know if you can ever repeat an execution in a development environment to verify it. The thing is, if for some reason you really think you need to log inside a pure f…

> And here we see the damage caused by the modern OOP. People that complain about that want to replicate in Haskell the lob4j philosophy of adding logging into every interface And here we see a person slinging unsubstantiated accusations > if for some reason you really think you need to log inside a pure function, you either need an intermediate variable or your perceived needs are severely misguided. Clear demonstra…

What exactly do you expect to gain by logging inside a pure function?
Post reply on HN