Hamlet and functions that take multiple arguments

hamlet doesn't appear to support functions that take more than one argument. i.e. fun f x = [$hamlet| ^template.f.x^ |] produces the call template (f x) is there some way to make hamlet produce (template f) x?

On Wed, Jul 21, 2010 at 4:17 AM, Mark Bradley
hamlet doesn't appear to support functions that take more than one argument.
i.e.
fun f x = [$hamlet| ^template.f.x^ |]
produces the call template (f x)
is there some way to make hamlet produce (template f) x?
Unfortunately not. It's not any *technical* limitation in Hamlet, just that I can't think of a good, intuitive syntax for it. The way that I work around this is by defining variables in a where clause, eg fun f x = [$hamlet|^templateTmp^|] where templateTmp = template f x If you have better ideas, I'm open to hearing them ;). Michael

looking at the code it does appear that your grammar for ContentEmbed
objects could be extended to include lparen and rparen's. I'm not
sure exactly how this would translate with the deref function in
Text.Hamlet.Quasi (i havent used template haskell before) but it looks
like it is entirely possible, meaning my example would become:
fun f x = [$hamlet| ^(template.f).x^ |]
and all is well. you could add an encoding for this such as:
template.f,x
this would have the same effect as the $ function from regular haskell.
the problem with that encoding is that is it less general than just
allowing parens and probably more error prone.
the good thing about this is that it doesn't really matter how
complicated you make the encoding and parsing and haskell code
generation because it happens once at compile time.
On Wed, Jul 21, 2010 at 2:41 PM, Michael Snoyman
On Wed, Jul 21, 2010 at 4:17 AM, Mark Bradley
wrote: hamlet doesn't appear to support functions that take more than one argument.
i.e.
fun f x = [$hamlet| ^template.f.x^ |]
produces the call template (f x)
is there some way to make hamlet produce (template f) x?
Unfortunately not. It's not any *technical* limitation in Hamlet, just that I can't think of a good, intuitive syntax for it. The way that I work around this is by defining variables in a where clause, eg fun f x = [$hamlet|^templateTmp^|] where templateTmp = template f x If you have better ideas, I'm open to hearing them ;). Michael

It's true that it won't be a runtime hit at all, so the parsing complexity
isn't a concern from that perspective. I *am* worried about making Hamlet
too complicated however. Does anyone else out there have an opinion on this
topic?
Actually, using the new period-not-required syntax, your example could be
rewritten:
[$hamlet|^(template f) x^|]
which is definitely easier on my eyes. However, that syntax would not be
available in $forall, $maybe et al.
Michael
PS: I like your e-mail address.
On Thu, Jul 22, 2010 at 1:49 PM, Mark Bradley
looking at the code it does appear that your grammar for ContentEmbed objects could be extended to include lparen and rparen's. I'm not sure exactly how this would translate with the deref function in Text.Hamlet.Quasi (i havent used template haskell before) but it looks like it is entirely possible, meaning my example would become:
fun f x = [$hamlet| ^(template.f).x^ |]
and all is well. you could add an encoding for this such as:
template.f,x
this would have the same effect as the $ function from regular haskell.
the problem with that encoding is that is it less general than just allowing parens and probably more error prone.
the good thing about this is that it doesn't really matter how complicated you make the encoding and parsing and haskell code generation because it happens once at compile time.
On Wed, Jul 21, 2010 at 2:41 PM, Michael Snoyman
wrote: On Wed, Jul 21, 2010 at 4:17 AM, Mark Bradley
hamlet doesn't appear to support functions that take more than one argument.
i.e.
fun f x = [$hamlet| ^template.f.x^ |]
produces the call template (f x)
is there some way to make hamlet produce (template f) x?
Unfortunately not. It's not any *technical* limitation in Hamlet, just
wrote: that
I can't think of a good, intuitive syntax for it. The way that I work around this is by defining variables in a where clause, eg fun f x = [$hamlet|^templateTmp^|] where templateTmp = template f x If you have better ideas, I'm open to hearing them ;). Michael

