
Stefan O'Rear wrote:
Semantically, you are absolutely correct. However, there is a very subtle difference in sharing.
Consider these two functions:
foo (a,b) = (a,b) bar tuple = tuple
These two functions are denotationally identical, but at runtime one performs more allocations. If we use unboxed tuples, then the caller must always allocate if a tuple is needed; thus effectively we always get the allocation behavior of foo. That is, return unboxing is not always an optimization! However, it *is* always safe if the tuple is constructed in the function itself, for then it could not possibly be shared with anything. Having explicit unboxed tuples in the language allows this complexity to be moved out of the code generator, which is a Good Thing. (Incidentally, this is what the CPR analysis is all about - identifying places where a Constructed Product is Returned.)
hmm. so it might have to be some hypothetical syntax like (... -> {-#UNPACK#-} (a, b)) when in a data type (for some monad definition in GHC's code, so I don't want to lose performance by boxing it). (Either that or it might actually be more efficient if it were boxed!) Am I right that CPR analysis can look at particular functions, but there's no way for it to change the representation of a function stored in a data/newtype? ~Isaac