Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Prepend module name to procedures?

197 views
Skip to first unread message

Beliavsky

unread,
Nov 2, 2019, 9:44:11 PM11/2/19
to
If module foo contains function bar I write

use foo, only: bar
y = bar(x)

so I know where bar is coming from and so I don't import more from foo than is needed. It would be nice to also be able to write something like

use foo
y = foo::bar(x)

In Python you can write

import numpy
xdot = numpy.dot(x,x)

Has the standards committee considered prepending module names to procedures and module variables? Or is this already in Fortran 2018?

FortranFan

unread,
Nov 2, 2019, 10:17:08 PM11/2/19
to
Current Fortran standard 2018 does not support any kind of 'namespace' concept for MODULEs in Fortran, so qualifying a 'use'd module entity with the module name is not possible.

However, see this proposal at the last J3 meeting in Las Vegas mid-October 2019: https://j3-fortran.org/doc/year/19/19-246.txt

and this issue at the new GitHub site for Fortran proposals:
https://github.com/j3-fortran/fortran_proposals/issues/1

Now, the work-list of items toward Fortran 202X is "frozen", so unless something changes, something like this might get considered for Fortran 202Y where, perhaps, the concept of 'namespace' might get formally recognized and defined in Fortran in conjunction with the MODULE facility and in which case, something along the lines of what is of interest in the original post here might appear in the language. Coders can then hope for reliable implementations in year 203Z, a highly exciting prospect!!?

By the way, I had a similar interest in the same several years ago:
https://groups.google.com/d/msg/comp.lang.fortran/sNNnQaoqC9I/JFAEgsbeAPMJ

John Collins

unread,
Nov 3, 2019, 2:19:36 PM11/3/19
to
In fpt, particularly in interactive mode, you can refer to objects by specifying a full path. So, for example, if you want to get to the type component r in the type labeled_real in the module function myfun in module module_types you write
module_types%myfun%labeled_real%r

We use the delimiter % throughout. I think it would make sense to have a single parent-child delimiter in all cases, not to use, e.g. :: as in the proposal. Could this cause a problem if a module had the same name as a local derived type? Can this happen?

I very much like the proposal because it can provide for the case where two different modules can provide objects with the same name. You can, of course, rename an imported object in the use list, but you can't have a special character to indicate where the parent name ends and the imported name begins.

Best wishes,

John

pkla...@nvidia.com

unread,
Nov 4, 2019, 12:27:14 PM11/4/19
to
You can rename entities that are USE-associated, e.g.

use foo, only :: foo_bar => bar

Ron Shepard

unread,
Nov 4, 2019, 9:18:23 PM11/4/19
to
On 11/4/19 11:27 AM, pkla...@nvidia.com wrote:
> You can rename entities that are USE-associated, e.g.
>
> use foo, only :: foo_bar => bar

As far as I know, however, it is not possible to rename the module
itself. This prevents a programmer from using two different module
libraries that happen to be named the same thing in the same program
unit. That seems like it might be a nice thing to do sometimes, but I
don't really see a good way to implement that functionality.

As for the original question, there are many disadvantages to the idea
of prepending the module name to references of the the entities within
it. The most obvious is that changes within the implementation of the
module might then require changes in the calling program. That pretty
much negates many of the advantages of modules, and of libraries in
general, along with the general idea of abstraction.

However, I do know of other languages that work that way, so I guess it
does not preclude all productivity within the language.

$.02 -Ron Shepard

Beliavsky

unread,
Nov 4, 2019, 9:31:13 PM11/4/19
to
On Monday, November 4, 2019 at 9:18:23 PM UTC-5, Ron Shepard wrote:
> On 11/4/19 11:27 AM, pkla...@nvidia.com wrote:
> > You can rename entities that are USE-associated, e.g.
> >
> > use foo, only :: foo_bar => bar
>
> As far as I know, however, it is not possible to rename the module
> itself. This prevents a programmer from using two different module
> libraries that happen to be named the same thing in the same program
> unit. That seems like it might be a nice thing to do sometimes, but I
> don't really see a good way to implement that functionality.
>
> As for the original question, there are many disadvantages to the idea
> of prepending the module name to references of the the entities within
> it. The most obvious is that changes within the implementation of the
> module might then require changes in the calling program. That pretty
> much negates many of the advantages of modules, and of libraries in
> general, along with the general idea of abstraction.

If I could write

y = foo%bar(x)

the implementation of bar in module foo could change without having to change the calling code. There is only a problem if bar is moved to a module other than foo, but in my code I currently write

use foo, only: bar
y = bar(x)

so my code would need to change in any case. Just writing

use foo

