Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Support variable swapping #658

Open
TxzK opened this issue Dec 18, 2023 · 2 comments
Open

Feature request: Support variable swapping #658

TxzK opened this issue Dec 18, 2023 · 2 comments
Labels
enhancement New feature or request

Comments

@TxzK
Copy link

TxzK commented Dec 18, 2023

In Rust, you can to this:

let mut a = 0;
let mut b = 1;
(a, b) = (b, a); // a = 1, b = 0

But if you do the same thing in Rune, it says error: Cannot assign to expression. Swapping variables like this is often very useful. Please fix this so we can do this in Rune as well.

@udoprog udoprog added the enhancement New feature or request label Dec 18, 2023
@udoprog udoprog changed the title Variable Swapping Support variable swapping Dec 18, 2023
@udoprog udoprog changed the title Support variable swapping Feature request: Support variable swapping Mar 5, 2024
@HoloTheDrunk
Copy link

HoloTheDrunk commented Apr 23, 2024

This could be solved if

let (a, b) = (0, 1);
let (a, b) = (b, a);

was allowed but unfortunately this currently throws a Pattern might panic warning. A warning is not the end of the world but it'd be cool if there was some static checking of tuple size in cases like this to automatically suppress it.

@udoprog
Copy link
Collaborator

udoprog commented Apr 23, 2024

This will be possible in 0.14 with #663. Before that change we weren't allowed to perform these kinds of optimizations easily, because we couldn't tell if a or b were Copy types. Copy types (like numbers) demanded that for each assignment a clone of the value is used, so a reassignment like the above has distinct behaviors depending on whether a and b are Copy or not. While the above transformation might've been possible, it would be more difficult to implement coherently.

In 0.14 an onwards, all dynamic values (including primitives) are instead always structurally shared:

let a = 11;
let b = 22;
let closure = || a;

(b, a) = (a, b);

b += 1;
assert_eq!(closure(), 12);

For dynamic languages, this allows for arbitrarily complex transformations, without having to perform static analysis such as seeing the assignment of a and b.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants