[web-devel] Setting variables in hamlet forall
Mark Bradley
barkmadley at gmail.com
Fri Apr 8 15:45:20 CEST 2011
$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