is something I avoid because I want to know where imported procedures and variables are coming from. A USE statement without ONLY is similar to writing

from foo import *

in Python, which is frowned upon.

ga...@u.washington.edu

unread,
Nov 5, 2019, 12:19:44 AM11/5/19
to
On Monday, November 4, 2019 at 6:18:23 PM UTC-8, Ron Shepard wrote:

(snip)

> As far as I know, however, it is not possible to rename the module
> itself. This prevents a programmer from using two different module
> libraries that happen to be named the same thing in the same program
> unit. That seems like it might be a nice thing to do sometimes, but I
> don't really see a good way to implement that functionality.

The naming system for Java packages uses the domain name of
the originator in reverse order. For example:

com.oracle.java.

That way, you don't have to worry about anyone else naming
a package the same, as long as you keep your own names apart.

Ron Shepard

unread,
Nov 5, 2019, 3:07:38 AM11/5/19
to
On 11/4/19 8:31 PM, Beliavsky wrote:
> On Monday, November 4, 2019 at 9:18:23 PM UTC-5, Ron Shepard wrote:
>> On 11/4/19 11:27 AM, pkla...@nvidia.com wrote:
>>> You can rename entities that are USE-associated, e.g.
>>>
>>> use foo, only :: foo_bar => bar
>>
>> As far as I know, however, it is not possible to rename the module
>> itself. This prevents a programmer from using two different module
>> libraries that happen to be named the same thing in the same program
>> unit. That seems like it might be a nice thing to do sometimes, but I
>> don't really see a good way to implement that functionality.

After I posted this, I realized that it is possible after all. The
programmer could define a new module

module foo2
use foo
end module foo2

This basically renames the module from foo to foo2, and it allows both
foo2 and the second foo module to be used in the same program unit. Of
course, when this module is compiled, it would need to identify the
"correct" foo, and then later when the "other" foo is accessed, the
compiler would need to correctly identify that, but as far as the
fortran part itself is concerned, this would at least be a workaround
for the missing rename functionality.

>>
>> As for the original question, there are many disadvantages to the idea
>> of prepending the module name to references of the the entities within
>> it. The most obvious is that changes within the implementation of the
>> module might then require changes in the calling program. That pretty
>> much negates many of the advantages of modules, and of libraries in
>> general, along with the general idea of abstraction.
>
> If I could write
>
> y = foo%bar(x)
>
> the implementation of bar in module foo could change without having to change the calling code.

What if bar() within foo was originally written as a contained
procedure, in which case it would be referenced as above. Then later, it
is decided to refactor the routines and bar() is instead moved into
another module, say "new", which is used by foo. Now the references
would all need to be changed to

y = foo%new%bar(x)

As I said above, this notion is contrary to the idea of abstraction and
libraries. It requires the calling program to know the details of the
implementation of the whole library module hierarchy.

There is only a problem if bar is moved to a module other than foo, but
in my code I currently write
>
> use foo, only: bar
> y = bar(x)
>
> so my code would need to change in any case. Just writing
>
> use foo
>
> is something I avoid because I want to know where imported procedures and variables are coming from.

I do the same thing, I like to know where things come from too, but only
one level at a time. In your example, if bar() is implemented within
module new, then module foo will have something like

module foo
use new, only: bar ! plus whatever else is imported
...
end module foo

Now when module foo is USEd, it is not necessary to know exactly how
bar() was implemented, those details are abstracted, and the calling
program need not be changed if/when those details change in the future.

$.02 -Ron Shepard

Ian Harvey

unread,
Nov 5, 2019, 6:29:21 AM11/5/19
to
On 5/11/2019 5:37 pm, Ron Shepard wrote:
> On 11/4/19 8:31 PM, Beliavsky wrote:
>> On Monday, November 4, 2019 at 9:18:23 PM UTC-5, Ron Shepard wrote:
>>> On 11/4/19 11:27 AM, pkla...@nvidia.com wrote:
>>>> You can rename entities that are USE-associated, e.g.
>>>>
>>>>     use foo, only :: foo_bar => bar
>>>
>>> As far as I know, however, it is not possible to rename the module
>>> itself. This prevents a programmer from using two different module
>>> libraries that happen to be named the same thing in the same program
>>> unit. That seems like it might be a nice thing to do sometimes, but I
>>> don't really see a good way to implement that functionality.
>
> After I posted this, I realized that it is possible after all. The
> programmer could define a new module
>
>    module foo2
>    use foo
>    end module foo2
>
> This basically renames the module from foo to foo2, and it allows both
> foo2 and the second foo module to be used in the same program unit. Of
> course, when this module is compiled, it would need to identify the
> "correct" foo, and then later when the "other" foo is accessed, the
> compiler would need to correctly identify that, but as far as the
> fortran part itself is concerned, this would at least be a workaround
> for the missing rename functionality.

