
On Thu, 11 Nov 2004 09:16:04 +0000, Adrian Hey
That's the trouble with unsafePerformIO. Haskell is supposed to be a purely functional language and the compiler will assume all functions are pure. As soon as you use unsafePerformIO to create something that isn't a function you're in grave danger, even if it "looks safe" at the local level, it still isn't a function and the damage can't be contained at the local level. It's only really OK if it still is a function despite the use of unsafePerformIO (which is possible, but often hard to be sure about).
Your first reply convinced me that supplying once as a function would be bad. I'm still not entirely convinced that hiding it in the compiler implementation of (x <- someAction) is infeasible, but as you say the devil's in the details. Even if it could be hacked to work, the added complexity is probably not worth it.
But I thought the point you were making was that the once guaranteed that the resulting value was independent of when it got reduced (presumably for any action). This isn't generally true, any more than it would be true for the x <- someAction solution if some action can be *any* IO monadic operation.
Ok, I think that's where we diverged. I was trying to be more ambition and also consider actions such as reading in a configuration file, which seems to be another common use of unsafePerformIO. The idea behind "once" is that although the return value does depend on when it's reduced, this happens at a well-defined location (namely, where it first appears in the sequence of IO actions that makes up the program). But in any event, the proposal for oncePerString/Process/Type seems like a much a more robust solution than mine. Best, -Judah