goatlang / goat

Extended flavor of the Go programming language, aiming for increased value safety and maintainability
MIT License
63 stars 1 forks source link

Const Assignments #3

Open avivcarmis opened 2 years ago

avivcarmis commented 2 years ago

In most other use cases, assignment to a variable is a single-time operation. Const assignments allow preventing accidental shadowing and accidental rewriting of variables, and also allow code authors to convey intent.

Do we want to go with the direction of Kotlin supporting var and val assignments, or we want all assignments to default to const as Rust does with let and let mut?

More context in this blog post section.

avivcarmis commented 2 years ago

One way or the other, we should also address the following:

PaperPrototype commented 1 year ago

I've been thinking of some syntax.

Instead of val or var, how about mut and const

const being used for one time assignment variables, and mut being the usual mutable variable.

some syntax

mut person Person
person.Name = ""

Additionally, Golang's 2 ways of declaring variables with var or := becomes problematic when combined with the shorthand variable syntax:

// mut? or const?
person := Person{}

Instead I propose not only mut and const as variable declarators, but also a new syntax for declaring variables. The core concept would be that the type is always inferred from what is on the right side of the =:

// goat can guess the type based on what is on the right
mut person = Person{}

const person = Person{}

mut floating = 0.0 // defaults to float64

If the type needs to be explicit then casting can be used:

mut floating = float32(0) 
mut integer = int64(0) 

This also has some major side effects (which I find appealing).

You are no longer forced to set struct fields after variable declaration when using var syntax:

mut person Person
person.Name = "Abdiel Lopez"

Instead the following is possible, and is extremely explicit:

mut person = Person{
    Name: "Abdiel Lopez"
}

const person2 = Person{
    Name: "Aviv Carmi"
}
marcelloh commented 1 year ago

I don't see the difference :-(

var person = Person{
    Name: "Abdiel Lopez",
}

or

mut person = Person{
    Name: "Abdiel Lopez",
}
avivcarmis commented 1 year ago

yup, it's the same. I think we're in general agreement. I'll try to gather the thoughts and then we can finalize the small things:

Regarding the keywords themselves, I find const a bit problematic because in go it already is a keyword in go and it does some compiler optimization and allows only primitive types. I thing we should leave this one intact, and simply address which assignments the compiler allows to re-assign to and which not. In addition, i'm joining @marcelloh in saying your mut suggestion is behaving exactly like go's var. In this case I think renaming it will only lead to confusion. So i'm in favor of having var as mutable assignments and something other than const for immutable assignments. My suggestion is either var and val like kotlin and scala, or mut var, which is closer to rust.

avivcarmis commented 1 year ago

@PaperPrototype just to be clear, most of what you've suggested already exist in go: https://go.dev/play/p/B84ynfexzKk