I know that is a old feature request, but I want to make my point here, with a good example of usage.
Destructuring assignment would be very useful because it is very common one needs to use destructuring for functions call inside a inner scope (curly brackets). In Kotlin it’s annoying, and sometimes it’s best join variables in a class in the caller with no logic than use multiple return in functions.
I’m writing a kind of compiler. There is a routine called getToken
, the return is a token (using sealead class
) and the new cursor position. Cursor is global inside the compiler and the token has a local usage.
Unfortunately the cleanest solution is to create a class with the cursor and the token, just to force the return, because destructuring within a local scope, would oblige to reassign the returns to other variables, which would be very artificial.
What I’ve made schematically:
First I’ve declared a sealed class and a artifical class (TokEt) that will be the return type of my function.
sealed class Token() {
class Variaveis(...) : Token()
class Numeros(...): Token()
class Parenteses(...) : Token()
class Funcoes(.... ) : Token()
class Nada() : Token()
}
class TokEt(val tok: Token, val pos: Int)
Using the classes above defined for writing my function and the main code:
getToken(s: String, p: Int): TokEt {
// code for get token t and update cursor pNew
return TokEt(t, pNew)
}
fun buildTree(s: String) { // Scanning the string s
var p: Int = 0
while (p <= s.length - 1) {
var tk = getToken(s, p)
p = tk.pos
when (tk.tok) { // Processing token for build a tree
is Token.Variaveis -> { ... }
is Token.Numeros -> {... }
is Token.Parenteses -> {...}
is Token.Funcoes -> {...}
is Token.Nada -> { }
}
}
}
My wish
getToken(s: String, p: Int): Pair<Token,Int>{
// code for get token t and update cursor pNew
return Pair(t, pNew)
}
fun buildTree(s: String) { // Scanning the string s
var p: Int = 0
var pos = 0
var tok = Token.Nada()
while (p <= s.length - 1) {
// Illegal. Notice that I can't declare p and tok here!
(tok p) = getToken(s, p)
//=========================
when (tok)
...
}
}
}
Notice that allow one to use directly the returned token and updated cursor position as variables is a very nice syntactic sugar: no need to use superfluous property dot access and annoying reassignments (p = tk.pos
). In my adopted solution I prefer to define a dummy class in the main function than using real multiple return, because it would be very weird return the values and soon below I should realocate for variables with wider scope,