Skip to content

Confusion between v modules and subdirectoriesΒ #17232

Closed

Description

@bakul

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

Activity

  1. added
    BugThis tag is applied to issues which reports bugs.
    on Feb 6, 2023
  2. JalonSolov commented on Feb 6, 2023

    @JalonSolov
    Collaborator

    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.

  3. bakul commented on Feb 6, 2023

    @bakul
    ContributorAuthor

    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.

  4. JoanaBLate commented on Feb 6, 2023

    @JoanaBLate

    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.

  5. StunxFS commented on Feb 8, 2023

    @StunxFS
    Contributor

    Maybe something like:

    import os // from vlib
    import .os // from cwd
  6. JoanaBLate commented on Feb 9, 2023

    @JoanaBLate

    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.

  7. StunxFS commented on Feb 9, 2023

    @StunxFS
    Contributor

    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
  8. JalonSolov commented on Feb 9, 2023

    @JalonSolov
    Collaborator

    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.

  9. StunxFS commented on Feb 9, 2023

    @StunxFS
    Contributor

    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

  10. JoanaBLate commented on Feb 9, 2023

    @JoanaBLate
    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
  11. bakul commented on Apr 24, 2026

    @bakul
    ContributorAuthor

    Still not clear what to do when there is a local module foo as well as a vlib standard module foo and one needs to access them both. I can use as to rename it but my attempts at dealing with failed. This should be documented, hopefully with an example or two. Also note that ideally this does not rely on a sitename or a rooted path so that moving the entire module to a new path does not require any source changes as long as they reference local submodules. Thanks!

    In particular, the standard name space and local name space should be kept separate so that each can evolve independently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugThis tag is applied to issues which reports bugs.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions