[web-devel] Setting variables in hamlet forall

Mark Bradley barkmadley at gmail.com
Fri Apr 8 16:14:22 CEST 2011


check the patch again

On Fri, Apr 8, 2011 at 11:47 PM, Michael Snoyman <michael at snoyman.com> wrote:
> 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
>
>



-- 
-barkmadley
sent from an internet enabled device



More information about the web-devel mailing list