From: James Giles on
Submodules

I understand that when something is issued as a TR it's
basically already a part of the standard even though it
never went through a public review. However it was the
submodule feature that convinced me that public review is
just as important for TRs as for whole revised standards.

The submodule feature is supposed to have basically three
advantages. First, it provides a way of changing code
within modules without causing compilation cascades.
Second, it provides the ability for vendors to distribute
proprietary code without revealing source while still having
the advantage of interface checking at compile-time. Third,
it allows conceptually nesting of module scopes to any
depth.

At the time submodules were first proposed, several alter-
native ways to address the first two points above were also
proposed. Any of these would have been easier to integrate
into the standard, easier for programmers to learn, and
easier to incorporate into existing programs than submodules.
Submodules were essentially the most verbose and least
convenient of the ways proposed to deal with those issues.

As for the third of the "advantages" of submodules, nesting
of scopes to any depth, is something that I believe the
language shouldn't support. Once upon a time (in the F8x
proposal) internal procedures were permitted to nest to any
depth. The F90 standard (I believe correctly) disallowed
that. For both practical reasons, and because I've read
papers indicating just this point in other languages, I'm
convinced that nesting of program units is counterproductive.

As I said, I'm aware that submodules are already officially
part of the language and nothing I say can reverse that.
If submodules were not themselves also allowed to have
submodules, I probably would not have made any comment at
all - in spite of the verbose way they manage avoidance of
compilation cascades.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare

"Simplicity is prerequisite for reliability" -- E. W. Dijkstra


From: Peter C. Chapin on
James Giles wrote:

> As for the third of the "advantages" of submodules, nesting
> of scopes to any depth, is something that I believe the
> language shouldn't support. Once upon a time (in the F8x
> proposal) internal procedures were permitted to nest to any
> depth. The F90 standard (I believe correctly) disallowed
> that. For both practical reasons, and because I've read
> papers indicating just this point in other languages, I'm
> convinced that nesting of program units is counterproductive.

Do you happen to know any specific references on this topic? I am
interested to know why the nesting of procedures is considered
counterproductive.

Peter
From: Richard Maine on
James Giles <jamesgiles(a)worldnet.att.net> wrote:

> The submodule feature is supposed to have basically three
> advantages.

You missed what I consider to be a significant advantage of submodules.
Admitedly, some of the writeups from the committee have been known to
miss it as well, which probably leads other people to do the same.

To me submodules allow the language to correctly reflect the
dependencies of some codes. This happens to include a lot of my own
codes, but it arrises from a common and useful way of defining things.
To me, the compilation cascade problem was, in many cases, a symptom of
the incorrect dependency. Submodules address the underlying cause
instead of just the symptom. I think it unfortunate that so much
material on submodules just talks about the symptom; in my view, that
does disservice to the feature.

Yes, the main advocate of the submodules TR tended to do diservice to
his own proposal by missing this point. I tried to explain it to him
several times, but though I'd get agreement that this was also an
advantage of submodules, it didn't seem to really "stick", and I'd see
the same disservice done in subsequent papers. Ah well. Up to us book
writers to explain the feature better. The term "submodule" could
probably also be more evocative.

The dependency that submodules correctly express is that of an API. Yes,
I mean pretty much any API, which makes it a large set. Ideally, an API
is defined and then *BOTH* the code that implements the API and the code
that uses it depend on the API definition. That's exactly the structure
that submodules allow. The main module defines the API. You write that
code first. Code that uses the API USEs the module and depends on it.
The code that implements the API is in the submodule, which also depends
on the module. The module does not depend on the submodule. Thus, when
the module implementation changes, code using the module doesn't need to
be recompiled.

I have several applications where the application defines an API for
user-written code that the application calls. For example, my parameter
estimation program specifies an API for user-written code to define the
equations of motion being used. Without submodules, I pretty much can't
distribute my application in any form other than source. Every user has
to make a personal copy of the source and recompile the whole thing. If
a user uses multiple variants of the equations of motion (as is common),
that user needs to maintain multiple copies of the entire application
source. All these multiple copies are a pain in terms of maintenance. It
isn't just a question of the source being proprietary (it isn't); it is
just the maintenance hassle that arises from having to have multiple
copies all over the place.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
From: James Giles on
Peter C. Chapin wrote:
> James Giles wrote:
>
>> As for the third of the "advantages" of submodules, nesting
>> of scopes to any depth, is something that I believe the
>> language shouldn't support. Once upon a time (in the F8x
>> proposal) internal procedures were permitted to nest to any
>> depth. The F90 standard (I believe correctly) disallowed
>> that. For both practical reasons, and because I've read
>> papers indicating just this point in other languages, I'm
>> convinced that nesting of program units is counterproductive.
>
> Do you happen to know any specific references on this topic? I am
> interested to know why the nesting of procedures is considered
> counterproductive.