The rules around global identifiers (F2018 19.2) prohibit having two
program units (and hence two modules) with the same identifier within a
program.

Compilers take advantage of this rule when generating linker symbols for
things within modules.

You may be able to trick the compiler into incorporating multiple
modules with the same name into the one program, but the approach is
non-conforming, and may fail if linker symbols do end up clashing.

I'm not sure how much of a problem it is in practice, but the potential
for name clashes amongst global identifiers seems tangible to me.
Nearly all my projects have a module named "Kinds" for instance.
Outside of changes to the language, naming conventions for modules could
be a work around (e.g. rename "Kinds" for project Xyz to Xyz_Kinds).

Ian Harvey

unread,
Nov 5, 2019, 6:56:06 AM11/5/19
to
On 4/11/2019 4:49 am, John Collins wrote:
> In fpt, particularly in interactive mode, you can refer to objects by
> specifying a full path. So, for example, if you want to get to the
> type component r in the type labeled_real in the module function
> myfun in module module_types you write
> module_types%myfun%labeled_real%r
>
> We use the delimiter % throughout. I think it would make sense to
> have a single parent-child delimiter in all cases, not to use, e.g.
> :: as in the proposal. Could this cause a problem if a module had
> the same name as a local derived type? Can this happen?

Language rules prohibit local identifiers for things such as data
objects (you are not sticking `%` onto a "local derived type" now anyway
given the current language) to have the same name as a global identifier
that is used in the scope of the local identifier. Whether all the
restrictions given by those language rules are required has been
debated, for example some people have expressed a desire to be able to
name a module the same as the principle derived type that it defines.

But scope resolution and object selection are two different concepts, as
evidenced by syntax choices made in other languages. Given they are
different concepts, I would avoid using the same syntax. It is also
that the two concepts might be both applicable to things like module or
type names too, in some future language revision.

The language already has a syntax for parent : child style identifiers -
it uses a single colon. Unfortunately in general statements I suspect
that syntax conflicts with construct names.

> I very much like the proposal because it can provide for the case
> where two different modules can provide objects with the same name.
> You can, of course, rename an imported object in the use list, but
> you can't have a special character to indicate where the parent name
> ends and the imported name begins.

It should be bleedingly obvious in 99.99% of cases given some sane
name/prefix convention though, or you are writing some very obtuse source.

Some questions that immediately come to mind:

Things from modules can be accessed by identifiers that are not names.
What happens with them?

Things from modules that are accessible by a name can be combined
together with things from different modules that are accessible by the
same name? What happens with them?

The mere use of one module (and perhaps others going forward) results in
change in behaviour within the relevant scoping unit. Does that still
apply?

Gary Scott

unread,
Nov 5, 2019, 8:20:03 AM11/5/19
to
That's generally what I do, even though "kinds" has the same content in
all apps (presently). However, within a module, all exportable
variables and procedures have a prefix identifying the module from
whence they came. I tend to see all this as attempts to cover up poor
module configuration management practices.

Ron Shepard

unread,
Nov 5, 2019, 11:40:24 AM11/5/19
to
On 11/5/19 5:29 AM, Ian Harvey wrote:
> The rules around global identifiers (F2018 19.2) prohibit having two
> program units (and hence two modules) with the same identifier within a
> program.

I think this is correct. When I read that section, it does seem to allow
intrinsic module names to be overridden, but not normal modules. The
restriction is imposed on the program, and not just a single program
unit as I originally thought.

$.02 -Ron Shepard

FortranFan

unread,
Nov 5, 2019, 1:55:29 PM11/5/19
to
On Tuesday, November 5, 2019 at 3:07:38 AM UTC-5, Ron Shepard wrote:

> ..
> After I posted this, I realized that it is possible after all. The
> programmer could define a new module
>
> module foo2
> use foo
> end module foo2
>
> This basically renames the module from foo to foo2, and it allows both
> foo2 and the second foo module to be used in the same program unit. Of
> course, when this module is compiled, it would need to identify the
> "correct" foo, and then later when the "other" foo is accessed, the
> compiler would need to correctly identify that, but as far as the
> fortran part itself is concerned, this would at least be a workaround
> for the missing rename functionality.
>

No, that is not "basically renames the module from foo to foo2," it is defining a new module. This is not a workaround, it's more like a sledgehammer likely to cause more damage than good.

