
Brian Hulley wrote:
Brian Hulley wrote:
Robin Green wrote:
<snip> So simply make strictness the default and have laziness annotations (for arguments), instead of making laziness the default and having strictness annotations.
Where would you put these laziness annotations? If you put them in the function declaration eg as in:
if' :: Bool -> ~a -> ~a -> a [corrected]
presumably you'd want the compiler to pass the args as thunks instead of evaluated values. However this means that all args to every function would have to be passed as thunks, even though for strict functions these thunks would immediately be evaluated. The problem is that there is no way for the compiler to optimize out the thunk creation / evaluation step because it occurs across the "black box" of a function call, thus we wouldn't get the same efficiency as in a language such as ML where no thunks are created in the first place.
I'm just soooo slow!!! ;-) Of course the laziness info would now be part of the function's type so the compiler would be able to generate the correct code to prepare thunks or evaluated values before calling the function. So your idea of laziness annotations for args would give the best of both worlds :-)
For an eager language, a state monad could perhaps be defined by data ST m a = ST ~(m -> (m,a)) and the other operations would work as normal without any additional annotations. (?) I must admit I'm a bit confused as to why the strictness annotations in Haskell (and Clean) are only allowed in data declarations and not function declarations, since it seems a bit random to have to guess which args can be evaluated strictly at the call site although it of course gives flexibility (eg to use (+) strictly or lazily). The type system doesn't prevent someone from writing (>>) m0 $! m1 even though the author of (>>) may have been relying on m1 being lazily evaluated... (?) For an eager language, it would seem that lazy annotations would have to be allowed as part of a function's type so that if' could be implemented. Does anyone know of a type system that incorporates lazy annotations, and/or how these would be propagated? What would the signature of a lazy map function be? map :: (~a -> ~b) -> ~[a] -> ~[b] map :: (a -> b) -> ~[~a~] -> ~[b~] etc etc - quite a puzzle!!! Thanks, Brian.