
== Refactor the Thunk and Param nodes

Make Thunk a List containing (body, params) or even a map (body => node, params
=> [...]).

Override Thunk's fmap to not fmap over the params. They can not and should not
ever be reduced - it is the thunk reducer's responsibility to.

* Provide type analisys
* Remove and bind items from the parameter stack an App provides (perl backend)

In fact, Param should not inherit Blondie::Node at all (but a constructor
should still be exported from Blondie::Nodes, or incorperated into the thunk
constructor).

Affected code:

* placeholder type inferrencing
* thunk type constructor
* reduce_thunk, reduce_param and possibly reduce_app everywhere

This frees the Seq node to mean what it really means, instead of being the hack it is.

The perl interpreter can have its own type of prim, and can compile thunks
into a seq that pops params of the stack, but that sounds more work than the
efficient version ;-)

= Add support for list types

Initially implement with perl arrays in Vals, e.g.

	Val([1, 2, 3])

This requires some modification of the type constructors

= Make the example interactive

Provide a prompt to choose a runtime

All runtimes must provide ->run, so just use that

Generalize the Perl::Silly backend to be Blondie::Backend::OpMasking, that can
wrap any backend and filter the ->provides method call to illustrate hash
replacing.

= Medium

== AST level branching

Right now if prelude builtin provides thunks to the <?? !!> operator. The
ternary operator is actually pretty broken - it evalutaes both its params, and
then returns one, so if takes thunks, evaluates the condition, asks ?? !! to
return one of the thunks, and then applies that thunk.

We need support for branching at the top level of the AST for various analyses,
and it also makes much more sense.

However, if, &&, ||, c-style-for-loop, while etc are all *functions* that are
implemented in terms of the branch node. This way they can be implemented
circularly, and the emitter may do whatever it pleases at the emission level,
but only really needs to implement branch.

Affected code:

* most reducers will need a new reducer
* runtimes will need to be updated

== Type infer higher order functions

Allow the reduction helpers for * and ** in the prelude to be statically typed

A generics approach could be used for unboxing. We have to decide who is
responsible (the type annotator, or the emitter).

After this is done, make the annotator stop creating separate annotations for
duplicate nodes and simplify the C emitter's duplicate node finding code.

== Refactor type inferring code to use better constructions of the type object

The type object is currently overly nested sometimes, this could be cleaned up
a bit, and the functions to "resolve" types (type annotator, c emitter) could
be thrown away.

The needed type values:

* Runtime types - these are just values circulated for the runtime, the
values that come out of its Prims, and go back to its casts.

* Thunk values - this is a type that has other types, including params and
return value. Reduciton of apps must ensure that the node they are trying to
apply is of this type. This is a higher order value and symbols as well as
params can be of this type. It's essentially a tree.

* Apps with no parameters can flatten the thunk type into the return value
and eliminate the app all together... See the peephole optimizer.

== Optimizer

This is actually a simple step, but probably a lot of work.

Introduce a new family of reducers that is applied between every conversion
(between initial and compilation, between compilation and SSA, between SSA and
type annotation, between type annotation and emission). This step will apply
pluggable reducers as it sees fit by being told at what step it is.

The only pluggable reducer that I think is useful right now is a peephole
optimizer (which is pluggable in itself).

The peephole optimizer has plugins which say to what step they apply, and what
root node they need. The root node is passed to the highest priority peephole
pattern, and the result is then reapplied. If the peephole pattern made no
change, the next one is tried.

An example pattern:

	peephole App(Thunk(x)) = x

If $x happens to be an App(Thunk($y)) the pattern will be reapplied on its
result anyway.

== Variable Assignment & binding

Container creation and binding of values is good for defining the prelude as a program, and 

(Blondie could be SSA, or could be converted by an SSA converter - either
example works well).

Look at the Administrative Normal Form autrijus was talking about at e.g.

http://citeseer.ist.psu.edu/flanagan93essence.html

== Lexical scoping

I don't like dynamic scoping, but lexical scoping makes little sense in an AST
with no definitions. Once we have assignment forms, we can see how lexical
scoping enters the picture.

== PIR emitter

Coke volunteered to help... shouldn't be too hard.

Share code with the C emitter - they're essentially the same.

= Hard

== Dynamic type inferrence

	my $i = int(rand(2)); # rand :: int -> float, int :: num -> int, $i :: int
	my @array = (1, "two"); # @array :: [ int|str ],
	@arrray[$i]; # int|str

The type returned from the last expression must be boxed, containing the value
and its type.

Perhaps lessons should be learned from Dynaml.

The SSA phi operation can help us generate the type UNIONS and upgrade a value
into a dynamic type as late as possible to reduce the overhead.


