
Well, than, what would you expect from this:
let {f x = g x; g 0 = 0; g n = f (n-1)} in show f
Well, not show, because any show instance for functions breaks r.t. But the interactive interpreter, if it is not subject to r.t., might show:
let { f x = g x; g 0 = 0; g n = f (n-1) } in f
Actually, most of those reduction systems were strongly, but dynamically typed, so the original example would give something like this (no reductions possible): let {f x = g x; g 0 = 0; g n = f (n-1)} in show f And if you applied something like 'show' to something it can work with (let's wrap it in a function to make things interesting), \x->show [1,2] you might get, unsurprisingly (but watch your representation levels!) \x->"[1,2]" As far as referential transparency is concerned, you'd need to keep your reference levels straight, which can seem confusing if you can only communicate via representations(*:-) The easy part is semantics and inverse eval :: representation -> meaning reify :: meaning -> representation Since several program representations can have the same meaning, the inverse is not usually a function, but a relation, so Haskell picks a partial implementation of 'reify', named 'show', applicable only to things that have a uniquely determined representation. And since Haskell implementations can't display things by themselves, they use 'show' to show at least some things. Now for the tricky part: as we write down or implement a semantics, we're using a secondary level of representation, so we have representations of program representations and representations of program meanings (we might say that the 'semantics of 3', '[| 3 |]', is the number '3'). In other words, we have a representation of 'eval' that maps representations of representations to representations of meanings. So when we write down a program, it is a program to us, but just a string to be interpreted for the implementation. And the implementation can give back a representation of the meaning to us, without ever passing such representation to other parts of the program (no 'show' involved). Concretely, we type in '(\x->\y->x+2) 1', and the implementation gives back '\y->3' without having to support any kind of reification operation in the program itself - no problem with referential transparency there. Claus (*:-) ".. The name of the song is called `Haddocks' Eyes'" "Oh, that's the name of the song, is it?" Alice said, trying to feel interested. "No, you don't understand," the Knight said, looking a little vexed. "That's what the name is called. The name really is `The Aged Aged Man.'" "Then I ought to have said `That's what the song is called'?" Alice corrected herself. "No, you oughtn't: that's quite another thing! The song is called `Ways And Means': but that is only what it's called, you know!" "Well, what is the song, then?" said Alice, who was by this time completely bewildered. "I was coming to that," the Knight said. "The song really is `A-sitting On A Gate'.." (Lewis Caroll, Through The Looking-Glass)