<div dir="ltr">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:<div>
<br></div><div>$width foo <- bar</div><div> #{foo}</div><div><br></div><div>Michael<br><br><div class="gmail_quote">On Fri, Apr 8, 2011 at 4:45 PM, Mark Bradley <span dir="ltr"><<a href="mailto:barkmadley@gmail.com">barkmadley@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">$with definitely differentiates it from the way that haskell does let<br>
binding and even makes it more obvious about the scoping (with<br>
bindings in languages like python/javascript work this way), even<br>
hinting that it doesn't to pattern matching. I'm in favour.<br>
<br>
If we were to implement a $let it would probably have to work on the<br>
current scope otherwise it would confuse, and allow for mutual<br>
recursion perhaps.<br>
<div><div></div><div class="h5"><br>
On Fri, Apr 8, 2011 at 11:40 PM, Michael Snoyman <<a href="mailto:michael@snoyman.com">michael@snoyman.com</a>> wrote:<br>
> Hi Mark,<br>
> Do you have an opinion on the naming, i.e. with versus let? Does anyone<br>
> else?<br>
> Michael<br>
><br>
> On Fri, Apr 8, 2011 at 4:35 PM, Mark Bradley <<a href="mailto:barkmadley@gmail.com">barkmadley@gmail.com</a>> wrote:<br>
>><br>
>> your latest change makes my original patch not work. I updated the<br>
>> pull request to handle this and deal with the foldable forall problem<br>
>> that arises from piggy backing on the LineForall construct. It now<br>
>> uses the LineMaybe to the same effect.<br>
>><br>
>> On Fri, Apr 8, 2011 at 8:08 PM, Michael Snoyman <<a href="mailto:michael@snoyman.com">michael@snoyman.com</a>><br>
>> wrote:<br>
>> > Oh, you weren't joking, that really is a small patch. I should have<br>
>> > looked<br>
>> > before writing this email. OK, it's using the inner block approach. I<br>
>> > think<br>
>> > I'm OK including that if we rename it to $with, e.g.:<br>
>> > $with x <- foo bar<br>
>> > #{x}<br>
>> > Michael<br>
>> ><br>
>> > On Fri, Apr 8, 2011 at 1:05 PM, Michael Snoyman <<a href="mailto:michael@snoyman.com">michael@snoyman.com</a>><br>
>> > wrote:<br>
>> >><br>
>> >><br>
>> >> On Fri, Apr 8, 2011 at 2:47 AM, Mark Bradley <<a href="mailto:barkmadley@gmail.com">barkmadley@gmail.com</a>><br>
>> >> wrote:<br>
>> >>><br>
>> >>> On Thu, Apr 7, 2011 at 11:22 PM, Michael Snoyman <<a href="mailto:michael@snoyman.com">michael@snoyman.com</a>><br>
>> >>> wrote:<br>
>> >>> > A few points:<br>
>> >>> > 1) The cost is twofold: making Hamlet more complex from a user<br>
>> >>> > perspective,<br>
>> >>> > and making the codebase more complex. I'm not a fan of either,<br>
>> >>> > unless<br>
>> >>> > it's<br>
>> >>> > really justified.<br>
>> >>> > 2) I'm not really certain how your example below works as far as<br>
>> >>> > disambiguating Maybe versus [] (i.e., $maybe versus $forall), but if<br>
>> >>> > we're<br>
>> >>> > willing to go in this direction, you already have $let for free:<br>
>> >>> > $forall foo <- foos<br>
>> >>> > $forall foobar <- return $ bar foo<br>
>> >>> > #{foobar}<br>
>> >>><br>
>> >>> I was really going out there with my suggestions and examples. The<br>
>> >>> real benefit of a unified approach is that you can extend it to apply<br>
>> >>> to your custom container types. Making it pretty similar to foldable<br>
>> >>> but with an default behaviour when the data structure is empty.<br>
>> >>><br>
>> >> Actually, forgetting the rest of the discussion here, I think extending<br>
>> >> $forall to work on any Foldable is a great idea. Any objections?<br>
>> >><br>
>> >>><br>
>> >>> Also if you already have let for free using forall and return, why not<br>
>> >>> make a sugared version that compiles down to that?<br>
>> >>><br>
>> >> I haven't looked at your patch yet (thank you btw), but my concern is<br>
>> >> that<br>
>> >> introducing $let, the same way it's used in Haskell, introduces scoping<br>
>> >> issues that we don't otherwise have. $forall and $maybe already add a<br>
>> >> significant complexity to deal with the bound variable names, but at<br>
>> >> least<br>
>> >> it's bound for only the inner block. With $let, we would want it to be<br>
>> >> bound<br>
>> >> for the remainder of the block most likely. So we'd have two choices:<br>
>> >> * Implement a whole bunch of complexity defining and implementing new<br>
>> >> scoping rules.<br>
>> >> * Have totally different semantics from Haskell.<br>
>> >> I'm not sure which approach your patch took. But maybe the problem was<br>
>> >> with my choice of name ($let); $with would likely make more sense for<br>
>> >> the<br>
>> >> inner block approach. But even so, I'm still concerned that this is<br>
>> >> complexity without enough reward.<br>
>> >><br>
>> >>><br>
>> >>> > Here, return would be for the [] instance of Monad. We could also<br>
>> >>> > use<br>
>> >>> > $maybe, using the Maybe instance of Monad.<br>
>> >>> > Michael<br>
>> >>> ><br>
>> >>> > On Thu, Apr 7, 2011 at 3:46 PM, Mark Bradley <<a href="mailto:barkmadley@gmail.com">barkmadley@gmail.com</a>><br>
>> >>> > wrote:<br>
>> >>> >><br>
>> >>> >> On Thu, Apr 7, 2011 at 10:34 PM, Mark Bradley<br>
>> >>> >> <<a href="mailto:barkmadley@gmail.com">barkmadley@gmail.com</a>><br>
>> >>> >> wrote:<br>
>> >>> >> > On Thu, Apr 7, 2011 at 7:51 PM, Max Cantor <<a href="mailto:mxcantor@gmail.com">mxcantor@gmail.com</a>><br>
>> >>> >> > wrote:<br>
>> >>> >> >> put me in the opposed category.<br>
>> >>> >> >><br>
>> >>> >> >> You can just as easily put:<br>
>> >>> >> >> let formId rs = fromMaybe "" $ lookup $...<br>
>> >>> >> >><br>
>> >>> >> >> in the haskell function that loads the hamlet file then you just<br>
>> >>> >> >> have<br>
>> >>> >> >> to put<br>
>> >>> >> >> #{formId rs}<br>
>> >>> >> >><br>
>> >>> >> >> in the hamlet. I think adding syntax should be done only when<br>
>> >>> >> >> very<br>
>> >>> >> >> necessary. seems like a very small win here at a big cost.<br>
>> >>> >> ><br>
>> >>> >> > Where is the cost? Most of the effort would be just glueing<br>
>> >>> >> > together<br>
>> >>> >> > some pieces of existing code. Given that there are already two<br>
>> >>> >> > places<br>
>> >>> >> > where hamlet does variable binding, adding a third will not hurt<br>
>> >>> >> > it,<br>
>> >>> >> > or perhaps a single more expressive form of variable binding is<br>
>> >>> >> > required. Something like monadic bind (>>=) where you can bind<br>
>> >>> >> > non-monadic values using the identity monad.<br>
>> >>> >><br>
>> >>> >> An example:<br>
>> >>> >><br>
>> >>> >> $bind row <- rs<br>
>> >>> >> $bind formId <- Identity $ fromMaybe "" $ IntMap.lookup $ getInt<br>
>> >>> >> "form_id" row<br>
>> >>> >> <td>#{formId counties}<br>
>> >>> >> <td>#{formId customers}<br>
>> >>> >><br>
>> >>> >> It could also be possible to do else cases where it didn't bind:<br>
>> >>> >><br>
>> >>> >> -- list bind<br>
>> >>> >> $bind row <- rs<br>
>> >>> >> -- identity bind<br>
>> >>> >> $bind formId <- Identity $ fromMaybe "" $ IntMap.lookup $ getInt<br>
>> >>> >> "form_id" row<br>
>> >>> >> <td>#{formId counties}<br>
>> >>> >> <td>#{formId customers}<br>
>> >>> >> -- maybe bind<br>
>> >>> >> $bind someValue <- someMaybeValue<br>
>> >>> >> <div>content<br>
>> >>> >> -- maybe value was Nothing<br>
>> >>> >> $nobind<br>
>> >>> >> <div>other content<br>
>> >>> >> -- not possible with identity bind possible place for<br>
>> >>> >> error/warning<br>
>> >>> >> $nobind<br>
>> >>> >> <div>This should not happen!<br>
>> >>> >><br>
>> >>> >> -- empty list<br>
>> >>> >> $nobind<br>
>> >>> >> <div>i left my content in my other pants<br>
>> >>> >><br>
>> >>> >><br>
>> >>> >><br>
>> >>> >> ><br>
>> >>> >> >><br>
>> >>> >> >> yes, if you have a situation where many handlers are calling the<br>
>> >>> >> >> same<br>
>> >>> >> >> hamlet file, there might be some duplication, but then you can<br>
>> >>> >> >> always raise<br>
>> >>> >> >> the formId function to a top-level function.<br>
>> >>> >> >><br>
>> >>> >> >> max<br>
>> >>> >> >><br>
>> >>> >> >> On Apr 7, 2011, at 5:15 PM, Michael Snoyman wrote:<br>
>> >>> >> >><br>
>> >>> >> >>> I've been very hesitant about adding more features to Hamlet,<br>
>> >>> >> >>> especially ones that are already implemented in Haskell. That's<br>
>> >>> >> >>> been my<br>
>> >>> >> >>> reasoning for avoiding any kind of variable definitions until<br>
>> >>> >> >>> now.<br>
>> >>> >> >>> However,<br>
>> >>> >> >>> this does seem like a compelling use case.<br>
>> >>> >> >>><br>
>> >>> >> >>> I don't think it would make sense to limit it to foralls: it<br>
>> >>> >> >>> makes<br>
>> >>> >> >>> as<br>
>> >>> >> >>> much sense in maybes, and I think it would be confusing if it<br>
>> >>> >> >>> only<br>
>> >>> >> >>> applied<br>
>> >>> >> >>> in some cases. As for syntax, how about:<br>
>> >>> >> >>><br>
>> >>> >> >>> $forall row <- rs<br>
>> >>> >> >>> $let formId = fromMaybe "" $ IntMap.lookup $ getInt<br>
>> >>> >> >>> "form_id"<br>
>> >>> >> >>> row<br>
>> >>> >> >>> ...<br>
>> >>> >> >>><br>
>> >>> >> >>> I'm not 100% sold on this yet, what does everyone else think?<br>
>> >>> >> >>><br>
>> >>> >> >>> One last note: I'm probably going to be announcing a feature<br>
>> >>> >> >>> freeze on<br>
>> >>> >> >>> Yesod 0.8 *very* soon, and making a beta release to Yackage so<br>
>> >>> >> >>> that people<br>
>> >>> >> >>> can test. If you have any last-minute input, now's the time.<br>
>> >>> >> >>> I'm<br>
>> >>> >> >>> planning on<br>
>> >>> >> >>> giving the beta test period about a week, and then releasing to<br>
>> >>> >> >>> Hackage.<br>
>> >>> >> >>><br>
>> >>> >> >>> Michael<br>
>> >>> >> >>><br>
>> >>> >> >>> On Thu, Apr 7, 2011 at 2:57 AM, <<a href="mailto:vagif.verdi@gmail.com">vagif.verdi@gmail.com</a>> wrote:<br>
>> >>> >> >>> I noticed a pattern that in hamlet $forall i often retrieve the<br>
>> >>> >> >>> same<br>
>> >>> >> >>> value<br>
>> >>> >> >>> from a map, Sometimes 3,4 times.<br>
>> >>> >> >>><br>
>> >>> >> >>> $forall row <- rs<br>
>> >>> >> >>> <td><a href=@{FormR (getInt "form_id" row)}>#{getStr<br>
>> >>> >> >>> "form_name"<br>
>> >>> >> >>> row}<br>
>> >>> >> >>> <td>#{getStr "docname" row}<br>
>> >>> >> >>> ...<br>
>> >>> >> >>> <td>#{fromMaybe "" (IntMap.lookup (getInt "form_id"<br>
>> >>> >> >>> row)<br>
>> >>> >> >>> counties)}<br>
>> >>> >> >>> <td>#{fromMaybe "" (IntMap.lookup (getInt "form_id"<br>
>> >>> >> >>> row)<br>
>> >>> >> >>> customers)}<br>
>> >>> >> >>><br>
>> >>> >> >>> Would it be possible to allow let statement in forall for often<br>
>> >>> >> >>> used<br>
>> >>> >> >>> values ?<br>
>> >>> >> >>><br>
>> >>> >> >>> Regards,<br>
>> >>> >> >>> Vagif Verdi<br>
>> >>> >> >>><br>
>> >>> >> >>> _______________________________________________<br>
>> >>> >> >>> web-devel mailing list<br>
>> >>> >> >>> <a href="mailto:web-devel@haskell.org">web-devel@haskell.org</a><br>
>> >>> >> >>> <a href="http://www.haskell.org/mailman/listinfo/web-devel" target="_blank">http://www.haskell.org/mailman/listinfo/web-devel</a><br>
>> >>> >> >>><br>
>> >>> >> >>> _______________________________________________<br>
>> >>> >> >>> web-devel mailing list<br>
>> >>> >> >>> <a href="mailto:web-devel@haskell.org">web-devel@haskell.org</a><br>
>> >>> >> >>> <a href="http://www.haskell.org/mailman/listinfo/web-devel" target="_blank">http://www.haskell.org/mailman/listinfo/web-devel</a><br>
>> >>> >> >><br>
>> >>> >> >><br>
>> >>> >> >> _______________________________________________<br>
>> >>> >> >> web-devel mailing list<br>
>> >>> >> >> <a href="mailto:web-devel@haskell.org">web-devel@haskell.org</a><br>
>> >>> >> >> <a href="http://www.haskell.org/mailman/listinfo/web-devel" target="_blank">http://www.haskell.org/mailman/listinfo/web-devel</a><br>
>> >>> >> >><br>
>> >>> >> ><br>
>> >>> >> ><br>
>> >>> >> ><br>
>> >>> >> > --<br>
>> >>> >> > -barkmadley<br>
>> >>> >> > sent from an internet enabled device<br>
>> >>> >> ><br>
>> >>> >><br>
>> >>> >><br>
>> >>> >><br>
>> >>> >> --<br>
>> >>> >> -barkmadley<br>
>> >>> >> sent from an internet enabled device<br>
>> >>> ><br>
>> >>> ><br>
>> >>><br>
>> >>><br>
>> >>><br>
>> >>> --<br>
>> >>> -barkmadley<br>
>> >>> sent from an internet enabled device<br>
>> >><br>
>> ><br>
>> ><br>
>><br>
>><br>
>><br>
>> --<br>
>> -barkmadley<br>
>> sent from an internet enabled device<br>
><br>
><br>
<br>
<br>
<br>
</div></div>--<br>
<div><div></div><div class="h5">-barkmadley<br>
sent from an internet enabled device<br>
</div></div></blockquote></div><br></div></div>