On Fri, Jul 23, 2010 at 7:31 PM, Michael Snoyman
It's true that it won't be a runtime hit at all, so the parsing complexity isn't a concern from that perspective. I *am* worried about making Hamlet too complicated however. Does anyone else out there have an opinion on this topic? Actually, using the new period-not-required syntax, your example could be rewritten: [$hamlet|^(template f) x^|]
i like that
which is definitely easier on my eyes. However, that syntax would not be available in $forall, $maybe et al.
an interesting perspective of this would be to use syntax in the forall to show that you are working with a list (not sure how this could be extended for maybe et al.) $forall [(map snd) tupleList] val
Michael PS: I like your e-mail address.
Cheers, Mark
On Thu, Jul 22, 2010 at 1:49 PM, Mark Bradley
wrote: looking at the code it does appear that your grammar for ContentEmbed objects could be extended to include lparen and rparen's. I'm not sure exactly how this would translate with the deref function in Text.Hamlet.Quasi (i havent used template haskell before) but it looks like it is entirely possible, meaning my example would become:
fun f x = [$hamlet| ^(template.f).x^ |]
and all is well. you could add an encoding for this such as:
template.f,x
this would have the same effect as the $ function from regular haskell.
the problem with that encoding is that is it less general than just allowing parens and probably more error prone.
the good thing about this is that it doesn't really matter how complicated you make the encoding and parsing and haskell code generation because it happens once at compile time.
On Wed, Jul 21, 2010 at 2:41 PM, Michael Snoyman
wrote: On Wed, Jul 21, 2010 at 4:17 AM, Mark Bradley
wrote: hamlet doesn't appear to support functions that take more than one argument.
i.e.
fun f x = [$hamlet| ^template.f.x^ |]
produces the call template (f x)
is there some way to make hamlet produce (template f) x?
Unfortunately not. It's not any *technical* limitation in Hamlet, just that I can't think of a good, intuitive syntax for it. The way that I work around this is by defining variables in a where clause, eg fun f x = [$hamlet|^templateTmp^|] where templateTmp = template f x If you have better ideas, I'm open to hearing them ;). Michael

Implementing that feature was amazingly simple. I'm still not 100% sold on
the syntax, as I'm worried it's complicated Hamlet too much. But having the
feature available probably isn't too dangerous. It also doesn't cause any
problems with existing code as far as my tests go.
As a bonus, the $forall/$maybe issue was very easy to solve: just surround
it with parentheses.
[$hamlet|
$forall ((foo bar) baz) bin
$bin$
|]
Code's up on github, let me know what you think.
Michael
On Fri, Jul 23, 2010 at 4:22 PM, Mark Bradley
It's true that it won't be a runtime hit at all, so the parsing complexity isn't a concern from that perspective. I *am* worried about making Hamlet too complicated however. Does anyone else out there have an opinion on
On Fri, Jul 23, 2010 at 7:31 PM, Michael Snoyman
wrote: this topic? Actually, using the new period-not-required syntax, your example could be rewritten: [$hamlet|^(template f) x^|]
i like that
which is definitely easier on my eyes. However, that syntax would not be available in $forall, $maybe et al.
an interesting perspective of this would be to use syntax in the forall to show that you are working with a list (not sure how this could be extended for maybe et al.) $forall [(map snd) tupleList] val
Michael PS: I like your e-mail address.
Cheers, Mark
On Thu, Jul 22, 2010 at 1:49 PM, Mark Bradley
wrote:
looking at the code it does appear that your grammar for ContentEmbed objects could be extended to include lparen and rparen's. I'm not sure exactly how this would translate with the deref function in Text.Hamlet.Quasi (i havent used template haskell before) but it looks like it is entirely possible, meaning my example would become:
fun f x = [$hamlet| ^(template.f).x^ |]
and all is well. you could add an encoding for this such as:
template.f,x
this would have the same effect as the $ function from regular haskell.
the problem with that encoding is that is it less general than just allowing parens and probably more error prone.
the good thing about this is that it doesn't really matter how complicated you make the encoding and parsing and haskell code generation because it happens once at compile time.
On Wed, Jul 21, 2010 at 2:41 PM, Michael Snoyman
wrote: On Wed, Jul 21, 2010 at 4:17 AM, Mark Bradley
wrote: hamlet doesn't appear to support functions that take more than one argument.
i.e.
fun f x = [$hamlet| ^template.f.x^ |]
produces the call template (f x)
is there some way to make hamlet produce (template f) x?
Unfortunately not. It's not any *technical* limitation in Hamlet, just that I can't think of a good, intuitive syntax for it. The way that I work around this is by defining variables in a where clause, eg fun f x = [$hamlet|^templateTmp^|] where templateTmp = template f x If you have better ideas, I'm open to hearing them ;). Michael

