vlang / v

Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io
MIT License
35.81k stars 2.17k forks source link

Module Variables #22714

Open StunxFS opened 2 weeks ago

StunxFS commented 2 weeks ago

Describe the feature

Weeks ago, on V's Telegram channel, I had proposed the idea of ​​introducing module variables.

The objective of this idea is to remove __global from the compiler completely, since module variables could replace its function (in a safer and more idiomatic way).

Global variables in V require a flag to work (-enable-globals) and can be accessed from anywhere in the code, plus they are always mutable, making them somewhat unsafe to use.

Additionally, with the implementation of module variables, you could make const stop receiving values ​​that are computed in runtime, because static would fulfill that function perfectly. Then const would receive pure values ​​that can be computed in comptime.

My suggestion is to use the static keyword (already used to declare static variables inside functions) to declare module variables, which can be declared as pub and mut as needed:

// report/report.v
module report

pub static mut errors = int(0)
// main.v
module main

import report

fn main() {
    report.errors += 1
}

Use Case

In addition to what has already been said, the idea is also to make a distinction for constants, which currently receive all types of values ​​(both runtime and comptime), which could confuse new users who are learning V, but come from other languages ​​where const receives pure values ​​that are computed in comptime.

Proposed Solution

No response

Other Information

No response

Acknowledgements

Version used

latest

Environment details (OS name and version, etc.)

anywhere

[!NOTE] You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.

jorgeluismireles commented 2 weeks ago

Like a singleton pattern? Would be able to be shared among threads?

medvednikov commented 2 weeks ago

I like the idea of consts being comptime only.

I don't like having mutable globals in the language, not hidden behind ugly keyword and a compiler flag.

Wajinn commented 2 weeks ago

As a user and upon reading this, have various thoughts about it.

1) Thought the point of keeping global variables was low level and compatibility issues with other languages.

If that is the case, then wouldn't various V users want them to be "accessed from anywhere in the code"? For the turned on global variables to act and be similar to the situation that people are use to in other low level languages... Not quite sure how module variables would be received, when V's __globalis as easily identifiable as const, even for newbies.

2) My understanding is that team V wants to discourage both global and static variable usage.

Some time ago (upon me starting to play with V), I posted this discussion, #13926. The sentiment was for functions to use structs at the module level. Static variables only within functions and inside unsafe.

However, it can be argued that the documentation fails to make this usage clear, with examples of structs replacing usage of global and static variables. This might be leading to confusion or even frustration, because it's a different (even if arguably better) way. I do want to make it clear that I've become accustomed to V's way, and agree with the reasoning, but I do think team V may want to be mindful of the difference for people coming in from other languages.

StunxFS commented 2 weeks ago

Module variables could be used to handle C global variables perfectly, and this could also fix issue #22691, making it so that a module variable can be identified as external and thus used correctly in the code.

module main

@[c_extern('gVar')]
static mut c_var int

fn main() {
    c_var += 1
    println(c_var)
}

Of course, module variables could also be shared safely between threads, as long as the variable is not mutable.