
* Evan Laforge
Although equal? treats the two as the *same*, they're different lists because if we modify one (e.g by set-car!) the other won't be affected.
So here comes another question: when we say a function always give the same output for the same input, what the *same* means here? ídentity or equality?
If you don't have set-car!, then identity and equality are impossible to differentiate. And haskell doesn't have set-car!.
However, as was noted, it does have something like mutable pointers via IORef, and sure enough, you can do pointer comparisons with them:
h <- newIORef 12 h' <- newIORef 12 print $ h == h --> True print $ h == h' --> False
Since they're pointers, to compare by value you have to explicitly derefence them:
print =<< liftM2 (==) (readIORef h) (readIORef h') --> True
If you're wondering about the implementation of "(1:[], 1:[])", ghc might be smart enough to do CSE in this case and hence use the same memory for both lists, but in general CSE doesn't happen to avoid accidental recomputation. There's some stuff in the ghc manual about lambda and let lifting that describes when CSE will and won't happen. I wouldn't count on it in general, but I don't read core well enough to tell. Maybe someone who knows more about core can help me here:
Very clear explanation, thanks Evan :-) -- jan=callcc{|jan|jan};jan.call(jan)