v
v copied to clipboard
Confusion between v modules and subdirectories
Describe the bug
If the code has "import os" and it is in a directory with a subdir called "os" the compilation fails if the subdir "os" has no .v files.
Expected Behavior
Program run correctly.
Current Behavior
$ v run x.v
x.v:2:1: builder error: cannot import module "os" (no .v files in "/home/bakul/src/v-lang/os")
1 | module main
2 | import os
| ~~~~~~~~~
3 | fn main() { println(os.args) }
Reproduction Steps
$ mkdir os
$ cat > x.v <EOF
module main
import os
fn main() { println(os.args) }
EOF
$ v run x.v
Possible Solution
No response
Additional Information/Context
v should not usurp local name space. Suggest looking at how go handles this.
V version
Any
Environment details (OS name and version, etc.)
all
Although V is similar to Go, it is not Go.
V uses subdirs as local modules. This means if you have a local subdir which matches a V standard lib module, V is going to look at your local subdir instead of the standard lib module.
This is a very useful feature, allowing you to make changes without affecting the standard lib files.
Go has a lot of problems doing something similar.
This is a very useful feature, allowing you to make changes without affecting the standard lib files.
This is not a common use pattern. Worse, it will confuse users. There should be a distinct way of referring to modules in local subdir vs standard modules.
While I am reading someone's V code, if I read "import os", there is no reason for considering that the imported module is not the one in the standard vlib. I think some special annotation that clearly states "this is not from vlib" is necessary.
Maybe something like:
import os // from vlib
import .os // from cwd
Maybe something like:
import os // from vlib import .os // from cwd
@StunxFS
I like your syntax.
Now, after seeing your sample, I started to wonder what happens if someone writes code exactly like that, importing 2 "os" modules. I know it is not advisable. But how should V handle this case?
Obviously, in the code we would need a syntax for differentiating the call to the vlib 'os' from the call to the custom 'os'.
So, calls to custom 'os' would have to be prefixed with ".". But that conflicts with the syntax for enums.
I remember that V uses '@' for escaping reserved words. Maybe we could use the same syntax ('@os') everywhere (imports and functions).
On a second thought, it is easy to create hard to find bugs if the programmer forgets the prefix ('@') when calling a function that both modules have.
And I fear that step by step V becomes less simple and small than what it intended to be.
The most simple solution is not to allow modules with names that match builtin V modules at all.
If someone really needs a custom module called 'os'. It just name it as 'myos'. Absolutely clear. No need for adding any special rule to the language.
The most simple solution is not to allow modules with names that match builtin V modules at all.
@JoanaBLate as simple as this
import os // from vlib
import .os as my_os // from cwd
That's not simple, though. It would require modifications to V syntax, compiler, etc.
"Simple" is just naming your own module my_os
(or anything else that doesn't collide with a V standard module) instead of os
.
Isn't it simple? For me it is, also that syntax would also help to differentiate imports of local or installed modules in ~/.vmodules
or those of vlib
import os // from vlib import .os as my_os // from cwd
It is indeed simple, but since you agree to use the prefix "my_os" (inside functions), all you need is to name your module as "my_os":
- you write the module "my_os"
- you import "my_os"
- you call "my_os" functions