RE: Suggestion for bang patterns documentation

2009-02-27 Thread Simon Peyton-Jones
good idea. done

| -Original Message-
| From: glasgow-haskell-users-boun...@haskell.org [mailto:glasgow-haskell-users-
| boun...@haskell.org] On Behalf Of Brian Bloniarz
| Sent: 27 February 2009 03:56
| To: glasgow-haskell-users@haskell.org
| Subject: Suggestion for bang patterns documentation
|
|
| I got confused by the GHC documentation recently, I was wondering how
| it could be improved. From:
| http://www.haskell.org/ghc/docs/latest/html/users_guide/bang-patterns.html
|
|  A bang only really has an effect if it precedes a variable or wild-card 
pattern:
|  f3 !(x,y) = [x,y]
|  f4 (x,y)  = [x,y]
|  Here, f3 and f4 are identical; putting a bang before a pattern that
|  forces evaluation anyway does nothing.
|
| The first sentence is true, but only in settings where the pattern is being
| evaluated eagerly -- the bang in:
|  f3 a = let !(x,y) = a in [1,x,y]
|  f4 a = let (x,y) = a in [1,x,y]
| has an effect.
|
| The first time I read this, I took the first sentence to be a unqualified 
truth
| and ended up thinking that !(x,y) was equivalent to (x,y) everywhere. Stuff
| that comes later actually clarifies this, but I missed it.
|
| What about making the distinction clear upfront? Something like:
|  A bang in an eager pattern match only really has an effect if it precedes a
| variable
|  or wild-card pattern:
|  f3 !(x,y) = [x,y]
|  f4 (x,y)  = [x,y]
|  Because f4 _|_ will force the evaluation of the pattern match anyway, f3 
and f4
|  are identical; the bang does nothing.
|
| It also might be a good idea to immediately follow this with the let/where 
usage:
|
|  A bang can also preceed a let/where binding to make the pattern match 
strict. For
| example:
|  let ![x,y] = e in b
|  is a strict pattern...
| (in the existing docs, let comes a bit later):
|
| Just a thought. Hopefully someone can come up with a better way of
| wording what I'm getting at.
|
| Thanks,
| -Brian
|
| _
| Windows Live(tm) Hotmail(r)...more than just e-mail.
| 
http://windowslive.com/howitworks?ocid=TXT_TAGLM_WL_t2_hm_justgotbetter_howitworks_0
| 22009___
| Glasgow-haskell-users mailing list
| Glasgow-haskell-users@haskell.org
| http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Suggestion for bang patterns documentation

2009-02-27 Thread Christian Maeder
Brian Bloniarz wrote:
 I got confused by the GHC documentation recently, I was wondering how
 it could be improved. From:
 http://www.haskell.org/ghc/docs/latest/html/users_guide/bang-patterns.html

Seeing the rule
 pat ::= !pat

you'll probably want to avoid patterns like: !!pat, ! ! pat, or ~ !
~ pat.

Even the current http://www.haskell.org/onlinelibrary/exps.html#sect3.17.1

  apat - ~ apat

allows ~ ~x. (Note the space!) So maybe a separate non-terminal bpat
should be used with:

 bpat - [~|!] apat

(and bpat used within pat). You may also want to exclude v@ ~(...) in
favor of ~v@(...).

 A bang only really has an effect if it precedes a variable or wild-card 
 pattern:
 f3 !(x,y) = [x,y]
 f4 (x,y)  = [x,y]
 Here, f3 and f4 are identical; putting a bang before a pattern that
 forces evaluation anyway does nothing.

Maybe the duality (if it is one) should be added that an irrefutable
pattern above would make a difference but not within the let below.

 The first sentence is true, but only in settings where the pattern is being
 evaluated eagerly -- the bang in:
 f3 a = let !(x,y) = a in [1,x,y]
 f4 a = let (x,y) = a in [1,x,y]
 has an effect.

Cheers Christian

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Suggestion for bang patterns documentation

2009-02-27 Thread Christian Maeder
Brian Bloniarz wrote:
 I got confused by the GHC documentation recently, I was wondering how
 it could be improved. From:
 http://www.haskell.org/ghc/docs/latest/html/users_guide/bang-patterns.html

cite
The let-binding can be recursive. However, it is much more common for
the let-binding to be non-recursive, in which case the following law
holds: (let !p = rhs in body)  is equivalent to (case rhs of !p - body)
/cite

