This message is directed specifically at people who are interested in the *internals* of the Glasgow Haskell compiler. If you aren't, then just delete this message. We don't have an exhaustive list of all ghc-internals users, which is why this message is going to the Haskell mailing list. Simon ********************************************** Dear ghc-internals person, We want to consult you about a proposed change to the definition of the Core data type, which plays a central role in the compiler. Because any change to Core affects virtually everyone, we thought we should propose it first before doing it by fiat! PROPOSED CHANGE ~~~~~~~~~~~~~~~ At the moment, an application (CoApp) can have an arbitrary expression as argument. Instead, we'd like to restrict the arguemnt to be atomic -- that is, a variable, literal or niladic constructor. And likewise for primitive applications (CoPrim) and constructor applications (CoCon). That's it. Incidentally, we already enforce the atomic-arg constraint for constructors; this proposal just extends the idea to primitives and general applications, and encodes it in the data type. It would be possible to enforce the constraint without changing the data type, but it seems tidier to encode the constraint in the data type itself. The atomic-arg constraint would make Core look much more like STG code; indeed STG would be more-or-less an annotated form of Core. Other things being equal this would be a Good Thing. EXAMPLE ~~~~~~~ For example, consider the following expression f (g x) In current Core it would be expressed like this: CoApp (CoVar f) (CoApp (CoVar g) (CoVar x)) [the f,g,x being suitable Ids]. Under the new proposal, you'd have to write let a = g x in f a or, in Core, CoLet (CoNonRec a (CoApp g x)) (CoApp f a) (of course, nobody writes Core, except the compiler itself!) WHY DO IT? ~~~~~~~~~~ We've found that there is a small raft of transformations which have to be duplicated if the above transformation isn't applied. For example, suppose you have let x = let y = ... in y:ys in ... It is often a Jolly Good Idea to transform to let y = ... in let x = y:ys in ... (Why? Because then x is allocated as a fixed, unchanging cons cell, rather than as a thunk which later has to be updated.) Supposing, anyway, that this *is* a transformation you want to do, there is another very similar one: f (let y = ... in y:ys) becomes let y = ... in f (y:ys) Now the argument of f is non-updatable, and we save an update as before. If function arguments are forced to be atomic, then the first transformation subsumes the second. There are several other transformations which suffer a similar duplication. The compiler becomes simpler if arguments are atomic. ANY DISADVANTAGES? ~~~~~~~~~~~~~~~~~~ I havn't been able to think of any serious disadvantages; but maybe you can (hence this msg). The only time it seems less convenient is when rearranging associative operators: (a `op` b) `op` c ===> a `op` (b `op` c) is definitely more tiresome in the let-form. But that's a very localised problem, and quite soluble. Over to you. To save troubling everyone else, maybe you should send replies direct to me, and I'll bundle them together and send them to all responders. If we hear nothing we'll just do it! Best wishes Simon