wren-lang / wren

The Wren Programming Language. Wren is a small, fast, class-based concurrent scripting language.
http://wren.io
MIT License
6.86k stars 550 forks source link

Suggestion: Support multiple assignment #559

Open macabeus opened 6 years ago

macabeus commented 6 years ago

Some languages, such Python, Swift, Lua and JS, support multiple assignment. For example:

# Python and Lua
a, b = 1, 2

// Swift
let (a, b) = (1, 2)

// JS
let [a, b] = [1, 2]

In Wren, I think that

var a, b = [1, 2]
c, d = [3, 4]

should be a syntax sugar for

var a = 1
var b = 2
c = 3
d = 4

It is useful to add it in Wren, especially to handle function with multiple returns:

var someValue = "key:value"
var key, value = someValue.split(":")

instead of

var someValue = "key:value"
var result = someValue.split(":")
var key = result[0]
var value = result[1]

Edge case

What to do if have a different mount on right and left side? Each language have a different behavior:

// Swift
let (a, b) = (1, 2, 3) // Will crash
let (a, b, c) = (1, 2) // Will crash

# Python
a, b = 1, 2, 3 # Will crash
a, b, c = 1, 2 # Will crash

# Lua
a, b = 1, 2, 3 // a is 1 and b is 2
a, b, c = 1, 2 // a is 1, b is 2 and c is nil

// JS
let [a, b] = [1, 2, 3] // a is 1 and b is 2
let [a, ...b] = [1, 2, 3] // (using spread operator) a is 1 and b is [2, 3]

let [a, b, c] = [1, 2] // a is 1, b is 2 and c is undefined
let [a, b, ...c] = [1, 2] // (using spread operator) a is 1, b is 2 and c is []

I don't know what the ideal behavior to use in Wren. Each way has a different advantage:

Assignment and Setter

Wren has assignment for variables and setter for property. What to do in this situation?

var foo, person.age = [100, 74]
mhermier commented 6 years ago

I don't think it is feasble as this, and would require a LOT of plumbing. In addition there is an ambiguity if you consider: var a, b = [1, 2, 3] what should be the value of b ? 2 or [2, 3] then it make ambigus: var a, b = [1, 2] since it should make b equals to either 2 or [2] Anyway if we consider var a = [1] to still be valid then the only sane consideration is to make: var a, b = [1, 2, 3] with b = [2, 3] which deafeat the purpose of your suggestion ...

I agree it is nice to have support for multiple return values, but not with this syntax.