Shouldn't the bang be removed in the final case pattern?

Furthermore with existential types the let binding is not supported:

 data E = forall a . Show a = E a

 f :: E - String
 f x = case x of E a - show a

f works, but g

 g :: E - String
 g x = let !(E a) = x in show a

fails (with or without the bang):

My brain just exploded.
I can't handle pattern bindings for existentially-quantified
constructors.
Instead, use a case-expression, or do-notation, to unpack the
constructor.
In the binding group for
!(E a)
In a pattern binding: !(E a) = x
In the expression: let !(E a) = x in show a
In the definition of `g': g x = let !(E a) = x in show a

Cheers Christian

P.S. It should be mentioned that ~ and ! only make sense for single
variant data types (like tuples)

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: Suggestion for bang patterns documentation

2009-02-27 Thread Simon Peyton-Jones
| cite
| The let-binding can be recursive. However, it is much more common for
| the let-binding to be non-recursive, in which case the following law
| holds: (let !p = rhs in body)  is equivalent to (case rhs of !p - body)
| /cite
|
| Shouldn't the bang be removed in the final case pattern?

No.  If p was a simple variable, then
case rhs of x - body
is non-strict in Haskell, but should be strict here.

| P.S. It should be mentioned that ~ and ! only make sense for single
| variant data types (like tuples)

That isn't true.  Both are useful for multi-variant types

Simon
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Suggestion for bang patterns documentation

2009-02-27 Thread Christian Maeder
Simon Peyton-Jones wrote:
 | cite
 | The let-binding can be recursive. However, it is much more common for
 | the let-binding to be non-recursive, in which case the following law
 | holds: (let !p = rhs in body)  is equivalent to (case rhs of !p - body)
 | /cite
 |
 | Shouldn't the bang be removed in the final case pattern?
 
 No.  If p was a simple variable, then
 case rhs of x - body
 is non-strict in Haskell, but should be strict here.

Thanks for pointing this out. But the case with a simple variable (and
no distinction) is special anyway (sort of a monomorphic let binding).

 | P.S. It should be mentioned that ~ and ! only make sense for single
 | variant data types (like tuples)
 
 That isn't true.  Both are useful for multi-variant types

Right, a non-empty list should behave like a pair as long as I don't
want to know the variant beforehand and thereby forcing evaluation anyway.

Cheers Christian

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Suggestion for bang patterns documentation

2009-02-26 Thread Brian Bloniarz

I got confused by the GHC documentation recently, I was wondering how
it could be improved. From:
http://www.haskell.org/ghc/docs/latest/html/users_guide/bang-patterns.html

 A bang only really has an effect if it precedes a variable or wild-card 
 pattern:
 f3 !(x,y) = [x,y]
 f4 (x,y)  = [x,y]
 Here, f3 and f4 are identical; putting a bang before a pattern that
 forces evaluation anyway does nothing.

The first sentence is true, but only in settings where the pattern is being
evaluated eagerly -- the bang in:
 f3 a = let !(x,y) = a in [1,x,y]
 f4 a = let (x,y) = a in [1,x,y]
has an effect.

The first time I read this, I took the first sentence to be a unqualified truth
and ended up thinking that !(x,y) was equivalent to (x,y) everywhere. Stuff
that comes later actually clarifies this, but I missed it.

What about making the distinction clear upfront? Something like:
 A bang in an eager pattern match only really has an effect if it precedes a 
 variable
 or wild-card pattern:
 f3 !(x,y) = [x,y]
 f4 (x,y)  = [x,y]
 Because f4 _|_ will force the evaluation of the pattern match anyway, f3 and 
 f4
 are identical; the bang does nothing.

It also might be a good idea to immediately follow this with the let/where 
usage:

 A bang can also preceed a let/where binding to make the pattern match strict. 
 For example:
 let ![x,y] = e in b
 is a strict pattern...
(in the existing docs, let comes a bit later):

Just a thought. Hopefully someone can come up with a better way of
wording what I'm getting at.

Thanks,
-Brian

_
Windows Live™ Hotmail®…more than just e-mail. 
http://windowslive.com/howitworks?ocid=TXT_TAGLM_WL_t2_hm_justgotbetter_howitworks_022009___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users