Core functional representation

Resolves #710 when merged, but not even nearly ready yet.

Not sure there is much to talk about yet, I was hoping to get a bit further with it, so everything is subject to change still.
I don't think the goal should be to make the core representation as small as we can, just to get rid of the parts we don't need for optimization and code gen. 

What sort of optimizations are enabled by turning sums into products, for example? I can't think of any. Or certainly none that I would want to sacrifice readability of the code for.