On 6 Oct 2012, at 23:58, Ralith <
ral...@gmail.com> wrote:
> Is it generally true that IR case statements must handle values of
> every type (by jumping to the default alternative when a type other
> than that which they were written for is supplied?), or is it just
> EVAL that behaves specially in that regard? The former possibility
> seems counterintuitive, given how strongly typed the source language
> is. Would the IR optimization passes you describe make the
> aforementioned assumption completely safe again?
Here's the problem - the following things all have type Nat:
O
S O
plus (S O) (S O)
head []
The following things all have type Int:
6
42
factorial 8
head []
(Of course, if you require everything to be total, the last one goes away in each case)
Yes, you know what type they are, but you don't know in general at run-time whether they're in normal form. This is an important part of the operational semantics that the type system doesn't tell you. The idea with EVAL is to make sure that any function which needs to inspect a value knows that that value is in head normal form, so you can safely inspect a constructor or integer and know the range of values it can be.
The next trick is to eliminate the calls to EVAL where it is known at compile time that a value must be in head normal form.
> This brings to mind another tangental question: What motivated the
> decision to use defunctionalization instead of (what I understand to
> be) the more common practice of passing function pointer+environment
> structs around? If it was merely the observation that not all targets
> support that sort of thing, would it be reasonable for codegen for a
> particular target (e.g. LLVM) to take this approach?
I wanted to try defunctionalisation because I wanted to see what would be the benefits and drawbacks of moving EVAL and APPLY out of the runtime system, and making them representable in the IR. It seems to be a good idea, in a language that is supposed to help you prove things, to have a very simple run time system and easily explainable (and formalisable) transformations from one step to the next.
There's nothing to stop you using the higher level representation, and it may make sense for some backends, but if so you'll have to implement EVAL and APPLY yourself, and you may lose any optimisations that take advantage of them being IR code. There's some other things I want to try too, e.g. serialising closures for web/cloud programming.
Edwin.