Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introducing Internal Modules to V #21976

Closed
2 tasks
geekstakulus opened this issue Jul 31, 2024 · 10 comments
Closed
2 tasks

Introducing Internal Modules to V #21976

geekstakulus opened this issue Jul 31, 2024 · 10 comments
Labels
Feature/Enhancement Request This issue is made to request a feature or an enhancement to an existing one.

Comments

@geekstakulus
Copy link

geekstakulus commented Jul 31, 2024

Describe the feature

V's modularity is a strength, but the current system lacks the ability to restrict sub-module visibility, something akin to Go's way of doing it with the internal modules approach. This proposal suggests introducing module visibility, providing a mechanism for better code organization, encapsulation, and testing.

Use Case

Currently, V doesn't have a way of restricting visibility of the sub-modules to its parent module and siblings. This can lead to:

  • Exposure of internal implementation details: exposure of unnecessary implementation details to any module, making code harder to maintain and refactor.
  • Tight coupling: Excessive dependencies between modules can hinder code re-usability and testing.
  • Lack of clear module boundaries: Without clear distinctions between public and private modules, code organization can become less effective.

Proposed Solution

We can approach this in two ways:

  • Syntax based
  • Folder structure similar to how Go handles internal modules

Syntax Approach

  • Introduce a new keyword, internal or private, to create an internal module.

Example:

internal module mymodule or private module mymodule

Folder Structure Approach

With this approach we would create a folder internal inside the parent module, just like it is handled in Go.

Behaviour

This approach would allow the following behaviour:

  • Visibility:
    • Elements declared with an internal or private keyword, or placed inside an internal module are accessible only from its immediate ancestor and sibling modules.
    • Private components are only accessible from the same module just like for ordinary modules
    • Other modules from outside the parent module cannot import or use elements from these modules.
  • Testing:
    • Internal modules can be tested using internal test files within the same module.
    • External tests cannot access internal modules or their elements, unless they are sibling modules or direct ancestor module.

Benefits

  • Improved code organization: Internal modules allow for better separation of concerns and code encapsulation.
  • Enhanced code maintainability: By hiding implementation details, code becomes easier to modify and refactor.
  • Increased code reusability: Reducing dependencies between modules promotes better code modularity.
  • Better testing: Internal modules facilitate focused unit testing without exposing unnecessary details.

Other Information

Potential Considerations

  • Compatibility: Ensure backward compatibility with existing code.
  • Performance: Evaluate potential performance implications of introducing internal modules.

Acknowledgements

  • I may be able to implement this feature request
  • This feature might incur a breaking change

Version used

0.4.7

Environment details (OS name and version, etc.)

V full version: V 0.4.7 bf04adc
OS: linux, Ubuntu 22.04.4 LTS
Processor: 4 cpus, 64bit, little endian, Intel(R) Core(TM) i5-4570 CPU @ 3.20GHz

getwd: /home/viegasfh/workspace/v/learning
vexe: /home/viegasfh/.local/share/v/v
vexe mtime: 2024-07-28 20:16:09

vroot: OK, value: /home/viegasfh/.local/share/v
VMODULES: OK, value: /home/viegasfh/.vmodules
VTMP: OK, value: /tmp/v_1000

Git version: git version 2.34.1
Git vroot status: weekly.2023.42-1771-gbf04adcc (20 commit(s) behind V master)
.git/config present: true

CC version: cc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
thirdparty/tcc status: thirdparty-linux-amd64 a0799a5b

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.

@geekstakulus geekstakulus added the Feature/Enhancement Request This issue is made to request a feature or an enhancement to an existing one. label Jul 31, 2024
@JalonSolov
Copy link
Contributor

Actually, the only thing public by default in a V module is the module name. All structs, fields in structs, receiver methods, constants, functions, etc. must be marked with the pub keyword to make them public (with none of the Go nonsense of the capitalization of the first letter of a name controlling public vs private).

@geekstakulus
Copy link
Author

geekstakulus commented Jul 31, 2024

Actually, the only thing public by default in a V module is the module name. All structs, fields in structs, receiver methods, constants, functions, etc. must be marked with the pub keyword to make them public (with none of the Go nonsense of the capitalization of the first letter of a name controlling public vs private).

That's what I meant by modules being public by default. That means that they can be imported from anywhere. This proposal is to restrict that.

Thanks for your input!

PS: I also prefer the pub keyword over the capitalization used in Go, but that doesn't stop me from coding in Go.

@JalonSolov
Copy link
Contributor

I code in Go all day at work.

I don't understand the problem of a module name being public. You can import it all day, but if nothing in it is marked public, you can't do anything with it... you just have a "dead" import.

@geekstakulus
Copy link
Author

I code in Go all day at work.

I don't understand the problem of a module name being public. You can import it all day, but if nothing in it is marked public, you can't do anything with it... you just have a "dead" import.

If you work in Go all day, then you know why internal modules exist, right? It is basically the same concept as Go's internal modules.

@JalonSolov
Copy link
Contributor

Yes, I know they exist, and they do it by directory structure, not keywords.

An import of a path containing the element “internal” is disallowed if the importing code is outside the tree rooted at the parent of the “internal” directory.

Never used them - never saw the need. However, I understand that some might like "hiding" modules. I was mainly responding to your quote that everything in V modules is public, which it isn't. Only the module names are public by default, not the contents.

@geekstakulus
Copy link
Author

Yes, I know they exist, and they do it by directory structure, not keywords.

An import of a path containing the element “internal” is disallowed if the importing code is outside the tree rooted at the parent of the “internal” directory.

Never used them - never saw the need. However, I understand that some might like "hiding" modules. I was mainly responding to your quote that everything in V modules is public, which it isn't. Only the module names are public by default, not the contents.

OK, reading again, I agree that the wording makes it seem that it is all public by default, but what is meant is that the module itself is public, not its contents. If you make something public (struct, function, etc..), then all modules can import it. There is no way of limiting this to only the parent module and sibling modules.

I will change the wording to reflect this.

Thanks once again!

@geekstakulus
Copy link
Author

As for the keyword, it was mainly because when I asked if it was supported in V, someone mentioned it. I don't really care if it uses a directory "internal" or if it uses a keyword. I have only suggested the two ways for discussion.

@medvednikov
Copy link
Member

Many people think it's unnecessary. I feel like we should copy Go's behavior and allow internal modules. Easy to do by just comparing the name to internal.

@geekstakulus
Copy link
Author

Many people think it's unnecessary. I feel like we should copy Go's behavior and allow internal modules. Easy to do by just comparing the name to internal.

Hi, Alex!

I think that'll do. Thanks for your input!

@Delta456
Copy link
Member

Delta456 commented Aug 1, 2024

Better turn this into a GitHub discussion

@vlang vlang locked and limited conversation to collaborators Aug 1, 2024
@Delta456 Delta456 converted this issue into discussion #21978 Aug 1, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Feature/Enhancement Request This issue is made to request a feature or an enhancement to an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants