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.
This would make some JS specific optimisations harder, but seems reasonable. I introduced the `Meta` constructor for annotating stuff that can be ignored in core but is useful to some cases, so could probably use that to retain the ability to use `instanceof` when matching constructors rather than comparing a `$ctor` property or something.

Any `data` declarations we make now are essentially compiled to a record, are they not? The instantiation method we're using in JS now is so they have a prototype for performance, etc, but they're essentially treated as records in that they're objects with properties.