The case for explicit `read` variable bindings

allowing explicit mut could resolve this inconsistency:

def my_append(my_list: List[Int]):
    my_list.append(0)  
    # Error need to use mut/owned:

def my_append(mut my_list: List[Int]):
    my_list.append(0)  # now it works 

def my_append(ref my_list: List[Int]):
    my_list.append(0)  # error my_list could be immutable since it's parametric


# where as in for loops
def f():
    for my_list in nested:
        my_list.append(0)  # Error use ref/var instead of mut/owned?
    
    for ref my_list in nested:
        my_list.append(0)  # now it works and the ref is mutable

I think if we want to unify arg convention and variable convention we can use:

Convention Read Mutate Move Delete
own :white_check_mark: :white_check_mark: :white_check_mark: :red_question_mark:linear
ref :white_check_mark: :red_question_mark:inferred :cross_mark: :cross_mark:
mut :white_check_mark: :white_check_mark: :cross_mark: :cross_mark:
read :white_check_mark: :cross_mark: :cross_mark: :cross_mark:

I think var comes from the word vary/variable, so it can be easily confused with mut which means mutate - both convey the concept change, so using own instead of var will avoid this confusion.

Both mutable reference and owned variable are mutable/changeable/variable the difference is ownership which the own keyword makes obvious unlike the var keyword.

The case for adding both read - immutable reference and const - immutable owned is to ensure you received a reference and not an owned value, so you would get an error, but I’m not convinced how common it is and if it justify the complexity of adding yet another convention where python has none.
using read for both similar to for loops solves the immutability concerns.

Related: changing the default to read everywhere

2 Likes