[web-devel] Setting variables in hamlet forall

Michael Snoyman michael at snoyman.com
Fri Apr 8 15:47:22 CEST 2011


I agree with your comments about $let, which is why I'm reluctant to do so.
If no one has any objections, I'll pull your patch and rename to with. Also,
for consistency, I'll use <- instead of =. In other words:

$width foo <- bar
    #{foo}

Michael

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

> $with definitely differentiates it from the way that haskell does let
> binding and even makes it more obvious about the scoping (with
> bindings in languages like python/javascript work this way), even
> hinting that it doesn't to pattern matching.  I'm in favour.
>
> If we were to implement a $let it would probably have to work on the
> current scope otherwise it would confuse, and allow for mutual
> recursion perhaps.
>
> On Fri, Apr 8, 2011 at 11:40 PM, Michael Snoyman <michael at snoyman.com>
> wrote:
> > 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
> >
> >
>
>
>
> --
> -barkmadley
> sent from an internet enabled device
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/web-devel/attachments/20110408/19a2ce0b/attachment-0001.htm>


More information about the web-devel mailing list