flang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

# Assignment Notation

What should the assignment and definition operators be. Odersky started a discussion about switchin to `:=` for assignment in Scala: Use := for Assignment, a video by Context Free discusses this: Demo Zoo: Assignment, Vars, & Consts.

## Assignment Operations

There basically these operations

• Assignment to a variable, in Java `a = b;`
• Declaration of a new variable, in Java `type a = b;`
• Declaration of a new variable with type inference, in Java `var a = b;`
• Comparison of two values, in Java `a == b`
• Declaration of a routine with result type inference, in Fuzion so far `a => b`

## Considerations

### Mathematical Notation

Using `=` for an assignment is mathemetically very unsatisfactory, code such as `x = x + 1` mathematically does not make sense.

### Discourage Mutation

Assignments are mutations of a variable and should be avoided, declarations should be preferred whenever possible.

### left-to-right execution order

Assignments and declarations are the wrong way around, instead of writing

```  sum := a + b + c
```

a notation that puts the variable at the end represents the flow of execution better, e.g.,

```  a + b + c =: sum;
```

### Assinments for Control Flow

A common reason for assignments are values depending on control flow, e.g.,

```  next i32
if x < 999
next = x + 1
else
next = 0
tailCall(next)  -- some use of next
```

One way to avoid this is statements results that can be used in a declaration:

```  next := if x < 999
x + 1
else
0
tailCall(next)
```

Or maybe using the left-to-right order

```  if x < 999
x + 1
else
0
=: next
tailCall(next)
```

## Assignment as Expression with Result

Having assignments produce a result is an awful idea from a functional perspective: An assignment as part of an expression introduces a side-effect. Even if only used as a declaration of a new variable, this variable can be hidden deep in an expression and toghether with lazy operations, it additionally results in complex visibility rules.

The most convincing example in the big discussion about Python 3.8's walrus operator that I have seen is this loop

```# Python code:
while chunk:
process(chunk)
```

Which can be simplified to

```# Python code:
process(chunk)
```

For Fuzion, the powerful loop syntax instead should allow

```  for chunk := file.read(8192)
while chunk?
{
process(chunk)
}
```

Which avoids the second call to `file.read`. Disregarding the braces, the code essentially adds `chunk` once, which is so little additional typing that it does not justify the complexity of having assignments as expressions.

## Future Fuzion Proposal

• Assignment: `set v := expr`, where `set` indicates to set an existing field. Alternatively `expr =: set v`
• Declaring a new field: `v type := expr` or `expr =: v type`.
• Declaring a new field with type inference: `v := expr` or `expr =: v`.
• Comparison of two values: `a = b`
• Declaration of a routine with result type inference: `a => b`

### Open Questions

Will the `set` keyword in an assignment make the definition more popular?

Are the left-to-right versions too confusing or could they turn out to be useful once one got used to this syntax?

So far, a field is immutable if there is no assinment to it except for the inital assignment. Together with the fact that assignments are not allowed outside of the feature that declares the field, the compiler can easily distinguish mutable from immutable fields. However, do we need better syntax to make this obvious for the human eye, e.g., requiring a keyword such as `var` in the declaration such that we get ```var x i32 := 0``` to declare a mutable field `x`?

## Python, Scala

The assignment operator causes big emotional discussions, Odersky had to step back, Guido van Rossum gave up his postion as BDFL for Python when the walrus operator `:=` was introduced.