[Haskell-cafe] Serialization of (a -> b) and IO a
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
[*] 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