
On Sun, Feb 13, 2011 at 6:56 PM, Dmitry Kurochkin
On Sun, 13 Feb 2011 18:09:08 +0200, Michael Snoyman
wrote: On Sun, Feb 13, 2011 at 5:26 PM, Rafael Cunha de Almeida
wrote: Michael Snoyman
disse: You could go either way on that one. The content of an interpolation is specifically *not* a fully-powered Haskell expression.
Why is that? I have a little experience with RoR, there I could do something like this:
- @people.each do |person| = person.name
I think you don't want to have a fully-powered Haskell expression to avoid people adding too much code to the view (thinking in MVC pattern). However, it's not like people can't do it just because it's a little harder. Meanwhile, there are a lot of useful things that could be done if all (or most) haskell syntax was allowed to be interpolated.
Instead of having special syntax like $forall, wouldn't it be better to just provide monad tranformers to allow for those sort of loops? Something like Control.Monad.LoopWhile module provides. That way hamlet would need only to provide a ${} syntax that allow for adding haskell code which will be evaluated but won't print anything to the site. That way things could work a lot like in ruby, which I think makes things a lot simpler.
Allowing for a new sort of interpolation and any sort of haskell expression to be interpolated, hamlet wouldn't need to create its own flow control statements. The user could write their views freely using only haskell syntax when code logic is required.
There's a few reasons for this:
1) I do *not* think it is a good thing for a template language to expose the full power of the programming language. As it is, I think Hamlet already stretches the bounds of what a designer would feel comfortable with.
2) This needs to get coded at some point, and frankly I don't feel like completely reinventing a full-blown Haskell parser. I'm aware of packages like haskell-src-exts-qq, but they are very heavy-weight and introduce a huge body of possible bugs/unanticipated behavior to Hamlet.
3) I'm not quite certain how you would intend to completely replace all of the control structures with some variable splicing, I think that would require further elucidation. However, I *highly* doubt it will come out as concise as a forall statement currently is. My goal for Hamlet isn't to provide absolute power in templates: it's to provide a user-friendly, terse syntax to achieve 95% of what people want to do easily. And for that extra 5%, it's very easy to call out to a helper Haskell function.
The list syntax itself does not really bother me, though it does just beg the question of where we draw the line. For instance, I have *no* intention of implementing do-notation inside an interpolation. To bring up Dmitry's suggestion: operators introduce all kinds of precedence issues, since we won't have access to the precedence levels Haskell is aware of. I think barking up *that* tree is a recipe for very unintuitive behavior.
How about allowing "(+) a b"?
That seems pretty safe.
Somewhat unrelated question: Why ToCss class is not exported? I wanted to add a pixel size type that would allow +, -, *, / and append "px" suffix. I ended up with explicit toPixel function for that.
There's a very good reason ToCss is not exported: I messed up ;). I'll address that soon.
What do you think about adding more types and functions for CSS? Similar to SCSS. E.g. functions to manipulate Color.
I think it's a good idea. It could be done as either an add-on package (once ToCss is exported) or as patches to hamlet. You interested in undertaking this? Michael