[web-devel] Setting variables in hamlet forall

Michael Snoyman michael at snoyman.com
Fri Apr 8 15:40:21 CEST 2011


Hi Mark,

Do you have an opinion on the naming, i.e. with versus let? Does anyone
else?

Michael

On Fri, Apr 8, 2011 at 4:35 PM, Mark Bradley <barkmadley at gmail.com> wrote:

> your latest change makes my original patch not work.  I updated the
> pull request to handle this and deal with the foldable forall problem
> that arises from piggy backing on the LineForall construct.  It now
> uses the LineMaybe to the same effect.
>
> On Fri, Apr 8, 2011 at 8:08 PM, Michael Snoyman <michael at snoyman.com>
> wrote:
> > Oh, you weren't joking, that really is a small patch. I should have
> looked
> > before writing this email. OK, it's using the inner block approach. I
> think
> > I'm OK including that if we rename it to $with, e.g.:
> > $with x <- foo bar
> >     #{x}
> > Michael
> >
> > On Fri, Apr 8, 2011 at 1:05 PM, Michael Snoyman <michael at snoyman.com>
> wrote:
> >>
> >>
> >> On Fri, Apr 8, 2011 at 2:47 AM, Mark Bradley <barkmadley at gmail.com>
> wrote:
> >>>
> >>> On Thu, Apr 7, 2011 at 11:22 PM, Michael Snoyman <michael at snoyman.com>
> >>> wrote:
> >>> > A few points:
> >>> > 1) The cost is twofold: making Hamlet more complex from a user
> >>> > perspective,
> >>> > and making the codebase more complex. I'm not a fan of either, unless
> >>> > it's
> >>> > really justified.
> >>> > 2) I'm not really certain how your example below works as far as
> >>> > disambiguating Maybe versus [] (i.e., $maybe versus $forall), but if
> >>> > we're
> >>> > willing to go in this direction, you already have $let for free:
> >>> > $forall foo <- foos
> >>> >     $forall foobar <- return $ bar foo
> >>> >         #{foobar}
> >>>
> >>> I was really going out there with my suggestions and examples.  The
> >>> real benefit of a unified approach is that you can extend it to apply
> >>> to your custom container types.  Making it pretty similar to foldable
> >>> but with an default behaviour when the data structure is empty.
> >>>
> >> Actually, forgetting the rest of the discussion here, I think extending
> >> $forall to work on any Foldable is a great idea. Any objections?
> >>
> >>>
> >>> Also if you already have let for free using forall and return, why not
> >>> make a sugared version that compiles down to that?
> >>>
> >> I haven't looked at your patch yet (thank you btw), but my concern is
> that
> >> introducing $let, the same way it's used in Haskell, introduces scoping
> >> issues that we don't otherwise have. $forall and $maybe already add a
> >> significant complexity to deal with the bound variable names, but at
> least
> >> it's bound for only the inner block. With $let, we would want it to be
> bound
> >> for the remainder of the block most likely. So we'd have two choices:
> >> * Implement a whole bunch of complexity defining and implementing new
> >> scoping rules.
> >> * Have totally different semantics from Haskell.
> >> I'm not sure which approach your patch took. But maybe the problem was
> >> with my choice of name ($let); $with would likely make more sense for
> the
> >> inner block approach. But even so, I'm still concerned that this is
> >> complexity without enough reward.
> >>
> >>>
> >>> > Here, return would be for the [] instance of Monad. We could also use
> >>> > $maybe, using the Maybe instance of Monad.
> >>> > Michael
> >>> >
> >>> > On Thu, Apr 7, 2011 at 3:46 PM, Mark Bradley <barkmadley at gmail.com>
> >>> > wrote:
> >>> >>
> >>> >> On Thu, Apr 7, 2011 at 10:34 PM, Mark Bradley <barkmadley at gmail.com
> >
> >>> >> wrote:
> >>> >> > On Thu, Apr 7, 2011 at 7:51 PM, Max Cantor <mxcantor at gmail.com>
> >>> >> > wrote:
> >>> >> >> put me in the opposed category.
> >>> >> >>
> >>> >> >> You can just as easily put:
> >>> >> >>  let formId rs = fromMaybe "" $ lookup $...
> >>> >> >>
> >>> >> >> in the haskell function that loads the hamlet file then you just
> >>> >> >> have
> >>> >> >> to put
> >>> >> >>  #{formId rs}
> >>> >> >>
> >>> >> >> in the hamlet.  I think adding syntax should be done only when
> very
> >>> >> >> necessary.  seems like a very small win here at a big cost.
> >>> >> >
> >>> >> > Where is the cost? Most of the effort would be just glueing
> together
> >>> >> > some pieces of existing code. Given that there are already two
> >>> >> > places
> >>> >> > where hamlet does variable binding, adding a third will not hurt
> it,
> >>> >> > or perhaps a single more expressive form of variable binding is
> >>> >> > required. Something like monadic bind (>>=) where you can bind
> >>> >> > non-monadic values using the identity monad.
> >>> >>
> >>> >> An example:
> >>> >>
> >>> >> $bind row <- rs
> >>> >>    $bind formId <- Identity $ fromMaybe "" $ IntMap.lookup $ getInt
> >>> >> "form_id" row
> >>> >>        <td>#{formId counties}
> >>> >>        <td>#{formId customers}
> >>> >>
> >>> >> It could also be possible to do else cases where it didn't bind:
> >>> >>
> >>> >> -- list bind
> >>> >> $bind row <- rs
> >>> >>    -- identity bind
> >>> >>    $bind formId <- Identity $ fromMaybe "" $ IntMap.lookup $ getInt
> >>> >> "form_id" row
> >>> >>        <td>#{formId counties}
> >>> >>        <td>#{formId customers}
> >>> >>        -- maybe bind
> >>> >>        $bind someValue <- someMaybeValue
> >>> >>            <div>content
> >>> >>        -- maybe value was Nothing
> >>> >>        $nobind
> >>> >>            <div>other content
> >>> >>    -- not possible with identity bind possible place for
> error/warning
> >>> >>    $nobind
> >>> >>        <div>This should not happen!
> >>> >>
> >>> >> -- empty list
> >>> >> $nobind
> >>> >>    <div>i left my content in my other pants
> >>> >>
> >>> >>
> >>> >>
> >>> >> >
> >>> >> >>
> >>> >> >> yes, if you have a situation where many handlers are calling the
> >>> >> >> same
> >>> >> >> hamlet file, there might be some duplication, but then you can
> >>> >> >> always raise
> >>> >> >> the formId function to a top-level function.
> >>> >> >>
> >>> >> >> max
> >>> >> >>
> >>> >> >>  On Apr 7, 2011, at 5:15 PM, Michael Snoyman wrote:
> >>> >> >>
> >>> >> >>> I've been very hesitant about adding more features to Hamlet,
> >>> >> >>> especially ones that are already implemented in Haskell. That's
> >>> >> >>> been my
> >>> >> >>> reasoning for avoiding any kind of variable definitions until
> now.
> >>> >> >>> However,
> >>> >> >>> this does seem like a compelling use case.
> >>> >> >>>
> >>> >> >>> I don't think it would make sense to limit it to foralls: it
> makes
> >>> >> >>> as
> >>> >> >>> much sense in maybes, and I think it would be confusing if it
> only
> >>> >> >>> applied
> >>> >> >>> in some cases. As for syntax, how about:
> >>> >> >>>
> >>> >> >>> $forall row <- rs
> >>> >> >>>     $let formId = fromMaybe "" $ IntMap.lookup $ getInt
> "form_id"
> >>> >> >>> row
> >>> >> >>>     ...
> >>> >> >>>
> >>> >> >>> I'm not 100% sold on this yet, what does everyone else think?
> >>> >> >>>
> >>> >> >>> One last note: I'm probably going to be announcing a feature
> >>> >> >>> freeze on
> >>> >> >>> Yesod 0.8 *very* soon, and making a beta release to Yackage so
> >>> >> >>> that people
> >>> >> >>> can test. If you have any last-minute input, now's the time. I'm
> >>> >> >>> planning on
> >>> >> >>> giving the beta test period about a week, and then releasing to
> >>> >> >>> Hackage.
> >>> >> >>>
> >>> >> >>> Michael
> >>> >> >>>
> >>> >> >>> On Thu, Apr 7, 2011 at 2:57 AM, <vagif.verdi at gmail.com> wrote:
> >>> >> >>> I noticed a pattern that in hamlet $forall i often retrieve the
> >>> >> >>> same
> >>> >> >>> value
> >>> >> >>> from a map, Sometimes 3,4 times.
> >>> >> >>>
> >>> >> >>>    $forall row <- rs
> >>> >> >>>            <td><a href=@{FormR (getInt "form_id" row)}>#{getStr
> >>> >> >>> "form_name"
> >>> >> >>> row}
> >>> >> >>>            <td>#{getStr "docname" row}
> >>> >> >>>            ...
> >>> >> >>>            <td>#{fromMaybe "" (IntMap.lookup (getInt "form_id"
> >>> >> >>> row)
> >>> >> >>> counties)}
> >>> >> >>>            <td>#{fromMaybe "" (IntMap.lookup (getInt "form_id"
> >>> >> >>> row)
> >>> >> >>> customers)}
> >>> >> >>>
> >>> >> >>> Would it be possible to allow let statement in forall for often
> >>> >> >>> used
> >>> >> >>> values ?
> >>> >> >>>
> >>> >> >>> Regards,
> >>> >> >>> Vagif Verdi
> >>> >> >>>
> >>> >> >>> _______________________________________________
> >>> >> >>> web-devel mailing list
> >>> >> >>> web-devel at haskell.org
> >>> >> >>> http://www.haskell.org/mailman/listinfo/web-devel
> >>> >> >>>
> >>> >> >>> _______________________________________________
> >>> >> >>> web-devel mailing list
> >>> >> >>> web-devel at haskell.org
> >>> >> >>> http://www.haskell.org/mailman/listinfo/web-devel
> >>> >> >>
> >>> >> >>
> >>> >> >> _______________________________________________
> >>> >> >> web-devel mailing list
> >>> >> >> web-devel at haskell.org
> >>> >> >> http://www.haskell.org/mailman/listinfo/web-devel
> >>> >> >>
> >>> >> >
> >>> >> >
> >>> >> >
> >>> >> > --
> >>> >> > -barkmadley
> >>> >> > sent from an internet enabled device
> >>> >> >
> >>> >>
> >>> >>
> >>> >>
> >>> >> --
> >>> >> -barkmadley
> >>> >> sent from an internet enabled device
> >>> >
> >>> >
> >>>
> >>>
> >>>
> >>> --
> >>> -barkmadley
> >>> sent from an internet enabled device
> >>
> >
> >
>
>
>
> --
> -barkmadley
> sent from an internet enabled device
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/web-devel/attachments/20110408/0fc4c242/attachment-0001.htm>


More information about the web-devel mailing list