> ..
> What if bar() within foo was originally written as a contained
> procedure, in which case it would be referenced as above. Then later, it
> is decided to refactor the routines and bar() is instead moved into
> another module, say "new", which is used by foo. Now the references
> would all need to be changed to
>
> y = foo%new%bar(x) ..

No, not if it "is used by foo" and made PUBLIC by it, in which case the proposal will still allow 'y = foo::bar(x)'.

spectrum

unread,
Nov 6, 2019, 5:05:15 AM11/6/19
to
On Tuesday, November 5, 2019 at 10:20:03 PM UTC+9, Gary Scott wrote:
> On 11/5/2019 5:29 AM, Ian Harvey wrote:
...
> > I'm not sure how much of a problem it is in practice, but the potential
> > for name clashes amongst global identifiers seems tangible to me. Nearly
> > all my projects have a module named "Kinds" for instance. Outside of
> > changes to the language, naming conventions for modules could be a work
> > around (e.g. rename "Kinds" for project Xyz to Xyz_Kinds).
>
> That's generally what I do, even though "kinds" has the same content in
> all apps (presently). However, within a module, all exportable
> variables and procedures have a prefix identifying the module from
> whence they came. I tend to see all this as attempts to cover up poor
> module configuration management practices.

Just for confirmation, does the above discussion refer to something like
adding tags to all exported entities manually? (for example, as in "GTK" toolkit routines)

https://en.wikipedia.org/wiki/GTK
https://en.wikipedia.org/wiki/GTK#Example

# In the above example, I guess all exported routines are given a name like gtk_xxx()
and they are "star imported" via an include statement (#include <gtk/gtk.h>).

Gary Scott

unread,
Nov 6, 2019, 8:57:18 AM11/6/19
to
It is what I do, yes. It is a common and long-standing practice. It
makes it "completely" unambiguous.

ga...@u.washington.edu

unread,
Nov 6, 2019, 10:45:17 AM11/6/19
to
On Wednesday, November 6, 2019 at 5:57:18 AM UTC-8, Gary Scott wrote:
> On 11/6/2019 4:05 AM, spectrum wrote:

(snip)
> > # In the above example, I guess all exported routines are given
> > a name like gtk_xxx()
> > and they are "star imported" via an include statement (#include <gtk/gtk.h>).

> It is what I do, yes. It is a common and long-standing practice. It
> makes it "completely" unambiguous.

At least back to OS/360, where IBM gives each separate part
its own three letter prefix, usually starting with I (for IBM).

The compilers and libraries (run-time systems) have separate prefixes.

Also, error messages have the same prefix, making it easier to find
where to look them up.

But to be really unambiguous, you need a system to register the
prefix, such that two different people don't use the same one!

FortranFan

unread,
Nov 6, 2019, 11:15:59 AM11/6/19
to
On Wednesday, November 6, 2019 at 8:57:18 AM UTC-5, Gary Scott wrote:

> ..
> It is what I do, yes. It is a common and long-standing practice. It
> makes it "completely" unambiguous.

It's not a manageable coding convention/style for anything but one's own little "toy" programs or effectively single-developer applications. Any suggestion here one's coding convention/style shall be offered up as a workaround for any need such as in the original post on this thread or with the proposal in the new GitHub Issues forum (https://github.com/j3-fortran/fortran_proposals) is not a respectful argument.

Ron Shepard

unread,
Nov 6, 2019, 11:31:41 AM11/6/19
to
On 11/6/19 7:57 AM, Gary Scott wrote:
>> # In the above example, I guess all exported routines are given a name
>> like gtk_xxx()
>> and they are "star imported" via an include statement (#include
>> <gtk/gtk.h>).
>>
> It is what I do, yes.  It is a common and long-standing practice.  It
> makes it "completely" unambiguous.

This naming convention is what I do also, for certain types of
libraries, but with regard to the original post, I would characterize
this practice as overriding the module hierarchy rather than exposing
it. It achieves the opposite of what was suggested in the original post.

Regarding my other suggestion of renaming modules, consider

module foo
use foo_version_2019
end module foo

Suppose you have several versions of a library, and you want to abstract
which one you are using in your program. This approach allows you to do
that with a single fortran statement. If you change the use statement to

use foo_version_2020

then the rest of the program is good to go. There is no need to edit the
USE statements in the source code throughout your whole program to make
this change, just a single line is sufficient.

And regarding the original post, with the existing module convention
there is of course no need to edit your entire source code to change all
of the "foo_version_2019%bar()" references to "foo_version_2020%bar()"
references.

FortranFan called this a "sledgehammer" approach. That seems a little
harsh. I rather think this is how the language was designed to be used.

$.02 -Ron Shepard
0 new messages