Re: Lifted Tuples
Paul writes | It has occurred to me that unlifted tuples achieved via a special | "newtype" decl are not the same as those achieved with strictness | annotations. This is because with "newtype" it seems that people want | a situation where (_|_,_|_) = _|_. But with strictness annotations on | both arguments a few other things also happen: | | (x,_|_) = _|_ | (_|_,y) = _|_ Well said--This is what I was trying to say the other day, that with the strictness annotations on lifted tuples we would have unlifted, but not lazy products. Anyway, I don't think this (by itself) will do. --Joe
Re: Lifted Tuples
Regarding Lifted vs. Unlifted Tuples I pretty strongly agree with the general oberservation that "tuples for free" is a Good Idea, whether it be motivated from ADT's (as Simon first did), from function results (as Joe did), or as function arguments/currying (as Phil did). I think HOW we get them is the real question. I admit that strictness annotations on a single-constructor data decl are kind of a hack, and I kind of like the notion of having a separate decl for this purpose (Phil's "newtype" seems best, but I'm not picky). On the other hand, the following obervation may be worth considering: It has occurred to me that unlifted tuples achieved via a special "newtype" decl are not the same as those achieved with strictness annotations. This is because with "newtype" it seems that people want a situation where (_|_,_|_) = _|_. But with strictness annotations on both arguments a few other things also happen: (x,_|_) = _|_ (_|_,y) = _|_ where x and y are arbitrary values. This version is obviously less defined than the other, but has the nice property that it can be an instance of the class Strict with a SEQUENTIAL method for "seq" (i.e., parallelism isn't required) that does what is "expected" (i.e., SOMETHING gets evaluated, despite Joe's excellent attempt to argue that this isn't what we should expect! :-). Furthermore, I believe (someone correct me if I'm wrong!) that the following isomorphisms still hold: (a,(b,c)) = ((a,b),c) = (a,b,c) (a,b) -> c = a -> b -> c -Paul
Re: Lifted Functions
Regarding Lifted vs. Unlifted Function Spaces - Gee, maybe lifted functions aren't such a good idea after all! (:-) But before reaching that conclusion, there are a few points that need clarification. In particular, Simon mentions two problems that I think need further discussion: First, Simon points out that this version of putString: putString = \cs -> case cs of (c:cs) -> \s -> case (putChar c) of (_,s') -> putString cs s cannot be transformed into this version: putString = \cs s -> case cs of (c:cs) -> case (putChar c) of (_,s') -> putString cs s if we have lifted function spaces. True! However, one of the motivations (for me, at least) for having lifted function spaces was so that we could define strict as well as non-strict functions. I suggested earlier that there might be an "annotation" for doing this, just as LML does for strict constructors. Using "!" for such an annotation, the following version of putString IS equivalent to the first above: putString = \!cs s -> case cs of (c:cs) -> case (putChar c) of (_,s') -> putString cs s The root of this transformation is the following: \cs-> case cs of (c:cs) -> \s -> exp<==> \!cs s -> case cs of (c:cs) -> exp In fact, we can observe the following two tidy transformations as being valid over lifted function spaces: f cs s = case cs of (c:cs) -> exp<==> f ~(c:cs) s = exp f !cs s = case cs of (c:cs) -> exp<==> f (c:cs) s = exp So, we could have lifted function spaces and Simon could still achieve his transformation safely. Simon's second problem is the following: Consider f x y = x+y Quick! Is this strict in x? Would your answer be any different if I wrote f x = \y -> x+y orf = \xy -> x+y (I hope not.) The point is this. We would usually say that f is strict iff f _|_ = _|_ But, if function space is lifted, then f _|_ is certainly not _|_! So is f strict or not? Blargh. Jonathan Young and I observed this distinction in our POPL '84 paper on higher-order strictness analysis (Alan Mycroft and Christine Ernoult recently re-did our stuff in a more semantically sound way which will soon appear in JFP). One must in fact make a choice about primitives such as (+). You can have either: (+) _|_ = _|_ or (+) _|_ = \y -> _|_ (Just because _|_ /= \x->_|_ does not mean that there can't be functions which when applied to _|_ yield _|_! putString is one such function.) To get the first behavior out of f above, one could write: f !x y = x+y I agree that this may complicate strictness analysis, although I think (but don't know for sure) that it is manageable. -Paul P.S. Similar arguments can be used to explain Ian's examples given in a subsequent message (and it should be pointed out that "symmetry of arguments" is not something lost with lifted function spaces, because Haskell never had it to begin with! :-)
more GHC 0.18 ("hackers' release") files available
In pub/haskell/glasgow/working on ftp.dcs.glasgow.ac.uk: -rw-rw-r-- 7588053 Nov 5 20:27 ghc-0.18-bin-sun4.tar.gz -rw-rw-r-- 141709 Nov 6 11:17 ghc-0.18-hi-files-ghc-0.16.tar.gz -rw-rw-r-- 101853 Nov 6 11:16 ghc-0.18-hi-files-hbc.tar.gz -rw-rw-r-- 3028811 Nov 5 19:40 ghc-0.18-src.tar.gz -rw-rw-r-- 3497 Nov 5 19:52 ghc-0.18.ANNOUNCE That's Sun4 (SunOS 4.1.x) binary stuff [no instructions -- I assume hackers know what to do :-], and 0.16- and hbc-produced .hi files for ghc/compiler/*/*.hi, in case you choose to compile with one of those. (The source distrib has 0.18-produced .hi files in it.) Will