only irrefutable patterns allowed in `let bindings`
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
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.
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 Yes, that's a known trade off. It is impossible to tell whether it is a single-constructor or not during parsing.
This is also a breaking change, maybe we should make this a warning at first?
you already get the warning for partial pattern match?
Yes, but an augmented one that we're possibly gonna deprecate the non-irrefutable patterns in the future. Might be a bad idea…
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.
@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
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.