On Fri, Apr 8, 2011 at 8:08 PM, Michael Snoyman <
michael@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@snoyman.com> wrote:
>>
>>
>> On Fri, Apr 8, 2011 at 2:47 AM, Mark Bradley <
barkmadley@gmail.com> wrote:
>>>
>>> On Thu, Apr 7, 2011 at 11:22 PM, Michael Snoyman <
michael@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@gmail.com>
>>> > wrote:
>>> >>
>>> >> On Thu, Apr 7, 2011 at 10:34 PM, Mark Bradley <
barkmadley@gmail.com>
>>> >> wrote:
>>> >> > On Thu, Apr 7, 2011 at 7:51 PM, Max Cantor <
mxcantor@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@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@haskell.org
>>> >> >>>
http://www.haskell.org/mailman/listinfo/web-devel
>>> >> >>>
>>> >> >>> _______________________________________________
>>> >> >>> web-devel mailing list
>>> >> >>>
web-devel@haskell.org
>>> >> >>>
http://www.haskell.org/mailman/listinfo/web-devel
>>> >> >>
>>> >> >>
>>> >> >> _______________________________________________
>>> >> >> web-devel mailing list
>>> >> >>
web-devel@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
>>
>
>