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 do think we need a representation for sum types, if only because how those are compiled depends heavily on the backend (subtyping is idiomatic for any OO back-end). But having *multiple* ways to encode product types is against the principle of having a small core language, and will make manipulation, transformation, and optimization of core much more difficult, because code must be replicated to work on two isomorphic representations.

If there's more than 1 way to do anything, it's not yet a core. In my opinion, the bar for introducing multiple encodings for the same thing needs to be *very high*. Not that we shouldn't necessarily do it, but the advantages have to be extremely clear. Any duplication at all in core makes life harder for everything that follows.