Open yorickpeterse opened 1 year ago
Another option is to solve this at the standard library. Types such as Entry
, Option
, Result
, etc could provide a let
method that yields in the OK/some/etc case, passing its components as separate arguments. For example, for Entry
you'd then write something like this:
map.into_iter.each fn (entry) {
entry.let fn (key, value) {
...
}
}
You'd still have an extra level of indentation, though at least we wouldn't have to further complicate the compiler.
Kotlin has a somewhat similar feature to the let
method described above: https://kotlinlang.org/docs/scope-functions.html#let
Description
At some point Inko supported pattern matching in
let
, meaning you could write e.g.let Some(val) = some_option else return
orlet (a, b) = c
. This was removed due to the complexity of the implementation, as it wasn't able to reuse the same compilation steps formatch
expressions, instead having to re-implement/copy portions of it.I would like to re-introduce this in a limited form, as not having it can result in deeply nested code. For example, now you end up with this:
Instead of something like this (which is nicer):
As for the implementation: we should implement this as a desugaring pass that operates on HIR, before type-checking. Essentially for every
let PATTERN = VALUE
we encounter, we turn that intomatch VALUE { case PATTERN -> after }
whereafter
is all the code that follows thelet
expression. Thus this:Becomes this:
Re-introducing
let ... else
would complicate matters, as the expression ofelse
must return/break from the surrounding scope, as the code that comes after can't run without the pattern matching. Part of the complexity of the past implementation involved handling that, generating the correct code, type-checking, etc. As such I'm inclined to just not re-introducing that, and directing people to just usingmatch
for such needs. Given the two most common cases are destructuring tuples and classes (and not e.g. enums), I think not supportingelse
should be fine.With that all said, I find myself mostly needing this when iterating over a
Map
and wanting to break theEntry
values down into separate variables. Outside of that I haven't had a real need for this, so I'm not yet convinced this is actually worth the maintenance overhead and compiler complexity.Related work
No response