# The \`mut\` keyword in variable declaration

**URL:** <https://forum.modular.com/t/the-mut-keyword-in-variable-declaration/2513>\
**Category:** Language Design\
**Created:** [December 10, 2025, 12:15am UTC](https://forum.modular.com/t/the-mut-keyword-in-variable-declaration/2513 "2025-12-10T00:15:09Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![taylorpool](https://avatars.discourse-cdn.com/v4/letter/t/ce73a5/32.png) [@taylorpool](https://forum.modular.com/u/taylorpool)\
**Post date:** [December 10, 2025, 12:15am UTC](https://forum.modular.com/t/the-mut-keyword-in-variable-declaration/2513/1 "2025-12-10T00:15:09Z")

</div>

**The problem**

Mojo applies the`mut` keyword inconsistently.

1. `x: Int = 0` declares and initializes a mutable variable.
2. `fn foo(self)` takes `self`immutably
3. `fn foo(mut self)`takes `self`mutably.

**Proposed Solution**

Make `x: Int = 0` immutable. Make `mut x: Int = 0`mutable.

The solution dovetails nicely with the recent elimination of the need for `var `in variable declarations.

**Prior Work**

Rust

**Drawbacks**

Deviates from Python programming where everything is mutable.

Variables initialized over multiple statements would have to be declared with `mut`.

**Acknowledgements**

I recognize that `mut `was removed from variable declarations about 2 years ago (couldn’t find the relevant discussion). I think it’s worth considering if it should be added back in now that `var` is optional for variable declaration.

---

<div class="post-metadata">

**Author:** ![leb-kuchen](https://avatars.discourse-cdn.com/v4/letter/l/a183cd/32.png) [@leb-kuchen](https://forum.modular.com/u/leb-kuchen)\
**Post date:** [December 10, 2025, 6:14am UTC](https://forum.modular.com/t/the-mut-keyword-in-variable-declaration/2513/2 "2025-12-10T06:14:09Z")

</div>

Mut serves no real purpose.  
Mutable aliasing is checked at the function level; therefore, there is no technical need for mutable aliases with variable declarations.

It’s hard for beginners to learn, and it’s annoying for everyone else to fix the Mut compile errors every time they change the code.

It may be clearer, but you could also use an LSP MUT feature like InlayHints. I don’t really see this as an argument either.

---

<div class="post-metadata">

**Author:** ![owenhilyard](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/owenhilyard/32/41_2.png) [@owenhilyard](https://forum.modular.com/u/owenhilyard)\
**Post date:** [December 10, 2025, 4:36pm UTC](https://forum.modular.com/t/the-mut-keyword-in-variable-declaration/2513/3 "2025-12-10T16:36:50Z")

</div>

You might want to shuffle over to [Mojo proposal: renaming `read` to `immut` - #50 by owenhilyard](https://forum.modular.com/t/mojo-proposal-renaming-read-to-immut/2449/50) where some discussion in adjacent are is happening.

---

<div class="post-metadata">

**Author:** ![owenhilyard](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/owenhilyard/32/41_2.png) [@owenhilyard](https://forum.modular.com/u/owenhilyard)\
**Post date:** [December 10, 2025, 4:38pm UTC](https://forum.modular.com/t/the-mut-keyword-in-variable-declaration/2513/4 "2025-12-10T16:38:51Z")

</div>

> Mutable aliasing is checked at the function level; therefore, there is no technical need for mutable aliases with variable declarations.

I disagree. Declaring that something isn’t mutable removes the cognitive burden of figuring out whether it is ever mutated when reading the code, and lets the user know that the value will stay the same for the entire function. This is very useful for larger functions which may have to compute some values at runtime because one of the inputs to the computation is only known at runtime.

---

<div class="post-metadata">

**Author:** ![leb-kuchen](https://avatars.discourse-cdn.com/v4/letter/l/a183cd/32.png) [@leb-kuchen](https://forum.modular.com/u/leb-kuchen)\
**Post date:** [December 11, 2025, 8:56am UTC](https://forum.modular.com/t/the-mut-keyword-in-variable-declaration/2513/5 "2025-12-11T08:56:45Z")

</div>

> [@owenhilyard](#):
>
> I disagree. Declaring that something isn’t mutable removes the cognitive burden of figuring out whether it is ever mutated when reading the code,

What exactly is your plan? Would you like to reintroduce “let” and rename it “const,” or introduce “mut”? Should annotating mutated variables be mandatory or optional? What should the new keyword mean? Would it also apply to struct fields or variables?

I’m surprised you care about reading code. Otherwise, you would always want to introduce features that make writing code by hand faster and result in slightly shorter code. However, introducing these features would also make the code harder to read.

---

<div class="post-metadata">

**Author:** ![christoph\_schlumpf](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/christoph_schlumpf/32/274_2.png) [@christoph\_schlumpf](https://forum.modular.com/u/christoph_schlumpf)\
**Post date:** [December 11, 2025, 9:45am UTC](https://forum.modular.com/t/the-mut-keyword-in-variable-declaration/2513/6 "2025-12-11T09:45:54Z")

</div>

> [@owenhilyard](#):
>
> This is very useful for larger functions which may have to compute some values at runtime because one of the inputs to the computation is only known at runtime.

Agree. There are many use cases where you might want something to stay constant which is only known at runtime like the current time, a user input or the return value of any function that can only be calculated at runtime.

There were some discussions on this in the forum and on discord too and there is already a way to achieve a "runtime constant“ in Mojo but this has to be implemented separately as Mojo and the stdlib do not provide it out of the box.

```mojo
fn readonly[o: ImmutOrigin, T: AnyType](ref [o] val: T) -> ref [o] T:
    return val

fn main():
    ref start_time = readonly(get_current_time())
    ...

```

See [The case for explicit `read` variable bindings](https://forum.modular.com/t/the-case-for-explicit-read-variable-bindings/1604) too.

One easy straight forward solution would be to provide this function in the stdlib and add a description to it (e.g “Get an immutable reference to a runtime value. Prefer `comptime` for values that are known at compilation time”). So anyone asking for a “runtime constant” can be pointed to this function. It would avoid code fragmentation too. If this function gets used in many places It would be possible to provide some syntactic sugar for it in Mojo 1.x.

---

<div class="post-metadata">

**Author:** ![christoph\_schlumpf](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/christoph_schlumpf/32/274_2.png) [@christoph\_schlumpf](https://forum.modular.com/u/christoph_schlumpf)\
**Post date:** [December 23, 2025, 8:55am UTC](https://forum.modular.com/t/the-mut-keyword-in-variable-declaration/2513/7 "2025-12-23T08:55:53Z")

</div>

> <https://github.com/modular/modular/pull/5704>
>
> \`ReadOnly\` wraps a value that is initialized at runtime and can't be
> modified t…hereafter. It provides an immutable reference to the underlying value.
> Example:
> \`\`\`mojo
> from time import current\_time\_ns
> def main():
> ref start\_time = ReadOnly(current\_time\_ns())\[\]
> # value is known at runtime but must stay immutable thereafter
> # ... any code here is garanteed to not modify start\_time ...
> # start\_time = 0 # compile-time error
> var duration = current\_time\_ns() - start\_time
> print("Duration (ns): ", duration)
> \`\`\`
> Prefer \`comptime\` for constant values that are known at compilation time:
> \`\`\`mojo
> def main():
> comptime magic\_number = 42
> # value is known at compilation time
> # ... any code here is garanteed to not modify magic\_number ...
> print("Magic Number: ", magic\_number)
> \`\`\`
> 
> \### Motivation
> From time to time developers are asking how to declare value that must be calculated at runtime but needs to be constant thereafter (e.g. in the form https://forum.modular.com/t/the-mut-keyword-in-variable-declaration/2513/4 and on Discord). As Mojo does not have any notion of a \`const\` declaration several solutions/code snippets were provided like a \`readonly(val)\` function that returns an immutable reference to the provided value:
> \`\`\`mojo
> fn readonly\[o: ImmutOrigin, T: AnyType\](ref \[o\] val: T) -\> ref \[o\] T:
> return val
>     
> \`\`\`
> The downside of such a \`readonly\` function is that it only guarantees that the value can't be modified through this value binding. If there are other \`mutable\` value bindings to the same value, the value can still be modified.
> \`\`\`mojo
> var start = current\_time\_ns())
> ref start\_time = readonly(start)
> start = 0 # start\_time is now \`0\` as it references to the same value.
> \`\`\`
> 
> \`ReadOnly\` does not have this flaw.
> 
> I see the following reasons to provide a \`ReadOnly\` reference implementation in the stdlib:
> \- Provides a canonical "solution" to a frequently requested feature.
> \- Does not require any additional complexity/sugar in the compiler and origin system (no \`const\` statement).
> \- Advices the developer on when to use it and when \*\*not\*\* to use it (e.g. comptime)
> \- Better than copying around code snippets that might have flaws and differ in naming and implementation details
> \- Can be kept up to date with the evolution of Mojo as part of the stdlib
