[Haskell-cafe] Serialization of (a -> b) and IO a

Dan Doel dan.doel at gmail.com
Thu Nov 11 20:16:15 EST 2010

On Thursday 11 November 2010 11:54:56 am Sjoerd Visscher wrote:
> Yes, but it would not break any existing code. It would only break code
> that knowingly did the wrong thing.

Well, if we added a function that randomly scrambled GHC's heap memory, it 
wouldn't break any existing code, because none would use it. :)

> > We already have a weak case of this, since (\x -> undefined x) can be
> > distinguished from undefined using seq, but that can be hand-waved away
> > by not worrying about bottoms so much. That isn't going to work for
> > serialize.
> Why not?

Because, there is an argument to be made in the seq case that no one really 
cares about the differences it introduces. I don't usually care how my code 
works on bottoms, except inasmuch as it determines various performance 
characteristics of the code*, or whether it works on infinite values. I try, 
generally speaking, to write total functions, and run them on well-defined 
inputs. So when I reason about the programs, it is this aspect that I care 
most about, not about what happens when I feed in undefineds.

There are even folks that have worked on making this perspective rigorous. 
See, Fast and Loose Reasoning is Morally Correct.

serialize is not at all the same in this regard. There is no class of 
functions that is immune to its inspection powers, presumably, because that's 
its whole point. But that also means that there is no class of functions for 
which we are justified in reasoning equationally using the standard 
extensional equality. The only way that would be justified is saying, 
"serialize doesn't exist."

> Then don't do that. Being able to serialize functions is just as dangerous
> as having unsafePerformIO. If you don't use it, you don't have problems.

And unsafePerformIO's very name suggests that you're breaking things when you 
use it. It comes with lots of caveats, and the Haskell community will 
generally heap scorn on you if you use it for trivialities (or even non-
trivialities). I don't understand why it would be desirable for a serialize 
function to be branded, "don't ever use this unless you're an expert who knows 
what he's doing."

unsafePerformIO is, for many uses, a concession to low-level compiler 
extensibility. You can implement a fair amount of stuff in a library using 
unsafePerformIO that would otherwise require some kind of compiler support. 
What is the analogous motivation for functions to be turned into pure strings 
containing their code?

Of course, if you want, "everything is unsafe, be careful," there are many, 
many languages out there that already do that. For instance, ML**, Lisp, C, 
Java, Python, .... But this is Haskell, and we try to do a little better than 

-- Dan

[*] Which is irrelevant to the reasoning in question. In fact, if you follow 
Bird's methodology, you first write a naive, obviously correct program, and 
then you transform it into a more efficient version via transformations you've 
shown to preserve semantics. This approach doesn't work if there are no 
correctness-preserving transformations, though.

[**] In fact, Alice ML (I think that's the right one) already has very fancy 
serialization stuff. You can store and load and send entire modules over an 
internet connection, I believe.

More information about the Haskell-Cafe mailing list