RE: Suggestion for bang patterns documentation
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
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
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
| 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
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
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