I had two, and I've turned the place upside-down looking for them.
They were survey papers giving user experiences with the languages
Ada and Modula-2. In both of those languages users have the ability
to nest program units to any depth. Both also have modules (Ada
calls them packages). Modules are considered program units, so
even they can be nested to any depth. Well, both survey papers
noted that users experienced a significant improvement in productivity
if they stopped nesting their code and placed it into modules modules
instead (all procedures in modules and no modules nested at all,
and no nesting within procedures). The Ada paper expressed it
by saying that a flat wide scope topology beats a deep narrow one.
I wish I could find those, but at the time I last saw them Fortran
didn't allow things to arbitrarily nest nad it didin't look like it ever
would, so I didn't think they would ever be important.

There are theoretical reasons that nesting might be harmful. The
whole point of modules is to divide a large project into several
smaller ones that can be independently develop, write, and test.
It's almost a tautology, but adding dependencies makes those
pieces less independent. Scope nesting is a rather stronger
kind of dependency than separate modules that inter-depend
by only USE association.

There are practical problems with nesting. Suppose two distant
cousins in the nesting topology need to share access to something:
you have to declare it in some common ancestor of both. It will
look incongruously out of place there and program units in-between
will have it in their namespaces. If you discover a third cousin that
also needs access, the shared item will likely need to move up.
If the shared entity is itself a procedure, it will likely drag things
it needs to share to yet other different locals. It becomes a non-
trivial problem.

Now you might object that if two cousins need access to some
shared item, that item should be placed in a module that's outside
the hierarchy of nesting and the two cousins should USE that
module. Then, if a third cousin needed to share the same item,
you would just add the appropriate USE in that third place.
But wait a minute, if you had designed the code that way in
the first place you wouldn't have needed the nesting at all.
And that's the point. When people stopped nesting and started
USEing, their productivity went up.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare

"Simplicity is prerequisite for reliability" -- E. W. Dijkstra


From: James Giles on
Richard Maine wrote:
....
> The dependency that submodules correctly express is that of an API.
> Yes, I mean pretty much any API, which makes it a large set. Ideally,
> an API is defined and then *BOTH* the code that implements the API
> and the code that uses it depend on the API definition. That's
> exactly the structure that submodules allow. The main module defines
> the API. You write that code first. Code that uses the API USEs the
> module and depends on it. The code that implements the API is in the
> submodule, which also depends on the module. The module does not
> depend on the submodule. Thus, when the module implementation
> changes, code using the module doesn't need to be recompiled.
>
> I have several applications where the application defines an API for
> user-written code that the application calls. For example, my
> parameter estimation program specifies an API for user-written code
> to define the equations of motion being used. Without submodules, I
> pretty much can't distribute my application in any form other than
> source. Every user has to make a personal copy of the source and
> recompile the whole thing. If a user uses multiple variants of the
> equations of motion (as is common), that user needs to maintain
> multiple copies of the entire application source. All these multiple
> copies are a pain in terms of maintenance. It isn't just a question
> of the source being proprietary (it isn't); it is just the
> maintenance hassle that arises from having to have multiple copies
> all over the place.

Yes, it true that every API needs to specify its interface separately
from its implementation. There were several alternatives to submodules
that could also accomplish that. I'm pretty sure all those would have
permitted you to do what you are describing (in one way or another).
It's hard to tell though. Perhaps if wrote a specific example of what
you want to do and why alternatives wouldn't work you could have got
your point across easier. I still don't see anything new here. But, the
armwaving vagueness may be distracting me from your point.

I can even think of one thing that nesting does that can't be done
any other way (without some new feature). But no one has ever
even mentioned it in connection with submodules. I call the idea
to deal with it "parochial scope". Perhaps you can figure out the
feature from the name? I still don't tink arbitrary nesting levels are
the answer to anything.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare

"Simplicity is prerequisite for reliability" -- E. W. Dijkstra