[web-devel] Setting variables in hamlet forall

vagif.verdi at gmail.com vagif.verdi at gmail.com
Fri Apr 8 17:13:05 CEST 2011


Will it be

$with foo <- getFoo
         bar <- getBar


or will it be

$with foo <- getFoo
    $with bar <- getBar


On Friday, April 08, 2011 06:47:22 AM you 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



More information about the web-devel mailing list