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

Allow mut function parameters of primitive type #811

Open
sbillig opened this issue Nov 15, 2022 · 1 comment
Open

Allow mut function parameters of primitive type #811

sbillig opened this issue Nov 15, 2022 · 1 comment

Comments

@sbillig
Copy link
Collaborator

sbillig commented Nov 15, 2022

What is wrong?

(#777 follow-up)

It's not currently possible to define a function that takes a mut parameter that is a primitive (number, bool, etc) type. For example:

fn example() {
  let mut x: u64 = 0
  increment(x)
}

fn increment(mut x: u64) {
  x += 1
}

This should modify the passed-in value in the calling scope. We've discussed adding the val-lang-inspired use of the & sigil to indicate mutation, which would make this more clear. Eg increment(&x)

How can it be fixed

This one's kinda complicated. The simple way would be to put all mutable integers in memory (or, better, those that are passed mutably into fns), so that we can pass a pointer into a function so that it can modify it, but that would be inefficient. In simple examples, inlining the function would solve the problem, but in complex cases it maybe be most efficient to compile it down to something like:

fn example() {
  let mut x: u64 = 0
  x = increment(x)
}
fn increment(x: u64) -> u64 {
    return x + 1
}

so, mut primitive args would become return values, the args would be passed by value, and the value in the calling scope would be reassigned.

@sbillig sbillig mentioned this issue Nov 16, 2022
3 tasks
@alfsb
Copy link

alfsb commented Feb 22, 2024

mut primitive args simulated with invisible return values may work with stack allocated primitives, but would fail for heap allocated objects.

struct MutantTurtle {
    pub mut pizzas: u64
}

let t = new MutantTurtle { pizzas = 0 }
mut1( t , t.pizzas )

pub fn mut1( t: &MutantTurtle, mut pi: &u64 ) {
    pi = 1
    mut2( t , pi )
}

pub fn mut2( t: &MutantTurtle, mut zza: &u64 ) MutantTurtle {
    assert( t.pizzas == zza )                 // will fail
    return new MutantTurtle { pizzas = zza }; // copy
}

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

No branches or pull requests

2 participants