radon-project / radon

The Radon Programming Language
https://radon-project.github.io
GNU General Public License v3.0
21 stars 2 forks source link

Explicit variable declaration #154

Closed angelcaru closed 1 month ago

angelcaru commented 1 month ago

Is your feature request related to a problem? Please describe. Currently there is no distinction between variable assignment and declaration. This is bad because we also have block scoping, so variable assignment inside blocks is unnecessarily cumbersome. (Almost always when I want to assign to a variable I do so inside of an if statement or a loop. These are blocks, so they need the nonlocal keyword to assign variables defined outside)

Describe the solution you'd like

Code examples Old syntax:

x = input_int()
if x < 5 {
    nonlocal x = 5
}
print(x)

New syntax:

var x = input_int()
if x < 5 {
    x = 5
}
print(x)

Old syntax:

list = [1, 2, 3, 4, 5]
sum = 0
for elt in list {
    nonlocal sum += elt
}
print(sum)

New syntax:

var list = [1, 2, 3, 4, 5]
var sum = 0
for elt in list {
    sum += elt
}
print(sum)

Describe alternatives you've considered We could also remove block scoping, but that solution also has its disadvantages.

angelcaru commented 1 month ago

@Almas-Ali What do you think?

Almas-Ali commented 1 month ago

What if I want to declare without var. Will it work with var and also normal assignments?

angelcaru commented 1 month ago

I was thinking that if you try to declare a variable without var it gives an error

Almas-Ali commented 1 month ago

But, I think this clear syntax is good and clean. Adding a keyword with it will look bad.

Almas-Ali commented 1 month ago

var assignment will work similarly to how regular assignment does currently, with the difference being that it gives an error if the variable already exists

We already have const for preventing from re-assignment.

angelcaru commented 1 month ago

Adding a keyword with it will look bad.

May I show you this example from the standard library:

    fun usage(program_name) {
        ret = "Usage: "+program_name+" <flags> <options>\n"
        ret += "OPTIONS:\n"
        for opt in this.pos_opts {
            nonlocal ret += "    " + opt["name"] + ": " + opt["desc"] + "\n"
        }
        ret += "FLAGS:\n"
        for flag in this.flags {
            nonlocal ret += "    " + flag["fullname"] + ", " + flag["shortname"] + ": " + flag["desc"] + "\n"
        }
        for named in this.named {
            nonlocal ret += "    " + named["name"] + " <value>: " + named["desc"] + "\n"
        }
        return ret
    }

And how it would look with my proposed change:

    fun usage(program_name) {
        var ret = "Usage: "+program_name+" <flags> <options>\n"
        ret += "OPTIONS:\n"
        for opt in this.pos_opts {
            ret += "    " + opt["name"] + ": " + opt["desc"] + "\n"
        }
        ret += "FLAGS:\n"
        for flag in this.flags {
            ret += "    " + flag["fullname"] + ", " + flag["shortname"] + ": " + flag["desc"] + "\n"
        }
        for named in this.named {
            ret += "    " + named["name"] + " <value>: " + named["desc"] + "\n"
        }
        return ret
    }

That's not "more keywords"

angelcaru commented 1 month ago

We already have const for preventing from re-assignment.

This is not like that. You would still be able to reassign, just not redeclare

Almas-Ali commented 1 month ago

I got your point. The syntax looks Okay. Not much var like we had initially. I think it will be good addition and we don't have to use nonlocal everywhere.