Skip to content

Allow modules to be nested like in Python #86

Open
@certik

Description

@certik

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 has constants.f90, then the modules will clash. Pretty much the only solution is to name the modules as libraryname_constants (usually implemented in libraryname_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:

mylib
├── a.py
├── b.py
└── __init__.py

and then one can import files as follows:

>>> import mylib
>>> import mylib.a
>>> import mylib.b

This particular import will become possible in Fortran with #1, but in the meantime one could do the equivalent of this:

>>> from mylib import something
>>> from mylib.a import something
>>> from mylib.b import something

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:

$PREFIX/include/mylib.mod
$PREFIX/include/mylib/a.mod
$PREFIX/include/mylib/b.mod

Perhaps it could even be:

$PREFIX/include/mylib/__module__.mod
$PREFIX/include/mylib/a.mod
$PREFIX/include/mylib/b.mod

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 do use mylib%b, only: something. You would have to have something in mylib.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:

use, namespace :: mylib
use, namespace :: mylib%a
use, namespace :: mylib%b
...
call mylib%a%something()

and

use mylib, only: something
use mylib%a, only: something
use mylib%b, only: something
...
call something()

Metadata

Metadata

Assignees

No one assigned

    Labels

    Clause 14Standard Clause 14: Program units

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions