Holy shit, Parsec looks fucking fabulous — I think I’m going to set the ORM bullshit aside tonight and hammer out a parser for the subset of Yaml I’d like to use for configuration files.
Speaking of ORM bullshit though, Template Haskell is pretty strange and cool. The concept of handling syntax trees as first-class types and using them to generate code (either as a String, or as first-class types) is fucking awesome and cleaned up the code a fuckton. I think my only issues with it are that it’s nigh impossible to craft complex expressions with [| ... |] notation, and that the syntax constructs are basically undocumented. The later issue will be fixed when the Language.Haskell.TH.Syntax and Language.Haskell.Syntax modules get unified (since the later is documented) — though I doubt anyone’s actively working on that.
I’ll post some examples of dynamically creating record definitions and shit once I’ve got some freetime or something. It’s pretty neat shit (but not as neat as Parsec looks).
I’ve mostly come to the conclusion that my implementation of an ORM wrapper is completely and fundamentally broken — it has turned into an amorphous unmaintainable mess of code and overcomplicated the build process while adding very little value to anything.
I also think the Routing subsystem is a little broken as well — the abortion of a Yaml parser is a terrible, unextensible hack. It would be really nice to have something which can serve as a generic configuration tool for not only routes, but schemas (if a reasonable ORM layer ever appears) and general configuration as well. The part of the Routing system which sits on that (effectively just a state machine to parse the request URI) is fine.
In light of this, I’m going to read over the Data.Data papers, which will (hopefully) supply a means to automatically marshall SQL result sets to output formats (through HStringTemplate or a JSON encoder).
In the meanwhile, I guess I should think about a useful project which I can actually apply this crap to so it isn’t just pointless learning exercises. Bleh.
I just discovered a really fucking massive huge flaw in my shitty ORM shit. The ORM layer is supposed to lazily resolve foreign references, right? So if you have a schema
You’ll notice that the post table contains a self-reference. So the ORM layer will generate the following code for that table –
The own-table foreign key, post_parent is a killer, because it causes parseSql' to lazily enter an infinite loop. While this isn’t bad, when you throw that DbRecord to the automatically-generated JSON thingy, it tries chomping through the entire thing and gets tangled up.
There’s no good way to fix this, aside from doing a topological sort of all the inter-table relations and having the ORM layer go “oh hey” when it starts to loop. That kind of functionality could be added to either the parseSql' function above, or to the toAscListJSON function, which converts the DbRecord into a JSON-injestable form (and should be replaced by using Data.Data instead…)
Realistically, I should throw this shit out and do it some other way, especially since the code generation bit has become pig disgusting. Fuck! (Eventually I’ll rewrite it using Template Haskell or something).