Hi,<br><br>One could also argue that a good email client should automatically hide long quotes. In fact, I guess many people are not even aware of the problem because their client does this.<br><br><br>Cheers,<br>Pedro<br>
<br><div class="gmail_quote">On Thu, Jan 19, 2012 at 11:14, Malcolm Wallace <span dir="ltr"><<a href="mailto:malcolm.wallace@me.com">malcolm.wallace@me.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Sorry to pick on your post in particular Matthew, but I have been seeing a lot of this on the Haskell lists lately.<br>
<br>
I find it completely unreasonable for a reply to a very long post to quote the entire text, only to add a single line at the bottom (or worse, embedded in the middle somewhere). In this case, there are 7 pages of quotation before your one-sentence contribution. (That is on my laptop. I dread to think how many pages it represents on a smartphone screen...) Usually, if I need to scroll even to the second page-worth of quotation and have still not found any new text, I now just delete the post without reading it.<br>
<br>
It is a failure to communicate well, on the part of the writer who values their own time more highly than that of their intended readers. Even the much-maligned top-posting style, as forced upon Outlook users (and as I am doing right here), is preferable to the failure to trim, or to get to the point quickly. My inbox has >1600 unread messages in it, and life is just too short. So I offer this plea as a constructive social suggestion - if you want your ideas to reach their intended audience, don't annoy them before they have even seen what you want to say.<br>
<br>
Regards,<br>
Malcolm<br>
<br>
<br>
On 15 Jan 2012, at 20:33, Matthew Farkas-Dyck wrote:<br>
<br>
> On 13/01/2012, Simon Peyton-Jones <<a href="mailto:simonpj@microsoft.com">simonpj@microsoft.com</a>> wrote:<br>
>> Thanks to Greg for leading the records debate. I apologise that I<br>
>> don't have enough bandwidth to make more than an occasional<br>
>> contribution. Greg's new wiki page, and the discussion so far has<br>
>> clarified my thinking, and this message tries to express that new<br>
>> clarity. I put a conclusion at the end.<br>
>><br>
>> Simon<br>
>><br>
>> Overview<br>
>> ~~~~~~~~<br>
>> It has become clear that there are two elements to pretty much all the<br>
>> proposals we have on the table. Suppose we have two types, 'S' and 'T',<br>
>> both with a field 'f', and you want to select field 'f' from a record 'r'.<br>
>> Somehow you have to disambiguate which 'f' you mean.<br>
>><br>
>> (Plan A) Disambiguate using qualified names. To select field f, say<br>
>> (S.f r) or (T.f r) respectively.<br>
>><br>
>> (Plan B) Disambiguate using types. This approach usually implies<br>
>> dot-notation.<br>
>> If (r::S), then (r.f) uses the 'f' from 'S', and similarly if<br>
>> (r::T).<br>
>><br>
>> Note that<br>
>><br>
>> * The Frege-derived records proposal (FDR), uses both (A) and (B)<br>
>> <a href="http://hackage.haskell.org/trac/ghc/wiki/Records/NameSpacing" target="_blank">http://hackage.haskell.org/trac/ghc/wiki/Records/NameSpacing</a><br>
>><br>
>> * The Simple Overloaded Record Fields (SORF) proposal uses only (B)<br>
>> <a href="http://hackage.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields" target="_blank">http://hackage.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields</a><br>
>><br>
>> * The Type Directed Name Resolution proposal (TDNR) uses only (B)<br>
>><br>
>> <a href="http://hackage.haskell.org/trac/haskell-prime/wiki/TypeDirectedNameResolution" target="_blank">http://hackage.haskell.org/trac/haskell-prime/wiki/TypeDirectedNameResolution</a><br>
>><br>
>> I know of no proposal that advocates only (A). It seems that we are agreed<br>
>> that we must make use of types to disambigute common cases.<br>
>><br>
>> Complexities of (Plan B)<br>
>> ~~~~~~~~~~~~~~~~~~~~~~~~<br>
>> Proposal (Plan B) sounds innocent enough. But I promise you, it isn't.<br>
>> There has ben some mention of the "left-to-right" bias of Frege type<br>
>> inference engine; indeed the wohle explanation of which programs are<br>
>> accepted and which are rejected, inherently involves an understanding<br>
>> of the type inference algorithm. This is a Very Bad Thing when the<br>
>> type inference algorithm gets complicated, and GHC's is certainly<br>
>> complicated.<br>
>><br>
>> Here's an example:<br>
>><br>
>> type family F a b<br>
>> data instance F Int [a] = Mk { f :: Int }<br>
>><br>
>> g :: F Int b -> ()<br>
>> h :: F a [Bool] -> ()<br>
>><br>
>> k x = (g x, x.f, h x)<br>
>><br>
>> Consider type inference on k. Initially we know nothing about the<br>
>> type of x.<br>
>> * From the application (g x) we learn that x's type has<br>
>> shape (F Int <something>).<br>
>> * From the application (h x) we learn that x's type has<br>
>> shape (F <something else> [Bool])<br>
>> * Hence x's type must be (F Int [Bool])<br>
>> * And hence, using the data family we can see which field<br>
>> f is intended.<br>
>><br>
>> Notice that<br>
>> a) Neither left to right nor right to left would suffice<br>
>> b) There is significant interaction with type/data families<br>
>> (and I can give you more examples with classes and GADTs)<br>
>> c) In passing we note that it is totally unclear how (Plan A)<br>
>> would deal with data families<br>
>><br>
>> This looks like a swamp. In a simple Hindley-Milner typed language<br>
>> you might get away with some informal heuristics, but Haskell is far<br>
>> too complicated.<br>
>><br>
>> Fortunately we know exactly what to do; it is described in some detail<br>
>> in our paper "Modular type inference with local assumptions"<br>
>> <a href="http://www.haskell.org/haskellwiki/Simonpj/Talk:OutsideIn" target="_blank">http://www.haskell.org/haskellwiki/Simonpj/Talk:OutsideIn</a><br>
>><br>
>> The trick is to *defer* all these decisions by generating *type constraints*<br>
>> and solving them later. We express it like this:<br>
>><br>
>> G, r:t1 |- r.f : t2, (Has t1 "f" t2)<br>
>><br>
>> This says that if r is in scope with type t1, then (r.f) has type t2,<br>
>> plus the constraint (Has t1 "f" t2), which we read as saying<br>
>><br>
>> Type t1 must have a field "f" of type t2<br>
>><br>
>> We gather up all the constraints and solve them. In solving them<br>
>> we may figure out t1 from some *other* constraint (to the left or<br>
>> right, it's immaterial. That allow us to solve *this* constraint.<br>
>><br>
>> So it's all quite simple, uniform, and beautiful. It'll fit right<br>
>> into GHC's type-constraint solver.<br>
>><br>
>> But note what has happened: we have simply re-invented SORF. So the<br>
>> conclusion is this:<br>
>><br>
>> the only sensible way to implement FDR is using SORF.<br>
>><br>
>> What about overloading?<br>
>> ~~~~~~~~~~~~~~~~~~~~~~~<br>
>> A feature of SORF is that you can write functions like this<br>
>><br>
>> k :: Has r "f" Int => r -> Int<br>
>> k r = r.f + 1<br>
>><br>
>> Function 'k' works on any record that has a field 'f'. This may be<br>
>> cool, but it wasn't part of our original goal. And indeed neither FDR<br>
>> nor TDNR offer it.<br>
>><br>
>> But, the Has constraints MUST exist, in full glory, in the constraint<br>
>> solver. The only question is whether you can *abstract* over them.<br>
>> Imagine having a Num class that you could not abstract over. So you<br>
>> could write<br>
>><br>
>> k1 x = x + x :: Float<br>
>> k2 x = x + x :: Integer<br>
>> k3 x = x + x :: Int<br>
>><br>
>> using the same '+' every time, which generates a Num constraint. The<br>
>> type signature fixes the type to Float, Integer, Int respectively, and<br>
>> tells you which '+' to use. And that is exactly what ML does!<br>
>><br>
>> But Haskell doesn't. The Coolest Thing about Haskell is that you get<br>
>> to *abstract* over those Num constraints, so you can write<br>
>><br>
>> k :: Num a => a -> a<br>
>> k x = x + x<br>
>><br>
>> and now it works over *any* Num type.<br>
>><br>
>> On reflection, it would be absurd not to do ths same thing for Has<br>
>> constraints. If we are forced to have Has constraints internally, it<br>
>> woudl be criminal not to abstract over them. And that is precisely<br>
>> what SORF is.<br>
>><br>
>><br>
>> Is (Plan A) worth it?<br>
>> ~~~~~~~~~~~~~~~~<br>
>><br>
>> Once you have (Plan B), and SORF in full glory, plus of course the<br>
>> existing ability to name fields T_f, S_f, if you want, I think it is<br>
>> highly questionable whether we need the additional complexities of<br>
>> (Plan A)?<br>
>><br>
>> And I do think (Plan A) has lots of additional complexities that we<br>
>> have not begun to explore yet. The data-family thing above is an<br>
>> example, and I can think of some others.<br>
>><br>
>> But even if it was simple, we still have to ask: does *any* additional<br>
>> complexity give enough payoff, if you already have SORF? I suspect<br>
>> not.<br>
>><br>
>><br>
>> Extensions to SORF<br>
>> ~~~~~~~~~~~~~~~~~~<br>
>> Frege lets you add "virtual fields" to a record type, using an extra<br>
>> RExtension mechanism that I do not yet understand. But SORF lets you<br>
>> do so with no additional mechanism. See "Virtual record selectors"<br>
>> on <a href="http://hackage.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields" target="_blank">http://hackage.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields</a><br>
>> The point is that the existing type-class instance mechanisms do just<br>
>> what we want.<br>
>><br>
>><br>
>> Syntax<br>
>> ~~~~~~<br>
>> The debate on the mailing list has moved sharply towards discussing<br>
>> lexical syntax. I'm not going to engage in that discussion because<br>
>> while it is useful to air opinions, it's very hard to get agreement.<br>
>> But for the record:<br>
>><br>
>> * I don't mind having Unicode alternatives, but there must be<br>
>> ASCII syntax too<br>
>><br>
>> * I think we must use ordinary dot for field selection.<br>
>><br>
>> * I think it's fine to insist on no spaces; we are already<br>
>> doing this for qualified names, as someone pointed out<br>
>><br>
>> * I think we should not introduce new syntax unless we are<br>
>> absolutely forced into it. Haskell's record update syntax<br>
>> isn't great, but we have it.<br>
>><br>
>><br>
>> Conclusion<br>
>> ~~~~~~~~~~<br>
>> I am driven to the conclusion that SORF is the way to go.<br>
>> - Every other proposal on the table requires SORF (either<br>
>> visibly or invisibly)<br>
>> - When you have SORF, you don't really need anything else<br>
>><br>
>> The blocking issues are described on<br>
>> <a href="http://hackage.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields" target="_blank">http://hackage.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields</a><br>
>><br>
>> a) "Representation hiding" (look for that heading)<br>
>><br>
>> b) "Record update" (ditto), most especially for records whose<br>
>> fields have polymorphic types<br>
><br>
> I posted to the wiki a possible solution to (b):<br>
> <a href="http://hackage.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields#AlternativeProposal" target="_blank">http://hackage.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields#AlternativeProposal</a><br>
><br>
>> If we fix these we can move forward.<br>
>><br>
>><br>
>><br>
>> _______________________________________________<br>
>> Glasgow-haskell-users mailing list<br>
>> <a href="mailto:Glasgow-haskell-users@haskell.org">Glasgow-haskell-users@haskell.org</a><br>
>> <a href="http://www.haskell.org/mailman/listinfo/glasgow-haskell-users" target="_blank">http://www.haskell.org/mailman/listinfo/glasgow-haskell-users</a><br>
>><br>
><br>
> _______________________________________________<br>
> Glasgow-haskell-users mailing list<br>
> <a href="mailto:Glasgow-haskell-users@haskell.org">Glasgow-haskell-users@haskell.org</a><br>
> <a href="http://www.haskell.org/mailman/listinfo/glasgow-haskell-users" target="_blank">http://www.haskell.org/mailman/listinfo/glasgow-haskell-users</a><br>
<br>
<br>
_______________________________________________<br>
Glasgow-haskell-users mailing list<br>
<a href="mailto:Glasgow-haskell-users@haskell.org">Glasgow-haskell-users@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/glasgow-haskell-users" target="_blank">http://www.haskell.org/mailman/listinfo/glasgow-haskell-users</a><br>
</blockquote></div><br>