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