Bang patterns

Ian Lynagh ian at
Mon Feb 4 00:22:12 CET 2013

On Sun, Feb 03, 2013 at 10:34:04PM +0000, Ben Millwood wrote:
> On Fri, Feb 01, 2013 at 05:10:42PM +0000, Ian Lynagh wrote:
> >
> >The first is suggested by "A bang only really has an effect if it
> >precedes a variable or wild-card pattern" on
> >
> >
> >We could therefore alter the lexical syntax to make strict things into
> >lexems, for example
> >   reservedid -> ...
> >               | _
> >               | !_
> >   strictvarid -> ! varid
> >etc. This would mean that "f !x" is 2 lexemes, and "f ! x" 3 lexemes,
> >with the former defining the function 'f' and the latter defining the
> >operator '!'.
> >
> >This has 3 downsides:
> >
> >* It would require also accepting the more radical proposal of making
> > let strict, as it would no longer be possible to write
> >   let ![x,y] = undefined in ()
> We really can't make let strict, in my view: its laziness is sort of
> fundamental. I don't see why the given example necessitates it
> though: just use case-of in that scenario.

Well, true, that's another option. It's rather unpleasant when you have
multiple bindings, as when converted to 'case's, each 'case' requires
you to indent deeper (or to use more braces).

> >The third is to parse '!' in patterns in the same way that '~' is parsed
> >in patterns, except that (!) would be accepted as binding the operator
> >'!'. This means that "f ! x" defines f.
> This is roughly how it's done at present, right?

I think it's roughly what GHC does now, yes.

> You missed the option of going the way of ~ and making ! an illegal
> name for an operator. Obvious drawbacks, probably not a good idea,
> but it would be the most consistent solution, so I wouldn't dismiss
> it immediately.

Yes, OK. That's basically option 3 as far as patterns are concerned, but
also disallows ! as an operator.

> (If we do come up with a way that doesn't involve making ! illegal,
> maybe we should consider allowing ~ as an operator as well!)

Right, if we went for option 3 then making ~ an operator in the same way
as ! would be possible. I think we should be cautious about doing so,
though, as it's a semi-one-way change, i.e. once it's an operator and
people start using it it becomes a lot trickier to revert the decision.

> Anyway, in light of my above comments, I think I like the first
> option the best (so bang patterns only apply to variables, let
> doesn't become strict).

So just to clarify what you're proposing, this wouldn't be valid:
    let ![x] = e in ...
and I guess these wouldn't either?:
    let !x = e in ...
    let [!x] = e in ...
    let (x, ~(y, !z)) = e in ...
but these would?:
    let f !x = e in ...
    case x of ~(y, !z) -> ()

i.e. you wouldn't be able to use ! in the 'pat' in the
    decl -> pat rhs

You'd also no longer support:
    do ![x]          <- e; ...
and so again for consistency I guess these wouldn't work?:
    do !x            <- e; ...
    do [!x]          <- e; ...
    do (x, ~(y, !z)) <- e; ...

i.e. you also wouldn't be able to use ! in the 'pat' in the
    stmt -> pat <- exp ;


More information about the Haskell-prime mailing list