-
Notifications
You must be signed in to change notification settings - Fork 16
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
Allow modules to be nested like in Python #86
Comments
I think that you conflate source file names with module names above. They're actually independent. Can you state the problem you're trying to solve just in terms of module names and Fortran? |
In the above I assume the module name is the same as the file name. I agree the standard does not care about the file name, just the module name. The two use cases I give are already formulated in terms of module names (edit: I see, I updated the above description to be specific that I mean module names, not file names). If you have some specific question, I'll be happy to clarify. |
The set of global identifiers (19.2) is a flat namespace. I think you're proposing that, at least for module names and submodule identifiers (q.v.), that they could be distinct members of an independent set of identifiers associated with a module rather than in the set of global identifiers. If that's right, then I suggest that way to indicate that module
A Does this make sense, or have I missed the point? (EDIT: syntax changed to look more like |
@klausler yes that's exactly what I am proposing. (There might be more details to iron out beyond what you just wrote.) |
That seems quite useful and would be easy to implement. |
Is Or is |
I guess that I was thinking the former rather than the latter, since other parts of the program would contain |
After more reflection: how is this concept any different from using |
@certik wrote:
@certik, I have long debated in my own mind whether Fortran should formally introduce the concept of NAMESPACEs or whether MODULEs can themselves be elevated to first-class namespaces. Looking at your proposal here and with #1, I'm presently inclined toward the former. Whilst I don't quite have a list of the requirements and specifications necessary toward an initial proposal, a sketch of the idea is to include either a new NAMESPACE scope and/or NAMESPACE attribute to MODULEs in addition to PUBLIC/PRIVATE visibility of MODULEs in a NAMESPACE. Then a given NAMESPACE can IMPORT other NAMESPACEs. Fortran can formally define a GLOBAL namespace and state all EXTERNAL MODULEs (a la external procedures) in a program are part of this namespace. The language can then have some rules for name qualification and aliasing. Code then might look like the following with illustrative syntax:
Note the above is based on the use cases in #1 and this one; once more use cases are brought to light, it might help refine the idea of a NAMESPACE. |
@FortranFan would you mind please opening a separate issue for namespaces? Let's discuss it there. Namespaces are another approach how to fix some of the issues reported here, but it is I think premature to decide that modules are dead, namespaces are the way to go, because namespaces have downsides also. We just need to discuss both approaches and see. Update: I created #87 for namespaces. |
Submodules do not allow you to import a symbol from a submodule. For example, let's say you have a parent module TOP and a submodule A. If A defines With nested modules as I am proposing, the TOP module can be empty. You can still put things into it if you want to, but you don't have to. Just like in Python. |
Further advantage of nested modules over submodules: Nested modules would not (should not!) share names via host association. If in a big library you have several levels of sub- modules, e.g. modules, sub-modules, sub-sub-modules, it can become very cumbersome to find out, where a given name comes from. Looking at a name in the sub-sub-module, it can be either something local, something defined in the parent sub-module or in grand-parent module, so you would have to look up 3 files to check for it. I think, submodules are a perfect way to separate interfaces from implementations in order to avoid re-compiling cascades. (For this, you only need modules and one level of submodules.) But I don't think, that they are the right construct for structuring a big library. |
Thanks for the clarification vs. submodules, I think that I understand the distinction. So something like this would work for you?
(with additional extensions to EDIT: Make |
@klausler I think that would work. And I want multiple level of nesting, just like in Python. It's just too bad that submodules were designed the way they were. It's a missed opportunity. I don't know if there is a way to adapt them to do what we want, or if the above must be a separate functionality. |
Even for nested modules it would make sense to divide each of them into an interface part and an implementation part to avoid recompilation cascades. For that, the submodule construct is perfect as it is now. So, I think, what we need is an additional mechanism enabling module nesting. |
Submodules seem entirely complementary to your nested modules. Submodules automatically inherit from their ancestors and supply implementations. Nested modules define interfaces (and implementations) to be composed by their parents. The information flows in opposite directions. |
Yes you are right, indeed the nested modules are exactly the opposite of submodules. So we should have both. |
In Python, the package hierarchy is tightly connected to the directory structure. In Fortran, due to the lack of that concept in the standard, we can not rely on any file system information for the hierarchy. That means the hierarchy information basically reduces to an arbitrary hierarchy-prefix you can add to your modules (a kind of name mangling). The only rule we need, I guess, to require that no module can import any other module being above it in the hierarchy. Connected with namespaces (#1) we could get quite close to what Python offers. And we could still keep the sub-module concept for the separation of interface and implementation. Based on @klausler's suggestion, I am thinking about something like the following:
It could be realized also without namespaces, if that turns out to be a problem, then it would correspond to the |
Use Cases
Module name clashes
It is very common to have modules named
constants.f90
,mesh.f90
,solver.f90
,utils.f90
,types.f90
, etc. (the modules have the same name as the file name in this example). When writing an application this is not a problem. But when writing a library, one cannot name modules like that, because if the application that uses the library also hasconstants.f90
, then the modules will clash. Pretty much the only solution is to name the modules aslibraryname_constants
(usually implemented inlibraryname_constants.f90
). This is suboptimal, because when the application uses any module from the library, it has to type in the long name (e.g.,use libraryname_constants, only: pi
).Distribution
When you distribute a Fortran library, you have to distribute all modules, which can easily be dozens and dozens of
.mod
files, which all end up littering your$PREFIX/include
.Solution
Allow modules to be nested. In Python, one creates the following directory structure:
and then one can import files as follows:
This particular import will become possible in Fortran with #1, but in the meantime one could do the equivalent of this:
This solution fixes both uses cases above. There can be
mylib.constants
and there will be no name clashes. When the library is distributed, it is installed as:Perhaps it could even be:
So there is no littering.
Issues to resolve
The Fortran standard does not talk about files and filesystem. Unless we want to change it, the module nesting feature must be implemented similar to submodules. The exact syntax needs to be figured out.
Why not submodules? Submodules unfortunately do not allow to implement the above use case with
mylib
to be able to import nested modules. With submodules a large Fortran library would have to stop using modules, it would only have one module and lots of small submodules. My understanding is that the submodule can only extend things declared in the main module. So you cannot for example douse mylib%b, only: something
. You would have to havesomething
inmylib.f90
itself. This does not scale for large libraries with hundreds of files.Syntax: Regarding syntax, probably using % would work, to make it consistent with #1, so the above Python imports would translate to:
and
The text was updated successfully, but these errors were encountered: