# Provide an option to require explicit \`var\` declarations

**URL:** <https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207>\
**Category:** Mojo 1.0 Beta\
**Tags:** discussion\
**Created:** [June 7, 2026, 6:22am UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207 "2026-06-07T06:22:57Z")\
**Posts on this page:** 20\
**Page:** 1

<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:** [June 7, 2026, 6:22am UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/1 "2026-06-07T06:22:58Z")

</div>

Mojo has two variable declaration styles:

- “explicit block scoped `var` declarations” and
- “implicit function scoped variable declarations”

Both styles can be mixed, even inside one function. This can lead to confusion and render some guarantees impossible that “explicit `var` declarations” could provide. There is no guarantee that all variables are explicitly declared. Therefore it is always possible to (accidentally) introduce implicit variables that can lead to less readable code or even bugs.

Removing implicit variable declarations from Mojo altogether would be very controversial and is not in scope here.

The following alternatives for requiring explicit `var` declarations have already been proposed:

- Provide a Mojo linter with a corresponding rule
- Provide a compiler option
- Don’t allow mixing both styles inside the same function

Maybe now is a good time to consider those alternatives before Mojo 1.0 is finalized.

What do you think?

This is a spin-off from this broader forum topic: [Block scope vs. function scope of variables](https://forum.modular.com/t/block-scope-vs-function-scope-of-variables/3138)

---

<div class="post-metadata">

**Author:** ![Wouks](https://avatars.discourse-cdn.com/v4/letter/w/94ad74/32.png) [@Wouks](https://forum.modular.com/u/Wouks)\
**Post date:** [June 7, 2026, 4:21pm UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/2 "2026-06-07T16:21:52Z")

</div>

Having used Python for a few years I can say with using Mojo I always use the `var` keyword with the declaration of the variable as this helps me to easily see in the code where I start to create the variables and what the type is.

Having explicit block scoped `var` declarations has also been really great as I don’t have to worry about weird bugs of accidentally overwriting some variable. A great example of this is writing a python for loop like `for df in dfs: …` and then losing the data for the original `df` that you had before the loop. Yes this can be avoided, but using a Jupyter notebook you will have a ton of variables in global scope.

I feel `var` should not be optional at all, unless done so via a compiler option and even in this case it should not allow mixing of explicit and implicit declarations within the same method and function.

---

<div class="post-metadata">

**Author:** ![jbemmel](https://avatars.discourse-cdn.com/v4/letter/j/5daacb/32.png) [@jbemmel](https://forum.modular.com/u/jbemmel)\
**Post date:** [June 7, 2026, 4:57pm UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/3 "2026-06-07T16:57:17Z")

</div>

There is an additional question I raised:  
\* Is “var” the right keyword for declaring a local block scoped variable?

I would suggest “local” instead

---

<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:** [June 7, 2026, 5:45pm UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/4 "2026-06-07T17:45:18Z")

</div>

Yes, `local` might better indicate the block scoped nature of `var` declarations. But there are block scoped `ref` declarations too. I think it is more important that `var` is used throughout Mojo to represent a “locally declared owned value binding”.

See [Proposal: Make ':=' the standard declaration operator in Mojo (Go-style) - #3 by christoph\_schlumpf](https://forum.modular.com/t/proposal-make-the-standard-declaration-operator-in-mojo-go-style/3198/3) for the different usages of `var` in Mojo.

---

<div class="post-metadata">

**Author:** ![KilianKlaiber](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/kilianklaiber/32/436_2.png) [@KilianKlaiber](https://forum.modular.com/u/KilianKlaiber)\
**Post date:** [June 8, 2026, 5:16am UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/5 "2026-06-08T05:16:09Z")

</div>

The Mojo team has made a deliberate choice to stay close to Python syntax and semantics unless technical constraints require deviation. From what Chris mentioned, these differences are expected to stay.

Because of this, I’ve decided to avoid Python-style implicit variable declarations entirely in my own code. I now always use explicit var declarations instead. This helps me avoid the scoping and behavior surprises you described earlier.

I’d advise that new Mojo users also adopt explicit var declarations instead of Python-style syntax, at least while learning, for the reasons discussed in your post. In my humble opinion, that’s currently the best we can do.

---

<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:** [June 8, 2026, 6:08am UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/6 "2026-06-08T06:08:17Z")

</div>

@Wouks: Your example points to another difference between Mojo and Python: loop variables are always block scoped in Mojo.

Python:

```python
def main():
    value = 0
    values = [1, 2, 3]
    for value in values:
        print(value)
    print(value) # prints 3, the last value of the loop variable. Everything is function scoped.

main()

```

Mojo:

```mojo
def main():
    value = 0
    values = [1, 2, 3]
    for value in values: # not using `var` here means: read-only, but block scoped.
        print(value)
    print(value) # Surprise!, prints "0".

```

This is one more reason why I would like an option to require explicit `var` declarations. This implies that everything is block scoped.

```mojo
def main():
    var value = 0
    var values = [1, 2, 3]
    for value in values: # not using `var` here means: read-only, but block scoped.
        print(value)
    print(value) # No surprice, prints "0". Everything is block scoped.

```

---

<div class="post-metadata">

**Author:** ![jbemmel](https://avatars.discourse-cdn.com/v4/letter/j/5daacb/32.png) [@jbemmel](https://forum.modular.com/u/jbemmel)\
**Post date:** [June 9, 2026, 3:31pm UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/7 "2026-06-09T15:31:59Z")

</div>

To me that’s a bug, not a feature

Either Mojo implements Python variable scoping rules, or it defines its own. Having this in between state will lead to subtle bugs and mismatched programmer expectations.

IMHO the compiler should issue an error here - for-loop variable must have a unique name. Perhaps with a compiler option to downgrade that to a warning

---

<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:** [June 9, 2026, 4:15pm UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/8 "2026-06-09T16:15:22Z")

</div>

Mojo has it‘s own scoping rules:

- `var` or `ref` declarations: always block scoped.
- loop variables: always block scoped, defaults to read-only reference.
- Implicit variable declarations: function scoped (like Python)

I think it is the third rule that causes confusion, especially if mixed with the first two rules.

---

<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:** [June 10, 2026, 5:35am UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/9 "2026-06-10T05:35:28Z")

</div>

Is there any reason that makes mixing implicit and explicit variable declarations inside the same function a good thing? If no, why allowing it at all?

---

<div class="post-metadata">

**Author:** ![KilianKlaiber](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/kilianklaiber/32/436_2.png) [@KilianKlaiber](https://forum.modular.com/u/KilianKlaiber)\
**Post date:** [June 10, 2026, 12:07pm UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/10 "2026-06-10T12:07:39Z")

</div>

There is no reason for having two ways of declaring variables at all. “There should be one-- and preferably only one --obvious way to do it.” (Zen of Python.) “In Mojo however, we intentionally stay close to Python to make it easier to learn (and many other reasons). The cases we diverge (e.g. requiring static types) are related to the core mission and use-cases we need to support” Chris Lattner.

One of the two have to go and if you follow Chris’ mantra then the “Explicitly-declared variables” must go.

# From the mojo documentation:

## Variable declarations

Mojo has two ways to declare a variable:

- Explicitly-declared variables are created with the `var` keyword.

- Implicitly-declared variables are created the first time the variable is used,  
either with an assignment statement or with a type annotation:

I suggested to add for declaration + type inferrence:

```mojo
a := 5

```

And restrict the usage of

```mojo
 a = 5

```

To the assigment of a new value to an existing variable.

I was told in this forum that this it technically impossible or just deviates too far from python. Oh well, whatever it is, it’s definitely closer to python than the current system.

---

<div class="post-metadata">

**Author:** ![Wouks](https://avatars.discourse-cdn.com/v4/letter/w/94ad74/32.png) [@Wouks](https://forum.modular.com/u/Wouks)\
**Post date:** [June 10, 2026, 4:18pm UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/11 "2026-06-10T16:18:07Z")

</div>

Using `:=` to declare a variable in Mojo would be even more out of sync with Python.

If you write this in Python you will actually get a SyntaxError. (Tested on 3.14.3)

```python
def main() -> None:
    x := 5
    print("x is:", x)

if __name__ == " __main__":
    main()

```

So using this in my opinion would deviate even more from Python.

That being said I am wondering how scoping rules for the walrus operator should then work. Currently it does work like Python, but I have always felt that this can hurt readability as people can now create variables in the middle of the elif section.

```mojo
def main() raises -> None:
    var x = -1
    for x in range(10, 16): # this x is used within the for loop (not in the else section)
        print(t"Within for-loop x={x}") # prints 10 to 15
        if x > 20:
            print(t"Within for loop: x={x} | BREAK") # does not print
            break
    else: # no break
        print("No Break occurred:", x) # prints -1

    print("This is x outside of for loop:", x) # prints -1
    
    var y = -1 # assignment to 'y' was never used; assign to '_' instead? warning
    var z = -10
    if (y := 10) > 10:
        print("This is y within if branch:", y) # does not print
    elif y > 0 and (z := 100) > 0: # y is now assigned 10 here
        print("This is y within elif branch:", y, "This is z:", z) # prints y=10 and z=100
    
    print("This is y outside of if scope:", y) # prints 10
    print("This is z:", z) # prints 100

```

This is the output:

```bash
/home/wouks/Documents/MojoProjects/test_new_mojo/main_walrus.mojo:13:13: warning: assignment to 'y' was never used; assign to '_' instead?
    var y = -1 # assignment to 'y' was never used; assign to '_' instead? warning
            ^
Within for-loop x=10
Within for-loop x=11
Within for-loop x=12
Within for-loop x=13
Within for-loop x=14
Within for-loop x=15
No Break occurred: -1
This is x outside of for loop: -1
This is y within elif branch: 10 This is z: 100
This is y outside of if scope: 10
This is z: 100

```

So the for-loop with the else conditions makes sense to me with the scope rules that Mojo has.

With the walrus operator I would expect the `:=` assigned variable to only be available within the `if-elif-else` blocks/statement and then no longer outside of that block given the scoping rules. I know this would not agree with how Python does it, but we already have now different rules and having this one act this way seems to clash with the current scoping rules.

---

<div class="post-metadata">

**Author:** ![KilianKlaiber](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/kilianklaiber/32/436_2.png) [@KilianKlaiber](https://forum.modular.com/u/KilianKlaiber)\
**Post date:** [June 10, 2026, 4:27pm UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/12 "2026-06-10T16:27:32Z")

</div>

> [@Wouks](#):
>
> Using `:=` to declare a variable in Mojo would be even more out of sync with Python.

Strange that you didn’t notice that these three rules will lead to a syntax error:

var a = 5  
var b: Float64 = 3.14  
var c: String

Can you count to three?

These set of rules are obviously much more in sync and much closer to python:

a := 5  
b: Float64 = 3.14  
c: String

a=5 for reassignment.

---

<div class="post-metadata">

**Author:** ![Wouks](https://avatars.discourse-cdn.com/v4/letter/w/94ad74/32.png) [@Wouks](https://forum.modular.com/u/Wouks)\
**Post date:** [June 10, 2026, 5:09pm UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/13 "2026-06-10T17:09:21Z")

</div>

I agree that these would be more in sync with python:

b: Float64 = 3.14  
c: String

But this one of `a := 5` would not be and that is all that I meant with that. In Python this is not an assignment statement, but rather a assignment expression. Which is why a SyntaxError is raised in Python when used like a assignment statement. Obviously they could decide in Mojo to go that route and do it like this instead if they wanted to.

Just my personal opinion, but I actually like the `var` keyword. I also understand people will have different preferences. I just feel Mojo is already so different from Python in a lot of aspects, that it has become a bit hard indicating that one thing needs to be closer to Python while something else must absolutely change.

I was actually a bit disappointed when they removed the `let` keyword from Mojo a while back. I thought having a way to declare that a type was immutable was pretty handy and made you not have to think of whether that variable might have a different value elsewhere in the function.

So whatever decision is made by them on this, it would just be a matter of consistency within the Mojo language while keeping the scoping rules. I feel that is a major improvement for readability and to prevent confusion as I indicated earlier with the `for-loop` scoping difference with Python.

---

<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:** [June 10, 2026, 5:10pm UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/14 "2026-06-10T17:10:23Z")

</div>

Maybe it would be better to discuss this in the thread dedicated to this: [Proposal: Make ':=' the standard declaration operator in Mojo (Go-style)](https://forum.modular.com/t/proposal-make-the-standard-declaration-operator-in-mojo-go-style/3198)

---

<div class="post-metadata">

**Author:** ![KilianKlaiber](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/kilianklaiber/32/436_2.png) [@KilianKlaiber](https://forum.modular.com/u/KilianKlaiber)\
**Post date:** [June 10, 2026, 5:15pm UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/15 "2026-06-10T17:15:30Z")

</div>

“But this one of `a := 5` would not be and that is all that I meant with that.” Oh really?

This `a := 5` is used in the context of expressions for declaring + initializing variables in python. It’s known as the walus operator. So this is used in a different context with the same meaning in python. So this use much closer to python than var, var, var…

---

<div class="post-metadata">

**Author:** ![forfudan](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/forfudan/32/925_2.png) [@forfudan](https://forum.modular.com/u/forfudan)\
**Post date:** [June 15, 2026, 8:14pm UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/16 "2026-06-15T20:14:09Z")

</div>

I think “provide a Mojo linter with a corresponding rule” is a good solution. It preserves the flexible and Pythonic variable declaration syntax while allowing teams to enforce a stricter coding style in larger or more sophisticated projects.

This is similar to how Python tooling provides different levels of type checking. For example, Pylance/Pyright allows users to choose between modes such as basic, standard, and strict, depending on their preferences and project requirements.

A compiler option would also be nice to have. I would probably enable it for my own projects if it were available. 😃

---

<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:** [June 16, 2026, 6:55pm UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/17 "2026-06-16T18:55:13Z")

</div>

One more reason to provide an option to require explicit `var` declarations:

> [@Book: Mojo By Example is now updated with changes corresponding to Mojo 1.0.b2](https://forum.modular.com/t/book-mojo-by-example-is-now-updated-with-changes-corresponding-to-mojo-1-0-b2/3242/3):
>
> … the following compiles and runs without issue:
> 
> ```mojo
> comptime counter: Int = 1
> 
> def main():
> # compiler prevents modification of compile time constants... or does it?
> print(counter)
> counter = counter + 3
> print(counter)
> 
> ```
> 
> ```auto
> (mojo-by-example) ➜ mojo 03_constants_variables.mojo
> 1
> 4
> 
> ```
> 
> Inside the function `counter` is implicitly declared as a new local variable shadowing the global constant… tricky!

---

<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:** [June 16, 2026, 7:16pm UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/18 "2026-06-16T19:16:50Z")

</div>

I could open an issue (feature request) on github to add a complier flag like proposed by @samufi :

> [@Block scope vs. function scope of variables](https://forum.modular.com/t/block-scope-vs-function-scope-of-variables/3138/13):
>
> Maybe a good middle ground for now would be to add a compiler argument `--enforce-var` (or `--warn-on-missing-var`) so that people building complex software can spot their potential bugs, and others can keep scripting.

Would the Modular team agree to open such an issue to discuss the details?

---

<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:** [July 6, 2026, 9:20am UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/19 "2026-07-06T09:20:49Z")

</div>

There is already a related issue: [[Feature] make `var` required for variable declarations in `fn` functions · Issue #5841 · modular/modular · GitHub](https://github.com/modular/modular/issues/5841#issuecomment-4891100019)

---

<div class="post-metadata">

**Author:** ![qja](https://avatars.discourse-cdn.com/v4/letter/q/87869e/32.png) [@qja](https://forum.modular.com/u/qja)\
**Post date:** [July 6, 2026, 10:12am UTC](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207/20 "2026-07-06T10:12:51Z")

</div>

I don’t understand the friction here. If you ask me, the concept of a scope is completely arbitrary anyways. For example, why should with statements introduce a new scope?

```mojo
with self.parser_context(Flags.Loop):
    stmt = self.parse_statement()

```

It’s entirely possible to build complex software entirely using implicit variable declarations.

[Next page](https://forum.modular.com/t/provide-an-option-to-require-explicit-var-declarations/3207.md?page=2)
