syntax icon indicating copy to clipboard operation
syntax copied to clipboard

only irrefutable patterns allowed in `let bindings`

Open bobzhang opened this issue 4 years ago • 8 comments

Currently people can do let pat = exp , the pat can be exhaustive, this is an unsafe behavior which should already trigger an warning.

As we discussed, it may be better just providing a subset of patterns in let bindings.

The irrefutable patterns could be a conservative approximation, e.g,

irrefutable-patterns:
   | simple-identifier
   | tuple
   | record
   | module unpack

bobzhang avatar Jan 21 '21 02:01 bobzhang

Thanks for the write-up after the team discussion. I put it on the planning for the first week of February.

We should probably think about implementing a similar scheme for for-expression

for pattern in expression to expression …

Not sure if it makes sense to do something similar here.

IwanKaramazow avatar Jan 21 '21 07:01 IwanKaramazow

if I’m understanding this correctly, this would mean that the following code won’t be allowed anymore?

type t = A(int, int)
let a = A(1, 2)
let A(b, c) = a

I would miss that, since single-constructor variants are often useful.

Although, I probably don’t use them in let bindings as often as I do in function arguments, like this:

let f = (A(a, b)) => a + b

As long as that’s still allowed, that would be great.

johnridesabike avatar Jan 28 '21 12:01 johnridesabike

@johnridesabike Yes, that's a known trade off. It is impossible to tell whether it is a single-constructor or not during parsing.

bobzhang avatar Jan 30 '21 09:01 bobzhang

This is also a breaking change, maybe we should make this a warning at first?

IwanKaramazow avatar Jan 30 '21 11:01 IwanKaramazow

you already get the warning for partial pattern match?

bobzhang avatar Jan 31 '21 04:01 bobzhang

Yes, but an augmented one that we're possibly gonna deprecate the non-irrefutable patterns in the future. Might be a bad idea…

IwanKaramazow avatar Jan 31 '21 13:01 IwanKaramazow

I have inexhaustive pattern matching set to error, would making that a default error be an easier way to tackle this? It might just need a different error message in the let binding position versus an inexhaustive switch match list.

TheSpyder avatar Feb 17 '21 19:02 TheSpyder

@IwanKaramazow The recent addition of pattern match over modules make me think that it is a good idea to explore the let pat = exp in a different way.

Currently, let pat = exp is exactly the same as switch exp { pat .. }, the benefit is unclear to have two syntaxes to do the similar things, so instead of let pat = exp, we think it as let ad-hoc-pat = exp

The ad-hoc-pat would allow us to do different things which can not be done in traditional pattern match:

  • pattern match over module We can even extend the current syntax to make it possible to import submodules:
    let {A, length } = module (List)
    
  • pattern match over structural objects:
 let {"property1" , "property2" } = obj
  • pattern match over arrays without a fixed length
 let [a,b,c, ... ] = array // The length of array does not have to be 3
 assert let [a,b,c ..] = array else {
   ...
 }
  • maybe in the future, we can add regex pattern match too

bobzhang avatar Mar 09 '21 03:03 bobzhang

The rescript-lang/syntax repo is obsolete and will be archived soon. If this issue is still relevant, please reopen in the compiler repo (https://github.com/rescript-lang/rescript-compiler) or comment here to ask for it to be moved. Thank you for your contributions.

stale[bot] avatar May 28 '23 23:05 stale[bot]