On Sun, Jul 25, 2010 at 3:40 AM, Michael Snoyman
Implementing that feature was amazingly simple. I'm still not 100% sold on the syntax, as I'm worried it's complicated Hamlet too much. But having the feature available probably isn't too dangerous. It also doesn't cause any problems with existing code as far as my tests go. As a bonus, the $forall/$maybe issue was very easy to solve: just surround it with parentheses. [$hamlet| $forall ((foo bar) baz) bin $bin$ |]
well done on being so quick. I didn't even get a chance to try and implement it myself. The code looks very clean and accurate. Should the spaces allowed argument be propagated to the sub expression parser derefParens? Also doesn't parsec have a between combinator? i.e. derefParens as = between (char '(') (char ')') (deref as) derefSingle as = derefParens as <|> fmap DerefLeaf ident deref spaceAllowed = do let delim = if spaceAllowed then (char '.' <|> (many1 (char ' ') >> return ' ')) else char '.' x <- derefSingle spaceAllowed xs <- many $ delim >> derefSingle return $ foldr1 DerefBranch $ x : xs Mark
Code's up on github, let me know what you think. Michael
On Fri, Jul 23, 2010 at 4:22 PM, Mark Bradley
wrote: On Fri, Jul 23, 2010 at 7:31 PM, Michael Snoyman
wrote: It's true that it won't be a runtime hit at all, so the parsing complexity isn't a concern from that perspective. I *am* worried about making Hamlet too complicated however. Does anyone else out there have an opinion on this topic? Actually, using the new period-not-required syntax, your example could be rewritten: [$hamlet|^(template f) x^|]
i like that
which is definitely easier on my eyes. However, that syntax would not be available in $forall, $maybe et al.
an interesting perspective of this would be to use syntax in the forall to show that you are working with a list (not sure how this could be extended for maybe et al.) $forall [(map snd) tupleList] val
Michael PS: I like your e-mail address.
Cheers, Mark
On Thu, Jul 22, 2010 at 1:49 PM, Mark Bradley
wrote: looking at the code it does appear that your grammar for ContentEmbed objects could be extended to include lparen and rparen's. I'm not sure exactly how this would translate with the deref function in Text.Hamlet.Quasi (i havent used template haskell before) but it looks like it is entirely possible, meaning my example would become:
fun f x = [$hamlet| ^(template.f).x^ |]
and all is well. you could add an encoding for this such as:
template.f,x
this would have the same effect as the $ function from regular haskell.
the problem with that encoding is that is it less general than just allowing parens and probably more error prone.
the good thing about this is that it doesn't really matter how complicated you make the encoding and parsing and haskell code generation because it happens once at compile time.
On Wed, Jul 21, 2010 at 2:41 PM, Michael Snoyman
wrote: On Wed, Jul 21, 2010 at 4:17 AM, Mark Bradley
wrote: hamlet doesn't appear to support functions that take more than one argument.
i.e.
fun f x = [$hamlet| ^template.f.x^ |]
produces the call template (f x)
is there some way to make hamlet produce (template f) x?
Unfortunately not. It's not any *technical* limitation in Hamlet, just that I can't think of a good, intuitive syntax for it. The way that I work around this is by defining variables in a where clause, eg fun f x = [$hamlet|^templateTmp^|] where templateTmp = template f x If you have better ideas, I'm open to hearing them ;). Michael

On Sun, Jul 25, 2010 at 1:00 PM, Mark Bradley
Implementing that feature was amazingly simple. I'm still not 100% sold on the syntax, as I'm worried it's complicated Hamlet too much. But having
On Sun, Jul 25, 2010 at 3:40 AM, Michael Snoyman
wrote: the feature available probably isn't too dangerous. It also doesn't cause any problems with existing code as far as my tests go. As a bonus, the $forall/$maybe issue was very easy to solve: just surround it with parentheses. [$hamlet| $forall ((foo bar) baz) bin $bin$ |]
well done on being so quick. I didn't even get a chance to try and implement it myself.
The code looks very clean and accurate. Should the spaces allowed argument be propagated to the sub expression parser derefParens?
It's not necessary; the only reason to disallow spaces is when dealing with a $forall et al. However, once inside parentheses, we can allow the spaces without ambiguity.
Also doesn't parsec have a between combinator?
i.e. derefParens as = between (char '(') (char ')') (deref as) derefSingle as = derefParens as <|> fmap DerefLeaf ident deref spaceAllowed = do let delim = if spaceAllowed then (char '.' <|> (many1 (char ' ') >> return ' ')) else char '.' x <- derefSingle spaceAllowed xs <- many $ delim >> derefSingle return $ foldr1 DerefBranch $ x : xs
I wasn't aware of between, cleaned up the code nicely. Thanks! Unless
there's objections, I'll release the new code as Hamlet 0.4.1. Michael
participants (2)
-
Mark Bradley
-
Michael Snoyman