Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The "world" equivalence is not a useful way to think about it. A more useful description would be a tuple that contains two items, the first one being the description of the action to execute, and the second one being the function that will be called with the value retrieved with the action executed.

So in JS notation:

  { action: {type: 'readFile', fileName: f}, next: content => mkPrintAction(content) }


> The "world" equivalence is not a useful way to think about it.

Regardless of your opinion on the matter, that's how it's actually implemented. IO is roughly equivalent to "State RealWorld#" with some extra strictness/unboxing stuff.

What you're talking about is basically the free monad over the (Request, Response -> a) functor. That would probably work, but be less performant and harder to extend.

IO is nice because it's really easy to safely integrate with FFI calls. I don't think you could easily do the same with your proposal.


Its just that when you mention this, the assumption is that "World" is the state of the world. Which is not true, since world is just a token to impose ordering of execution in a lazy language, but its a fake state token since its not present at run time... and that complicates the explanation further.

The interpreter is simpler and easy to implement in any language too.


That's true, the compiler does optimize away the explicit dependency on the world. But it still makes sense; when you call "print", it returns a "new world" that is the state of the world after printing. You can't inspect the state of the world, so it doesn't really matter whether it's just a token or an actual description of the universe. The behavior is indistinguishable either way.


That assumes there is only one program running in the world. Its simply not clear what the "world" type means. Its a bad name. I'd rather go ahead and explain it as a token.


I don't see why it assumes there is only one program. If the world value is impossible to inspect (which it is), you can assign whatever semantics you like to it.

If you look at the generated core code, it's important to notice that it's not the same "token" being passed around everywhere. Each IO action returns a new token, which could be a different value from the old token. (Again, this is entirely theoretical, as the token/world state doesn't exist in the binary.)


Ok, I'll put it this way:

Saying

> when you call "print", it returns a "new world" that is the state of the world after printing

makes no sense, since the word "state of the world" will be interpreted completely differently by the receiver of the explanation. State of the world = a large state object with lots of fields describing every single thing in some "World" (what world: program world? computer world? network world? all the world?). Thats what people hear.

The name of the type is horrible, and the world-passing intuition is also horrible. "Token" would've been much better, but its still not clear how to implement or why its even necessary (in a non-lazy language)

On the other hand, a tuple representing the current action and the function that will return the next action (or nil) is fairly clear, easy to implement an interpreter for, the pure/nonpure distinction becomes obvious (the runtime interpreter is the impure part), and laziness doesn't even need to get into the mix.

oh, and also regarding FFI: {type: 'FFICall', fn: string, arguments: [...]}


That's a fair argument. People might get caught up on thinking that the world object actually has to contain a description of the world.

> {type: 'FFICall', fn: string, arguments: [...]}

I agree that this is simpler to understand, but it's no good in practice. It's obviously not type safe, and you still have to bake support into the interpreter/runtime for whatever your string value is. It's also effectively impossible to inline/optimize away. Which, again, is probably why it's done using "State RealWorld#" in GHC.

I would like to reiterate that however RealWorld# happens to be defined, the way its use is enforced in GHC is the exact same as if it did actually contain a description of the entire universe. You just aren't allowed to look at it. But, you are correct, this is more confusing than a request/response free monad.




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

Search: