From gale at sefer.org Sun Oct 1 05:29:11 2006 From: gale at sefer.org (Yitzchak Gale) Date: Sun Oct 1 04:35:08 2006 Subject: Pattern guards In-Reply-To: <3d96ac180609301837g78b5ebb5n1c3a18b4af6a2307@mail.gmail.com> References: <2608b8a80609280640o601955fx639362cf6735a932@mail.gmail.com> <5ab17e790609281152y15f2913dn75d2650b338fe7b@mail.gmail.com> <2608b8a80609301708s25d58a4x5e811e001d71ddda@mail.gmail.com> <2608b8a80609301823n1b03804ft6c9a318b808104fb@mail.gmail.com> <3d96ac180609301837g78b5ebb5n1c3a18b4af6a2307@mail.gmail.com> Message-ID: <2608b8a80610010229hb19d220u20e34c35fba6ecb8@mail.gmail.com> Sebastian Sylvan wrote: > I would argue that most Haskell programmers > would *never* write the various snippets of code > demonstrated in this thread in your way, I agree, too. I am not advocating that people should write code exactly that way in real life. My construction is meant to be a proof that pattern guards do not provide any significant simplification even in the worst case. In real life, the monadic approach usually leads to a significant simplification. I find that whenever I feel an urge to use a pattern guard, it is a sure sign that I have landed in the wrong monad. I step back and look again at my overall design, and the result is invariably much better code. And the urge goes away. > Adding syntactic sugar is cheap, as long as the > core concepts are small and elegant. The graveyard is littered with the remains of programming languages that took that approach and met an ignoble end. The entire language must remain small and elegant - not just the individual pieces of new syntax that are bolted on. Feature-creep is what eventually kills every programming language. Since Haskell is already a mature language as it first becomes adapted for general use, we need to be especially vigilant. -Yitz From gale at sefer.org Sun Oct 1 07:40:18 2006 From: gale at sefer.org (Yitzchak Gale) Date: Sun Oct 1 06:46:20 2006 Subject: Pattern guards In-Reply-To: <2608b8a80609280640o601955fx639362cf6735a932@mail.gmail.com> References: <2608b8a80609280640o601955fx639362cf6735a932@mail.gmail.com> Message-ID: <2608b8a80610010440va353df9h7c1de48bccf64a1@mail.gmail.com> On 9/28/06, I wrote: > I would like to suggest a correction to ticket #56, > "Pattern Guards". Here is a summary of the discussion: There seems to be a consensus that the main "Pro" currently listed in the ticket is not the real reason. Pros: - Many people have been accustomed to using this syntax for a long time. - Some people find pattern guards to be elegant and aesthetically pleasing. - The alternative monadic style requires knowledge of monads. - More selections are pushed to the lefthand-side of bindings. - Already implemented in most compilers, appears to be easy to implement. Cons: - The semantics of "<-" are further overloaded in a potentially confusing way. - At least one person does not find pattern guards to be elegant and aesthetically pleasing at all. :) - Some people feel that the net gain, if any, is not worth the cost of changing the syntax of the core of Haskell. (Others do not see it as so much of a change, since it has been available in practice for a long time.) Anything else? -Yitz From john at repetae.net Sun Oct 1 19:21:20 2006 From: john at repetae.net (John Meacham) Date: Sun Oct 1 18:26:57 2006 Subject: Pattern guards In-Reply-To: <2608b8a80609301708s25d58a4x5e811e001d71ddda@mail.gmail.com> References: <2608b8a80609280640o601955fx639362cf6735a932@mail.gmail.com> <5ab17e790609281152y15f2913dn75d2650b338fe7b@mail.gmail.com> <2608b8a80609301708s25d58a4x5e811e001d71ddda@mail.gmail.com> Message-ID: <20061001232120.GC22388@momenergy.repetae.net> Just a few thoughts, It is well known pattern guards can be simulated with haskell 98, I don't think anyone has doubted that. The need for supplemental condition testing and splitting the pattern matching among the where clause and the boolean guards is considered very cumbersome by some. Personally I feel it very much obscures the intent of the programmer and comingles the body of the branch with the matching criteria for it in an unpleasant way. the (<-) notation isn't overloaded at all really, any more than it is in list comprehensions. <- always means monadic bind. it is fully general in 'do'. restricted to the list monad in list comprehensions, and restricted to something like the exit monad you mention in pattern guards. They are all consistent uses of (<-). pattern guards have almost unanimous support for inclusion in haskell'. so, even if a couple people on the comitee switched positions, pattern guards would still most likely end up in. Since they are just syntatic sugar, there cannot be an overriding technical reason they won't work, and it is unlikely that many peoples aethetics of coding will change. John -- John Meacham - ?repetae.net?john? From ross at soi.city.ac.uk Sun Oct 1 20:12:58 2006 From: ross at soi.city.ac.uk (Ross Paterson) Date: Sun Oct 1 19:18:55 2006 Subject: Pattern guards In-Reply-To: <2608b8a80609301708s25d58a4x5e811e001d71ddda@mail.gmail.com> References: <2608b8a80609280640o601955fx639362cf6735a932@mail.gmail.com> <5ab17e790609281152y15f2913dn75d2650b338fe7b@mail.gmail.com> <2608b8a80609301708s25d58a4x5e811e001d71ddda@mail.gmail.com> Message-ID: <20061002001258.GA21370@soi.city.ac.uk> On Sun, Oct 01, 2006 at 02:08:35AM +0200, Yitzchak Gale wrote: > An important clarification: the main monad at work > here is the Exit monad. The "bind" notation in a > pattern guard is just an obfuscated Exit monad. > However, in many simple examples, the Maybe monad > can be used as a special case of the Exit monad. You don't use >>=, just >>. Similarly Exit is used only in the form Exit e (), which is equivalent to Maybe e, i.e. if we define exitMaybe :: Exit e () -> Maybe e exitMaybe (Continue _) = Nothing exitMaybe (Exit e) = Just e then we have runExit m = fromJust (exitMaybe m) exitMaybe (x >> y) = exitMaybe x `mplus` exitMaybe y exitMaybe (maybeExit m) = m so we can replace the Exit monad with Maybe. From kahl at cas.mcmaster.ca Sun Oct 1 20:33:07 2006 From: kahl at cas.mcmaster.ca (kahl@cas.mcmaster.ca) Date: Sun Oct 1 19:39:01 2006 Subject: Replacing and improving pattern guards with PMC syntax Message-ID: <20061002003307.15687.qmail@schroeder.cas.mcmaster.ca> One of the problems of pattern matching in Haskell is that it might well be regarded as not very declarative: function definition lines cease being generalisable equations, and the definition of the rewriting strategy involved in Haskell pattern matching extends over about three pages, no matter whether you look in the Haskell report, or for a definition of the ``functional rewriting strategy'' in the theoretical literature. To fix exactly this problem was my original goal when I started developing a family of Pattern Matching Calculi, see http://www.cas.mcmaster.ca/~kahl/PMC/ . (Other pattern matching calculi in the literature have different goals.) The original calculus, which I shall call ``PMC'' for the remainder of this message, is a confluent rewriting system with a normalising strategy that incorporates Haskell pattern matching --- the confluence proof has been mechanised using Isabelle. So far I never considered it important to devise a concrete syntax for PMC, but triggered by the current pattern guards thread on haskell-prime, I now try to give a PMC syntax that blends well with Haskell. PMC ``automatically'' includes the ``expression pattern'' of pattern guards, but organised differently, see below. I am now presenting a series of syntactic extensions to Haskell. without assuming that the reader is familiar with PMC, but I will also explain how these extensions relate with PMC. One of my gripes with Haskell pattern matching is that the anonymous variant, namely case expressions, has an application to an argument built in, and therefore does not by itself produce a function. However, lambda-abstraction already allows single-alternative pattern matching, so I propose to relax this to multi-alternative pattern matching: > length = \ > [] -> 0 > x : xs -> 1 + length xs (Lists of alternatives correspond to the ``matchings'' of PMC, and concatenation of those lists (using ``;'' or layout) corresponds to matching alternative in PMC. ``\ m'' then corresponds to ``{| m |}'' in PMC. ) For multi-argument pattern matching, I propose to allow nested matchings: > zip = \ > x : xs -> y : ys -> (x,y) : zip xs ys > _ -> _ -> [] > take' = \ > 0 -> _ -> [] > n -> { [] -> [] > ; x : xs -> x : take (pred n) xs > } This means that the alternative ``->'' now can have either an expression or a list of alternatives as its right argument. (Having an expression there corresponds to ``lifting'' $\leftharpoonup \_ \rightharpoonup$ in PMC.) Pattern guards now can be seen as a special case of alternatives-level argument application (``argument supply'' $\righttriangle$ in PMC). I find it useful to write the argument first, as in PMC. I see two options of writing argument supply in Haskell: either using new keywords, giving rise to the syntax production alt -> match exp with alts or using a keyword infix operator: alt -> exp |> alts (Using this kind of argument supply instead of pattern guards also has the advantage that multiple alternatives become possible.) I start with Simon Peyton Jones' standard example: > clunky env v1 v2 | Just r1 <- lookup env v1 > , Just r2 <- lookup env v2 = r1 + r2 > | otherwise = v1 + v2 This could now be written using either ``match _ with _'': > clunky env v1 v2 = \ > match lookup env v1 with > Just r1 -> match lookup env v2 with > Just r2 -> r1 + r2 > v1 + v2 or infix ``_ |> _'': > clunky env v1 v2 = \ > lookup env v1 |> Just r1 -> > lookup env v2 |> Just r2 -> r1 + r2 > v1 + v2 Note that the syntactic structure is different from pattern guards; here is the fully parenthesised version: > clunky env v1 v2 = \ > { lookup env v1 |> { Just r1 -> > { lookup env v2 |> { Just r2 -> r1 + r2 }}} > ; v1 + v2 > } Boolean guards are matches against True: > take = \ > 0 -> _ -> [] > n -> match n > 0 with > True -> > { [] -> [] > ; x : xs -> x : take (pred n) xs > } > _ -> error "take: negative argument" But Boolean guards can also be kept as syntactic sugar: > take = \ > 0 -> _ -> [] > n | n > 0 -> > { [] -> [] > ; x : xs -> x : take (pred n) xs > } > | otherwise -> error "take: negative argument" Now we have all the syntax in place --- PMC's ``failure'' is of course the empty alternative (allowed in Haskell 98). For the grammar, the relevant productions in Haskell 98 are: exp10 -> \ apat1 ... apatn -> exp (lambda abstraction, n>=1) | "case" exp "of" { alts } (case expression) alts -> alt1 ; ... ; altn (n>=1) alt -> pat "->" exp [where decls] | pat gdpat [where decls] | (empty alternative) gdpat -> gd "->" exp [ gdpat ] gd -> | exp This would change to the following, where I propose to rename ``alt'' to ``match'' for ``matching'' as in PMC, since this is now a full-fledged syntactic category of importance similar to that of expressions (PMC works essentially because of this separation of syntactic categories): exp10 -> \ { matchs } (lambda abstraction) | "case" exp "of" { matchs } (case expression) matchs -> match1 ; ... ; matchn (alternative, n>=1) match -> expr (result) | pat "->" { matchs } [where decls] (pattern matching) | pat gdpat [where decls] (pat. mat. w. Boolean guards) | (empty alternative) | "match" exp "with" { matchs } (pattern argument supply) gdpat -> gd "->" { matchs } [ gdpat ] gd -> | exp (case expressions would than be syntactic sugar: > case exp of {matchs} = \ match exp with {matchs} ) These productions imply that we would loose multiple abstraction: \ x y z -> 3 becomes \ x -> y -> z -> 3 . For reasons of declarativity, I am also tempted to argue that ``='' should only be allowed for one-line definitions, so we would write: > f 0 -> 1 > f n -> n * f (n - 1) An easy-to-remember motto for this could be ``if it can fall through, use ->''. This would of course break every single textbook and tutorial, so I won't insist... No matter whether with ``->'' or with ``='', the above would of course be syntactic sugar for: > f = \ > 0 -> 1 > n -> n * f (n - 1) LAWS ==== The most important nice thing is that we can now use equational reasoning for expressions involving pattern matching. The PMC laws (see the papers for more explanation) translate into the syntax presented above as follows (note that most of these equations are between matchings, i.e., between (lists of) alternatives, and only some are between expressions): --------------------------------------------------------------------- Failure as unit: > {- empty alternative -} ; alts = alts Failure lifting: > \ { } = undefined Result lifting: > \ { exp } = exp Argument propagation into matching: > (\ { alts }) exp = \ { match exp with { alts } } Argument propagation into expression: > match arg with { exp } = exp arg First match wins (no backtracking after first success): > exp ; alts = exp Failure-strictness of argument supply: > match arg with { } = {- empty alternative -} Distributivity of argument supply over alternative: > match arg with { alts1 ; alts2 } = > match arg with { alts1 } ; match arg with { alts2 } beta (v is a variable): > match arg with { v -> { alts } } = alts[v \ arg] -- substitution Match when matching the same constructor: > match c(e1,...,en) with {c(p1,...,pn) -> {alts}} > = match e1 with {p1 -> ... -> match en with pn -> {alts}} Mismatch when matching different constructors: > match c(e1,...,em) with {d(p1,...,pn) -> {alts}} > = {- empty alternative -} Strictness of matching against constructors: > match undefined with {c(p1,...,pn) -> {alts}} = undefined --------------------------------------------------------------------- Together with Strictness of function application in the function: > undefined arg = undefined -- already in Haskell , these laws, when oriented as rules, produce a confluent rewriting system, and the standard definition of strong head normal form induces a normalising strategy. Besides extending syntactic convenience even beyond pattern guards, adopting the abstract syntax of PMC would therefore also simplify the definition of the semantics of pattern matching in Haskell, and extend the scope of equational reasoning to pattern matching. For the concrete syntax I have no strong feelings, but hope that I provided a starting point for discussion. Wolfram From kahl at cas.mcmaster.ca Mon Oct 2 07:59:39 2006 From: kahl at cas.mcmaster.ca (kahl@cas.mcmaster.ca) Date: Mon Oct 2 07:05:32 2006 Subject: [Haskell] Replacing and improving pattern guards with PMC syntax In-Reply-To: <4520BAA5.7070001@yahoo-inc.com> (message from Brandon Moore on Mon, 02 Oct 2006 00:07:17 -0700) References: <20061002003307.15687.qmail@schroeder.cas.mcmaster.ca> <4520BAA5.7070001@yahoo-inc.com> Message-ID: <20061002115939.15767.qmail@schroeder.cas.mcmaster.ca> Brandon Moore wrote in his answer to my PMC syntax proposal: > > Maybe the '\' could be reiterated to introduce the layout group: > > take' = \ > 0 _ -> [] > n \[] -> [] > (x:x) -> x : take (pred n) xs Definitely not, since the lambda gets us back into expressions, destroying the fall-through properties of matchings. (In this particular case this is no problem, but in general it would destroy fall-through.) > > > alt -> match exp with alts > Maybe reuse "case", unless a new keyword is needed to avoid confusion. We definitely need this construct to produce a matching (or ``alt''). If we use ``case'' here, then case expressions don't exist anymore. Wolfram From kahl at cas.mcmaster.ca Mon Oct 2 08:01:10 2006 From: kahl at cas.mcmaster.ca (kahl@cas.mcmaster.ca) Date: Mon Oct 2 07:07:01 2006 Subject: [brandonm@yahoo-inc.com: Re: [Haskell] Replacing and improving pattern guards with PMC syntax] Message-ID: <20061002120110.15771.qmail@schroeder.cas.mcmaster.ca> Brandon asked me to forward this --- I already posted a small clarification. Wolfram ------- Start of forwarded message ------- Date: Mon, 02 Oct 2006 00:07:17 -0700 From: Brandon Moore To: kahl@cas.mcmaster.ca CC: haskell-prime@haskell.org Subject: Re: [Haskell] Replacing and improving pattern guards with PMC syntax In-Reply-To: <20061002003307.15687.qmail@schroeder.cas.mcmaster.ca> kahl@cas.mcmaster.ca wrote: ... > So far I never considered it important to devise a concrete syntax for PMC, > but triggered by the current pattern guards thread on haskell-prime, > I now try to give a PMC syntax that blends well with Haskell. I think with some alterations your syntax would blend even better. In particular, it would be really nice to have a backwards-compatible syntax. > One of my gripes with Haskell pattern matching is > that the anonymous variant, namely case expressions, > has an application to an argument built in, > and therefore does not by itself produce a function. > > However, lambda-abstraction already allows single-alternativepattern matching, so I propose to relax this to multi-alternative > pattern matching: >> length = \ >> [] -> 0 >> x : xs -> 1 + length xs I'm with you here. Extending lambda to introduce a layout group of alternatives makes sense even without the rest of the changes to matching. This isn't completely backwards-compatible, but it's pretty close. While we're at it, why not have the identifier of a top level definition introduce a layout group of alternatives, rather than requiring the name to be repeated all the time. How about take 0 _ = [] _ [] = [] n (x:xs) = x : take (pred n) ns > (Lists of alternatives correspond to the ``matchings'' of PMC, > and concatenation of those lists (using ``;'' or layout) corresponds > to matching alternative in PMC. > ``\ m'' then corresponds to ``{| m |}'' in PMC. > ) > > For multi-argument pattern matching, > I propose to allow nested matchings: >> zip = \ >> x : xs -> y : ys -> (x,y) : zip xs ys >> _ -> _ -> [] This deviates from the current syntax of multi-argument lambda, and introduces overloading on ->. Perhaps -> could be reserved for "match and lift", and whitespace could separate several alternatives: zip = \ (x:xs) (y:ys) -> (x,y) : zip xs ys _ _ -> [] There is some tension in the current between argument lists which allow several arguments and require parentheses around constructor applications to delimit patterns, and case expression which match only one item, but without grouping. If we are trying to unify things, perhaps case could be extended to support matching several values together, perhaps separating expressions with commas in the head and using the syntax of a lambda for the cases. Perhaps '=' in function declarations vs. "->" for other matching could also be simplified somehow. I don't have any ideas here. >> take' = \ >> 0 -> _ -> [] >> n -> { [] -> [] >> ; x : xs -> x : take (pred n) xs >> } I'm not sure how to handle a case like this. Introducing layout at whitespace seems a bit excessive, but requiring explicit separators looks a bit heavy on punctuation next to the current grammar, where only records (and perhaps Maybe the '\' could be reiterated to introduce the layout group: take' = \ 0 _ -> [] n \[] -> [] (x:x) -> x : take (pred n) xs > > Pattern guards now can be seen as a special case of > alternatives-level argument application > (``argument supply'' $\righttriangle$ in PMC). > I find it useful to write the argument first, as in PMC. > > I see two options of writing argument supply in Haskell: > either using new keywords, giving rise to the syntax production > > alt -> match exp with alts Maybe reuse "case", unless a new keyword is needed to avoid confusion. > or using a keyword infix operator: > > alt -> exp |> alts > > (Using this kind of argument supply instead of pattern guards > also has the advantage that multiple alternatives become possible.) I'm not using -> to separate patterns, but some leading symbol is required to separate the last pattern from the expression. I like '|' from the current syntax, selected with hopes of incorporating and extending the current guard syntax. I'm pretty sure incorporating the existing guard syntax will require that the grammar keep track whether the last "bit" of the matching was a pattern or a guard (just like currently | switches from patterns separated by whitespace to a list of guards separated by commas). Pattern guards can be translated to matching plus argument supply, so argument supply needs to be part of the primitive matching syntax. I like the suggestion alt | exp |> alts It would be unambiguous but require unbounded lookahead to allow a case to begin with argument supply: foo :: [Int] -> [Int] foo = \lookup env v |> (Just r) [] -> [r] Given argument supply, we can sugar in the existing guard syntax by allowing alt | guard, guards, exp |> alts and alt | guards -> expr The sequence "->\" will transition from guards back to matching more arguments. It might be nice to abbreviate that to '\'. Guards can be eliminated with the translations alt | exp, guards ... ==> alt | exp |> True |guards alt | exp -> expr ==> alt | exp |> True -> expr alt | pat <- exp, guards ==> alt | exp |> {pat | guards ... } alt | pat <- exp -> expr ==> alt | exp |> pat -> expr > > I start with Simon Peyton Jones' standard example: > >> clunky env v1 v2 | Just r1 <- lookup env v1 >> , Just r2 <- lookup env v2 = r1 + r2 >> | otherwise = v1 + v2 I'd like to accepts this unchanged. I think the treatment of guards above will work. > This could now be written using either ``match _ with _'': > >> clunky env v1 v2 = \ >> match lookup env v1 with >> Just r1 -> match lookup env v2 with >> Just r2 -> r1 + r2 >> v1 + v2 > > or infix ``_ |> _'': > >> clunky env v1 v2 = \ >> lookup env v1 |> Just r1 -> >> lookup env v2 |> Just r2 -> r1 + r2 >> v1 + v2 Because I'm using space to separate patterns, I would require parentheses (or the pat <- exp sugar) clunky env v1 v2 | lookup env v1 |> (Just r1) , lookup env v2 |> (Just r2) -> r1 + r2 > Boolean guards are matches against True: >> take = \ >> 0 -> _ -> [] >> n -> match n > 0 with >> True -> >> { [] -> [] >> ; x : xs -> x : take (pred n) xs >> } >> _ -> error "take: negative argument" take = \ 0 _ -> [] n | n > 0 \[] -> [] (x:xs) -> x : take (pred n) ns This syntax has a pretty nice pronunciation, reading | as "such that", a comma as an "and" (between guards), and both space between patterns or '\' after a guard as "and" or "and then" (either way, introducing a pattern for another argument). This PMC stuff seems like a description/semantics for pattern matching. Hopefully my attempts at backwards-compatible syntax help people give the semantics a deeper look. Brandon ------- End of forwarded message ------- From kahl at cas.mcmaster.ca Mon Oct 2 15:33:37 2006 From: kahl at cas.mcmaster.ca (kahl@cas.mcmaster.ca) Date: Mon Oct 2 14:39:40 2006 Subject: [Haskell] Replacing and improving pattern guards with PMC syntax In-Reply-To: <45215B84.9060800@yahoo-inc.com> (message from Brandon Moore on Mon, 02 Oct 2006 11:33:40 -0700) References: <20061002003307.15687.qmail@schroeder.cas.mcmaster.ca> <4520BAA5.7070001@yahoo-inc.com> <20061002115939.15767.qmail@schroeder.cas.mcmaster.ca> <45215B84.9060800@yahoo-inc.com> Message-ID: <20061002193337.3984.qmail@schroeder.cas.mcmaster.ca> Brandon, > Both of these constructs amount to minor syntactical overloading, > allowing lambda and "case" constructs in the expression grammar and the > match grammar with slightly different meanings. This seems to be pretty > similar to the way we already allow (Constr x y z) as an expression or a > pattern. I'm afraid this could easily lead to ambiguity on the grammar level and, independently, to confusion in the human head. But if these issues can be resolved, I currently do not feel strongly either way. Note however that > f xs = case xs of > (x : xs) -> case xs of > (y : ys) -> 1 > _ -> 2 and > g xs = case xs of > (x : xs) -> match xs with > (y : ys) -> 1 > _ -> 2 are different: f "01" = 1 g "01" = 1 f "0" = undefined g "0" = 2 f "" = 2 g "" = 2 f is in Haskell 98, and g can be rewritten using pattern guards: > g xs = case xs of > (x : xs) | (y : ys) <- xs -> 1 > _ -> 2 That is what I mean with ``fall-through'' --- and from this you see that you need an indicator for whether what is coming after the ``->'' is a matching or an expression. As long as the production alt -> expr is included, nothing that parses as an expression can be allowed to also parse as a matching according to a different production. In PMC, the corresponding production is match -> \leftharpoonup expr \rightharpoonup , so there, using ``case'' both for expressions and for matchings would ``only'' be confusing... But using delimiters is of course an option. (I also considered a different arrow for one of the two cases, for example ``|=>'' as in PMC, or even ``=>'', but I thought that the delimiter-less option was more ``Haskell-ish'', and with care in the grammar design can be made to work.) Several of your suggestions, including > I suggested whitespace rather than -> to separate sequential patterns could be feasible alternatives for the concrete syntax --- but we first need agreement on the abstract syntax. Perhaps the extension alt -> "match" exp "with" { alts } could be considered as an independent extension; this is more powerful than pattern guards, and probably less controversial than multi-alternative lambda. Wolfram From gale at sefer.org Mon Oct 2 17:58:44 2006 From: gale at sefer.org (Yitzchak Gale) Date: Mon Oct 2 17:04:35 2006 Subject: Pattern guards In-Reply-To: <20061002001258.GA21370@soi.city.ac.uk> References: <2608b8a80609280640o601955fx639362cf6735a932@mail.gmail.com> <5ab17e790609281152y15f2913dn75d2650b338fe7b@mail.gmail.com> <2608b8a80609301708s25d58a4x5e811e001d71ddda@mail.gmail.com> <20061002001258.GA21370@soi.city.ac.uk> Message-ID: <2608b8a80610021458p7c53c293q96ee165cb9a3a08d@mail.gmail.com> I wrote: >> ...the main monad at work here is the Exit monad. Ross Paterson wrote: > ...if we define > exitMaybe :: Exit e () -> Maybe e > exitMaybe (Continue _) = Nothing > exitMaybe (Exit e) = Just e > then we have > runExit m = fromJust (exitMaybe m) > exitMaybe (x >> y) = exitMaybe x `mplus` exitMaybe y > exitMaybe (maybeExit m) = m > so we can replace the Exit monad with Maybe. Maybe monads quit on failure and continue on success. We want the opposite semantics for guards, pattern matching, and the like. The Exit monad is the dual of the Maybe monad in this sense. In particular, your identity > exitMaybe (x >> y) = exitMaybe x `mplus` exitMaybe y is not true. If we let x = Continue () and y = Exit z, then exitMaybe (x >> y) = Just z but exitMaybe x `mplus` exitMaybe y = Nothing -Yitz From gale at sefer.org Mon Oct 2 18:35:15 2006 From: gale at sefer.org (Yitzchak Gale) Date: Mon Oct 2 17:41:06 2006 Subject: Pattern guards In-Reply-To: <20061001232120.GC22388@momenergy.repetae.net> References: <2608b8a80609280640o601955fx639362cf6735a932@mail.gmail.com> <5ab17e790609281152y15f2913dn75d2650b338fe7b@mail.gmail.com> <2608b8a80609301708s25d58a4x5e811e001d71ddda@mail.gmail.com> <20061001232120.GC22388@momenergy.repetae.net> Message-ID: <2608b8a80610021535g1870d67dm7eeb6f251f98aa0e@mail.gmail.com> > The need for supplemental condition testing and > splitting the pattern matching among the where > clause and the boolean guards is considered > very cumbersome by some. Yes, it is. But that was only an artificial construction, meant to work in general. I wouldn't do it that way really. When an individual problem is reformulated in the correct monad, the entire program becomes much simpler. > the (<-) notation isn't overloaded at all really, any > more than it is in list comprehensions. <- always > means monadic bind. it is fully general in 'do'. > restricted to the list monad in list comprehensions, > and restricted to something like the exit monad you > mention in pattern guards. They are all consistent > uses of (<-). No, they are not the same. Bind in a list comprehension translates to the exact same bind in do notation. I cannot think of any translation of pattern guards for which the same thing is true. For example, in my construction, pat <- e translates to pat <- return (e). That is a very significant semantic difference. -Yitz From ross at soi.city.ac.uk Mon Oct 2 18:55:48 2006 From: ross at soi.city.ac.uk (Ross Paterson) Date: Mon Oct 2 18:01:56 2006 Subject: Pattern guards In-Reply-To: <2608b8a80610021458p7c53c293q96ee165cb9a3a08d@mail.gmail.com> References: <2608b8a80609280640o601955fx639362cf6735a932@mail.gmail.com> <5ab17e790609281152y15f2913dn75d2650b338fe7b@mail.gmail.com> <2608b8a80609301708s25d58a4x5e811e001d71ddda@mail.gmail.com> <20061002001258.GA21370@soi.city.ac.uk> <2608b8a80610021458p7c53c293q96ee165cb9a3a08d@mail.gmail.com> Message-ID: <20061002225548.GA21808@soi.city.ac.uk> On Mon, Oct 02, 2006 at 11:58:44PM +0200, Yitzchak Gale wrote: > Ross Paterson wrote: > >...if we define > > exitMaybe :: Exit e () -> Maybe e > > exitMaybe (Continue _) = Nothing > > exitMaybe (Exit e) = Just e > > Maybe monads quit on failure and > continue on success. We want the opposite > semantics for guards, pattern matching, and > the like. And that's what mplus does. > In particular, your identity > > >exitMaybe (x >> y) = exitMaybe x `mplus` exitMaybe y > > is not true. If we let x = Continue () and y = Exit z, then > > exitMaybe (x >> y) = Just z > > but > > exitMaybe x `mplus` exitMaybe y = Nothing exitMaybe (Continue ()) `mplus` exitMaybe (Exit z) = Nothing `mplus` Just z = Just z From claus.reinke at talk21.com Mon Oct 2 20:13:33 2006 From: claus.reinke at talk21.com (Claus Reinke) Date: Mon Oct 2 19:19:30 2006 Subject: Replacing and improving pattern guards with PMC syntax References: <20061002003307.15687.qmail@schroeder.cas.mcmaster.ca> Message-ID: <00f401c6e680$c4ab4980$3c318351@cr3lt> I'm not sure I follow all the details, but I think I agree ;) with Wolfram on several points, even if I've arrived there via a different route. Some of this may sound strange to those who equate "declarative" with "equational", so let me state in advance that I do not agree with that particular notion - expression-level programs, such as parsers built from parser combinators, can be just as declarative as equations. However, I do agree that pattern matching has become a problem in functional languages (I once knew a fpl where that part of the language and implementation was of roughly the same complexity as the whole rest of it), and Haskell is unfortunately no exception. The problem is not that there is syntactic sugar for pattern matching, but that this isn't sugar coating at all - there is functionality hidden in there that cannot be provided by the remainder of the language. In other words, pattern matching and associated "sugar" become part of Haskell's core, which thus becomes more complex, without offering sufficient compensation in terms of expressiveness. The particular issue at hand is not that case is modeled after let rather than after lambda, but that pattern match failure and fall through are built-in concepts that cannot be programmed in the language but have to be dealt with in specific syntactic forms. Following the old adage of "simplicity through generality", I would prefer instead if we would have available language- constructs for matchings, composition of matchings, and "splicing" of such rule sets back into expressions ("\" in Wolfram's description). Then pattern match fall-through would be programmable, patterns matching constructs could be composed as easily as parser combinators (as an added bonus, getting closer to first-class patterns), case, multi-equations, and do-notation would become true syntactic sugar, and Haskell's core would finally start to become simpler, for once. My own awkward-looking translations were driven by having found two tool's in Haskell that come close to this ideal, even if the syntax is awkward: the mapping of pattern-match failure to "fail" in do-notation, and the use of "fail msg=mzero" in MonadPlus. By these means, matchings (lambdas with patterns and explicit match failure) can be represented as do-blocks: lhs->rhs ==> \x->do { lhs <- return x; return rhs } (1) and then be composed (the examples I gave moved the \s to the front instead and used "mplus" to compose matchings, but we could also lift the compositions to function-level instead), and finally "spliced" back (turning explicit into implicit match failure) using fromJust or suchlike. Adding pattern guards into this translation was straightforward - they simply go between the two returns. Now, instead of repeatingWolfram's arguments about case and multi-equations, let's have a look at do-notation, as used in (1): it is obvious that this part of the translation is the source of the awkwardness I mentioned, as the right-hand side of (1) has a lot more syntax noise than the left-hand side. What we really want here is some way of "lifting" lambda-abstractions so as to make potential pattern-match failures explicit and handleable. Perhaps we can get rid of some of that syntax noise? \x->do { lhs <- return x; return rhs } --> \x->(return x >>= \lhs->return rhs) --> \x->(>>= (\lhs->return rhs)) (return x) --> (>>= (return . (\lhs->rhs))) . return hey, that's great! so the lifting we are looking for is simply lift match = (>>= (return . match)) . return right? wrong, unfortunately. Looking more closely at the translation of do-notation in 3.14 of the Report, we see that it actually creates a new function by syntactic rather than semantic manipulation (in fact mapping the problem of fall-through back to a multi-equation first, then to "fail"), so we have no hope of reproducing the nice behaviour wrt pattern-match failure without using the do-notation, and all the syntax noise that implies. I'm not sure whether Wolfram suggested only a simplication of the specification of pattern matching or an actual reification of the concepts of matching, composition of matching, and splicing of matchings into multi-alternative lambdas. Personally, I'd very much like to see the latter, as this issue frequently confronts me, eg., when embedding domain-specific languages and their patterns in Haskell. When Haskell came into being, it started from the lambda calculus, but nowadays, a substantial portion of Haskell programs use various monads to capture program patterns. If Haskell was designed today, monads would not be a late add-on with some syntax to be translated away, but they would be at the core of the language, with other features translated away into that generalised core. And one of the things that would make possible is to replace some previously built-in and non-composable notions, like pattern-match fall through and composition of rule alternatives, by a smaller, yet more expressive core. And that is always a worthwhile goal for language redesign, isn't it?-) Cheers, Claus PS. Outside of Haskell98, we can come closer to defining that lift function, but it gets rather ugly. Here is a first approximation: lift match = \x->either (fail . show) return $! unsafePerformIO $ (return $! Right $! match x) `Control.Exception.catch` (return . Left) Main> lift head ([False]::[Bool]) >>= print False Main> lift head ([]::[Bool]) >>= print Program error: user error (pattern match failure: head []) Main> lift head ([]::[Bool]) `mplus` (Just True) Just True Main> lift head ([False]::[Bool]) `mplus` (Just True) Just False From ashley at semantic.org Mon Oct 2 21:16:03 2006 From: ashley at semantic.org (Ashley Yakeley) Date: Mon Oct 2 20:22:23 2006 Subject: All Monads are Functors In-Reply-To: <20060930144610.GA12814@soi.city.ac.uk> References: <30955.1156607805@calligramme.charmers> <451E57F6.8030908@cs.nott.ac.uk> <20060930144610.GA12814@soi.city.ac.uk> Message-ID: Ross Paterson wrote: > Ashley's quite ambitious to push this refactoring of Monad for Haskell', > since there is limited experience with Applicative, and class system > changes that might help with fine-grained hierarchies are unlikely to > be available, but I wish him luck. I agree that a language extension for superclass defaults is not on the cards for Haskell Prime, but really, just how hard is it to write the necessary instances? Especially as we can provide helper functions. -- Ashley Yakeley Seattle WA From gale at sefer.org Tue Oct 3 04:25:16 2006 From: gale at sefer.org (Yitzchak Gale) Date: Tue Oct 3 03:31:06 2006 Subject: Pattern guards In-Reply-To: <20061002225548.GA21808@soi.city.ac.uk> References: <2608b8a80609280640o601955fx639362cf6735a932@mail.gmail.com> <5ab17e790609281152y15f2913dn75d2650b338fe7b@mail.gmail.com> <2608b8a80609301708s25d58a4x5e811e001d71ddda@mail.gmail.com> <20061002001258.GA21370@soi.city.ac.uk> <2608b8a80610021458p7c53c293q96ee165cb9a3a08d@mail.gmail.com> <20061002225548.GA21808@soi.city.ac.uk> Message-ID: <2608b8a80610030125x58145eeep64425ac4db1c995c@mail.gmail.com> Ross Paterson wrote: > Yitzchak Gale wrote: >> Maybe monads quit on failure and >> continue on success. We want the opposite >> semantics for guards, pattern matching, and >> the like. > And that's what mplus does. >> In particular, your identity... is not true... Oops, yes it is, sorry. You are using mplus as the "dual" of (<<) rather than dualiing the monad. -Yitz From apfelmus at quantentunnel.de Tue Oct 3 11:03:56 2006 From: apfelmus at quantentunnel.de (apfelmus@quantentunnel.de) Date: Tue Oct 3 12:14:55 2006 Subject: Replacing and improving pattern guards with PMC syntax In-Reply-To: <00f401c6e680$c4ab4980$3c318351@cr3lt> References: <20061002003307.15687.qmail@schroeder.cas.mcmaster.ca> <00f401c6e680$c4ab4980$3c318351@cr3lt> Message-ID: > The > problem is not that there is syntactic sugar for pattern matching, > but that this isn't sugar coating at all - there is functionality hidden > in there that cannot be provided by the remainder of the language. > > In other words, pattern matching and associated "sugar" become > part of Haskell's core, which thus becomes more complex, > without offering sufficient compensation in terms of expressiveness. I agree. The pattern matching problem is best solved by supplying sugar which either is compositional or fundamental. The compositional structure behind pattern guards is of course (MonadPlus Maybe). So an idea could be to give the plus in MonadPlus suitable syntactic sugar (which it currently lacks) and get pattern guards for free. This can be too much, but at least there might be some kind of sugar for the specific (MonadPlus Maybe) which actually yields pattern guards. I think of sugar along the lines of the following example f (Right (Right p)) = p f (Left p) = p f p = p and its sugared version f p = fromJust $ | Right q <= p | Right r <= q = r | Left q <= p = q | = p where the nested pattern is split in two parts for purpose of demonstration. I don't know whether this can be parsed, but it's intended to be parenthesized as follows: {| {Right q <= p; {| { Right r <= q; = r;}}; }; {| {Left q <= p; = q;}}; {| {= p;}}; The intention is that | behaves like do with the extra feature that adjacent | are collected together by `mplus`. So the desugaring of a list of | statements is like data | a = | a desugarBar :: [| (Maybe a)] -> Maybe a desugarBar xs = foldr1 mplus [expr | {| expr} <- xs ] Further, pat <= expr is equivalent to pat <- return (expr) and that's why we add <= different from <-. Note that <= is not equivalent to {let pat = expr;} and this is actually the whole point of the story. The {= p;} should of course desugar to {return p;} and can somehow end a | scope. It might be difficult to parse but looks much better than return p. Inside the |, things are like in do notation. This means that the delimiter is (;) and not (,) and we have full (<-) access to monadic actions of type (Maybe a): | Right q <= p; Right r <= q = r <==> do Right q <- return p Right r <- return q return r | val <- lookup key xs; val2 <- lookup key2 xs; = val1+val2 <==> do val <- lookup key xs val2 <- lookup key2 xs return (val1 + val2) It's possible to nest | as we all know it from do | Right q <= p; {| Left r <= p = r | Right r <= p = r } with curly braces added only for clarity. Layout should eliminate them. Note how this works nicely with the fact the the last statement in do notation implicitly determines the returned value. Another thing to consider are boolean guards which could be automatically enclosed by a corresponding (guard): | Right q <= p; p > 5; = p-5 <==> do Right q <- return p guard (p > 5) return (p-5) One last thing is to eliminate fromJust: f x | (interesting things here) should be syntactic sugar for f x = fromJust $ | (interesting things here) Regards, apfelmus From carette at mcmaster.ca Wed Oct 4 11:23:56 2006 From: carette at mcmaster.ca (Jacques Carette) Date: Wed Oct 4 10:37:10 2006 Subject: Replacing and improving pattern guards with PMC syntax In-Reply-To: <00f401c6e680$c4ab4980$3c318351@cr3lt> References: <20061002003307.15687.qmail@schroeder.cas.mcmaster.ca> <00f401c6e680$c4ab4980$3c318351@cr3lt> Message-ID: <4523D20C.8060508@mcmaster.ca> Claus Reinke wrote: > My own awkward-looking translations were driven by having > found two tool's in Haskell that come close to this ideal, even > if the syntax is awkward: the mapping of pattern-match failure > to "fail" in do-notation, and the use of "fail msg=mzero" in > MonadPlus. By these means, matchings (lambdas with patterns > and explicit match failure) can be represented as do-blocks: > > lhs->rhs ==> \x->do { lhs <- return x; return rhs } (1) > > and then be composed (the examples I gave moved the \s to the front > instead and used "mplus" to compose matchings, but we could also lift > the compositions to function-level instead), and finally "spliced" > back (turning explicit into implicit match failure) using fromJust or > suchlike. Adding pattern guards into this translation was > straightforward - they simply go between the two returns. Note that it is very much this issue of 'monadic choice' in the case of pattern-match failure which is dealt with (in gory, assembly-level categoretical terms) in the MPC2006 paper you can find at http://www.cas.mcmaster.ca/~kahl/PMC/ (disclaimer: I am a co-author of that particular paper). An early draft of this paper relied heavily on `mplus` with an extra condition -- until it was realized that very few monads satisfy this! This is where 'function lifting' came in, where we essentially add enough arrows "on the left" (in a completely deterministic and typed manner, see the boxed-; and boxed-+ definitions) to pull failure up to the right type, so that failure could be dealt with at the 'right time'. It is only function types that introduce complications -- all other types are quite straightforward to deal with. [Deleted: Claus' derivation of a monadic lifting of pattern-match failure which sure looks equivalent/ very close to what was in our MPC2006 paper]. > hey, that's great! so the lifting we are looking for is simply > > lift match = (>>= (return . match)) . return > > right? wrong, unfortunately. Looking more closely at the > translation of do-notation in 3.14 of the Report, we see > that it actually creates a new function by syntactic rather > than semantic manipulation (in fact mapping the problem > of fall-through back to a multi-equation first, then to "fail"), so we > have no hope of reproducing the nice behaviour wrt pattern-match > failure without using the do-notation, and all the syntax noise that > implies. The MPC2006 paper has a section describing *which* monad that Haskell98 "bakes in" to its syntactic-level translation. So we agree with your observation that there is a whole 'design space' of what to do on match failure, but Haskell 98 bakes a particular choice in. See that section for how other published papers "bake in" other choices, and how large the design space can really be [for example, using the List monad leads to quite interesting ideas, as does using LogicT]. > I'm not sure whether Wolfram suggested only a simplication > of the specification of pattern matching or an actual reification > of the concepts of matching, composition of matching, and > splicing of matchings into multi-alternative lambdas. Wolfram's PMC [1] is an all-out reification of the concepts of matching, composition, splicing, etc. The biggest thing it doesn't handle are some of Barry Jay's excellent ideas on generic pattern-matching (see http://www-staff.it.uts.edu.au/~cbj/patterns/). The issue, as far as I see it, is that although Barry's latest ideas are first-rate, they seem extremely difficult to 'type' [and getting PMC to 'type' was really non-trivial]. > And one of the things that would make possible is to replace some > previously built-in and non-composable notions, like pattern-match > fall through and composition of rule alternatives, by a smaller, yet > more expressive core. And that is always a worthwhile goal for > language redesign, isn't it?-) Agreed! Jacques [1] Proper attribution: the PMC is Wolfram's, I just thought it was so cool that I insisted on 'helping' him with the type system... From bringert at cs.chalmers.se Thu Oct 5 04:05:20 2006 From: bringert at cs.chalmers.se (Bjorn Bringert) Date: Thu Oct 5 03:11:08 2006 Subject: Proposal for stand-alone deriving declarations? Message-ID: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> On http://hackage.haskell.org/trac/haskell-prime/wiki/ DerivedInstances it says: "- There is no way to derive an instance of a class for a data type that is defined elsewhere (in another module)." Though there is no proposal to fix this. Would such a proposal be appropriate for Haskell'? If so, I propose to add a top-level declaration on the form: 'deriving' qtycls 'for' qtycon which produces the same instance as a deriving clause in the declaration of the datatype or newtype would. I have recently (thanks to the GHC Hackathon) implemented this in GHC. /Bj?rn From simonpj at microsoft.com Thu Oct 5 04:36:54 2006 From: simonpj at microsoft.com (Simon Peyton-Jones) Date: Thu Oct 5 03:42:39 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> References: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> Message-ID: <036EAC76E7F5EC4996A3B3C3657D411606BD7472@EUR-MSG-21.europe.corp.microsoft.com> Thanks for doing this. Is this the syntax we settled on? I remember we discussed it at some length S | -----Original Message----- | From: haskell-prime-bounces@haskell.org [mailto:haskell-prime-bounces@haskell.org] On Behalf Of | Bjorn Bringert | Sent: 05 October 2006 09:05 | To: haskell-prime@haskell.org | Subject: Proposal for stand-alone deriving declarations? | | On http://hackage.haskell.org/trac/haskell-prime/wiki/ | DerivedInstances it says: | | "- There is no way to derive an instance of a class for a data type | that is defined elsewhere (in another module)." | | Though there is no proposal to fix this. Would such a proposal be | appropriate for Haskell'? | | | If so, I propose to add a top-level declaration on the form: | | 'deriving' qtycls 'for' qtycon | | which produces the same instance as a deriving clause in the | declaration of the datatype or newtype would. | | | I have recently (thanks to the GHC Hackathon) implemented this in GHC. | | /Bj?rn | | _______________________________________________ | Haskell-prime mailing list | Haskell-prime@haskell.org | http://www.haskell.org/mailman/listinfo/haskell-prime From chak at cse.unsw.edu.au Thu Oct 5 10:47:55 2006 From: chak at cse.unsw.edu.au (Manuel M T Chakravarty) Date: Thu Oct 5 09:54:08 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> References: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> Message-ID: <1160059675.19200.20.camel@trinity.localdomain> Bjorn Bringert: > On http://hackage.haskell.org/trac/haskell-prime/wiki/ > DerivedInstances it says: > > "- There is no way to derive an instance of a class for a data type > that is defined elsewhere (in another module)." > > Though there is no proposal to fix this. Would such a proposal be > appropriate for Haskell'? I think this would be a useful feature to have. (I certainly wished to have independent deriving declarations many times when writing Haskell code.) It also seems to be a fairly small, well understood extension. > If so, I propose to add a top-level declaration on the form: > > 'deriving' qtycls 'for' qtycon > > which produces the same instance as a deriving clause in the > declaration of the datatype or newtype would. I guess, the right way to go about this would be to say that independent deriving declarations are the fundamental way of deriving a type class. The original form of a deriving clause at a data/newtype declaration is, then, just a syntactic shorthand for a data/newtype declaration plus a bunch of independent deriving declarations. What is not so nice is that you take a new keyword ('for'), which is quite likely to have been used as a variable name in existing code. (Or does it work out to use one of the 'special' names here?) I think it would be useful to write the proposal in complete detail up on the Haskell' wiki. Manuel From bringert at cs.chalmers.se Thu Oct 5 10:50:24 2006 From: bringert at cs.chalmers.se (Bjorn Bringert) Date: Thu Oct 5 09:56:16 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <036EAC76E7F5EC4996A3B3C3657D411606BD7472@EUR-MSG-21.europe.corp.microsoft.com> References: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> <036EAC76E7F5EC4996A3B3C3657D411606BD7472@EUR-MSG-21.europe.corp.microsoft.com> Message-ID: <07CC5748-383B-48CA-94CC-DE5E8532E69B@cs.chalmers.se> What I implemented in GHC is an extension of the proposal below. The proposal just mentions: deriving Class for Type In GHC I also added a form for newtype deriving of multi-parameter type classes: deriving (Class t1 ... tn) for Type I think that it's close to what we ended up with when talking about it at the Hackathon. My intuition about this syntax is that except for the "for Type" part, it looks the same as a normal deriving clause. The "for" part is just there to connect it to a data/newtype declaration. This lets it pretty much use the normal code for deriving declarations. Stand-alone deriving declarations are currently a little bit weaker than normal deriving clauses, since the current implementation does not let you reference the type arguments of a newtype in the arguments of an MPTC. See my response to Bulat on cvs-ghc@haskell.org for more details. /Bj?rn On 5 okt 2006, at 10.36, Simon Peyton-Jones wrote: > Thanks for doing this. > > Is this the syntax we settled on? I remember we discussed it at > some length > > S > > | -----Original Message----- > | From: haskell-prime-bounces@haskell.org [mailto:haskell-prime- > bounces@haskell.org] On Behalf Of > | Bjorn Bringert > | Sent: 05 October 2006 09:05 > | To: haskell-prime@haskell.org > | Subject: Proposal for stand-alone deriving declarations? > | > | On http://hackage.haskell.org/trac/haskell-prime/wiki/ > | DerivedInstances it says: > | > | "- There is no way to derive an instance of a class for a data type > | that is defined elsewhere (in another module)." > | > | Though there is no proposal to fix this. Would such a proposal be > | appropriate for Haskell'? > | > | > | If so, I propose to add a top-level declaration on the form: > | > | 'deriving' qtycls 'for' qtycon > | > | which produces the same instance as a deriving clause in the > | declaration of the datatype or newtype would. > | > | > | I have recently (thanks to the GHC Hackathon) implemented this in > GHC. > | > | /Bj?rn > | > | _______________________________________________ > | Haskell-prime mailing list > | Haskell-prime@haskell.org > | http://www.haskell.org/mailman/listinfo/haskell-prime From simonpj at microsoft.com Thu Oct 5 10:53:34 2006 From: simonpj at microsoft.com (Simon Peyton-Jones) Date: Thu Oct 5 09:59:17 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <1160059675.19200.20.camel@trinity.localdomain> References: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> <1160059675.19200.20.camel@trinity.localdomain> Message-ID: <036EAC76E7F5EC4996A3B3C3657D411606C2A69B@EUR-MSG-21.europe.corp.microsoft.com> | What is not so nice is that you take a new keyword ('for'), which is | quite likely to have been used as a variable name in existing code. (Or | does it work out to use one of the 'special' names here?) The latter is what Bjorn has done. That is, 'for' is only special in this one context. You can use it freely otherwise. As I understand it anyway. | I think it would be useful to write the proposal in complete detail up | on the Haskell' wiki. Yes please. Bjorn? (It may just be a qn of transcribing the user manual stuff you have written.) S From bringert at cs.chalmers.se Thu Oct 5 11:04:21 2006 From: bringert at cs.chalmers.se (=?ISO-8859-1?Q?Bj=F6rn_Bringert?=) Date: Thu Oct 5 10:09:56 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <036EAC76E7F5EC4996A3B3C3657D411606C2A69B@EUR-MSG-21.europe.corp.microsoft.com> References: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> <1160059675.19200.20.camel@trinity.localdomain> <036EAC76E7F5EC4996A3B3C3657D411606C2A69B@EUR-MSG-21.europe.corp.microsoft.com> Message-ID: <45251EF5.3060804@cs.chalmers.se> Simon Peyton-Jones wrote: > | What is not so nice is that you take a new keyword ('for'), which is > | quite likely to have been used as a variable name in existing code. > (Or > | does it work out to use one of the 'special' names here?) > > The latter is what Bjorn has done. That is, 'for' is only special in > this one context. You can use it freely otherwise. As I understand it > anyway. Yes. There is even a "for" function somewhere in the libraries (or was it the testsuite, can't remeber), which tripped up one of my early versions, before I had remembered to make "for" as a special ID in the parser. > | I think it would be useful to write the proposal in complete detail up > | on the Haskell' wiki. > > Yes please. Bjorn? (It may just be a qn of transcribing the user > manual stuff you have written.) Sure. It seems that I have to be on the committee to write to the Wiki. Can I join it? /Bj?rn From iavor.diatchki at gmail.com Thu Oct 5 13:58:47 2006 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Thu Oct 5 13:04:34 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <45251EF5.3060804@cs.chalmers.se> References: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> <1160059675.19200.20.camel@trinity.localdomain> <036EAC76E7F5EC4996A3B3C3657D411606C2A69B@EUR-MSG-21.europe.corp.microsoft.com> <45251EF5.3060804@cs.chalmers.se> Message-ID: <5ab17e790610051058h7c73b3b5jb657ff87f5911a49@mail.gmail.com> Hello, A question about the syntax: would there be a problem if we made the 'deriving' declaration look like an instance? Then we would not need the special identifier 'for', and also we have a more standard looking notation. I am thinking something like: deriving Show SomeType deriving Eq (AnotherType a) -Iavor On 10/5/06, Bj?rn Bringert wrote: > Simon Peyton-Jones wrote: > > | What is not so nice is that you take a new keyword ('for'), which is > > | quite likely to have been used as a variable name in existing code. > > (Or > > | does it work out to use one of the 'special' names here?) > > > > The latter is what Bjorn has done. That is, 'for' is only special in > > this one context. You can use it freely otherwise. As I understand it > > anyway. > > Yes. There is even a "for" function somewhere in the libraries (or was > it the testsuite, can't remeber), which tripped up one of my early > versions, before I had remembered to make "for" as a special ID in the > parser. > > > | I think it would be useful to write the proposal in complete detail up > > | on the Haskell' wiki. > > > > Yes please. Bjorn? (It may just be a qn of transcribing the user > > manual stuff you have written.) > > Sure. It seems that I have to be on the committee to write to the Wiki. > Can I join it? > > /Bj?rn > _______________________________________________ > Haskell-prime mailing list > Haskell-prime@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-prime > From bringert at cs.chalmers.se Thu Oct 5 14:58:28 2006 From: bringert at cs.chalmers.se (Bjorn Bringert) Date: Thu Oct 5 14:04:21 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <5ab17e790610051058h7c73b3b5jb657ff87f5911a49@mail.gmail.com> References: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> <1160059675.19200.20.camel@trinity.localdomain> <036EAC76E7F5EC4996A3B3C3657D411606C2A69B@EUR-MSG-21.europe.corp.microsoft.com> <45251EF5.3060804@cs.chalmers.se> <5ab17e790610051058h7c73b3b5jb657ff87f5911a49@mail.gmail.com> Message-ID: We considered that syntax, but decided against it. Stand-alone deriving declarations are made to be as similar as possible to the current deriving mechanism, rather than be similar to instance declarations. The basic reason for maintaining a syntactic distinction between instance declarations and deriving declarations is to make the programmer aware of the restrictions of the deriving mechanism. These are some things that make deriving declarations different from instance declarations: - You can only derive instances for data types and newtypes. - For deriving declarations, the compiler figures out the constraints, whereas the programmer writes them for instance declarations. - In GHC, you can declare non-Haskell98 instances such as Eq (C X) where X is a concrete type, but you can't do deriving for them. - When deriving instances of multi-parameter type classes (again non- standard), the newtype for which the deriving is made must be the last argument to the class. If the syntax were "deriving (Class T1 ... Tn)", it might not be clear to the reader what type the deriving is for. I can't see any technical reason not to do as you propose. One advantage would be that it makes it possible to fully subsume GHC's current deriving extensions (though there are other ways to do this, see my recent e-mail to ghc-cvs). One slight disadvantage is that it does require a bit more footwork in the compiler to figure out which type to do the deriving for. /Bj?rn On 5 okt 2006, at 19.58, Iavor Diatchki wrote: > Hello, > A question about the syntax: would there be a problem if we made the > 'deriving' declaration look like an instance? Then we would not need > the special identifier 'for', and also we have a more standard looking > notation. I am thinking something like: > deriving Show SomeType > deriving Eq (AnotherType a) > -Iavor > > > > On 10/5/06, Bj?rn Bringert wrote: >> Simon Peyton-Jones wrote: >> > | What is not so nice is that you take a new keyword ('for'), >> which is >> > | quite likely to have been used as a variable name in existing >> code. >> > (Or >> > | does it work out to use one of the 'special' names here?) >> > >> > The latter is what Bjorn has done. That is, 'for' is only >> special in >> > this one context. You can use it freely otherwise. As I >> understand it >> > anyway. >> >> Yes. There is even a "for" function somewhere in the libraries (or >> was >> it the testsuite, can't remeber), which tripped up one of my early >> versions, before I had remembered to make "for" as a special ID in >> the >> parser. >> >> > | I think it would be useful to write the proposal in complete >> detail up >> > | on the Haskell' wiki. >> > >> > Yes please. Bjorn? (It may just be a qn of transcribing the user >> > manual stuff you have written.) >> >> Sure. It seems that I have to be on the committee to write to the >> Wiki. >> Can I join it? >> >> /Bj?rn >> _______________________________________________ >> Haskell-prime mailing list >> Haskell-prime@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-prime >> From bringert at cs.chalmers.se Thu Oct 5 19:32:23 2006 From: bringert at cs.chalmers.se (Bjorn Bringert) Date: Thu Oct 5 18:38:09 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: References: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> <1160059675.19200.20.camel@trinity.localdomain> <036EAC76E7F5EC4996A3B3C3657D411606C2A69B@EUR-MSG-21.europe.corp.microsoft.com> <45251EF5.3060804@cs.chalmers.se> <5ab17e790610051058h7c73b3b5jb657ff87f5911a49@mail.gmail.com> Message-ID: <2F04E4C7-D6D0-41A8-97B6-BF1493662A82@cs.chalmers.se> Off-list, Greg Fitzgerald pointed out that: > Those wanting to use the SYB library may want to write something > like this for every datatype in their heirarchy: > > deriving Data, Typable for Person, Team, Department, Company That seems like a useful extension to me, and the meaning is obvious. This would as far as I can tell not be possible (or at least not readable) without the "for". /Bj?rn On 5 okt 2006, at 20.58, Bjorn Bringert wrote: > We considered that syntax, but decided against it. Stand-alone > deriving declarations are made to be as similar as possible to the > current deriving mechanism, rather than be similar to instance > declarations. The basic reason for maintaining a syntactic > distinction between instance declarations and deriving declarations > is to make the programmer aware of the restrictions of the deriving > mechanism. > > These are some things that make deriving declarations different > from instance declarations: > > - You can only derive instances for data types and newtypes. > - For deriving declarations, the compiler figures out the > constraints, whereas the programmer writes them for instance > declarations. > - In GHC, you can declare non-Haskell98 instances such as Eq (C X) > where X is a concrete type, but you can't do deriving for them. > - When deriving instances of multi-parameter type classes (again > non-standard), the newtype for which the deriving is made must be > the last argument to the class. If the syntax were "deriving (Class > T1 ... Tn)", it might not be clear to the reader what type the > deriving is for. > > I can't see any technical reason not to do as you propose. One > advantage would be that it makes it possible to fully subsume GHC's > current deriving extensions (though there are other ways to do > this, see my recent e-mail to ghc-cvs). One slight disadvantage is > that it does require a bit more footwork in the compiler to figure > out which type to do the deriving for. > > /Bj?rn > > On 5 okt 2006, at 19.58, Iavor Diatchki wrote: > >> Hello, >> A question about the syntax: would there be a problem if we made the >> 'deriving' declaration look like an instance? Then we would not need >> the special identifier 'for', and also we have a more standard >> looking >> notation. I am thinking something like: >> deriving Show SomeType >> deriving Eq (AnotherType a) >> -Iavor >> >> >> >> On 10/5/06, Bj?rn Bringert wrote: >>> Simon Peyton-Jones wrote: >>> > | What is not so nice is that you take a new keyword ('for'), >>> which is >>> > | quite likely to have been used as a variable name in existing >>> code. >>> > (Or >>> > | does it work out to use one of the 'special' names here?) >>> > >>> > The latter is what Bjorn has done. That is, 'for' is only >>> special in >>> > this one context. You can use it freely otherwise. As I >>> understand it >>> > anyway. >>> >>> Yes. There is even a "for" function somewhere in the libraries >>> (or was >>> it the testsuite, can't remeber), which tripped up one of my early >>> versions, before I had remembered to make "for" as a special ID >>> in the >>> parser. >>> >>> > | I think it would be useful to write the proposal in complete >>> detail up >>> > | on the Haskell' wiki. >>> > >>> > Yes please. Bjorn? (It may just be a qn of transcribing the user >>> > manual stuff you have written.) >>> >>> Sure. It seems that I have to be on the committee to write to the >>> Wiki. >>> Can I join it? >>> >>> /Bj?rn >>> _______________________________________________ >>> Haskell-prime mailing list >>> Haskell-prime@haskell.org >>> http://www.haskell.org/mailman/listinfo/haskell-prime >>> > > _______________________________________________ > Haskell-prime mailing list > Haskell-prime@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-prime From rjmh at cs.chalmers.se Fri Oct 6 05:55:15 2006 From: rjmh at cs.chalmers.se (John Hughes) Date: Fri Oct 6 05:00:55 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <20061005135618.1ADCD3242DE@www.haskell.org> References: <20061005135618.1ADCD3242DE@www.haskell.org> Message-ID: <45262803.50901@cs.chalmers.se> What I implemented in GHC is an extension of the proposal below. The proposal just mentions: deriving Class for Type In GHC I also added a form for newtype deriving of multi-parameter type classes: deriving (Class t1 ... tn) for Type I think that it's close to what we ended up with when talking about it at the Hackathon. My intuition about this syntax is that except for the "for Type" part, it looks the same as a normal deriving clause. The "for" part is just there to connect it to a data/newtype declaration. This lets it pretty much use the normal code for deriving declarations. Stand-alone deriving declarations are currently a little bit weaker than normal deriving clauses, since the current implementation does not let you reference the type arguments of a newtype in the arguments of an MPTC. See my response to Bulat on cvs-ghc@haskell.org for more details. /Bj?rn > > > A suggestion re syntax: With the newtype-deriving extension, the instances named in a deriving clause are not just class names, but partial applications of class names to all but the last argument. Why all but the last one? Because the last one is the type being defined. Once deriving clauses are separated from type definitions, then there is no type being defined any more--hence the need for "for Type" in your syntax, and the introduction of another keyword. But why single out one class parameter, once deriving clauses are separated from type definitions? Why not simply write the FULL application of the class in the deriving list? Thus: deriving (Eq Foo, Ord Foo) instead of deriving (Eq, Ord) for Foo I find the former syntax clearer and more readable, actually. John From ketil+haskell at ii.uib.no Fri Oct 6 07:19:11 2006 From: ketil+haskell at ii.uib.no (Ketil Malde) Date: Fri Oct 6 06:25:03 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <5ab17e790610051058h7c73b3b5jb657ff87f5911a49@mail.gmail.com> (Iavor Diatchki's message of "Thu, 5 Oct 2006 10:58:47 -0700") References: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> <1160059675.19200.20.camel@trinity.localdomain> <036EAC76E7F5EC4996A3B3C3657D411606C2A69B@EUR-MSG-21.europe.corp.microsoft.com> <45251EF5.3060804@cs.chalmers.se> <5ab17e790610051058h7c73b3b5jb657ff87f5911a49@mail.gmail.com> Message-ID: "Iavor Diatchki" writes: > A question about the syntax: would there be a problem if we made the > 'deriving' declaration look like an instance? And you might as well keep the 'instance' keyword when instantiating, even if the instance is derived? Seems more consistent to me ('deriving' feels more like a kind of parameter to 'data' declarations) and avoids introducing a new keyword, except in the context of instance declarations. > deriving Show SomeType > deriving Eq (AnotherType a) instance Show Sometype derived instance Eq (AnotherType a) where (==) = ... -k -- If I haven't seen further, it is by standing in the footprints of giants From bringert at cs.chalmers.se Fri Oct 6 08:29:13 2006 From: bringert at cs.chalmers.se (=?ISO-8859-1?Q?Bj=F6rn_Bringert?=) Date: Fri Oct 6 07:34:41 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: References: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> <1160059675.19200.20.camel@trinity.localdomain> <036EAC76E7F5EC4996A3B3C3657D411606C2A69B@EUR-MSG-21.europe.corp.microsoft.com> <45251EF5.3060804@cs.chalmers.se> <5ab17e790610051058h7c73b3b5jb657ff87f5911a49@mail.gmail.com> Message-ID: <45264C19.8000309@cs.chalmers.se> Ketil Malde wrote: > "Iavor Diatchki" writes: > >> A question about the syntax: would there be a problem if we made the >> 'deriving' declaration look like an instance? > > And you might as well keep the 'instance' keyword when instantiating, > even if the instance is derived? Seems more consistent to me > ('deriving' feels more like a kind of parameter to 'data' > declarations) and avoids introducing a new keyword, except in the > context of instance declarations. > >> deriving Show SomeType >> deriving Eq (AnotherType a) > > instance Show Sometype derived > instance Eq (AnotherType a) where (==) = ... > > -k One problem with this is that there is no context in the declaration, e.g.: instance Eq (AnotherType a) derived Although the generated instance does have one: instance Eq a => Eq (AnotherType a) where ... (depending on how a is used by the data constructors of AnotherType). This goes back to the argument I was making earlier about the differences between instance and deriving declarations. /Bj?rn From bringert at cs.chalmers.se Fri Oct 6 10:22:09 2006 From: bringert at cs.chalmers.se (=?ISO-8859-1?Q?Bj=F6rn_Bringert?=) Date: Fri Oct 6 09:27:35 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <45262803.50901@cs.chalmers.se> References: <20061005135618.1ADCD3242DE@www.haskell.org> <45262803.50901@cs.chalmers.se> Message-ID: <45266691.7010803@cs.chalmers.se> John Hughes wrote: > What I implemented in GHC is an extension of the proposal below. The > proposal just mentions: > > deriving Class for Type > > In GHC I also added a form for newtype deriving of multi-parameter > type classes: > > deriving (Class t1 ... tn) for Type > > I think that it's close to what we ended up with when talking about > it at the Hackathon. My intuition about this syntax is that except > for the "for Type" part, it looks the same as a normal deriving > clause. The "for" part is just there to connect it to a data/newtype > declaration. This lets it pretty much use the normal code for > deriving declarations. > > Stand-alone deriving declarations are currently a little bit weaker > than normal deriving clauses, since the current implementation does > not let you reference the type arguments of a newtype in the > arguments of an MPTC. See my response to Bulat on cvs-ghc@haskell.org > for more details. > > /Bj?rn > >> >> >> > A suggestion re syntax: > > With the newtype-deriving extension, the instances named in a deriving > clause are not just class names, but partial applications of class names > to all but the last argument. Why all but the last one? Because the last > one is the type being defined. Once deriving clauses are separated from > type definitions, then there is no type being defined any more--hence > the need for "for Type" in your syntax, and the introduction of another > keyword. But why single out one class parameter, once deriving clauses > are separated from type definitions? Why not simply write the FULL > application of the class in the deriving list? Thus: > > deriving (Eq Foo, Ord Foo) > > instead of > > deriving (Eq, Ord) for Foo > > I find the former syntax clearer and more readable, actually. > > John The exact same thing is currently being discussed on cvs-ghc@haskell.org, and we seem to have reached a consensus to adopt the same syntax that you are proposing. Well, I was the only one who ever like the original syntax, so "reached a consensus" means "everybody else convinced me". I'll implement this syntax instead and then write up a Haskell' proposal. /Bj?rn From viritrilbia at gmail.com Fri Oct 6 11:39:39 2006 From: viritrilbia at gmail.com (Michael Shulman) Date: Fri Oct 6 10:45:18 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <45262803.50901@cs.chalmers.se> References: <20061005135618.1ADCD3242DE@www.haskell.org> <45262803.50901@cs.chalmers.se> Message-ID: On 10/6/06, John Hughes wrote: > deriving (Eq Foo, Ord Foo) > > instead of > > deriving (Eq, Ord) for Foo So what does newtype Foo a = Foo a newtype Bar b = Bar b class C a b deriving (C (Foo a) (Bar b)) mean? I could see it meaning any or all of the following: instance (C (Foo a) b) => (C (Foo a) (Bar b)) instance (C a (Bar b)) => (C (Foo a) (Bar b)) instance (C a b) => (C (Foo a) (Bar b)) Perhaps I am misunderstanding? Mike From ross at soi.city.ac.uk Sat Oct 7 09:46:51 2006 From: ross at soi.city.ac.uk (Ross Paterson) Date: Sat Oct 7 08:52:29 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> References: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> Message-ID: <20061007134651.GA3255@soi.city.ac.uk> On Thu, Oct 05, 2006 at 10:05:20AM +0200, Bjorn Bringert wrote: > I propose to add a top-level declaration on the form: > > 'deriving' qtycls 'for' qtycon > > which produces the same instance as a deriving clause in the > declaration of the datatype or newtype would. If this is added (whatever the syntax), you'd also want to permit multiple identical derived instances. The main use for this seems to be when a module defining a data type lacks an instance you want, and for some reason you can't get the original module changed. (It could also be used to derive instances of a class you just defined for existing newtypes, but that seems rarer.) Several modules might use this workaround for the same base module, and you wouldn't want those modules to be incompatible. From twanvl at gmail.com Sat Oct 7 10:44:17 2006 From: twanvl at gmail.com (Twan van Laarhoven) Date: Sat Oct 7 09:49:45 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <20061007134651.GA3255@soi.city.ac.uk> References: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> <20061007134651.GA3255@soi.city.ac.uk> Message-ID: <4527BD41.8040701@gmail.com> > The main use for this seems to be when a module defining a data type > lacks an instance you want, and for some reason you can't get the > original module changed. If you continue this line of reasoning: 1. The only reason a module can not be changed is that it is in some library as opposed to your own code. 2. The only instances that can be derived are for Prelude classes. 3. These classes are already known in library modules, so they could have been derived there. 4. The fact that they are not unnecessarily reduces the usefulness of the library, and could therefore be considered a bug. 5. In fact, looking at the standard libraries, they already provide instances for all relevant Prelude classes. This leaves me to wonder what stand-alone deriving is actually good for, only newtypes? Twan From bringert at cs.chalmers.se Sun Oct 8 05:55:46 2006 From: bringert at cs.chalmers.se (Bjorn Bringert) Date: Sun Oct 8 05:01:25 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <4527BD41.8040701@gmail.com> References: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> <20061007134651.GA3255@soi.city.ac.uk> <4527BD41.8040701@gmail.com> Message-ID: <8D09273B-CF09-4365-9466-D8947E70BD3A@cs.chalmers.se> On 7 okt 2006, at 16.44, Twan van Laarhoven wrote: > >> The main use for this seems to be when a module defining a data type >> lacks an instance you want, and for some reason you can't get the >> original module changed. > > If you continue this line of reasoning: > 1. The only reason a module can not be changed is that it is in > some library as opposed to your own code. > 2. The only instances that can be derived are for Prelude classes. In for example GHC, this is not entirely true. GHC can derive instances of Typeable and Data, and more could be added in the future. Also, compilers could conceivably allow user-defined deriving. > 3. These classes are already known in library modules, so they > could have been derived there. > 4. The fact that they are not unnecessarily reduces the usefulness > of the library, and could therefore be considered a bug. Existing libraries might not know about which classes future compiler versions can derive. Also, a library that wants to work with multiple compilers cannot have deriving classes for non-standard classes. > 5. In fact, looking at the standard libraries, they already provide > instances for all relevant Prelude classes. There are plenty of libraries which are not standard libraries. > This leaves me to wonder what stand-alone deriving is actually good > for, only newtypes? I agree that it's not exactly something you will use every day, but when you do need it, it can save a lot of work. Imagine defining standard Show and Read, or Data and Typeable, instances manually for some rich family of data types. Besides, as Manuel pointed out, stand-alone deriving generalizes the current deriving clauses. Thus it can be seen as a way to remove an unnecessary restriction. /Bj?rn From brianlsmith at gmail.com Sun Oct 8 12:22:59 2006 From: brianlsmith at gmail.com (Brian Smith) Date: Sun Oct 8 11:28:32 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <45266691.7010803@cs.chalmers.se> References: <20061005135618.1ADCD3242DE@www.haskell.org> <45262803.50901@cs.chalmers.se> <45266691.7010803@cs.chalmers.se> Message-ID: On 10/6/06, Bj?rn Bringert wrote: > > John Hughes wrote: > > deriving (Eq Foo, Ord Foo) > > > > instead of > > > > deriving (Eq, Ord) for Foo > > > > I find the former syntax clearer and more readable, actually. > > > > John > > I'll implement this syntax instead and then write up a Haskell' proposal. I am sure that it was already argued at great length, but I think it is wrong to start the declaration with "deriving." I believe that "derive instance" fits much better into the language. I understand the desire to avoid adding new keywords but I think that something along the lines of what was done for "for" could be done here for "derive." Regards, Brian -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-prime/attachments/20061008/a674b62b/attachment.htm From bringert at cs.chalmers.se Sun Oct 8 13:30:52 2006 From: bringert at cs.chalmers.se (Bjorn Bringert) Date: Sun Oct 8 12:36:25 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: References: <20061005135618.1ADCD3242DE@www.haskell.org> <45262803.50901@cs.chalmers.se> <45266691.7010803@cs.chalmers.se> Message-ID: <3E5B9BE1-5247-4B02-94BF-19C847E9C9AE@cs.chalmers.se> On 8 okt 2006, at 18.22, Brian Smith wrote: > On 10/6/06, Bj?rn Bringert wrote: > John Hughes wrote: > > deriving (Eq Foo, Ord Foo) > > > > instead of > > > > deriving (Eq, Ord) for Foo > > > > I find the former syntax clearer and more readable, actually. > > > > John > > I'll implement this syntax instead and then write up a Haskell' > proposal. > > I am sure that it was already argued at great length, but I think > it is wrong to start the declaration with "deriving." I believe > that "derive instance" fits much better into the language. I > understand the desire to avoid adding new keywords but I think that > something along the lines of what was done for "for" could be done > here for "derive." I agree that "derive" would be nicer, but as you say, the problem is that it would add a new keyword. Since the declaration would then start with "derive", I don't that think it could easily be made into a special identifier. A deriving declaration would look like this: derive Eq Foo which looks just like the beginning of a declaration of a function called "derive" which does some pattern matching, if derive can also be an identifier. /Bj?rn From brianlsmith at gmail.com Sun Oct 8 14:11:23 2006 From: brianlsmith at gmail.com (Brian Smith) Date: Sun Oct 8 13:16:56 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <3E5B9BE1-5247-4B02-94BF-19C847E9C9AE@cs.chalmers.se> References: <20061005135618.1ADCD3242DE@www.haskell.org> <45262803.50901@cs.chalmers.se> <45266691.7010803@cs.chalmers.se> <3E5B9BE1-5247-4B02-94BF-19C847E9C9AE@cs.chalmers.se> Message-ID: On 10/8/06, Bjorn Bringert wrote: > > > I agree that "derive" would be nicer, but as you say, the problem is > that it would add a new keyword. Since the declaration would then > start with "derive", I don't that think it could easily be made into > a special identifier. A deriving declaration would look like this: > > derive Eq Foo > > which looks just like the beginning of a declaration of a function > called "derive" which does some pattern matching, if derive can also > be an identifier. That is why I suggested "derive instance." Then the only ambiguity comes when "derive" is used as a name immediately before an instance declaration. which should be really, really rare. It's not 100% backward compatible but it is a better compromise than using "deriving." Regards, Brian -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-prime/attachments/20061008/06cabd05/attachment.htm From bringert at cs.chalmers.se Sun Oct 8 14:21:59 2006 From: bringert at cs.chalmers.se (Bjorn Bringert) Date: Sun Oct 8 13:27:33 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: References: <20061005135618.1ADCD3242DE@www.haskell.org> <45262803.50901@cs.chalmers.se> <45266691.7010803@cs.chalmers.se> <3E5B9BE1-5247-4B02-94BF-19C847E9C9AE@cs.chalmers.se> Message-ID: <4C4FDD43-43FF-48D1-9F40-2FFF4CF5F7C6@cs.chalmers.se> On 8 okt 2006, at 20.11, Brian Smith wrote: > On 10/8/06, Bjorn Bringert > wrote: > I agree that "derive" would be nicer, but as you say, the problem is > that it would add a new keyword. Since the declaration would then > start with "derive", I don't that think it could easily be made into > a special identifier. A deriving declaration would look like this: > > derive Eq Foo > > which looks just like the beginning of a declaration of a function > called "derive" which does some pattern matching, if derive can also > be an identifier. > > That is why I suggested "derive instance." Then the only ambiguity > comes when "derive" is used as a name immediately before an > instance declaration. which should be really, really rare. It's not > 100% backward compatible but it is a better compromise than using > "deriving." Oops, sorry. I should read more carefully. Would that work? I guess I'll have to try. I think that after layout resolution there can't be any identifiers right before instance declarations, so I guess that wouldn't be a problem. /Bj?rn From simonpj at microsoft.com Mon Oct 9 08:19:38 2006 From: simonpj at microsoft.com (Simon Peyton-Jones) Date: Mon Oct 9 07:27:10 2006 Subject: Proposal for stand-alone deriving declarations? In-Reply-To: <20061007134651.GA3255@soi.city.ac.uk> References: <0B8D410F-1639-4B99-9387-97E5ECAA0F50@cs.chalmers.se> <20061007134651.GA3255@soi.city.ac.uk> Message-ID: <036EAC76E7F5EC4996A3B3C3657D411606C780D0@EUR-MSG-21.europe.corp.microsoft.com> | > I propose to add a top-level declaration on the form: | > | > 'deriving' qtycls 'for' qtycon | > | > which produces the same instance as a deriving clause in the | > declaration of the datatype or newtype would. | | If this is added (whatever the syntax), you'd also want to permit multiple | identical derived instances. Perhaps so. This might generate duplicate code (one for each decl) but it'd be guaranteed identical since it's generated by a deriving clause. It'd require some .hi file support, to record that an instance came from a 'deriving' decl. I'm inclined to wait until someone asks for it "for real" as it were. Simon From bulat.ziganshin at gmail.com Tue Oct 10 08:11:31 2006 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Tue Oct 10 07:48:59 2006 Subject: Stand-alone deriving declarations added In-Reply-To: <036EAC76E7F5EC4996A3B3C3657D411606C2AA02@EUR-MSG-21.europe.corp.microsoft.com> References: <1658473344.20061005181406@gmail.com> <1160075043.19200.70.camel@trinity.localdomain> <036EAC76E7F5EC4996A3B3C3657D411606C2AA02@EUR-MSG-21.europe.corp.microsoft.com> Message-ID: <1445320044.20061010161131@gmail.com> Hello Simon, Friday, October 6, 2006, 11:41:21 AM, you wrote: > | declarations. The basic reason for maintaining a syntactic > | distinction between instance declarations and deriving declarations > | is to make the programmer aware of the restrictions of the deriving > | mechanism. unfortunately i don't see this whole message. but i disagree with this statement - imho, using several different mechanisms for deriving built-in classes, defining default instances, automatic generation of instances by TH, generic class definitions and automatic deriving for newtypes just confuse programmers and force to change code when one mechanism is replaced with another (say, when Typeable becomes built-in class instead of TH-generated one). so, i propose to leave only two forms of automatic instance definitions: - bundled with type definition: 'data ... deriving' clause - decoupled from type definition: 'instance Class Type' clause both forms should be allowed to be used with any class that may be automatically derived: 1) built-in classes Eq, Ord... 2) any class derived for newtype 3) class that has default definitions for all its methods: class (Enum a) => SuperEnum a where fromSuperEnum :: a -> Integer fromSuperEnum = toInteger . fromEnum 4) class that was defined using generics (currently GHC-only but i hope that future Haskell standards will support some form of Generic Haskell): class Generic a where f :: a -> a f (x :+: y) = ... f (x :*: y) = ... 5) i propose to extend GHC to allow TH generate default instance declarations. when one tries to derive XXX class, compiler should look up derivingXXX TH function and if it is defined, use this function to derive instance. so, the following: data A = B | C deriving(Binary) should be translated into data A = B | C $(derivingBinary 'A) Haskell is known as polymorphic language, but not generic one. It still lacks simple and powerful mechanism to generate class instances. Why i can't solve this problem completely, i hope that proposed extension may build some bridge to generic Haskell future, allowing at least GHC users to imagine that they work with compiler supporting user-controlled deriving mechanism imagine, for example, that you wrote serialization library with a Binary class. in first version, you have defined default Binary instance using generic classes: class Binary a where put (x :+: y) = ... put (x :*: y) = ... in the next version you have developed much more complex but efficient TH-based instance generation code: derivingBinary t = [| .... |] in third version, GHC comes with built-in Binary class support. and in the fourth version GHC includes Generic Haskell support so you can define default instance using GH. but independent of all these internal changes your clients continue to use the same deriving mechanism: data A = B | C deriving(Binary) is it not beautiful? :) | b) For deriving declarations, the compiler figures out the | constraints, whereas the programmer writes them for instance | declarations. it's real problem. in light of this i propose to extend 'deriving' mechanism so that it can derive in all the above-mentioned ways. plus, as Simon suggests, make the stand-alone 'deriving' clause the same syntax as 'instance' without constraints: data A = B | C deriving(Binary) data T a = T a deriving Binary (T a) where Binary deriving mechanism should by itself generate/check all necessary constraints -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From igloo at earth.li Fri Oct 13 10:07:31 2006 From: igloo at earth.li (Ian Lynagh) Date: Fri Oct 13 09:12:49 2006 Subject: Pattern matching order for records Message-ID: <20061013140731.GA885@matrix.chaos.earth.li> Hi all, Has clarifying the pattern matching order for records as described in http://hackage.haskell.org/trac/ghc/ticket/246 been discussed for haskell'? I couldn't see it on the proposals list. Personally I actually think hugs is doing the right thing according to the report and that there is no real ambiguity in the report's language, just a bit of unclarity. Furthermore, I think hugs' interpretation means that it is easier for the programmer to understand how his program will behave if he only has to look at the pattern to be matched, and not refer back to the definition of the record, even if this does make for slightly more desugaring work for the implementor. Thus I would propose just clarifying the language for Haskell'. Thanks Ian From Malcolm.Wallace at cs.york.ac.uk Fri Oct 13 12:19:09 2006 From: Malcolm.Wallace at cs.york.ac.uk (Malcolm Wallace) Date: Fri Oct 13 11:29:23 2006 Subject: Pattern matching order for records In-Reply-To: <20061013140731.GA885@matrix.chaos.earth.li> References: <20061013140731.GA885@matrix.chaos.earth.li> Message-ID: <20061013171909.11fa7b3f.Malcolm.Wallace@cs.york.ac.uk> Ian Lynagh wrote: > Has clarifying the pattern matching order for records as described in > http://hackage.haskell.org/trac/ghc/ticket/246 been discussed for > haskell'? I couldn't see it on the proposals list. Perhaps because this has already been fixed in the errata to the Haskell'98 Report? See http://haskell.org/definition/haskell98-revised-bugs.html Specifically: [July 2004] Page 32, Section 3.17.2, Informal Semantics of Pattern-Matching, case #6. Case 6 says: "Matching against a constructor using labeled fields is the same as matching ordinary constructor patterns except that the fields are matched in the order they are named in the field list. All fields listed must be declared by the constructor; fields may not be named more than once. Fields not named by the pattern are ignored (matched against _)." You could interpret 'field list' to mean the order the fields appear in the pattern, OR, the order in which the fields were declared. The choice of interpretation affects termination behaviour. The intention of the Report writers was to use the field order of the pattern, not the declaration. Thus, the Report can be clarified by changing the end of the first sentence above to read "the order they are named in the pattern field list". Regards, Malcolm From igloo at earth.li Fri Oct 13 16:53:10 2006 From: igloo at earth.li (Ian Lynagh) Date: Fri Oct 13 15:58:27 2006 Subject: Pattern matching order for records In-Reply-To: <20061013171909.11fa7b3f.Malcolm.Wallace@cs.york.ac.uk> References: <20061013140731.GA885@matrix.chaos.earth.li> <20061013171909.11fa7b3f.Malcolm.Wallace@cs.york.ac.uk> Message-ID: <20061013205310.GA7211@matrix.chaos.earth.li> On Fri, Oct 13, 2006 at 05:19:09PM +0100, Malcolm Wallace wrote: > Ian Lynagh wrote: > > > Has clarifying the pattern matching order for records as described in > > http://hackage.haskell.org/trac/ghc/ticket/246 been discussed for > > haskell'? I couldn't see it on the proposals list. > > Perhaps because this has already been fixed in the errata to the > Haskell'98 Report? Ooops, missed that. Sorry for the noise! Ian From bulat.ziganshin at gmail.com Sat Oct 14 10:57:01 2006 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sat Oct 14 10:32:57 2006 Subject: Two things that i still can't understand in Haskell standard Message-ID: <1343934117.20061014185701@gmail.com> Hello haskell-prime, first is the monomorphism restriction. why isn't it possible to check _kind_ of parameter-less equation and apply monomorphism restrictions only to values of kind '*'? so, this: sum = foldr1 (*) will become polymorphic because its kind is '*->*' while this exps = 1 : map (2*) exps will become monomorphic because its kind is * second is lack of support for prefix/postfix operations. why it is impossible to do in first pass only lexical analysis of Haskell program, then split it into sentences, extract all import/infix operations and only after processing of these operations, having all the information about operator types and precedence, do the syntax analysis? -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From bulat.ziganshin at gmail.com Sat Oct 14 11:19:32 2006 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sat Oct 14 10:33:10 2006 Subject: three syntax-sugar proposals Message-ID: <1112531495.20061014191932@gmail.com> Hello haskell-prime, 1. allow to use '_' in number literals. its used in Ruby and i found that this makes long number literals much more readable. for example maxint = 2_147_483_648 2. allow to use string literals in patterns as head of matched list: optionValue ("kb"++n) = read n * 2^10 optionValue ("mb"++n) = read n * 2^20 this syntax already used in Erlang 3. writing kinds is very rare task, but i still don't like to count number of stars in something like '* -> * -> * -> *'. i think that representing this as '****' will be more readable -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From iavor.diatchki at gmail.com Sat Oct 14 16:59:38 2006 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Sat Oct 14 16:04:52 2006 Subject: Monomorphism restriction Message-ID: <5ab17e790610141359t6bb82178h16faadf342214792@mail.gmail.com> Hello, On 10/14/06, Bulat Ziganshin wrote: > Hello haskell-prime, > > first is the monomorphism restriction. why isn't it possible to check > _kind_ of parameter-less equation and apply monomorphism restrictions > only to values of kind '*'? so, this: > > sum = foldr1 (*) > > will become polymorphic because its kind is '*->*' while this Kinds are use to classify _types_ and not _expressions_. In this case, the expression has the type "a -> a", with the constraint that "a" is a numeric type. This type is of kind *. In general, all the executable parts of a Haskell program have types that are of kind *. The things that have kinds like "* -> *" are type constructors. On the other hand, you might wonder why not use the _type_ of an expression in the monomorphism restriction (MR) and only monomorphize expressions of a non-functional type. The reason this would not work is that the MR is used to avoid repeated evaluation of overloaded expressions when they are instantiated to the same types, but the type of an expression does not tell us if the expression is already evaluated. Remember that in a functional language functions are values like any other, and so we might have to do computation to evaluate them. This is why the MR uses a syntactic heuristic. Having said that, many people find the MR weird because it is kind of implementation specific. Even without the MR, a compiler could perform an optimization that notices that a value is being instantiated with the same dictionary multiple times and avoid the repeated evaluation. The MR is especially weird if we consider the fact that the Haskell report does not even require implementations to have sharing (e.g., call by name semantics are OK), so implementation may duplicate evaluation at will... -Iavor From lennart at augustsson.net Sat Oct 14 23:45:06 2006 From: lennart at augustsson.net (Lennart Augustsson) Date: Sat Oct 14 22:50:53 2006 Subject: Two things that i still can't understand in Haskell standard In-Reply-To: <1343934117.20061014185701@gmail.com> References: <1343934117.20061014185701@gmail.com> Message-ID: <5AC0997B-1157-409F-A891-00E2E3253CB8@augustsson.net> You don't mean checking kind, but checking type. The same argument that can be made for the monomorphism restriction at base type can be used for function types too. There is nothing impossible about prefix&postfix operator. Haskell just happens not to have them. They could be added. -- Lennart On Oct 14, 2006, at 10:57 , Bulat Ziganshin wrote: > Hello haskell-prime, > > first is the monomorphism restriction. why isn't it possible to check > _kind_ of parameter-less equation and apply monomorphism restrictions > only to values of kind '*'? so, this: > > sum = foldr1 (*) > > will become polymorphic because its kind is '*->*' while this > > exps = 1 : map (2*) exps > > will become monomorphic because its kind is * > > > second is lack of support for prefix/postfix operations. why it is > impossible to do in first pass only lexical analysis of Haskell > program, then split it into sentences, extract all import/infix > operations and only after processing of these operations, having all > the information about operator types and precedence, do the syntax > analysis? > > -- > Best regards, > Bulat mailto:Bulat.Ziganshin@gmail.com > > _______________________________________________ > Haskell-prime mailing list > Haskell-prime@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-prime From guillaume.fortaine at wanadoo.fr Sun Oct 15 09:02:40 2006 From: guillaume.fortaine at wanadoo.fr (William DUCK) Date: Sun Oct 15 08:07:48 2006 Subject: Y0: (y-naught) Message-ID: <200610151502.40404.guillaume.fortaine@wanadoo.fr> Hello, I ask myself if we could take some ideas from this paper : http://www.eecs.harvard.edu/~aleks/papers/hoarelogic/httsep.pdf Y0: (y-naught) A next generation functional programming language. The focus of this project is a synthesis of good ideas from the ML, Haskell, Scheme, and LF communities. In particular, we are designing a language that like ML and Scheme, is primarily call-by-value, but like Haskell, provides good support for laziness. As in Haskell and FX, we are attempting to isolate effects and reflect them in the types. As in Haskell, O'Caml, and LF, we are trying to push the boundaries of type systems and type inference to the next level. Currently, I am working with Amal Ahmed, Mathew Fluet, and Aleks Nanevski on issues involving state and effects. I am also working with Norman Ramsey & Paul Govereau on integrating type-classes with ML-style modules. Concerning merging Haskell and ML, Manuel M T Chakravarty already did some great research : http://www.cse.unsw.edu.au/~chak/papers/mtc.ps.gz For dependent types, we have already : http://www.e-pig.org/ ( lacks dependent I/O ) Moreover, the parallel programming seems to be the future due to the massive multithreading abilities of next-gen processor... : http://en.wikipedia.org/wiki/Rock_processor http://en.wikipedia.org/wiki/CELL Best Regards, Will From guillaume.fortaine at wanadoo.fr Sun Oct 15 09:07:26 2006 From: guillaume.fortaine at wanadoo.fr (William DUCK) Date: Sun Oct 15 08:12:34 2006 Subject: Concurrency Message-ID: <200610151507.26570.guillaume.fortaine@wanadoo.fr> Hello, Just to point out, this marvellous work : http://www.seas.upenn.edu/~lipeng/homepage/unify.html Best Regards, Will From bulat.ziganshin at gmail.com Sun Oct 15 13:23:37 2006 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sun Oct 15 15:46:34 2006 Subject: Concurrency In-Reply-To: <200610151507.26570.guillaume.fortaine@wanadoo.fr> References: <200610151507.26570.guillaume.fortaine@wanadoo.fr> Message-ID: <281712961.20061015212337@gmail.com> Hello William, Sunday, October 15, 2006, 5:07:26 PM, you wrote: > http://www.seas.upenn.edu/~lipeng/homepage/unify.html can this be ported to windows? (i don't yet read the paper) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From claus.reinke at talk21.com Tue Oct 17 10:48:50 2006 From: claus.reinke at talk21.com (Claus Reinke) Date: Tue Oct 17 11:43:00 2006 Subject: (Pattern) Guards in lambdas Message-ID: <00da01c6f20a$96ef55a0$3e0c7ad5@cr3lt> since Pattern Guards appear to be popular with the committee, I suggest to revisit the decision to drop guards from lambdas: (a) http://www.cse.unsw.edu.au/~dons/haskell-1990-2000/msg00353.html (b) http://www.cse.unsw.edu.au/~dons/haskell-1990-2000/msg00382.html 1. I disagree that this was a simplification of Haskell the language became smaller (fewer valid programs), but that reduction in size was bought by breaking a symmetry (pattern matches are the same whereever they are used) and adding a restriction (no guards for patterns in lambdas), so the smaller language is actually more complicated. 2. adding guards to lambdas can only cause more program runs to fail (no chance of handling pattern-match/guard failure and fall through), so it is kind of understandable that this feature was considered dubious. however, - adding a guard there is comparable to adding an assertion, a feature often considered valuable - with pattern guards, the guard is no longer restricted to filtering, and that added functionality is not currently accessible for lambda patterns suggestion: undo removal of guards from lambdas, especially (but not only) if pattern guards make it into the language. claus ps. are there any notes regarding the discussion and stylistic grounds mentioned in (a)? From Malcolm.Wallace at cs.york.ac.uk Wed Oct 18 06:01:21 2006 From: Malcolm.Wallace at cs.york.ac.uk (Malcolm Wallace) Date: Wed Oct 18 05:09:01 2006 Subject: (Pattern) Guards in lambdas In-Reply-To: <00da01c6f20a$96ef55a0$3e0c7ad5@cr3lt> References: <00da01c6f20a$96ef55a0$3e0c7ad5@cr3lt> Message-ID: <20061018110121.4c10cef5.Malcolm.Wallace@cs.york.ac.uk> "Claus Reinke" wrote: > since Pattern Guards appear to be popular with the committee, > I suggest to revisit the decision to drop guards from lambdas: > > suggestion: undo removal of guards from lambdas, especially > (but not only) if pattern guards make it into the language. See the existing proposals http://hackage.haskell.org/trac/haskell-prime/wiki/LambdaCase http://hackage.haskell.org/trac/haskell-prime/wiki/MultiWayIf Regards, Malcolm From claus.reinke at talk21.com Wed Oct 18 06:44:29 2006 From: claus.reinke at talk21.com (Claus Reinke) Date: Wed Oct 18 05:49:34 2006 Subject: (Pattern) Guards in lambdas References: <00da01c6f20a$96ef55a0$3e0c7ad5@cr3lt> <20061018110121.4c10cef5.Malcolm.Wallace@cs.york.ac.uk> Message-ID: <00a501c6f2a2$64cf2a80$701f8351@cr3lt> >> suggestion: undo removal of guards from lambdas, especially >> (but not only) if pattern guards make it into the language. > > See the existing proposals > http://hackage.haskell.org/trac/haskell-prime/wiki/LambdaCase > http://hackage.haskell.org/trac/haskell-prime/wiki/MultiWayIf thanks. I'm a fan of the correspondence principle, and as we have a LetCase, there should be a LambdaCase as well (the other seems to be inspired by Lisp's cond?). but the syntax is slightly awkward. is there a reason not to merge LambdaCase and Lambda, thus addressing both my suggestion and the LambdaCase proposal? f | = \ | -> case x of (\ ) x claus ps. strawpoll-2 has both LambdaCase and MultiWayIf as 'no'. but that is numbers, not rationale.. From bulat.ziganshin at gmail.com Wed Oct 18 09:41:58 2006 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Wed Oct 18 09:35:03 2006 Subject: (Pattern) Guards in lambdas In-Reply-To: <00a501c6f2a2$64cf2a80$701f8351@cr3lt> References: <00da01c6f20a$96ef55a0$3e0c7ad5@cr3lt> <20061018110121.4c10cef5.Malcolm.Wallace@cs.york.ac.uk> <00a501c6f2a2$64cf2a80$701f8351@cr3lt> Message-ID: <353201988.20061018174158@gmail.com> Hello Claus, Wednesday, October 18, 2006, 2:44:29 PM, you wrote: > (\ ) x this looks great. smth like: proc $ \[x] -> x*2 \[x,y] -> x*y \[] -> 0 -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From simonmar at microsoft.com Thu Oct 19 07:27:26 2006 From: simonmar at microsoft.com (Simon Marlow) Date: Thu Oct 19 06:32:24 2006 Subject: Here-docs in Haskell source In-Reply-To: <20060922235902.GA9757@momenergy.repetae.net> Message-ID: <2E9B33CE230409489A7ED37E5E34090F05C52343@EUR-MSG-20.europe.corp.microsoft.com> haskell-prime-bounces@haskell.org wrote: > I would also like to see these. I like the python syntax > > """ > stuff... > """ > > but really most anything will do. > > the triple quote doesn't eat any usable syntax though and > won't require > any special cases in the parser so I would much prefer something like > that. Would someone like to make a ticket/wiki page for HereDocuments? I suggest that here documents could supplant string gaps, which are a pain both for the compiler and the user and interact badly with CPP. In fact, I suggest removing string gaps anyway, since "abc"++ "cde"++ ... is just as good as "abc\ \cde\ ... GHC optimises the first to the second anyway. I find myself using explicit ++ rather than string gaps these days, ever since the problems with recent versions of GNU CPP and string gaps arose (yes I know cpphs works with string gaps). Cheers, Simon From simonmar at microsoft.com Thu Oct 19 07:55:48 2006 From: simonmar at microsoft.com (Simon Marlow) Date: Thu Oct 19 07:00:50 2006 Subject: (Pattern) Guards in lambdas In-Reply-To: <00a501c6f2a2$64cf2a80$701f8351@cr3lt> Message-ID: <2E9B33CE230409489A7ED37E5E34090F05C52389@EUR-MSG-20.europe.corp.microsoft.com> haskell-prime-bounces@haskell.org wrote: >>> suggestion: undo removal of guards from lambdas, especially >>> (but not only) if pattern guards make it into the language. >> >> See the existing proposals >> http://hackage.haskell.org/trac/haskell-prime/wiki/LambdaCase >> http://hackage.haskell.org/trac/haskell-prime/wiki/MultiWayIf > > thanks. I'm a fan of the correspondence principle, and as we have > a LetCase, there should be a LambdaCase as well (the other seems > to be inspired by Lisp's cond?). but the syntax is slightly awkward. > is there a reason not to merge LambdaCase and Lambda, thus > addressing both my suggestion and the LambdaCase proposal? > > f | = > > \ | -> > > case x of > > (\ ) x > > claus > > ps. strawpoll-2 has both LambdaCase and MultiWayIf as 'no'. > but that is numbers, not rationale.. I find LambdaCase quite distasteful, mostly for the same reason that the 'f _ x' syntax for a section is ugly: its just hard to read, because you have to backtrack and re-read the expression when you figure out that there was an implicit lambda lurking earlier. MultiWayIf was my proposal, but I voted against it(!) mainly because (a) it isn't implemented anywhere, and (b) I'm beginning to feel that we don't *really* need any more syntax, at least not when the payoff is small like this. As for extending lambda to allow multiple guards and/or multiple pattern matches, I don't think we need that either. Lambda is a quiet syntax and will be lost at the beginning of a sequence of pattern matches/guards; it's best used for simple lambda expressions, complicated pattern matches should be done using function equations. Cheers, Simon From john at repetae.net Thu Oct 19 09:25:47 2006 From: john at repetae.net (John Meacham) Date: Thu Oct 19 08:30:27 2006 Subject: (Pattern) Guards in lambdas In-Reply-To: <2E9B33CE230409489A7ED37E5E34090F05C52389@EUR-MSG-20.europe.corp.microsoft.com> References: <00a501c6f2a2$64cf2a80$701f8351@cr3lt> <2E9B33CE230409489A7ED37E5E34090F05C52389@EUR-MSG-20.europe.corp.microsoft.com> Message-ID: <20061019132547.GF7057@momenergy.repetae.net> On Thu, Oct 19, 2006 at 12:55:48PM +0100, Simon Marlow wrote: > As for extending lambda to allow multiple guards and/or multiple pattern > matches, I don't think we need that either. Lambda is a quiet syntax > and will be lost at the beginning of a sequence of pattern > matches/guards; it's best used for simple lambda expressions, > complicated pattern matches should be done using function equations. I think I would like to allow a (single) guard on a lambda. for assertion checking, I am a sucker for assertion checking and the more lightweight the better when it comes to that sort of thing. John -- John Meacham - ?repetae.net?john? From Al.Falloon at synopsys.com Thu Oct 19 09:54:06 2006 From: Al.Falloon at synopsys.com (Alan Falloon) Date: Thu Oct 19 08:59:06 2006 Subject: Standard syntax for preconditions, postconditions, and invariants Message-ID: <4537837E.1030008@synopsys.com> I propose that haskell' include a standard syntax for invariants that the programmer wants to express. Here is a rough idea (just to get the point across): \begin{code} head :: [a] -> a head xs @ require { not (null xs) } head (x:xs) = x reverse :: [a] -> [a] reverse @ ensure { reverse (reverse xs) == xs } reverse [] = [] reverse (x:xs) = reverse xs ++ x data RedBlackTree a = RBLeaf a | RBNode Bool (RedBlackTree a) a (RedBlackTree a) invariant RedBlackTree a where RBNode False _ l _ r ==> redDepth l == redDepth r \end{code} The intent is not to have standardized checks on the invariants, its just to supply a common way to specify invariants to that the various strategies for checking them can all work from the same data. For example, one tool might use the invariants to generate QuickCheck properties, a compiler might provide a mode that does run-time checking of the invariants, and another tool might try to prove the invariants statically like in ESC [1]. Eventually, we might end up with sophisticated hybrid approaches that combine static proof with generating test cases for the unprovable bits. At the very least Haddock could include the invariants as part of the documentation. [1] http://www.cl.cam.ac.uk/~nx200/research/escH-hw.ps From ndmitchell at gmail.com Thu Oct 19 10:29:40 2006 From: ndmitchell at gmail.com (Neil Mitchell) Date: Thu Oct 19 09:34:37 2006 Subject: Standard syntax for preconditions, postconditions, and invariants In-Reply-To: <4537837E.1030008@synopsys.com> References: <4537837E.1030008@synopsys.com> Message-ID: <404396ef0610190729p37b1f842nb3aa885d1a4670f7@mail.gmail.com> Hi > reverse @ ensure { reverse (reverse xs) == xs } Question, does "reverse [1..]" meet, or not meet this invariant? What is the type signature for reverse? What about "reverse [(+),(-)]" ? Is anything going to be said about the semantics of the invariants? Or are we just reserving a little piece of syntax that no one else is going to trample on? > invariant RedBlackTree a where > RBNode False _ l _ r ==> redDepth l == redDepth r Where does this invariant hold? At all points in time? After a call has executed? Only between module boundaries? I'd be wary about taking too much time to specify the syntax of this kind of thing, and skipping the issue of semantics entirely :) Also, you might want to look at the programatica project, which I think has had invariants in their code for years. I'm not sure if the syntax is the same or not. That said, I think that embedding invariants/pre/postconditions in the code is very useful, I just don't think that Haskell' is a good target for this - there is a big design space that no one has yet explored. Thanks Neil From bulat.ziganshin at gmail.com Thu Oct 19 10:30:39 2006 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Thu Oct 19 12:04:28 2006 Subject: Standard syntax for preconditions, postconditions, and invariants In-Reply-To: <4537837E.1030008@synopsys.com> References: <4537837E.1030008@synopsys.com> Message-ID: <802361128.20061019183039@gmail.com> Hello Alan, Thursday, October 19, 2006, 5:54:06 PM, you wrote: > I propose that haskell' include a standard syntax for invariants that > the programmer wants to express. > The intent is not to have standardized checks on the invariants, its > just to supply a common way to specify invariants to that the various > strategies for checking them can all work from the same data. For > example, one tool might use the invariants to generate QuickCheck > properties seems that it should be a sort of annotation, yes? so we again need to define common annotation syntax and you can add this as one more possible usage to annotations-proposal page -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From taralx at gmail.com Thu Oct 19 18:58:50 2006 From: taralx at gmail.com (Taral) Date: Thu Oct 19 18:03:46 2006 Subject: Standard syntax for preconditions, postconditions, and invariants In-Reply-To: <404396ef0610190729p37b1f842nb3aa885d1a4670f7@mail.gmail.com> References: <4537837E.1030008@synopsys.com> <404396ef0610190729p37b1f842nb3aa885d1a4670f7@mail.gmail.com> Message-ID: On 10/19/06, Neil Mitchell wrote: > Hi > > > reverse @ ensure { reverse (reverse xs) == xs } > > Question, does "reverse [1..]" meet, or not meet this invariant? This is a good point. You can only do sensible conditions on functions if appropriate termination constraints are met. > > invariant RedBlackTree a where > > RBNode False _ l _ r ==> redDepth l == redDepth r > > Where does this invariant hold? At all points in time? After a call > has executed? Only between module boundaries? This invariant holds at the time you build the RBNode. It's effectively a precondition on the RBNode "function". > That said, I think that embedding invariants/pre/postconditions in the > code is very useful, I just don't think that Haskell' is a good target > for this - there is a big design space that no one has yet explored. I agree that Haskell' will not have this, if only under the "must already be implemented" requirement for major features. However, it seems that Haskell' is a good way to get people thinking about future improvements, and I'd hate to stifle that. -- Taral "You can't prove anything." -- G?del's Incompetence Theorem From Al.Falloon at synopsys.com Fri Oct 20 08:14:17 2006 From: Al.Falloon at synopsys.com (Alan Falloon) Date: Fri Oct 20 07:19:15 2006 Subject: Standard syntax for preconditions, postconditions, and invariants In-Reply-To: <802361128.20061019183039@gmail.com> References: <4537837E.1030008@synopsys.com> <802361128.20061019183039@gmail.com> Message-ID: <4538BD99.4050501@synopsys.com> Bulat Ziganshin wrote: > Thursday, October 19, 2006, 5:54:06 PM, you wrote: > >> I propose that haskell' include a standard syntax for invariants that >> the programmer wants to express. >> >> The intent is not to have standardized checks on the invariants, its >> just to supply a common way to specify invariants to that the various >> strategies for checking them can all work from the same data. For >> example, one tool might use the invariants to generate QuickCheck >> properties >> > > seems that it should be a sort of annotation, yes? so we again need to > define common annotation syntax and you can add this as one more > possible usage to annotations-proposal page > It does seem to fit as an annotation. What I am worried about, however, is that if there is no 'official' way to annotate the invariants, then the tool writers will come up with their own slightly incompatible invariant annotations, which would be a shame. This actually seems to be a common issue with annotations. Some of the other proposals are looking to use annotations to specify language extensions that are in effect, and they will also need an 'official' syntax if they want all the compilers to recognize them in the same way. Writing the invariants using a common annotation syntax is great idea though! In fact its better than what I originally had in mind because some tools that use the invariants may need additional information that isn't contained in the common invariant syntax. For instance, I expect any purely static checking of the invariants will probably need help from the developer at various points in a function to complete the proof. When you talk about the "annotations-proposal page", you are referring to the trac ticket right? http://hackage.haskell.org/trac/haskell-prime/ticket/88 Should I apply for an account on trac and modify the ticket? From ravi at bluespec.com Fri Oct 20 14:13:20 2006 From: ravi at bluespec.com (Ravi Nanavati) Date: Fri Oct 20 13:18:02 2006 Subject: (Pattern) Guards in lambdas In-Reply-To: <20061019132547.GF7057@momenergy.repetae.net> References: <00a501c6f2a2$64cf2a80$701f8351@cr3lt> <2E9B33CE230409489A7ED37E5E34090F05C52389@EUR-MSG-20.europe.corp.microsoft.com> <20061019132547.GF7057@momenergy.repetae.net> Message-ID: <453911C0.4060402@bluespec.com> John Meacham wrote: > On Thu, Oct 19, 2006 at 12:55:48PM +0100, Simon Marlow wrote: >> As for extending lambda to allow multiple guards and/or multiple pattern >> matches, I don't think we need that either. Lambda is a quiet syntax >> and will be lost at the beginning of a sequence of pattern >> matches/guards; it's best used for simple lambda expressions, >> complicated pattern matches should be done using function equations. > > I think I would like to allow a (single) guard on a lambda. for > assertion checking, I am a sucker for assertion checking and the more > lightweight the better when it comes to that sort of thing. > I like idea of a single guard on a lambda as well. I think it simplifies the language (slightly) by eliminating a special case where patterns are allowed but guards are not. - Ravi From haskell at henning-thielemann.de Sun Oct 22 09:48:04 2006 From: haskell at henning-thielemann.de (Henning Thielemann) Date: Sun Oct 22 08:54:05 2006 Subject: Indentation of If-Then-Else Message-ID: I object strongly to the proposal http://hackage.haskell.org/trac/haskell-prime/wiki/DoAndIfThenElse because it solves problems with syntactic sugar with even more sugar, where no sugar is needed at all. In order to solve the trouble I propose enhancements to teachers, compilers and standard libraries: 1. 'if' syntax should be teached as if a then b else c This indentation makes pretty clear, what is condition, and what is the result in both cases. It just resembles case a of True -> b False -> c . 2. Add 'if :: Bool -> a -> a -> a' or '(?) :: Bool -> (a,a) -> a' or both to the standard library, as discussed in the thread starting with http://www.haskell.org/pipermail/haskell-cafe/2006-July/016914.html 3. If a compiler suspects that a parsing problem is related to 'do' and 'if' it should suggest indentation if a then b else c or even better, the usage of if- or (?)-function. So, please add this to the 'Cons' list. From haskell at henning-thielemann.de Sun Oct 22 09:48:11 2006 From: haskell at henning-thielemann.de (Henning Thielemann) Date: Sun Oct 22 08:54:05 2006 Subject: Module imports anywhere Message-ID: I don't see the benefit of allowing imports anywhere at top-level. http://hackage.haskell.org/trac/haskell-prime/wiki/AllowImportAnywhere As with declarations I expect that imported identifiers are visible everywhere in a module. Thus the search for an imported identifier becomes even more complicated as it is today (due to anonymously imported identifiers and re-exported modules). Sometimes I missed a feature from the Modula-2 derivative named "Cluster", namely local imports of modules. Locally imported identifiers would be invisible to other functions. However I don't think that it is so important to be worth the trouble of implementing it. From ndmitchell at gmail.com Sun Oct 22 10:04:52 2006 From: ndmitchell at gmail.com (Neil Mitchell) Date: Sun Oct 22 09:09:40 2006 Subject: Indentation of If-Then-Else In-Reply-To: References: Message-ID: <404396ef0610220704o33f757e4jee30e4adff9086e6@mail.gmail.com> Hi > In order to solve the trouble I propose enhancements > to teachers, compilers and standard libraries: > 1. 'if' syntax should be teached as > if a > then b > else c I love being able to ident if however I like: if a then b else c Where b is a trivial case, and c is the hard one. if a then b else c Exactly like C. Clearly delimiting the b and teh c, by putting space between them. if a then b else c Short one if a then b else c I also occasionally use this. It seems better to change the language so it works like _everyone_ expects it does, rather than become syntax dictators. It's hard enough persuading people to move from C, but when you tell someone that their perfectly unambiguous sytnax is "wrong", they aren't going to be amused. Thanks Neil From haskell at henning-thielemann.de Sun Oct 22 10:21:14 2006 From: haskell at henning-thielemann.de (Henning Thielemann) Date: Sun Oct 22 09:26:31 2006 Subject: Indentation of If-Then-Else In-Reply-To: <404396ef0610220704o33f757e4jee30e4adff9086e6@mail.gmail.com> References: <404396ef0610220704o33f757e4jee30e4adff9086e6@mail.gmail.com> Message-ID: On Sun, 22 Oct 2006, Neil Mitchell wrote: > It seems better to change the language so it works like _everyone_ > expects it does, rather than become syntax dictators. It's hard enough > persuading people to move from C, but when you tell someone that their > perfectly unambiguous sytnax is "wrong", they aren't going to be > amused. I don't know why it is so important to convince every C programmers of Haskell. Making a language fit to everyone's taste eventually led to what is today known as Perl. From bulat.ziganshin at gmail.com Sun Oct 22 10:17:59 2006 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sun Oct 22 09:34:19 2006 Subject: Module imports anywhere In-Reply-To: References: Message-ID: <115555995.20061022181759@gmail.com> Hello Henning, Sunday, October 22, 2006, 5:48:11 PM, you wrote: > I don't see the benefit of allowing imports anywhere at top-level. it is useful to move together imports and related code. say: #if HUGS import Hugs.Base addInt = hugsAddInt #elseif GHC import GHC.Base addInt = ghcAddInt #endif currently we are forced to make separate sections for import and use: #if HUGS import Hugs.Base #elseif GHC import GHC.Base #endif #if HUGS addInt = hugsAddInt #elseif GHC addInt = ghcAddInt #endif just another example: -- higher-level stuff: openFile = ... -- medium-level-stuff createFD = .. -- low-level stuff import System,FD _create = ... System.FD.create (i don't propose subj. i just know pros and contras for it) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From ndmitchell at gmail.com Sun Oct 22 10:34:30 2006 From: ndmitchell at gmail.com (Neil Mitchell) Date: Sun Oct 22 09:39:18 2006 Subject: Indentation of If-Then-Else In-Reply-To: References: <404396ef0610220704o33f757e4jee30e4adff9086e6@mail.gmail.com> Message-ID: <404396ef0610220734r6ed3dca3i1dec8fc84a7a02f1@mail.gmail.com> > > It seems better to change the language so it works like _everyone_ > > expects it does, rather than become syntax dictators. It's hard enough > > persuading people to move from C, but when you tell someone that their > > perfectly unambiguous sytnax is "wrong", they aren't going to be > > amused. > > I don't know why it is so important to convince every C programmers of > Haskell. Making a language fit to everyone's taste eventually led to what > is today known as Perl. Ok, a more personal argument. I hate that this language won't allow _me_ to lay out _my_ if's as _I_ want them! Especially as the rest of Haskell lets the programmer choose the best layout, and just keeps hands off. I can be convinced through logical arguments that all the other restrictions/features of Haskell are a good idea, but this one doesn't have a good reason associated with it. Thanks Neil From brianlsmith at gmail.com Sun Oct 22 11:23:00 2006 From: brianlsmith at gmail.com (Brian Smith) Date: Sun Oct 22 10:27:48 2006 Subject: Indentation of If-Then-Else In-Reply-To: <404396ef0610220704o33f757e4jee30e4adff9086e6@mail.gmail.com> References: <404396ef0610220704o33f757e4jee30e4adff9086e6@mail.gmail.com> Message-ID: On 10/22/06, Neil Mitchell wrote: > > Hi > > > In order to solve the trouble I propose enhancements > > to teachers, compilers and standard libraries: > > 1. 'if' syntax should be teached as > > if a > > then b > > else c > > I love being able to ident if however I like: I agree with Henning. Reserved syntax for "if" is totally unnecessary in Haskell. It requires three keywords. Its costs (syntax wise) seem much greater than its benefits (which are practically zero). I don't think that it makes sense to make further complicate this unnecessary syntax. Instead, why not work on eliminating the special syntax altogether? For example, make the "then" and "else" keywords optional and schedule them for removal in the next revision. Hennings suggestion that implementations suggest the correct indention is a good one. The existing Haskell implementations do not do a good job diagnosing layout problems. As far as I know, they don't even try to recover from syntax errors at all. I would like to change both of these problems. The proposed layout changes (NondecreasingIndention and DoAndifThenElse and the one for case) should be postponed until more work on error diangosis and recovery has been done. Regards, Brian -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-prime/attachments/20061022/081f5dd0/attachment.htm From cgibbard at gmail.com Sun Oct 22 12:23:18 20