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

From: Sjoerd Visscher
On Nov 11, 2010, at 3:36 PM, Dan Doel wrote:
On Thursday 11 November 2010 6:22:06 am Sjoerd Visscher wrote:
The reasoning above is used regularly to shoot down some really useful functionality. So what would go wrong if we chose to take the practical path, and leave aside the theoretical issues?
You would lose many uses of equational reasoning in your programs. Have you every substituted 'x * 2' for the expression 'x + x' in one of your programs, or vice versa? You can no longer do that, because someone may be serializing the function you're writing, checking how it's implemented, and relying it.
Yes, but it would not break any existing code. It would only break code that knowingly did the wrong thing.
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?
I don't know to what extent it would apply in this hypothetical situation, but ghc (and probably other compilers) rely upon Haskell's semantics in performing various code transformations. If you break the semantics some transformations become invalid, resulting in incorrect code. I've experienced this with code that violated ref. transparency. The program behavior changed depending on the compiler's optimization settings. I'm not keen to go back to that. I think the only way this would work would be if you consider functions to be equal only to themselves, i.e. "x+x" and "2*x" are not equal. That's not a trade-off I would be willing to make. John

On Nov 11, 2010, at 6:34 PM, John Lato wrote:
I don't know to what extent it would apply in this hypothetical situation, but ghc (and probably other compilers) rely upon Haskell's semantics in performing various code transformations. If you break the semantics some transformations become invalid, resulting in incorrect code.
I've experienced this with code that violated ref. transparency. The program behavior changed depending on the compiler's optimization settings. I'm not keen to go back to that.
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. -- Sjoerd Visscher http://w3future.com

On Thursday 11 November 2010 12:34:21 pm John Lato wrote:
I think the only way this would work would be if you consider functions to be equal only to themselves, i.e. "x+x" and "2*x" are not equal. That's not a trade-off I would be willing to make.
In general, it doesn't even have to be based on a mathematical identity. As has been stated, this would in general simply break referential transparency. Are these two functions equal: f x = k (h x) (h x) g x = let y = h x in k y y Presumably, no, if serialize exists (and they may have different performance characteristics). You cannot factor out or inline subexpressions or without the difference being observable (presumably) by serialize. -- Dan

On Thu, Nov 11, 2010 at 10:28 PM, Dan Doel
On Thursday 11 November 2010 12:34:21 pm John Lato wrote:
I think the only way this would work would be if you consider functions to be equal only to themselves, i.e. "x+x" and "2*x" are not equal. That's not a trade-off I would be willing to make.
In general, it doesn't even have to be based on a mathematical identity. As has been stated, this would in general simply break referential transparency. Are these two functions equal:
f x = k (h x) (h x) g x = let y = h x in k y y
Presumably, no, if serialize exists (and they may have different performance characteristics).
You cannot factor out or inline subexpressions or without the difference being observable (presumably) by serialize.
Yes, exactly. Thanks for this example, because it illustrates better how far-reaching this would be. And it's true not just when these transformations are manually performed, but also when they're performed by the compiler. Haskell without referential transparency simply wouldn't be Haskell any more. And any code that used a pure serialize may or may not work, depending on compiler magic. Of course, this is presuming that serialize is pure. I suppose it might be possible for a serialize with type "a -> IO ByteString" to just dump stack+heap+whatever. You could use TH+Hint, LLVM, or likewise to get a similar effect now. John
participants (3)
-
Dan Doel
-
John Lato
-
Sjoerd Visscher