Struct Fields – Another Place Where var Feels Out of Place

Yes, that‘s an implicit variable binding inside a function body, but still a variable and not a reference (ref).

You see, and this also works:

def main():
    var first_tuple: Tuple[Int, String] = (1, "Example")
    ref var name: Tuple[Int, String] = first_tuple  # ref + var??
    print(name)

It prints (1, Example).

The point:

So what does var actually mean here? We have two conflicting keywords in one binding (var + ref).

This makes the claim that var is always clear (“always means take ownership/reference”) dubious at best. The syntax is messy, and I hope Mojo cleans this up.

ref var: Yes, that‘s messy. When ref was introduced for function body value bindings, nested var ref a = b value bindings were explicitly marked with a warning to not use this syntax. I think no one used the opposite ref var: Type value binding syntax with type annotation. I‘ll file an issue to warn on this syntax too.

The issue has been fixed in the latest nightly. All redundant nested ref var / var ref value bindings now produce a compile time warning:
nested 'var' or 'ref' patterns are redundant, remove the outer pattern

Additionally the value binding does not get declared and usage of the value binding produces a compile time error:
use of unknown declaration '...'

Example:

def main():
    var a = 1
    ref var b: Int = a  # warning: nested 'var' or 'ref' patterns are redundant, remove the outer pattern

    print(a)
    print(b)  #  error: use of unknown declaration 'b'

This will clarify some confusion concerning the usage and semantics of var vs. ref. Always only use one of the two to declare either a variable (var) or a reference (ref).