In the old days, I had several routines in one file and of course COMMON
blocks for global variables. If variables were needed by only a subset
of the routines, then I had these in a COMMON block which was present in
these routines only.
I'm glad that modules are better than COMMON for global variables.
However, is there an analog to the subset strategy? Sure, I can just
use a module variable, but this is the equivalent of "declared but never
used", which one would otherwise avoid. Sure, inheritance is a feature
of modules, and of course variables from the module are visible by
routines unless local variables of the same name are declared. If these
are global module variables, then presumably they are needed by several
routines and/or the program using the module. Variables used only by
only a couple of routines, however, shouldn't be available to the
program using the module.
One could break the module into several modules, grouped by routines,
but then things get too complicated. One could continue to use COMMON
in these cases. :-|
Is there an elegant solution?
I want to avoid thinking I am using a local variable but am actually
using a global variable of the same name. IMPLICIT NONE won't help here
since of course I can use by mistake variables not declared in the
routine if they are global module variables.
Is there an elegant solution?
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
5/30/2012 8:16:57 PM |
|
On 5/30/2012 3:16 PM, Phillip Helbig---undress to reply wrote:
....
> ...If these
> are global module variables, then presumably they are needed by several
> routines and/or the program using the module. Variables used only by
> only a couple of routines, however, shouldn't be available to the
> program using the module.
>
> One could break the module into several modules, grouped by routines,
> but then things get too complicated. One could continue to use COMMON
> in these cases. :-|
>
> Is there an elegant solution?
>
> I want to avoid thinking I am using a local variable but am actually
> using a global variable of the same name. IMPLICIT NONE won't help here
> since of course I can use by mistake variables not declared in the
> routine if they are global module variables.
>
> Is there an elegant solution?
Is there an echo in here...in here...in here??? :)
USE ONLY ! maybe ????
I'd agree it's only elegant in the case of including a few out of larger
module, "not so much" for excluding only a few. I know there has been
discussion here about something like the corollary of ONLY like "EXCEPT"
but afaik it's not been implemented.
--
|
|
0
|
|
|
|
Reply
|
none1568 (6651)
|
5/30/2012 8:27:13 PM
|
|
Phillip Helbig---undress to reply <helbig@astro.multiclothesvax.de> wrote:
> In the old days, I had several routines in one file and of course COMMON
> blocks for global variables. If variables were needed by only a subset
> of the routines, then I had these in a COMMON block which was present in
> these routines only.
> I'm glad that modules are better than COMMON for global variables.
> However, is there an analog to the subset strategy? Sure, I can just
> use a module variable, but this is the equivalent of "declared but never
> used", which one would otherwise avoid.
(snip)
> One could break the module into several modules, grouped by routines,
> but then things get too complicated. One could continue to use COMMON
> in these cases. :-|
You can replace each COMMON with a corresponding module, with
the same variables. That is, group exactly the same way as you
grouped the COMMONs. (Whether or not the modules contain any
module procedures to go with the variables.)
> Is there an elegant solution?
> I want to avoid thinking I am using a local variable but am actually
> using a global variable of the same name. IMPLICIT NONE won't help here
> since of course I can use by mistake variables not declared in the
> routine if they are global module variables.
It seems to me that it depends on what kind of program you
are working on.
If you write routines that have other uses than the current
program, you should try to write them such that those other
uses can easily adapt to the routines.
Often Fortran programs are written that have no other uses,
and many times those programs are very large. My usual example
is a program for weather forecasting, which might have a large
array containing the temperature and pressure at different
points around the earth. Such an array will likely need to
be referenced in many different places, such that it makes
sense for it to be really global.
It is usually best to try to group variables by function
instead of where they are used. Hopefully the two overlap,
but not always.
Modules variables aren't magic. Mostly they work the same way
as COMMON variables, but avoid some of the worst problems
with COMMON. (I will guess that you can't EQUIVALENCE to a
module variable with an array longer than the one equivalenced,
such that matrix elements equivalence to later variables.)
INCLUDE, I believe came as a DEC extension which was often used
to include the exact same COMMON and variable declarations in
many places. That helped against some of the COMMON problems,
but not all.
-- glen
|
|
0
|
|
|
|
Reply
|
gah (12258)
|
5/30/2012 8:37:00 PM
|
|
Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de>
wrote:
> In the old days, I had several routines in one file and of course COMMON
> blocks for global variables. If variables were needed by only a subset
> of the routines, then I had these in a COMMON block which was present in
> these routines only.
>
> I'm glad that modules are better than COMMON for global variables.
> However, is there an analog to the subset strategy?...
> One could break the module into several modules, grouped by routines,
> but then things get too complicated. One could continue to use COMMON
> in these cases. :-|
I don't apear to understand something about the question - at least the
bit referring to COMMON. You can do exactly the same thing with modules
as you could with COMMON in terms of putting subsets of the variables in
different modules. That seems no more and no less complicated than it
was with COMMON; rather it seems identical. Most of the work involved is
in deciding on the organization. So if you are saying that using COMMON
might be an approach to the solution, then I'm obviously missing
something.
See also the ONLY option on the USE statement, but that seems minor
compared to whatever confusion there is about modules being more
complicated than COMMON in this area.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
|
|
0
|
|
|
|
Reply
|
nospam47 (9742)
|
5/30/2012 8:52:29 PM
|
|
Richard Maine <nospam@see.signature> wrote:
> Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de>
> wrote:
>> In the old days, I had several routines in one file and of course COMMON
>> blocks for global variables. If variables were needed by only a subset
>> of the routines, then I had these in a COMMON block which was present in
>> these routines only.
(snip)
> I don't apear to understand something about the question - at least the
> bit referring to COMMON. You can do exactly the same thing with modules
> as you could with COMMON in terms of putting subsets of the variables in
> different modules. That seems no more and no less complicated than it
> was with COMMON; rather it seems identical. Most of the work involved is
> in deciding on the organization. So if you are saying that using COMMON
> might be an approach to the solution, then I'm obviously missing
> something.
That is exactly what I thought, though I wrote my reply in a
different way.
It seems to me that the OP is expecting something magically
different to happen with modules that removes the problems
of having to determine where each variable is used.
It would seem that one could write a program that would replace
all the COMMON in a program with the appropriate USE statements,
and generate the appropriate MODULEs to go with them.
I would probably do it in two passes, to correctly handle the
case where variables have different names in different routines.
-- glen
|
|
0
|
|
|
|
Reply
|
gah (12258)
|
5/30/2012 9:22:01 PM
|
|
In article <jq5vr5$d1$1@speranza.aioe.org>, dpb <none@non.net> writes:
> USE ONLY ! maybe ????
>
> I'd agree it's only elegant in the case of including a few out of larger
> module, "not so much" for excluding only a few. I know there has been
> discussion here about something like the corollary of ONLY like "EXCEPT"
> but afaik it's not been implemented.
Not in this case. Think of several routines all in one module. All the
routines inherit the global module variables. In most cases, this is
what I want. But what if, say, just 2 routines need to share a
variable; is there any alternative to having them all share it?
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
5/30/2012 9:31:22 PM
|
|
In article <jq60dc$1sj$1@speranza.aioe.org>, glen herrmannsfeldt
<gah@ugcs.caltech.edu> writes:
> > One could break the module into several modules, grouped by routines,
> > but then things get too complicated. One could continue to use COMMON
> > in these cases. :-|
>
> You can replace each COMMON with a corresponding module, with
> the same variables. That is, group exactly the same way as you
> grouped the COMMONs. (Whether or not the modules contain any
> module procedures to go with the variables.)
Right, but then I have several modules, whereas I want one module in one
file containing all the routines, since it makes sense only to use them
all together.
I've heard about submodules, but my compiler is too old. Would they be
relevant here?
What I would like:
MODULE FOOBAR
CONTAINS
SUBROUTINE A
SUBROUTINE B
SUBROUTINE C
USE SHARED_STUFF CD
SUBROUTINE D
USE SHARED_STUFF CD
SUBROUTINE F
SUBROUTINE G
SUBROUTINE H
SUBROUTINE I
SUBROUTINE J
SHARED_DATA CD
!stuff used only by C and D
END MODULE FOOBAR
In other words, a special type of module object which is contained
within a main module, like contained routines, but which is not visible
by default but can be used like an external module.
I suppose I could do this:
MODULE FOOBAR
CONTAINS
SUBROUTINE A
SUBROUTINE B
SUBROUTINE C
USE KLIMBIM
SUBROUTINE D
USE KLIMBIM
SUBROUTINE F
SUBROUTINE G
SUBROUTINE H
SUBROUTINE I
SUBROUTINE J
END MODULE FOOBAR
MODULE KLIMBIM
!stuff used only by C and D
END MODULE KLIMBIM
These could all be in one file. The main program would use only FOOBAR.
FOOBAR would use KLIMBIM.
This would have the same functionality. What I don't like about it is
that the main program COULD use KLIMBIM. Also, I would have to make
sure that no other module is named KLIMBIM. If KLIMBIM were contained
within FOOBAR, things would be more modular.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
5/30/2012 9:40:13 PM
|
|
In article <1kkwu4s.d0z0hmsy0js0N%nospam@see.signature>,
nospam@see.signature (Richard Maine) writes:
> I don't apear to understand something about the question - at least the
> bit referring to COMMON. You can do exactly the same thing with modules
> as you could with COMMON in terms of putting subsets of the variables in
> different modules. That seems no more and no less complicated than it
> was with COMMON; rather it seems identical. Most of the work involved is
> in deciding on the organization. So if you are saying that using COMMON
> might be an approach to the solution, then I'm obviously missing
> something.
I think my original post wasn't clear. Yes, one could translate COMMON
to MODULES. However, all these modules are on equal footing. Another
way of saying what I want: some sort of special module which can be used
only by certain routines (say, ones in the same regular module as this
special module).
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
5/30/2012 9:42:04 PM
|
|
In article <jq631p$9gf$1@speranza.aioe.org>, glen herrmannsfeldt
<gah@ugcs.caltech.edu> writes:
> It would seem that one could write a program that would replace
> all the COMMON in a program with the appropriate USE statements,
> and generate the appropriate MODULEs to go with them.
One could do this. One has the same problem with COMMON: If routines A
and B need to share date through COMMON, and C and D do as well, through
another COMMON block, one has to take into account that these two COMMON
blocks have to have different names, one can use them by mistake etc.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
5/30/2012 9:44:10 PM
|
|
On 2012-05-31 7:31 AM, Phillip Helbig---undress to reply wrote:
> In article<jq5vr5$d1$1@speranza.aioe.org>, dpb<none@non.net> writes:
>
>> USE ONLY ! maybe ????
>>
>> I'd agree it's only elegant in the case of including a few out of larger
>> module, "not so much" for excluding only a few. I know there has been
>> discussion here about something like the corollary of ONLY like "EXCEPT"
>> but afaik it's not been implemented.
>
> Not in this case. Think of several routines all in one module. All the
> routines inherit the global module variables. In most cases, this is
> what I want. But what if, say, just 2 routines need to share a
> variable; is there any alternative to having them all share it?
Submodules :)
|
|
0
|
|
|
|
Reply
|
ian_harvey (217)
|
5/30/2012 9:57:31 PM
|
|
In article <jq647c$i6t$3@online.de>,
Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de> wrote:
>
>I think my original post wasn't clear. Yes, one could translate COMMON
>to MODULES. However, all these modules are on equal footing. Another
>way of saying what I want: some sort of special module which can be used
>only by certain routines (say, ones in the same regular module as this
>special module).
>
It sounds to me like the term you are groping for is 'private'.
MODULE FOOBAR
[real,integer,whatever], private : stuff used only by C and D
CONTAINS
SUBROUTINE A
SUBROUTINE B
SUBROUTINE C
SUBROUTINE D
SUBROUTINE F
SUBROUTINE G
SUBROUTINE H
SUBROUTINE I
SUBROUTINE J
END MODULE FOOBAR
Yes, 'stuff' remains accessible to A, B, and F-J, as well as C and D. But
it can't be accessed by any program using FOOBAR, which is what it sounds
like you're worrying about.
--
Kathy Rages
|
|
0
|
|
|
|
Reply
|
rages1 (7)
|
5/30/2012 10:22:04 PM
|
|
In article <QZOdnSPxV_IRAFvSnZ2dnUVZ_omdnZ2d@posted.internetamerica>,
Kathy Rages <rages@darkstar.arc.nasa.gov> wrote:
>In article <jq647c$i6t$3@online.de>,
>Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de> wrote:
>>
>>I think my original post wasn't clear. Yes, one could translate COMMON
>>to MODULES. However, all these modules are on equal footing. Another
>>way of saying what I want: some sort of special module which can be used
>>only by certain routines (say, ones in the same regular module as this
>>special module).
>>
>
>It sounds to me like the term you are groping for is 'private'.
>
>MODULE FOOBAR
>[real,integer,whatever], private : stuff used only by C and D
Correction:
[real,integer,whatever], private :: stuff used only by C and D
>CONTAINS
>SUBROUTINE A
>SUBROUTINE B
>SUBROUTINE C
>SUBROUTINE D
>SUBROUTINE F
>SUBROUTINE G
>SUBROUTINE H
>SUBROUTINE I
>SUBROUTINE J
>END MODULE FOOBAR
>
>Yes, 'stuff' remains accessible to A, B, and F-J, as well as C and D. But
>it can't be accessed by any program using FOOBAR, which is what it sounds
>like you're worrying about.
--
Kathy Rages
|
|
0
|
|
|
|
Reply
|
rages1 (7)
|
5/30/2012 10:28:13 PM
|
|
Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de>
wrote:
> In article <1kkwu4s.d0z0hmsy0js0N%nospam@see.signature>,
> nospam@see.signature (Richard Maine) writes:
>
> > I don't apear to understand something about the question - at least the
> > bit referring to COMMON. You can do exactly the same thing with modules
> > as you could with COMMON in terms of putting subsets of the variables in
> > different modules. That seems no more and no less complicated than it
> > was with COMMON; rather it seems identical. Most of the work involved is
> > in deciding on the organization. So if you are saying that using COMMON
> > might be an approach to the solution, then I'm obviously missing
> > something.
>
> I think my original post wasn't clear. Yes, one could translate COMMON
> to MODULES. However, all these modules are on equal footing. Another
> way of saying what I want: some sort of special module which can be used
> only by certain routines (say, ones in the same regular module as this
> special module).
No, there's nothing like that. But then COMMON isn't like that either.
You can choose to include a COMMON block only in certain routines, but
you can also choose where you USE a module in pretty much the same way.
It was your implication that COMMON could somehow solve the problem that
I didn't understand. I understand that there can be lots of
complications in structuring things well, and that sometimes it doesn't
work out as cleanly as one might hope. But I don't see the "well then I
could use COMMON" as though that would help in any way.
Without a lot more detail (and spending more thought on it than I'd
probably want to invest), I might think that breaking your big module
into smaller ones might be in order. Not so if the variables in question
just happen to be used in only a subset of the routines in a module, but
if there are subsets of routines that inherently share substantial
information only within the subset, that sounds to me like the subset
belongs in its own module anyway - not just because it happens to share
some variables but perhaps because it probably has other coherence. Yes,
that adds extra modules, but I think you are stuck in that "magic" isn't
going to happen. Either you'll have to organize the subsets (in which
case it might as well be into modules), or you won't have them.
I'm not sure that submodules are necessarily an answer to what I'm
hearing. I'm just talking about breaking the large module into multiple
"ordinary" modules (as opposed to submodules). So no fancy f2003+
compiler required. Submodules might help with some parts, but I don't
see them as required. There are places where I see them as almost
required, but this isn't doesn't seem like one of those places.
I sometimes end up with a 3-layer structure somewhat like
module top_level_one
USE all the others
this is what gets used by "outsiders", who don't need to even see
the lower-level structure.
end module
module common_stuff
This bottom_level module has stuff that might be shared among
all the others.
It doesn't USE anything else.
end module
module a_mid_level_one
USE common_stuff
and might have other things private to itself.
end module
module another_mid_level_one
USE common_stuff
and things of its own.
end module
... more mid-level ones.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
|
|
0
|
|
|
|
Reply
|
nospam47 (9742)
|
5/31/2012 12:08:50 AM
|
|
In article <QZOdnSPxV_IRAFvSnZ2dnUVZ_omdnZ2d@posted.internetamerica>,
rages@darkstar.arc.nasa.gov (Kathy Rages) writes:
> In article <jq647c$i6t$3@online.de>,
> Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de> wrote:
> >
> >I think my original post wasn't clear. Yes, one could translate COMMON
> >to MODULES. However, all these modules are on equal footing. Another
> >way of saying what I want: some sort of special module which can be used
> >only by certain routines (say, ones in the same regular module as this
> >special module).
> >
>
> It sounds to me like the term you are groping for is 'private'.
>
> MODULE FOOBAR
> [real,integer,whatever], private : stuff used only by C and D
Right. I normally have PRIVATE as the default, then make things
explicitly PUBLIC which need it.
> Yes, 'stuff' remains accessible to A, B, and F-J, as well as C and D. But
> it can't be accessed by any program using FOOBAR, which is what it sounds
> like you're worrying about.
Right, that does solve this problem. However, I still think it would be
nice to have the stuff invisible to the other routines in the module.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
5/31/2012 5:31:34 AM
|
|
In article <1kkx2h8.1gt0bbe1chzipsN%nospam@see.signature>,
nospam@see.signature (Richard Maine) writes:
> No, there's nothing like that. But then COMMON isn't like that either.
Right. I was hoping there was some new MODULE functionality which
would be a bit more, errm, modular than COMMON.
> You can choose to include a COMMON block only in certain routines, but
> you can also choose where you USE a module in pretty much the same way.
> It was your implication that COMMON could somehow solve the problem that
> I didn't understand. I understand that there can be lots of
> complications in structuring things well, and that sometimes it doesn't
> work out as cleanly as one might hope. But I don't see the "well then I
> could use COMMON" as though that would help in any way.
I don't plan to use COMMON, but it would allow a) all routines to be in
one module and b) some variables to be accessible by only a few selected
routines.
MODULE FOOBAR
CONTAINS
SUBROUTINE A
COMMON /SHARED/ I, J
SUBROUTINE B
COMMON /SHARED/ I, J
SUBROUTINE C
SUBROUTINE D
SUBROUTINE E
Without COMMON, Either I and J are visible to all routines in the
module, which is what I want to avoid, or I have to have an extra module
which is used by only A and B. That is, either
MODULE FOOBAR
INTEGER :: I, J
CONTAINS
SUBROUTINE A
SUBROUTINE B
SUBROUTINE C
SUBROUTINE D
SUBROUTINE E
or
MODULE FOOBAR
CONTAINS
SUBROUTINE A
USE KLIMBIM
SUBROUTINE B
USE KLIMBIM
SUBROUTINE C
SUBROUTINE D
SUBROUTINE E
MODULE KLIMBIM
INTEGER :: I, J
Module variables are visible to all routines, local variables only to
their host. This would do what I want:
MODULE FOOBAR
CONTAINS
SUBROUTINE A
INTEGER :: I, J
SUBROUTINE B
USE A, ONLY: I, J
SUBROUTINE C
SUBROUTINE D
SUBROUTINE E
But of course this isn't allowed. I think it illustrates my goal,
though. This would then allow something like
MODULE FOOBAR
CONTAINS
SUBROUTINE A
INTEGER :: I, J
SUBROUTINE B
USE A, ONLY: I, J
SUBROUTINE C
INTEGER :: I, J !not the same as those in A and B
SUBROUTINE D
USE C, ONLY: I, J !not the same as those in A and B
SUBROUTINE E
While this might look confusing at first, there are cases where it would
be useful.
Yes, one could have I and J as module variables, and, say, K and L for
the second pair, but then one has to have perhaps inconvenient names to
differentiate them. With my approach (which doesn't work), one can
reuse the same names. This is also possible with COMMON. With modules,
I need an extra module for each set of routines which share variables.
This works, but I think my solution (which doesn't work) is more
elegant. With modules, I have to have
MODULE FOOBAR
CONTAINS
SUBROUTINE A
USE AB
SUBROUTINE B
USE AB
SUBROUTINE C
USE CD
SUBROUTINE D
USE CD
SUBROUTINE E
MODULE AB
INTEGER :: I, J
MODULE CD
INTEGER :: I, J
What I don't like about this is that, logically, AB and CD are part of
FOOBAR, but the definition above puts them on equal footing. I could
put everything above in one file, calling programs would use only FOOBAR
and I could give AB and CD strange names to avoid conflicts later on.
This will work, will do what I want and is standard. However, many F95
features can be written in F77, but F95 is more elegant.
> Without a lot more detail (and spending more thought on it than I'd
> probably want to invest), I might think that breaking your big module
> into smaller ones might be in order. Not so if the variables in question
> just happen to be used in only a subset of the routines in a module, but
> if there are subsets of routines that inherently share substantial
> information only within the subset, that sounds to me like the subset
> belongs in its own module anyway - not just because it happens to share
> some variables but perhaps because it probably has other coherence. Yes,
> that adds extra modules, but I think you are stuck in that "magic" isn't
> going to happen. Either you'll have to organize the subsets (in which
> case it might as well be into modules), or you won't have them.
Right. However, really everything (about 20 routines) is logically part
of one module and each routine makes sense only in the context of the
others. The subsets which share the variables I am talking about share
them for technical, not logical, reasons.
> module top_level_one
> USE all the others
> this is what gets used by "outsiders", who don't need to even see
> the lower-level structure.
> end module
>
> module common_stuff
> This bottom_level module has stuff that might be shared among
> all the others.
> It doesn't USE anything else.
> end module
>
> module a_mid_level_one
> USE common_stuff
> and might have other things private to itself.
> end module
>
> module another_mid_level_one
> USE common_stuff
> and things of its own.
> end module
>
> ... more mid-level ones.
This more complex structure would also do what I want, at the cost of
more complexity. The subsets would be in the mid-level modules and the
shared variables would be declared there. This has the advantage that
the shared variables are declared at the right level, but the common
stuff shared by all is, to me, at the wrong level. With my module
solution above, it is reversed: common stuff is in the main module and
thus at the right level whereas the shared variables are one level too
high.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
5/31/2012 6:02:02 AM
|
|
I was just looking through some old F77 code which was my motivation for
asking this. There are about a dozen routines, and about 4 pairs of
routines which need to share variables (in addition to some variables
shared by many of the routines, but that is not an issue). Making these
variables global module variables is a bit confusing. Having separate
external modules is a possibility, but is also a bit confusing. (It
does have the advantage that they could also be USEd by the calling
program if necessary.) The most elegant solution really would be a USE
statement in a routine contained in a module which USEs (some of the
local variables in) another routine in the same module. This is
self-documenting. If both routines USE an additional module, then this
is not self-documenting.
I don't know how difficult the implementation would be. However, since
the present situation is that local variables are invisible to all other
routines (except internal routines), and USE applies only to a module,
not a routine, USE ROUTINE, ONLY: X, Y would be orthogonal to existing
usage. (If the routine is PUBLIC, one might even contemplate allowing
whatever USEs the main module to also use some stuff from public
routines within that module.)
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
5/31/2012 8:38:20 AM
|
|
On 2012-05-31 4:02 PM, Phillip Helbig---undress to reply wrote:
> In article<1kkx2h8.1gt0bbe1chzipsN%nospam@see.signature>,
> nospam@see.signature (Richard Maine) writes:
>
> I was hoping there was some new MODULE functionality which
> would be a bit more, errm, modular than COMMON.
>
....
> With modules, I have to have
>
> MODULE FOOBAR
> CONTAINS
> SUBROUTINE A
> USE AB
> SUBROUTINE B
> USE AB
> SUBROUTINE C
> USE CD
> SUBROUTINE D
> USE CD
> SUBROUTINE E
> MODULE AB
> INTEGER :: I, J
> MODULE CD
> INTEGER :: I, J
>
> What I don't like about this is that, logically, AB and CD are part of
> FOOBAR, but the definition above puts them on equal footing. I could
> put everything above in one file, calling programs would use only FOOBAR
> and I could give AB and CD strange names to avoid conflicts later on.
> This will work, will do what I want and is standard. However, many F95
> features can be written in F77, but F95 is more elegant.
>
>> Without a lot more detail (and spending more thought on it than I'd
>> probably want to invest), I might think that breaking your big module
>> into smaller ones might be in order. Not so if the variables in question
>> just happen to be used in only a subset of the routines in a module, but
>> if there are subsets of routines that inherently share substantial
>> information only within the subset, that sounds to me like the subset
>> belongs in its own module anyway - not just because it happens to share
>> some variables but perhaps because it probably has other coherence. Yes,
>> that adds extra modules, but I think you are stuck in that "magic" isn't
>> going to happen. Either you'll have to organize the subsets (in which
>> case it might as well be into modules), or you won't have them.
>
> Right. However, really everything (about 20 routines) is logically part
> of one module and each routine makes sense only in the context of the
> others. The subsets which share the variables I am talking about share
> them for technical, not logical, reasons.
>
>> module top_level_one
>> USE all the others
>> this is what gets used by "outsiders", who don't need to even see
>> the lower-level structure.
>> end module
>>
>> module common_stuff
>> This bottom_level module has stuff that might be shared among
>> all the others.
>> It doesn't USE anything else.
>> end module
>>
>> module a_mid_level_one
>> USE common_stuff
>> and might have other things private to itself.
>> end module
>>
>> module another_mid_level_one
>> USE common_stuff
>> and things of its own.
>> end module
>>
>> ... more mid-level ones.
>
> This more complex structure would also do what I want, at the cost of
> more complexity. The subsets would be in the mid-level modules and the
> shared variables would be declared there. This has the advantage that
> the shared variables are declared at the right level, but the common
> stuff shared by all is, to me, at the wrong level. With my module
> solution above, it is reversed: common stuff is in the main module and
> thus at the right level whereas the shared variables are one level too
> high.
If we just put aside the teeny tiny complication that processor support
for submodules is all-but-non-existant, you might one day be able to do...
MODULE foobar
IMPLICIT NONE
! Let the processor know that the bodies for the following
! procedures will be found in submodules of foobar.
INTERFACE
MODULE SUBROUTINE a(xxx)
...
END MODULE SUBROUTINE a
MODULE SUBROUTINE b(yyy)
...
END MODULE SUBROUTINE b
MODULE SUBROUTINE d(zzz)
...
END MODULE SUBROUTINE c
MODULE SUBROUTINE d(aaa)
...
END MODULE SUBROUTINE d
END INTERFACE
END MODULE foobar
SUBMODULE (foobar) ab
IMPLICIT NONE
INTEGER :: i, j ! only a and b can play with me
CONTAINS
! Here we repeat the information that is in the interface
! block in the ancestor module, plus provide the actual
! body of the procedure that does the work.
MODULE SUBROUTINE a(xxx)
...
END SUBROUTINE a
MODULE SUBROUTINE b(yyy)
...
END SUBROUTINE b
END SUBMODULE ab
SUBMODULE (foobar) cd
IMPLICIT NONE
INTEGER :: i, j ! only c and d can play with me
CONTAINS
! Shortcut - use MODULE PROCEDURE to rely on
! the interface block in the ancestor module for
! details about the arguments.
MODULE PROCEDURE c
...
END PROCEDURE c
MODULE PROCEDURE d
...
END PROCEDURE d
END SUBMODULE cd
|
|
0
|
|
|
|
Reply
|
ian_harvey (217)
|
5/31/2012 11:43:21 AM
|
|
In article <uPIxr.7769$%E2.7141@viwinnwfe01.internal.bigpond.com>, Ian
Harvey <ian_harvey@bigpond.com> writes:
> If we just put aside the teeny tiny complication that processor support
> for submodules is all-but-non-existant, you might one day be able to do...
Right. :-(
Maybe the best way to go is to put ALL variables which are used to
communicate between pairs of routines in an additional module, rather
than have an additional module for each pair. I can then USE this
module. This keeps the main module free of clutter, which is my main
aim here. (For documentation purposes, I could have ONLY as well so
that it is clear which modules use which variables for communication.)
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
5/31/2012 12:37:06 PM
|
|
> Maybe the best way to go is to put ALL variables which are used to
> communicate between pairs of routines in an additional module, rather
> than have an additional module for each pair. I can then USE this
> module. This keeps the main module free of clutter, which is my main
> aim here. (For documentation purposes, I could have ONLY as well so
> that it is clear which modules use which variables for communication.)
To summarize: I think the above is the best solution. Again, the
problem: There are many related routines which share many variables and
it makes sense to have them all in one module. However, a few pairs of
modules need to share a few variables between them. They could of
course be among the variables shared by all routines, but this creates
some clutter, especially if the variables are more for technical stuff,
bookkeeping etc and not directly related to the purpose of module from
the user's point of view. In F77 I had COMMON blocks and the
corresponding variables declared only in the pair of routines in
question. Apart from the general problem that the same things are
defined in more than one place (INCLUDE was not standard), this is OK.
Of course, I could also do this in F95 but I prefer module variables to
COMMON. What I like about the COMMON approach here is that the tools
(variables and COMMON blocks) are defined only in the routines which use
them, and are a small part of these routines. Replacing COMMON blocks
one-to-one with MODULEs for shared variables means creating a module at
the same logical level as the main module which contains all the
routines, including those which need to share a few variables with only
one other routine. In other words, what is essentially a small part of
a routine is defined two logical levels too high.
What I would really like to see is the possibility for a routine in a
module to "use" what is essentially a local variable in another routine
in the same module:
module big
contains
subroutine alpha
real :: x, y, z
subroutine beta
real :: a, b, c
use alpha, only: x !maybe another word than "use"
subroutine gamma
subroutine delta
subroutine epsilon
end module big
To make it safe, something similar to TARGET might be useful, e.g.:
subroutine alpha
real :: x, y, z
allow beta, only: x
Does anyone else see a need for this feature? Would it be difficult to
implement technically? Is there a chance to get it into the next
standard?
It could also be useful where the routines involved are not module
routines but routines after a CONTAINS statement in another routine.
The basic goal is to define things at the level they are used, rather
than one level up (i.e. in the routine or module before CONTAINS) or two
levels up (in a separate module which is USEd by those needing the
variables). In this sense, the COMMON solution is more modular than the
solution with modules.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/1/2012 11:00:52 AM
|
|
Phillip Helbig---undress to reply <helbig@astro.multiclothesvax.de> wrote:
>> Maybe the best way to go is to put ALL variables which are used to
>> communicate between pairs of routines in an additional module, rather
>> than have an additional module for each pair. I can then USE this
>> module. This keeps the main module free of clutter, which is my main
>> aim here. (For documentation purposes, I could have ONLY as well so
>> that it is clear which modules use which variables for communication.)
> To summarize: I think the above is the best solution. Again, the
> problem: There are many related routines which share many variables and
> it makes sense to have them all in one module. However, a few pairs of
> modules need to share a few variables between them. They could of
> course be among the variables shared by all routines, but this creates
> some clutter, especially if the variables are more for technical stuff,
> bookkeeping etc and not directly related to the purpose of module from
> the user's point of view.
It is nice to group related variables together. Sometimes there
are clear groupings and it makes sense to follow them.
I don't understand, though, the "technical stuff, bookkeeping."
It seems that one might have one module with all such variables
(and no procedures). Maybe, though, they should go into a structure
passed as an argument to different routines.
> In F77 I had COMMON blocks and the
> corresponding variables declared only in the pair of routines in
> question. Apart from the general problem that the same things are
> defined in more than one place (INCLUDE was not standard), this is OK.
> Of course, I could also do this in F95 but I prefer module variables to
> COMMON.
Put all the variables in a module and USE it in the appropriate
places.
> What I like about the COMMON approach here is that the tools
> (variables and COMMON blocks) are defined only in the routines which use
> them, and are a small part of these routines. Replacing COMMON blocks
> one-to-one with MODULEs for shared variables means creating a module at
> the same logical level as the main module which contains all the
> routines, including those which need to share a few variables with only
> one other routine. In other words, what is essentially a small part of
> a routine is defined two logical levels too high.
I don't understand this. Yes, at some point module variables are
all at the same level. They are all static, there is no nesting
level, for example.
> What I would really like to see is the possibility for a routine in a
> module to "use" what is essentially a local variable in another routine
> in the same module:
> module big
> contains
> subroutine alpha
> real :: x, y, z
> subroutine beta
> real :: a, b, c
> use alpha, only: x !maybe another word than "use"
> subroutine gamma
> subroutine delta
> subroutine epsilon
> end module big
> To make it safe, something similar to TARGET might be useful, e.g.:
> subroutine alpha
> real :: x, y, z
> allow beta, only: x
> Does anyone else see a need for this feature? Would it be difficult to
> implement technically? Is there a chance to get it into the next
> standard?
Well, since Fortran 95 local variables can be automatic, and
they have to be in the case of RECURSIVE. They don't exist before
a routine is called, or after it returns. Note, though, that
they are available to internal procedures. Does that help?
> It could also be useful where the routines involved are not module
> routines but routines after a CONTAINS statement in another routine.
> The basic goal is to define things at the level they are used, rather
> than one level up (i.e. in the routine or module before CONTAINS) or two
> levels up (in a separate module which is USEd by those needing the
> variables). In this sense, the COMMON solution is more modular than the
> solution with modules.
As well as I know it, there is a very close relationship between
MODULE variables and COMMON variables. You USE them differently,
and the ways to misuse them are different, but otherwise they
are very similar.
-- glen
|
|
0
|
|
|
|
Reply
|
gah (12258)
|
6/1/2012 12:56:55 PM
|
|
Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de>
wrote:
> What I like about the COMMON approach here is that the tools
> (variables and COMMON blocks) are defined only in the routines which use
> them, and are a small part of these routines. Replacing COMMON blocks
> one-to-one with MODULEs for shared variables means creating a module at
> the same logical level as the main module which contains all the
> routines, including those which need to share a few variables with only
> one other routine. In other words, what is essentially a small part of
> a routine is defined two logical levels too high.
I still don't see this alleged difference between COMMON and modules for
the purpose you describe. As Glen notes, they are both global. Just
because you put the declarations for a COMMON only in the routines in
question, that doesn't mean that the COMMON is somehow local to them. It
is still global in exactly the same way that a module is global. Each
COMMON can map one-to-one onto a module with exactly the same variables.
I don't see this "level" difference.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
|
|
0
|
|
|
|
Reply
|
nospam47 (9742)
|
6/1/2012 3:38:11 PM
|
|
In article <1kl04zu.11pk0hkfdcc0kN%nospam@see.signature>,
nospam@see.signature (Richard Maine) wrote:
> Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de>
> wrote:
>
> > What I like about the COMMON approach here is that the tools
> > (variables and COMMON blocks) are defined only in the routines which use
> > them, and are a small part of these routines. Replacing COMMON blocks
> > one-to-one with MODULEs for shared variables means creating a module at
> > the same logical level as the main module which contains all the
> > routines, including those which need to share a few variables with only
> > one other routine. In other words, what is essentially a small part of
> > a routine is defined two logical levels too high.
>
> I still don't see this alleged difference between COMMON and modules for
> the purpose you describe. As Glen notes, they are both global. Just
> because you put the declarations for a COMMON only in the routines in
> question, that doesn't mean that the COMMON is somehow local to them. It
> is still global in exactly the same way that a module is global. Each
> COMMON can map one-to-one onto a module with exactly the same variables.
> I don't see this "level" difference.
I also don't see exactly what the problem is. From what I can
understand from the previous posts, something like the following
seems like an obvious and straightforward solution:
module integer_vars
integer :: i, j, k
end module integer_vars
module real_vars
real :: a, b, c
end module real_vars
module subs
contains
subroutine suba
use integer_vars, only: i, j, k
...
end subrouitne suba
subroutine subb
use integer_vars, only: i, j, k
...
end subroutine subb
subroutine subc
use real_vars, only: a, b, c
...
end subroutine subc
subroutine subd
use real_vars, only: a, b, c
...
end subroutine subd
subroutine sube
use integer_vars, only: i, j, k
use real_vars, only: a, b, c
...
end subroutine sube
end module subs
Routines suba and subb share just the integer variables, routines
subc and subd share just the real variables, and routine sube uses
both subsets.
Routines that need the integer_vars use that module, routines that
need the real_vars use that module, and modules that need both sets
of variables use both modules. The USE statements document clearly
which variables are being used at any point.
You can also do something like:
module all_vars
use integer_vars: only: i, j, k
use real_vars: only: a, b, c
end module all_vars
and then you could use just this module in those cases where you
want access to all of the variables. This hides the underlying
organization in those cases where it is not important or where you
don't want it to be exposed. You could also define a some_vars
module that uses some particular subset of all the variables. You
can't do this kind of thing with COMMON variables, it is one of many
advantages of modules over COMMON blocks. Except for naming the
modules on the END MODULE statement, I think this is all just f90,
nothing related to submodules or anything in the more recent
language versions is required. The above can all be in one file, or
if it makes better sense the modules could be put in separate files.
The idea of making local variables in one routine visible to another
routine seems really bad to me. For many reasons. The the main one
is that it would allow a local variable to just magically change
value in the middle of an execution sequence with no clue to the
programmer what might be happening. That's not supposed to happen,
no way no how. The above straightforward approach makes the data
usage obvious and clear. You can tell from the local declaration
which variables might change in contrast to the local variables that
don't and can't change. There are also issues with some variables
being implicitly saved, with automatic variables that are no longer
in scope being referenced, and (as others have mentioned) ambiguity
with local variables for recursive routines being referenced
externally. The whole idea just doesn't make sense.
$.02 -Ron Shepard
|
|
0
|
|
|
|
Reply
|
ron-shepard (1197)
|
6/2/2012 12:53:52 AM
|
|
I had almost finished a long posting to explain why most CLF postings are
now about installing compilers, successfully using them, or finding how to
express a simple F77 process in F90/95 or later code. I.e. complexity is
crippling productivity and comprehension of other's code
Then I read Phillip's posting and found he had matched exactly my own
posting of years ago, of my decription of trying to acheive something in
F90/95 that was SO simple in F77 (passing language text tables with the text
length counts, the text and the message number, using a COMMON block). It
was never solved by the Fortran community, in spite of a lot of suggestions,
and again, I stayed with F77.
"If it isn't broken, don't try to fix it".
|
|
0
|
|
|
|
Reply
|
tbwright1 (218)
|
6/2/2012 1:08:24 AM
|
|
Again! Exactly, Phillip!
|
|
0
|
|
|
|
Reply
|
tbwright1 (218)
|
6/2/2012 1:10:14 AM
|
|
Glen suggested:-
>Put all the variables in a module and USE it in the appropriate places.
And that what was most commonly (actually a pun) suggested for my problem,
too.
But if the (language table) text contents and message lengths have to read
in first and parsed, it just raises another level of complexity; where is
the external file reading to be done?.
COMMON worked; other methods didn't.
|
|
0
|
|
|
|
Reply
|
tbwright1 (218)
|
6/2/2012 1:18:04 AM
|
|
In article <9Idyr.7823$%E2.3568@viwinnwfe01.internal.bigpond.com>,
"Terence" <tbwright@bigpond.net.au> wrote:
> I had almost finished a long posting to explain why most CLF postings are
> now about installing compilers,
Yes, there are some of those.
> successfully using them,
Yes, those too.
> or finding how to
> express a simple F77 process in F90/95 or later code.
There are very few of those. In fact, I don't even remember the one
you are talking about, and that is probably the only one in the past
year or two.
> I.e. complexity is
> crippling productivity and comprehension of other's code
When you begin with an incorrect premise, you draw incorrect
conclusions.
>
> Then I read Phillip's posting and found he had matched exactly my own
> posting of years ago, of my decription of trying to acheive something in
> F90/95 that was SO simple in F77 (passing language text tables with the text
> length counts, the text and the message number, using a COMMON block).
Odd. My previous post explained several things that could be done
with modules that cannot be done with common blocks.
> It
> was never solved by the Fortran community, in spite of a lot of suggestions,
> and again, I stayed with F77.
>
> "If it isn't broken, don't try to fix it".
I expect you are in a small minority with your opinion. Perhaps a
minority of one.
$.02 -Ron Shepard
|
|
0
|
|
|
|
Reply
|
ron-shepard (1197)
|
6/2/2012 4:09:00 AM
|
|
In article <jqae6n$1mf$1@speranza.aioe.org>, glen herrmannsfeldt
<gah@ugcs.caltech.edu> writes:
> It is nice to group related variables together. Sometimes there
> are clear groupings and it makes sense to follow them.
>
> I don't understand, though, the "technical stuff, bookkeeping."
Suppose the module is concerned with calculating some quantity and this
is done partly through numerical integration. There might be some
low-level variables in a couple of routines which might save previously
calculated results, flag errors, collect statistics for debugging etc
which are conceptually independent of the real purpose of the module and
certainly not of interest to the calling program.
> Put all the variables in a module and USE it in the appropriate
> places.
Right; this is what I concluded is the best solution.
> > What I like about the COMMON approach here is that the tools
> > (variables and COMMON blocks) are defined only in the routines which use
> > them, and are a small part of these routines. Replacing COMMON blocks
> > one-to-one with MODULEs for shared variables means creating a module at
> > the same logical level as the main module which contains all the
> > routines, including those which need to share a few variables with only
> > one other routine. In other words, what is essentially a small part of
> > a routine is defined two logical levels too high.
>
> I don't understand this. Yes, at some point module variables are
> all at the same level. They are all static, there is no nesting
> level, for example.
Technically, yes, but aesthetically, no. :-)
The structure with COMMON is
module main
global variables
routine alpha
local variables a, b, c
routine beta
local variables a, b, c
common /both/ x, y
routine gamma
local variables a, b, c
routine delta
local variables a, b, c
routine epsilon
local variables a, b, c
common /both/ x, y
routine zeta
local variables a, b, c
so x and y are defined in beta and epsilon, where they are used.
The alternatives are
module main
global variables
x, y
routine alpha
local variables a, b, c
routine beta
local variables a, b, c
routine gamma
local variables a, b, c
routine delta
local variables a, b, c
routine epsilon
local variables a, b, c
routine zeta
local variables a, b, c
In this case, x and y are clutter since they are visible to all
routines, though only a couple use them. In contrast to some of the
other module variables, the calling program doesn't care about them.
They are also defined a level higher than where they are used.
or
module main
global variables
routine alpha
local variables a, b, c
routine beta
use both
local variables a, b, c
routine gamma
local variables a, b, c
routine delta
local variables a, b, c
routine epsilon
use both
local variables a, b, c
routine zeta
local variables a, b, c
module both
x, y
This keeps x and y visible only where they are used (and, in contrast to
common, defines them at only one place), but it means an extra module,
which is on the same logical level as the main module, though it is
concerned with variables used within a procedure contained within the
main module. For another pair, I would have
module main
global variables
routine alpha
local variables a, b, c
routine beta
use betaepsilon
local variables a, b, c
routine gamma
use gammadelta
local variables a, b, c
routine delta
use gammadelta
local variables a, b, c
routine epsilon
use beta epsilon
local variables a, b, c
routine zeta
local variables a, b, c
module both betaepsilon
x, y
module both gammadelta
x, y
which means an additional module for each subset. I think this is
better:
module main
global variables
routine alpha
local variables a, b, c
routine beta
use both, only: x, y
local variables a, b, c
routine gamma
use both, only: v, w
local variables a, b, c
routine delta
use both, only: v, w
local variables a, b, c
routine epsilon
use both, only: x, y
local variables a, b, c
routine zeta
local variables a, b, c
module both
x, y, v, w
> > What I would really like to see is the possibility for a routine in a
> > module to "use" what is essentially a local variable in another routine
> > in the same module:
>
> > module big
> > contains
> > subroutine alpha
> > real :: x, y, z
> > subroutine beta
> > real :: a, b, c
> > use alpha, only: x !maybe another word than "use"
> > subroutine gamma
> > subroutine delta
> > subroutine epsilon
> > end module big
>
> > To make it safe, something similar to TARGET might be useful, e.g.:
>
> > subroutine alpha
> > real :: x, y, z
> > allow beta, only: x
>
> > Does anyone else see a need for this feature? Would it be difficult to
> > implement technically? Is there a chance to get it into the next
> > standard?
>
> Well, since Fortran 95 local variables can be automatic, and
> they have to be in the case of RECURSIVE.
ALLOW would tell the compiler that these could be accessed by another
routine.
> They don't exist before
> a routine is called, or after it returns.
Unless they are SAVEd, presumably.
> Note, though, that
> they are available to internal procedures. Does that help?
Not in this case.
> As well as I know it, there is a very close relationship between
> MODULE variables and COMMON variables. You USE them differently,
> and the ways to misuse them are different, but otherwise they
> are very similar.
Indeed. What I like about COMMON in this case (otherwise, I want to
avoid it and use module variables and will probably do so even here) is
that the variables shared between a pair of routines are mentioned there
and nowhere else. With module variables, I have to define them outside
of these routines.
A country is divided into states, counties, towns etc. Imagine two
towns (in different states) have some sort of cooperation. It would be
logical for each one to have an office dealing with this. This is the
COMMON approach. With the module approach, there is either an office in
the national capital which deals with all such cooperations, or there is
an office in a third town which communicates with both towns in the
partnership.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/2/2012 9:23:09 AM
|
|
In article <1kl04zu.11pk0hkfdcc0kN%nospam@see.signature>,
nospam@see.signature (Richard Maine) writes:
> I still don't see this alleged difference between COMMON and modules for
> the purpose you describe. As Glen notes, they are both global. Just
> because you put the declarations for a COMMON only in the routines in
> question, that doesn't mean that the COMMON is somehow local to them. It
> is still global in exactly the same way that a module is global. Each
> COMMON can map one-to-one onto a module with exactly the same variables.
> I don't see this "level" difference.
As I noted in my first post from today, it is not a technical
distinction, but more an aesthetic one. Yes, COMMON is a global object.
However, in a chart of the module structure, it is enough to mention the
shared variables only within the routines concerned while with the
module approach they MUST be mentioned OUTSIDE the routines concerned.
Maybe the last paragraph in my other post about cooperation between
towns illustrates what I want to communicate.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/2/2012 9:25:45 AM
|
|
In article <ron-shepard-9B8689.19535201062012@news60.forteinc.com>, Ron
Shepard <ron-shepard@NOSPAM.comcast.net> writes:
> I also don't see exactly what the problem is. From what I can
> understand from the previous posts, something like the following
> seems like an obvious and straightforward solution:
Yes, this will work and is functionally the same. See my reply from
today to Richard Maine.
> The idea of making local variables in one routine visible to another
> routine seems really bad to me. For many reasons. The the main one
> is that it would allow a local variable to just magically change
> value in the middle of an execution sequence with no clue to the
> programmer what might be happening. That's not supposed to happen,
> no way no how.
If one were using a module variable visible to more than one routine,
this could also happen. Moreover, ANY routine in which it is visible
could change it. ALLOW alerts the programmer and compiler to this
possibility.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/2/2012 9:28:51 AM
|
|
In article <jqcm1t$8rs$1@online.de>,
helbig@astro.multiCLOTHESvax.de (Phillip Helbig---undress to
reply) wrote:
> Indeed. What I like about COMMON in this case (otherwise, I want to
> avoid it and use module variables and will probably do so even here) is
> that the variables shared between a pair of routines are mentioned there
> and nowhere else. With module variables, I have to define them outside
> of these routines.
This redundant declaration of common block variables is actually one
of the main problems with common blocks. In f77, there was no way
other than within the separate routines to declare shared data.
(Well, okay you could get clever with multiple entry points to some
extent, but this was rather limited.) It was the responsibility of
the programmer to ensure that these multiple definitions of the
common block variables were all consistent. And since the
individual variables declared within the common block in the
separate routines could have different names, this was sometimes an
almost impossible task in practice. With sequence association
aliasing and mixed real, integer, and double precision variables, it
was truly a mess, particularly regarding portability on machines
where you wanted to change precisions and/or data lengths. And
don't forget that you needed to SAVE these common blocks
consistently everywhere they were declared, something that most
programmers did not know and did not do correctly.
Many f77 compilers supported the (then) nonstandard INCLUDE
statement as an extension. This solved some of the problems by
allowing the common block variables (and the SAVE statement) to be
declared in one place, and then included into the various routines
that needed it. From your statement above, you probably would not
like this approach because it would "require" you to declare the
common block entities in a separate file. Of course this approach
also has several of its own problems, besides the fact that it was a
nonstandard extension, including the reference through a file name
rather than a global entity. File name conventions are OS dependent
and are completely outside of the fortran standard, so this approach
required putting something that was fundamentally nonportable
directly into your source code. Other problems included conflicts
between local variable names and these common block variable names
since there was no way to temporarily rename a common block variable
on the INCLUDE statement. Combined with the fact that IMPLICIT NONE
was also nonstandard in f77, this was all just another big mistake
waiting to happen to the programmer who happened to choose a wrong
variable name for what he thought was a local variable.
You may be too young to have encountered this, but it used to be
fairly common practice to specify overlay structures for data and
code in order to reuse as efficiently as possible the limited memory
that was available to the programmer. Common blocks were specified
by their common block names while subroutines were specified by
their names. In f77 this introduced an asymmetry between the way
these different entities were declared and used. Namely, the data
could only be declared within the subroutines in the source code,
but in the overlay specification they were treated rather
equivalently. And, of course, the programmer had to think of them
equivalently as he was writing the code, so this was another example
of how the f77 program structure was fighting against the
programmer. As computer memories grew larger over time, program
overlays became less common. I don't think I have seen an overlay
linker in over 20 years, and even that one was on a DECSYSTEM-20
originally from the late 70's.
Modules in f90 solved most of these problems. Variables could be
declared in one place, used anywhere they were needed, and renamed
locally if necessary in order to avoid conflicts. The OS-dependent
file name references were eliminated in the source code. The
modules could include data only, routines only, or mixtures of both,
so everything was now treated conceptually at the right level (one
was no longer artificially a subclass of the other). Sequence
association was eliminated, which (along with KINDs) eliminated many
of the problems related to changing precisions when porting codes
from one machine to another. Initial values could be assigned
locally within the module definition itself, eliminating the BLOCK
DATA problems associated with common blocks. And allocatable arrays
could be placed in modules, something that was simply not possible
with static common block storage. And best of all, the compiler can
help the programmer with many aspects of module usage, avoiding all
kinds of mistakes that would have occurred with common blocks where
the user alone, without help from the compiler, is responsible for
consistent usage.
One remaining problem is that I know of no way to avoid module name
conflicts. This occurred sometimes with common block names too, so
this is basically the same problem that remains unsolved. If you
are combining two different codes that happen to have a common
module name, then you must manually go through the codes and rename
one or both of them in order to avoid the conflict. At least with
modules you can use long identifiers to help avoid this issue. With
common blocks in f77 you were limited to six-character names, so it
was not uncommon to have these kinds of conflicts, especially with
library routines that shared data and where the programmer might not
have access to the source code or where the common block name itself
was not documented.
So all in all, while you view the redundant declaration of common
block variables as an advantage, I tend to think of it as several
levels of disadvantages all stacked on top each other.
$.02 -Ron Shepard
|
|
0
|
|
|
|
Reply
|
ron-shepard (1197)
|
6/2/2012 4:01:40 PM
|
|
In article <ron-shepard-47E8E0.11014002062012@news60.forteinc.com>, Ron
Shepard <ron-shepard@NOSPAM.comcast.net> writes:
> > Indeed. What I like about COMMON in this case (otherwise, I want to
> > avoid it and use module variables and will probably do so even here) is
> > that the variables shared between a pair of routines are mentioned there
> > and nowhere else. With module variables, I have to define them outside
> > of these routines.
>
> This redundant declaration of common block variables is actually one
> of the main problems with common blocks.
I agree, hence my proposal for one routine to "USE" what would otherwise
be a local variable in another routine: only declared at one place, and
within the units which use it.
> In f77, there was no way
> other than within the separate routines to declare shared data.
> (Well, okay you could get clever with multiple entry points to some
> extent, but this was rather limited.) It was the responsibility of
> the programmer to ensure that these multiple definitions of the
> common block variables were all consistent. And since the
> individual variables declared within the common block in the
> separate routines could have different names, this was sometimes an
> almost impossible task in practice. With sequence association
> aliasing and mixed real, integer, and double precision variables, it
> was truly a mess, particularly regarding portability on machines
> where you wanted to change precisions and/or data lengths. And
> don't forget that you needed to SAVE these common blocks
> consistently everywhere they were declared, something that most
> programmers did not know and did not do correctly.
I couldn't agree more, which is why I am moving to a non-COMMON
solution, even though I never used any of the ugly tricks you mention
above.
> Many f77 compilers supported the (then) nonstandard INCLUDE
> statement as an extension. This solved some of the problems by
> allowing the common block variables (and the SAVE statement) to be
> declared in one place, and then included into the various routines
> that needed it.
Right, but non-standard.
> From your statement above, you probably would not
> like this approach because it would "require" you to declare the
> common block entities in a separate file.
Right.
> Of course this approach
> also has several of its own problems, besides the fact that it was a
> nonstandard extension, including the reference through a file name
> rather than a global entity. File name conventions are OS dependent
> and are completely outside of the fortran standard, so this approach
> required putting something that was fundamentally nonportable
> directly into your source code. Other problems included conflicts
> between local variable names and these common block variable names
> since there was no way to temporarily rename a common block variable
> on the INCLUDE statement. Combined with the fact that IMPLICIT NONE
> was also nonstandard in f77, this was all just another big mistake
> waiting to happen to the programmer who happened to choose a wrong
> variable name for what he thought was a local variable.
Agreed. Module variables are MUCH better. The ONLY thing I like about
COMMON is the case I'm discussing here (a few out of a large number of
routines need to share a few variables only among themselves).
> You may be too young to have encountered this, but it used to be
> fairly common practice to specify overlay structures for data and
> code in order to reuse as efficiently as possible the limited memory
> that was available to the programmer.
Yes. When I started, typical workstation memory was 16 MB or so, so the
days of using EQUIVALENCE to save RAM (many people probably think that
it's original purpose was for the various tricks for which it has been
abused, rather than to save RAM) or deleting the source code from disk
after compilation were long gone. :-)
> One remaining problem is that I know of no way to avoid module name
> conflicts. This occurred sometimes with common block names too, so
> this is basically the same problem that remains unsolved. If you
> are combining two different codes that happen to have a common
> module name, then you must manually go through the codes and rename
> one or both of them in order to avoid the conflict.
Right.
> At least with
> modules you can use long identifiers to help avoid this issue.
That is what I do. Since my surname is not common among Fortran
programmers, I use it as a prefix. Many publicly available packages
have their own prefix for module names.
> So all in all, while you view the redundant declaration of common
> block variables as an advantage, I tend to think of it as several
> levels of disadvantages all stacked on top each other.
Agreed. I don't view the redundant declaration as an advantage, but
rather the fact that the common block and its variables are mentioned
ONLY within the routines which use them. (Of course, there is nothing
to prevent another routine from having the same declarations.) But
that's the only advantage.
A variant of my proposal could have a special scoping unit within a
routine which is for variables which can be accessed by other routines.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/2/2012 4:14:55 PM
|
|
Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de>
wrote:
> In article <1kl04zu.11pk0hkfdcc0kN%nospam@see.signature>,
> nospam@see.signature (Richard Maine) writes:
>
> > I still don't see this alleged difference between COMMON and modules for
> > the purpose you describe. As Glen notes, they are both global. Just
> > because you put the declarations for a COMMON only in the routines in
> > question, that doesn't mean that the COMMON is somehow local to them. It
> > is still global in exactly the same way that a module is global. Each
> > COMMON can map one-to-one onto a module with exactly the same variables.
> > I don't see this "level" difference.
>
> As I noted in my first post from today, it is not a technical
> distinction, but more an aesthetic one.
Well, I guess it is time for me to drop out of this discussion. I'm sure
not going to start up with explaining the *LONG* list of problems with
using COMMON. I have spent so much time in my career debugging messy
problems relating to COMMON that I have trouble seeing anything
aesthetically pleasing in it.
As just a hint to one of the items in the list, note that COMMON does
not share variables at all. It just shares memory locations (sort of -
digression into the strange implementations needed for the now obsolete
assigned GOTO would be long). The variables just happen to be
essentially equivalenced via those memory locations. Have lots of fun
debugging when you find out that two routines, both having syntactically
identical COMMON declarations don't necessarily cause the variables of
the same name to be associated. No, putting the declarations related to
the COMMON in an INCLUDE file doesn't guarantee this can't happen. It
helps, but it is not ironclad (because there is no way to say that no
extra attributes can be added, the dimension attribute being one
potential problem).
If you ever need to initialize anything in the COMMON, you get to deal
with the fun game of making BLOCK DATA actually work in all the
environments that your code might go to, particularly if people might do
even the most trivial modifications to your code... such as putting each
program unit in its own file without changing a single line of the code.
At least BLOCK DATA is sort of allowed, even if it often fails to work.
It isn't like the things that just aren't allowed in COMMON at all
because they aren't compatible with the storage association mechanism of
COMMON. (Goodby allocatables, for example.)
Ack! Gotta make myself stop with listing problems of it. No more on this
from me.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
|
|
0
|
|
|
|
Reply
|
nospam47 (9742)
|
6/2/2012 4:23:29 PM
|
|
On 6/2/2012 11:14 AM, Phillip Helbig---undress to reply wrote:
....
> I agree, hence my proposal for one routine to "USE" what would otherwise
> be a local variable in another routine: only declared at one place, and
> within the units which use it.
I think that is just evil, meself...if they are that restricted make
them arguments to the function or have a specfic module that
incorporates them if they are, indeed, to be global.
Don't screw up data-hiding and scope by somesuch illbred method of
"well, these two are needed but instead of making a proper interface
I'll just make them visible by this shortcut".
....
>> From your statement above, you probably would not
>> like this approach because it would "require" you to declare the
>> common block entities in a separate file.
>
> Right.
Which is, of course, the only sane way to have COMMON blocks and you'd
be hard pressed to find a current compiler that doesn't support INCLUDE
methinks, whatever level of the Standard it claims conformance to.
....
--
|
|
0
|
|
|
|
Reply
|
none1568 (6651)
|
6/2/2012 4:32:13 PM
|
|
In article <1kl20m3.1o2rpih1agavveN%nospam@see.signature>,
nospam@see.signature (Richard Maine) writes:
> > > I still don't see this alleged difference between COMMON and modules for
> > > the purpose you describe. As Glen notes, they are both global. Just
> > > because you put the declarations for a COMMON only in the routines in
> > > question, that doesn't mean that the COMMON is somehow local to them. It
> > > is still global in exactly the same way that a module is global. Each
> > > COMMON can map one-to-one onto a module with exactly the same variables.
> > > I don't see this "level" difference.
> >
> > As I noted in my first post from today, it is not a technical
> > distinction, but more an aesthetic one.
>
> Well, I guess it is time for me to drop out of this discussion. I'm sure
> not going to start up with explaining the *LONG* list of problems with
> using COMMON. I have spent so much time in my career debugging messy
> problems relating to COMMON that I have trouble seeing anything
> aesthetically pleasing in it.
As I wrote in reply to Ron Shepard a few minutes ago, I couldn't agree
more and definitely want to get away from COMMON. This is the ONLY
thing I like about COMMON, but even that is not strong enough for me to
use it instead of a module solution. I think I will have a module for
variables which are shared between just a few routines, and said
routines can USE this module (perhaps ONLY the variables they actually
need).
> As just a hint to one of the items in the list, note that COMMON does
> not share variables at all. It just shares memory locations (sort of -
> digression into the strange implementations needed for the now obsolete
> assigned GOTO would be long). The variables just happen to be
> essentially equivalenced via those memory locations.
Right; "shared variables" was just a shorthand notation.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/2/2012 4:33:56 PM
|
|
In article <jqdf6c$do9$1@speranza.aioe.org>, dpb <none@non.net> writes:
> > I agree, hence my proposal for one routine to "USE" what would otherwise
> > be a local variable in another routine: only declared at one place, and
> > within the units which use it.
>
> I think that is just evil, meself...if they are that restricted make
> them arguments to the function or have a specfic module that
> incorporates them if they are, indeed, to be global.
Neither function calls the other directly. Yes, one can pass a variable
through several levels of routines, but that is even worse in terms of
readable code.
> Don't screw up data-hiding and scope by somesuch illbred method of
> "well, these two are needed but instead of making a proper interface
> I'll just make them visible by this shortcut".
Actually, I think this shortcut is clearer in this case, since only the
routines involved have anything to do with the variables. Yes, one can
put them in a separate module, but this is creating a high-level
construct for a low-level problem.
> Which is, of course, the only sane way to have COMMON blocks and you'd
> be hard pressed to find a current compiler that doesn't support INCLUDE
> methinks, whatever level of the Standard it claims conformance to.
True, but I like to write 100% standard code and also as portable as
possible. OK, Fortran90 did standardize include, but of course file
names are not portable.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/2/2012 4:38:13 PM
|
|
On 6/2/2012 11:38 AM, Phillip Helbig---undress to reply wrote:
> In article<jqdf6c$do9$1@speranza.aioe.org>, dpb<none@non.net> writes:
>
>>> I agree, hence my proposal for one routine to "USE" what would otherwise
>>> be a local variable in another routine: only declared at one place, and
>>> within the units which use it.
>>
>> I think that is just evil, meself...if they are that restricted make
>> them arguments to the function or have a specfic module that
>> incorporates them if they are, indeed, to be global.
>
> Neither function calls the other directly. Yes, one can pass a variable
> through several levels of routines, but that is even worse in terms of
> readable code.
....
We'll have to "agree to disagree" on that one...
Your way there's no indication that some an otherwise apparently local
variable is shared w/ another routine X--it may be seen that it is
shared if it is COMMON, granted, but other than by comments or searching
the source can it be seen where that is.
If they are passed through the hierarchy, then that is clear even if it
takes a few layers of calls it is definitely in the chain.
USE has the same issue as far as where _else_ a module is used but it is
at least clear where it is defined and at least not hard to find
references to the module name w/ either IDE tools if they support such
or text searches or whatever means.
--
|
|
0
|
|
|
|
Reply
|
none1568 (6651)
|
6/2/2012 5:45:36 PM
|
|
Ron Shepard <ron-shepard@nospam.comcast.net> wrote:
(snip)
> Many f77 compilers supported the (then) nonstandard INCLUDE
> statement as an extension. This solved some of the problems by
> allowing the common block variables (and the SAVE statement) to be
> declared in one place, and then included into the various routines
> that needed it.
I believe INCLUDE originated in the DEC Fortran IV compilers.
That is, at least, the first place I saw it.
(snip)
> You may be too young to have encountered this, but it used to be
> fairly common practice to specify overlay structures for data and
> code in order to reuse as efficiently as possible the limited memory
> that was available to the programmer.
(snip)
> As computer memories grew larger over time, program
> overlays became less common. I don't think I have seen an overlay
> linker in over 20 years, and even that one was on a DECSYSTEM-20
> originally from the late 70's.
I was using them with MS-DOS programs close to less than 20 years ago.
At least until Win32 became popular enough.
I found the Watcom linker, even when using the Microsoft compilers,
to be a much better overlay linker than MS LINK. Though after not
so long I was mostly using the Watcom compilers, too.
Mostly I tried to overlay code, and not data. That avoids the fun
of non-SAVEd COMMON. (At least on most systems.)
-- glen
|
|
0
|
|
|
|
Reply
|
gah (12258)
|
6/2/2012 6:18:41 PM
|
|
In article <jqdjg0$pmi$1@speranza.aioe.org>, dpb <none@non.net> writes:
> Your way there's no indication that some an otherwise apparently local
> variable is shared w/ another routine X--it may be seen that it is
> shared if it is COMMON, granted, but other than by comments or searching
> the source can it be seen where that is.
Thus my idea for something like TARGET, perhaps ALLOW, which alerts the
user and the compiler to this possibility.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/2/2012 6:44:03 PM
|
|
In article <jqdfhl$rom$4@online.de>,
helbig@astro.multiCLOTHESvax.de (Phillip Helbig---undress to
reply) wrote:
> In article <jqdf6c$do9$1@speranza.aioe.org>, dpb <none@non.net> writes:
>
> > > I agree, hence my proposal for one routine to "USE" what would otherwise
> > > be a local variable in another routine: only declared at one place, and
> > > within the units which use it.
> >
> > I think that is just evil, meself...if they are that restricted make
> > them arguments to the function or have a specfic module that
> > incorporates them if they are, indeed, to be global.
>
> Neither function calls the other directly. Yes, one can pass a variable
> through several levels of routines, but that is even worse in terms of
> readable code.
Then this makes your proposal even more odd. I thought that one
routine was supposed to declare the variables, and then other called
routines were supposed to access them (like a contained routine, but
compiled at the same level within the module) while the calling
routine was active.
If the two routines that share the data are called separately by the
other calling routines, then they should treat their shared data
symmetrically. The shared data should be declared somewhere else,
and the routines that share it should all access it in a more or
less equivalent/symmetrical way. That is exactly the way it would
work with module variables.
>
> > Don't screw up data-hiding and scope by somesuch illbred method of
> > "well, these two are needed but instead of making a proper interface
> > I'll just make them visible by this shortcut".
>
> Actually, I think this shortcut is clearer in this case, since only the
> routines involved have anything to do with the variables. Yes, one can
> put them in a separate module, but this is creating a high-level
> construct for a low-level problem.
This seems like a high-level construct for a high-level problem.
This is shared data by equivalent routines in the calling hierarchy.
Module variables are used in cases like this, where the routines are
at the same levels and they both operate on/with the shared
variables, and they are also used when a high-level routine sets
some information that is then later used by lower-level routines.
The logical high-level separation of data and code is what allows
this flexibility. Your approach associates the data with one of the
routines, and then acts like a low-level hack to make it accessible
to the other routines.
It seems to me like module variables are the exact fit to your
programming problem. They provide a clear, simple, and unambiguous
solution. Your proposed approach would be obscure, complicated, and
ambiguous; :-) it just does not seem like a good fit to your problem.
If you are worried that it will complicate your build process by
having to create a new file with that data module, then that is not
necessary. The module can be defined in the same file as the
subroutines. In fact, in this situation I think that would probably
be best. There is not a one-to-one mapping between files and
modules, a file can have several modules within it. I usually put
these small modules like this up at the top of the file, so the
compiler sees the definition before it sees the USE statements, but
I don't think most compilers care where they occur. That is the way
my example was structured in my earlier post, the data modules were
first and the subroutine modules were last.
$.02 -Ron Shepard
|
|
0
|
|
|
|
Reply
|
ron-shepard (1197)
|
6/2/2012 6:45:53 PM
|
|
On 6/2/2012 1:45 PM, Ron Shepard wrote:
....
> ... a file can have several modules within it. I usually put
> these small modules like this up at the top of the file, so the
> compiler sees the definition before it sees the USE statements, but I
> don't think most compilers care where they occur....
They have to be such that the source of the module has been compile by
the time the compiler hits the USE statement or the compile will fail
(or use a potentially out-of-date .mod file).
--
|
|
0
|
|
|
|
Reply
|
none1568 (6651)
|
6/2/2012 8:32:18 PM
|
|
In article <jqdt8i$kco$1@speranza.aioe.org>, dpb <none@non.net>
wrote:
> On 6/2/2012 1:45 PM, Ron Shepard wrote:
> ...
>
> > ... a file can have several modules within it. I usually put
> > these small modules like this up at the top of the file, so the
> > compiler sees the definition before it sees the USE statements, but I
> > don't think most compilers care where they occur....
>
> They have to be such that the source of the module has been compile by
> the time the compiler hits the USE statement or the compile will fail
> (or use a potentially out-of-date .mod file).
I encountered this long ago with the first f90 compilers that I
used, but I think that modern compilers will scan through the file
and compile things in the right order regardless. Mostly out of
habit however, I still write code with the modules first, and USE
statements later. If there are compilers that require this, then
this module order is indeed more of a requirement than an esthetic
choice.
In any case, all of this is certainly compiler dependent and outside
the scope of the fortran language standard itself.
$.02 -Ron Shepard
|
|
0
|
|
|
|
Reply
|
ron-shepard (1197)
|
6/2/2012 10:48:27 PM
|
|
Ron Shepard wrote:-
"Odd. My previous post explained several things that could be done
with modules that cannot be done with common blocks."
It's not a transitive situation. The reverse may not be true (i.e things you
can do with Common that you cannot do with modules (as expressed by a few
postings above)..
The community could not solve my old F77 to F90/95 problem of convertion of
inter-subroutine communication via parameter passing ibn calls, without a
complete code re-write. And the whole point was to retain code between
compilers with minimum differences.
|
|
0
|
|
|
|
Reply
|
tbwright1 (218)
|
6/2/2012 11:11:51 PM
|
|
Phillip is describing a situation very well, that indicates that common
blocks can make coding clearer, shorter, and faster. And as long as a
compiler can support this "obsolescent" coding method, I will use it. I
can't say what Bachus's team previsaged for it in the future, but when I
learnt Fortran in 1960, I certainly understood the intent and usefulness of
the common block (which I also still use to spread larger matrices around
the memory spaces available in still-used small-memoried data-capture
computers).
|
|
0
|
|
|
|
Reply
|
tbwright1 (218)
|
6/2/2012 11:21:03 PM
|
|
On 6/2/2012 6:12 PM, Terence wrote:
....
> The community could not solve my old F77 to F90/95 problem of convertion of
> inter-subroutine communication via parameter passing ibn calls,...
What does the above say?
--
|
|
0
|
|
|
|
Reply
|
none1568 (6651)
|
6/3/2012 12:05:05 AM
|
|
On 6/2/2012 6:21 PM, Terence wrote:
> Phillip is describing a situation very well, that indicates that common
> blocks can make coding clearer, shorter, and faster....
1 of 3 being _possible_ ain't bad for a baseball average... :)
Shorter (in source lines) I'll agree is possibly so, clearer is
certainly an "in the eye of the beholder" item and I'd think it highly
unlikely to be any speed difference whatsoever.
--
|
|
0
|
|
|
|
Reply
|
none1568 (6651)
|
6/3/2012 12:08:17 AM
|
|
Terence <tbwright@bigpond.net.au> wrote:
(snip)
> It's not a transitive situation. The reverse may not be true (i.e things you
> can do with Common that you cannot do with modules (as expressed by a few
> postings above)..
One thing you can do with COMMON that I hope you can't do with
modules, is EQUIVALENCE overlap. Consider:
COMMON A(100),B(100),C
DIMENSION D(300)
EQUIVALENCE (A,D)
Now, the first 100 elements of D are EQUIVLANCEd with A (as you
expect), the next 100 EQUIVALENCEd to B (surprise) and element 201
with C (double surprise). (The double surprise happens when you
add a new variable onto a COMMON, not realizing the EQUIVALENCE
already there.)
-- glen
|
|
0
|
|
|
|
Reply
|
gah (12258)
|
6/3/2012 1:23:13 AM
|
|
In article <ron-shepard-831E38.13455202062012@news60.forteinc.com>, Ron
Shepard <ron-shepard@NOSPAM.comcast.net> writes:
> > Neither function calls the other directly. Yes, one can pass a variable
> > through several levels of routines, but that is even worse in terms of
> > readable code.
>
> Then this makes your proposal even more odd. I thought that one
> routine was supposed to declare the variables, and then other called
> routines were supposed to access them (like a contained routine, but
> compiled at the same level within the module) while the calling
> routine was active.
Yes, but the second routine is not directly called by the first, nor
vice versa.
> It seems to me like module variables are the exact fit to your
> programming problem. They provide a clear, simple, and unambiguous
> solution.
Yes, and that is the route I will take.
> Your proposed approach would be obscure, complicated, and
> ambiguous; :-) it just does not seem like a good fit to your problem.
I still think it would be nice if something could connect two low-level
routines without requiring a higher-level construct.
> If you are worried that it will complicate your build process by
> having to create a new file with that data module, then that is not
> necessary.
No, that's not an issue. All will be in one file.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/3/2012 8:31:32 AM
|
|
On 2012-06-01, Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de> wrote:
> To summarize: I think the above is the best solution. Again, the
> problem: There are many related routines which share many variables and
> it makes sense to have them all in one module. However, a few pairs of
> modules need to share a few variables between them.
Why don't you put these subroutines into one module, together with
the variables they need to share?
Seems they are closely related, anyway.
|
|
0
|
|
|
|
Reply
|
tkoenig1 (168)
|
6/3/2012 10:53:31 AM
|
|
In article <jqffnb$t1n$1@newsreader4.netcologne.de>, Thomas Koenig
<tkoenig@netcologne.de> writes:
> > To summarize: I think the above is the best solution. Again, the
> > problem: There are many related routines which share many variables and
> > it makes sense to have them all in one module. However, a few pairs of
> > modules need to share a few variables between them.
>
> Why don't you put these subroutines into one module, together with
> the variables they need to share?
Yes, that will work. There are several solutions which will work. I'm
just looking for the best one. Generally, I have related routines in
one module and one or maybe more modules in a file. Variables used by
most of the routines and/or by the calling program are module variables,
and hence seen by all. Some of the routines are only called by other
routines which are called by other routines etc. None of this is
visible to the calling program. Occasionally, pairs of low-level
routines need to share data. The goal was to avoid cluttering the main
module with this.
I think I'll create a separate module, in the same file, which will have
these low-level shared variables. Routines can then USE, ONLY the ones
they need.
(I generally make everything PRIVATE by default and explicitly specify
PUBLIC where needed. So, these variables wouldn't be visible to the
calling routine, but they are visible to the programmer.)
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/3/2012 11:33:24 AM
|
|
On 6/3/2012 3:31 AM, Phillip Helbig---undress to reply wrote:
....
> I still think it would be nice if something could connect two low-level
> routines without requiring a higher-level construct.
....
SUB A
REAL :: X
END
SUB B
REAL :: X
WORMHOLE :: X=A:X
END
maybe?
:)
--
|
|
0
|
|
|
|
Reply
|
none1568 (6651)
|
6/3/2012 1:05:51 PM
|
|
In article <jqfnfq$m2j$1@speranza.aioe.org>, dpb <none@non.net> writes:
> SUB A
> REAL :: X
> END
>
> SUB B
> REAL :: X
> WORMHOLE :: X=A:X
> END
>
> maybe?
Yes, something like this. Perhaps
SUB A
ALLOW B, ONLY: X !only B can mess with A, and only with the variable X
REAL :: X
END
SUB B
REAL :: X
WORMHOLE :: X=A:X
END
This is of course functionally equivalent to
SUB A
USE COMMON_STUFF
END
SUB B
USE COMMON_STUFF
END
MODULE COMMON_STUFF
REAL :: X
END
Imagine aside from A and B there are dozens of other routines in the
module. COMMON_STUFF is at the same level, but is there only to allow
A and B to share X. The (only) advantage of
REAL :: X
COMMON /STUFF/ X
in A and B is that there is no module necessary at the same level as
that containing A and B.
I'll probably do something like
SUB A
USE COMMON_STUFF, ONLY: A, B
END
SUB B
USE COMMON_STUFF, ONLY: A, B
END
SUB C
USE COMMON_STUFF, ONLY: C
END
SUB D
USE COMMON_STUFF, ONLY: C
END
SUB E
USE COMMON_STUFF, ONLY: X, Y, Z
END
SUB F
USE COMMON_STUFF, ONLY: X, Y, Z
END
SUB G
END
SUB H
END
SUB I
END
SUB J
END
MODULE COMMON_STUFF
REAL :: A, B, C, X, Y, Z
END
rather than having a module for each pair of routines which need to
share data.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/3/2012 1:38:56 PM
|
|
On 6/3/2012 8:38 AM, Phillip Helbig---undress to reply wrote:
> In article<jqfnfq$m2j$1@speranza.aioe.org>, dpb<none@non.net> writes:
>
....
>> WORMHOLE :: X=A:X
....
>> maybe?
>
> Yes, something like this. Perhaps
>
> SUB A
> ALLOW B, ONLY: X !only B can mess with A, and only with the variable X
> REAL :: X
> END
>
> SUB B
> REAL :: X
> WORMHOLE :: X=A:X
> END
>
> This is of course functionally equivalent to
>
> SUB A
> USE COMMON_STUFF
> END
>
> SUB B
> USE COMMON_STUFF
> END
> MODULE COMMON_STUFF
> REAL :: X
> END
>
> Imagine aside from A and B there are dozens of other routines in the
> module. COMMON_STUFF is at the same level, but is there only to allow
> A and B to share X. The (only) advantage of
>
> REAL :: X
> COMMON /STUFF/ X
>
> in A and B is that there is no module necessary at the same level as
> that containing A and B.
>
> I'll probably do something like
>
> SUB A
> USE COMMON_STUFF, ONLY: A, B
> END
> SUB B
> USE COMMON_STUFF, ONLY: A, B
> END
> SUB C
> USE COMMON_STUFF, ONLY: C
> END
....[further examples of similar elided for brevity]...
> MODULE COMMON_STUFF
> REAL :: A, B, C, X, Y, Z
> END
>
> rather than having a module for each pair of routines which need to
> share data.
Yes, that's what to me seems the logical solution if you're adamant that
you're going to make them GLOBAL as opposed to arguments.
BTW, I keep seeing your postings in reply to your own rather w/ my
responses quoted rather than as a reply to the response itself in the
newsreader...'tis somewhat confusing but don't know what to think about
the cause. I don't seem to see it w/ other postings.
--
|
|
0
|
|
|
|
Reply
|
none1568 (6651)
|
6/3/2012 2:11:50 PM
|
|
In article <jqfrb8$kc$1@speranza.aioe.org>, dpb <none@non.net> writes:
> Yes, that's what to me seems the logical solution if you're adamant that
> you're going to make them GLOBAL as opposed to arguments.
Since the routines don't call one another directly, passing arguments up
and down seems even worse.
> BTW, I keep seeing your postings in reply to your own rather w/ my
> responses quoted rather than as a reply to the response itself in the
> newsreader...'tis somewhat confusing but don't know what to think about
> the cause. I don't seem to see it w/ other postings.
I'm sure that I properly attribute and quote. Maybe some posts don't
arrive on your newsreader quickly enough and thus some are missing from
the thread.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/3/2012 2:56:49 PM
|
|
In article <jqfpdg$16r$1@online.de>,
helbig@astro.multiCLOTHESvax.de (Phillip Helbig---undress to
reply) wrote:
> SUB A
> USE COMMON_STUFF, ONLY: A, B
> END
> SUB B
> USE COMMON_STUFF, ONLY: A, B
> END
> SUB C
> USE COMMON_STUFF, ONLY: C
> END
> SUB D
> USE COMMON_STUFF, ONLY: C
> END
> SUB E
> USE COMMON_STUFF, ONLY: X, Y, Z
> END
> SUB F
> USE COMMON_STUFF, ONLY: X, Y, Z
> END
> SUB G
> END
> SUB H
> END
> SUB I
> END
> SUB J
> END
> MODULE COMMON_STUFF
> REAL :: A, B, C, X, Y, Z
> END
This looks reasonable to me. I don't know how important this might
be, and I also think this may be compiler dependent, but as a
practical matter it might be better to put the MODULE COMMON_STUFF
at the top of the file rather than at the bottom. This allows the
compiler to see the module before it sees the USE statements for it.
Other posts in this thread have said that this is required for some
compilers.
The fact that you are putting the module at the bottom reveals, I
think to some extent, your perspective on this. You are still
thinking of this as a substitute for a low-level hack rather than a
part of the high-level program structure. I don't think that is the
right way to look at this whole process. Data sharing is
intrinsically a high-level feature in the program, it is not a
low-level concept. Yes, if you have the low-level address of the
variable, then you can access it, but that is not the best way to
look at the issue. That is/was the problem with common blocks, they
subjugate the global sharing of data to within the individual
routines, and by making it a low-level language construct (basically
just address offsets and sequence association within the common
block), that is what opens the door to all of the problems
associated with common blocks. If instead you look at data sharing
as a high-level construct, something where you step back and start
looking at the overall program structure rather than the minute
details, then modules begin to make more sense. When you do this,
you realize that organization of the data within a program is just
as important as organization of the executable routines. This
happened to me when I used overlays with the program linker (pre
f77), which is why I mentioned this in the previous post, but that
is no longer an option for current programmers. So put that module
up at the top of the file and see if that gives you a different
perspective to this whole issue. :-) It really is a high-level
language concept, with the sharing of data being structured with
levels within levels within levels, just like the executable code is
structured.
You mentioned PRIVATE in order to hide those variables from the rest
of the calling program. There are many situations where I think
this would be useful, but I do not know how to do it. If you put
PRIVATE within MODULE COMMON_STUFF, then of course you cannot use
those variables anywhere else, which defeats the purpose of sharing
those variables. And once they are PUBLIC (whether declared or
not), then they really are PUBLIC for anyone to see.
So we have kind of an all-or-none situation now regarding sharing.
I've wondered about how the language might be changed to allow some
kind of restricted access. This isn't really a serious proposal,
but I've wondered about assigning a KEYWORD value to the PRIVATE
declaration which is matched with the same KEYWORD value on the USE
statement. I'm thinking that this would be a keyword/password kind
of value rather than a numeric value. USE by itself would allow
access only to the most public of variables, and access to the other
variables would require matching the corresponding keywords. If a
library is distributed without source code, then this would allow
partial access to the shared module variables while
protecting/hiding other variables completely. If the source code is
available to the programmer, then this might be used to prevent the
programmer from shooting himself in the foot and accessing some of
those variables unintentionally.
To give an example of this, suppose you use a library that does some
kind of iterative optimization. Normally a programmer would USE
OPTIMIZATION and the shared variables that he would access might
involve things like convergence tolerances and iteration limits.
But another programmer might need to access more fundamental aspects
of the process, such as specifying which nondefault algorithm to
use. So he might need something like USE OPTIMIZATION,
KEYWORD:CONFIGURE where CONFIGURE is what gives him access to those
additional variables. There could be multiple levels of these
keywords, revealing more and more details of the inner workings of
the optimization procedure. When the library is distributed, then
the documentation might include the description of the CONFIGURE
keyword only to those programmers who are developing algorithms
within the library, and normal end users of the library would never
know about those variables.
Well, it is a half-baked idea, but you can see where there is often
a need to do something like this. With the current situation, the
shared variables are either PUBLIC or PRIVATE, and you can either
access them or you can't, with nothing in between.
$.02 -Ron Shepard
|
|
0
|
|
|
|
Reply
|
ron-shepard (1197)
|
6/3/2012 4:57:12 PM
|
|
On 6/2/12 5:48 PM, Ron Shepard wrote:
> In article<jqdt8i$kco$1@speranza.aioe.org>, dpb<none@non.net>
> wrote:
>
>> On 6/2/2012 1:45 PM, Ron Shepard wrote:
>> ...
>>
>>> ... a file can have several modules within it. I usually put
>>> these small modules like this up at the top of the file, so the
>>> compiler sees the definition before it sees the USE statements, but I
>>> don't think most compilers care where they occur....
>>
>> They have to be such that the source of the module has been compile by
>> the time the compiler hits the USE statement or the compile will fail
>> (or use a potentially out-of-date .mod file).
>
> I encountered this long ago with the first f90 compilers that I
> used, but I think that modern compilers will scan through the file
> and compile things in the right order regardless. Mostly out of
> habit however, I still write code with the modules first, and USE
> statements later. If there are compilers that require this, then
> this module order is indeed more of a requirement than an esthetic
> choice.
>
> In any case, all of this is certainly compiler dependent and outside
> the scope of the fortran language standard itself.
>
> $.02 -Ron Shepard
The standard says
"At the time a USE statement is processed, the public portions of the
specied module shall be available."
It doesn't define "available", so it might mean anything from
pre-compiled to source code is in the same directory to you'll write it
when prompted. All the compilers I've used required pre-compiled
modules; but, that's not a requirement of the standard.
Back when I was young and foolish I had a project with a ton of modules
in a tree like structure with high level modules using lower level
modules, .... My normal method of compiling the whole project was to
delete all of the .mod and .o files and then repeat "compile *.f90"
commands until everything compiled. In the first compile, most of the
routines that had a USE statement would fail to compile; but, all the
base level modules would compile. The second compile was better, ....
I felt like a bad person for doing it this way; but, I couldn't think of
a better method that was truly system independent.
Dick Hendrickson
|
|
0
|
|
|
|
Reply
|
dick.hendrickson (1286)
|
6/3/2012 5:11:23 PM
|
|
Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de>
wrote:
> In article <jqfrb8$kc$1@speranza.aioe.org>, dpb <none@non.net> writes:
>
> > BTW, I keep seeing your postings in reply to your own rather w/ my
> > responses quoted rather than as a reply to the response itself in the
> > newsreader...'tis somewhat confusing but don't know what to think about
> > the cause. I don't seem to see it w/ other postings.
>
> I'm sure that I properly attribute and quote. Maybe some posts don't
> arrive on your newsreader quickly enough and thus some are missing from
> the thread.
I've been noticing the same thing, though it didn't seem worth fussing
about. It is just occasionally slightly confusing. No, I'm pretty sure
it has nothing to do with the newsreader (or the newshost). I know what
it looks like when a post is a followup to something that isn't (perhaps
yet) on the newhost I am using. Yours don't look like that. They look
like perfectly normal followups, but they are just followups to your own
articles rather than to what you are replying to.
It isn't the attribution or quoting. That's unrelated (and looks fine).
It is the xref header, which shows which post it is a followup to. I'm
not sure what posting software you are using (I don't see it obviously
indicated in the headers), so I can't help much on that.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
|
|
0
|
|
|
|
Reply
|
nospam47 (9742)
|
6/3/2012 5:11:46 PM
|
|
Dick Hendrickson <dick.hendrickson@att.net> wrote:
> Back when I was young and foolish I had a project with a ton of modules...
Must have been a long wait from when you were young until f90 compilers
were available. <ducks> :-)
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
|
|
0
|
|
|
|
Reply
|
nospam47 (9742)
|
6/3/2012 5:16:55 PM
|
|
On 6/3/2012 12:11 PM, Richard Maine wrote:
> Phillip Helbig---undress to reply<helbig@astro.multiCLOTHESvax.de>
> wrote:
>> In article<jqfrb8$kc$1@speranza.aioe.org>, dpb<none@non.net> writes:
>>
>>> BTW, I keep seeing your postings in reply to your own rather w/ my
>>> responses quoted rather than as a reply to the response itself in the
>>> newsreader...'tis somewhat confusing but don't know what to think about
>>> the cause. I don't seem to see it w/ other postings.
>>
>> I'm sure that I properly attribute and quote. Maybe some posts don't
>> arrive on your newsreader quickly enough and thus some are missing from
>> the thread.
>
> I've been noticing the same thing, though it didn't seem worth fussing
> about. It is just occasionally slightly confusing. No, I'm pretty sure
> it has nothing to do with the newsreader (or the newshost). I know what
> it looks like when a post is a followup to something that isn't (perhaps
> yet) on the newhost I am using. Yours don't look like that. They look
> like perfectly normal followups, but they are just followups to your own
> articles rather than to what you are replying to.
>
> It isn't the attribution or quoting. That's unrelated (and looks fine).
> It is the xref header, which shows which post it is a followup to. I'm
> not sure what posting software you are using (I don't see it obviously
> indicated in the headers), so I can't help much on that.
I wasn't really fussing; simply commented as it seemed to be consistent
and thought/figured Philip might recognize something was doing or a
setup if it were mentioned.
As you note, attributions/quoting and all are fine; just the XREF is
linked back to his posting as opposed to the one to which he is actually
responding. It is, as you say, no really, really big deal, just an
observed anomaly...
--
|
|
0
|
|
|
|
Reply
|
none1568 (6651)
|
6/3/2012 5:55:41 PM
|
|
On 2012-06-03 11:23 AM, glen herrmannsfeldt wrote:
> Terence<tbwright@bigpond.net.au> wrote:
>
> (snip)
>> It's not a transitive situation. The reverse may not be true (i.e things you
>> can do with Common that you cannot do with modules (as expressed by a few
>> postings above)..
>
> One thing you can do with COMMON that I hope you can't do with
> modules, is EQUIVALENCE overlap. Consider:
>
> COMMON A(100),B(100),C
> DIMENSION D(300)
> EQUIVALENCE (A,D)
>
> Now, the first 100 elements of D are EQUIVLANCEd with A (as you
> expect), the next 100 EQUIVALENCEd to B (surprise) and element 201
> with C (double surprise). (The double surprise happens when you
> add a new variable onto a COMMON, not realizing the EQUIVALENCE
> already there.)
Sincere apologies for dashing your hopes.
MODULE sequence_association_is_mostly_evil
IMPLICIT NONE
TYPE seq_type
SEQUENCE
REAL A(100)
REAL B(100)
REAL C
END TYPE seq_type
REAL :: D(300)
TYPE(seq_type) :: t
EQUIVALENCE (t,D)
END MODULE sequence_association_is_mostly_evil
PROGRAM Just_because_you_can_does_not_mean_you_should
USE sequence_association_is_mostly_evil
IMPLICIT NONE
D = 0.0
t%C = 1.0
PRINT *, D(201)
END PROGRAM Just_because_you_can_does_not_mean_you_should
I presume the number of use cases for this would be approaching the
number of programmers that think that the concept of COMMON was
fundamentally a good idea; and not just a necessary evil resulting from
the underlying implementation on machines of the day.
|
|
0
|
|
|
|
Reply
|
ian_harvey (217)
|
6/3/2012 7:39:43 PM
|
|
On 2012-06-01 9:00 PM, Phillip Helbig---undress to reply wrote:
....
> What I would really like to see is the possibility for a routine in a
> module to "use" what is essentially a local variable in another routine
> in the same module:
>
> module big
> contains
> subroutine alpha
> real :: x, y, z
> subroutine beta
> real :: a, b, c
> use alpha, only: x !maybe another word than "use"
> subroutine gamma
> subroutine delta
> subroutine epsilon
> end module big
>
> To make it safe, something similar to TARGET might be useful, e.g.:
>
> subroutine alpha
> real :: x, y, z
> allow beta, only: x
>
> Does anyone else see a need for this feature?
No.
1. Other solutions exist, whether they be submodules (processors that
support them are not far off - certainly a lot closer than any feature
that is just a thought bubble on clf); or the currently available
solution of creating a small helper module that simple has the shared
variable (if you want you could name(*) the module something like:
module big_helper__if_you_use_this_outside_of_big_I_will_kill_you
to discourage inadvertent use in the wrong place...); or if you feel
like afflicting your program with bizarre restrictions on the in-memory
placement of variables... common.
2. From a style and
trying-to-understand-what-the-hell-this-code-i-wrote_yesterday-does and
managing-program-complexity point of view - procedure internals, such as
local variables, should be internal to a procedure. Relatively opaque
links between units of code are a recipe for confusion, crisis and
chaos. If something is shared between scopes then the source code
should clearly reflect that.
(*) F2003 increased the number of characters permitted in a name to 63,
specifically to allow more colourful language to be used in describing
the consequences of inappropriate use of any named entities (sadly, I
hear that a related proposal to allow use of @!#% in identifiers where
context made it clear that the programmer was swearing at the reader
failed to get through). If you are restricted to F95, then you might
need to settle for appending "_internal" or something such similar,
perhaps augmented by some in source comments or explanatory sticky notes
placed around the periphery of your monitor or on the foreheads of your
co-workers.
|
|
0
|
|
|
|
Reply
|
ian_harvey (217)
|
6/3/2012 8:05:24 PM
|
|
In article <ron-shepard-8574EB.11571203062012@news60.forteinc.com>, Ron
Shepard <ron-shepard@NOSPAM.comcast.net> writes:
> This looks reasonable to me. I don't know how important this might
> be, and I also think this may be compiler dependent, but as a
> practical matter it might be better to put the MODULE COMMON_STUFF
> at the top of the file rather than at the bottom. This allows the
> compiler to see the module before it sees the USE statements for it.
> Other posts in this thread have said that this is required for some
> compilers.
Yes. Mine seems to want it as well. I would prefer it to be otherwise,
as this whole discussion is about how the relative importance of various
things is reflected in the source code.
> The fact that you are putting the module at the bottom reveals, I
> think to some extent, your perspective on this. You are still
> thinking of this as a substitute for a low-level hack rather than a
> part of the high-level program structure.
Probably to some extent.
> It really is a high-level
> language concept, with the sharing of data being structured with
> levels within levels within levels, just like the executable code is
> structured.
On one level, I agree. However, it has to be BEFORE the main module in
the file. I can just about accept it being a module (i.e. at the same
level as the main module), but now it has to come before the main module
in the source code. (Routines don't have to be ordered so that a given
routine has to occur in the file before the routine which calls it, but
variables do.)
> You mentioned PRIVATE in order to hide those variables from the rest
> of the calling program. There are many situations where I think
> this would be useful, but I do not know how to do it. If you put
> PRIVATE within MODULE COMMON_STUFF, then of course you cannot use
> those variables anywhere else, which defeats the purpose of sharing
> those variables. And once they are PUBLIC (whether declared or
> not), then they really are PUBLIC for anyone to see.
In this case, I was referring to private being the default and only
making things explicitly public which need to be. If the shared
variables are in their own module, of course, then they have to be
public. As "module variables" in the main module, they can be private,
as other routines in the module can see them.
> So we have kind of an all-or-none situation now regarding sharing.
> I've wondered about how the language might be changed to allow some
> kind of restricted access. This isn't really a serious proposal,
> but I've wondered about assigning a KEYWORD value to the PRIVATE
> declaration which is matched with the same KEYWORD value on the USE
> statement. I'm thinking that this would be a keyword/password kind
> of value rather than a numeric value. USE by itself would allow
> access only to the most public of variables, and access to the other
> variables would require matching the corresponding keywords. If a
> library is distributed without source code, then this would allow
> partial access to the shared module variables while
> protecting/hiding other variables completely. If the source code is
> available to the programmer, then this might be used to prevent the
> programmer from shooting himself in the foot and accessing some of
> those variables unintentionally.
This is not that different from my idea of accessing a locak variable in
one routine from another: one routine would USE (or some other word) the
other routine, but this routine would need an ALLOW statement for things
to be used. Sort of like TARGET but it would specify not only that
some other routine could access it but also which one.
I like the keyword/password concept for module variables.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/3/2012 9:11:15 PM
|
|
In article <1kl3yjv.ups13p1j6xppeN%nospam@see.signature>,
nospam@see.signature (Richard Maine) writes:
> I've been noticing the same thing, though it didn't seem worth fussing
> about. It is just occasionally slightly confusing. No, I'm pretty sure
> it has nothing to do with the newsreader (or the newshost). I know what
> it looks like when a post is a followup to something that isn't (perhaps
> yet) on the newhost I am using. Yours don't look like that. They look
> like perfectly normal followups, but they are just followups to your own
> articles rather than to what you are replying to.
Have my followups always been like this?
When I read threads, whether or not I am part of them, things appear in
the correct order to me.
> It isn't the attribution or quoting. That's unrelated (and looks fine).
> It is the xref header, which shows which post it is a followup to. I'm
> not sure what posting software you are using (I don't see it obviously
> indicated in the headers), so I can't help much on that.
The xref header I see (in all posts, just not my own) contains the
article number on the news server (not the message-ID). If this is a
new problem, maybe I can figure out what has changed. If not, I'm
surprised no-one has mentioned it before.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/3/2012 9:20:09 PM
|
|
On 6/3/2012 3:15 PM, David W Noon wrote:
....
> It most likely is the newsreader. It is not updating the References:
> header line properly, with the upshot that Philip's posts reference "one
> layer back" from what they should; when that missing layer is a
> follow-up to one of his posts, it looks like he is replying to himself.
....
Seems somewhat likely as it only occurs for his particular postings...
--
|
|
0
|
|
|
|
Reply
|
none1568 (6651)
|
6/3/2012 11:04:36 PM
|
|
Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de>
wrote:
> In article <1kl3yjv.ups13p1j6xppeN%nospam@see.signature>,
> nospam@see.signature (Richard Maine) writes:
>
> > I've been noticing the same thing, though it didn't seem worth fussing
> > about. It is just occasionally slightly confusing. No, I'm pretty sure
> > it has nothing to do with the newsreader (or the newshost). I know what
> > it looks like when a post is a followup to something that isn't (perhaps
> > yet) on the newhost I am using. Yours don't look like that. They look
> > like perfectly normal followups, but they are just followups to your own
> > articles rather than to what you are replying to.
>
> Have my followups always been like this?
I don't think so, though I suppose I might have overlooked it before, it
not being a horribly big deal. Maybe I'll try to search on some old
postings to check, but I didn't do so before writing this.
> When I read threads, whether or not I am part of them, things appear in
> the correct order to me.
Some newsreaders don't pay proper attention to the references header,
just showing you things in chronological order or some such thing. That
migt be the case.
> > It isn't the attribution or quoting. That's unrelated (and looks fine).
> > It is the xref header, which shows which post it is a followup to. I'm
> > not sure what posting software you are using (I don't see it obviously
> > indicated in the headers), so I can't help much on that.
>
> The xref header I see (in all posts, just not my own) contains the
> article number on the news server (not the message-ID). If this is a
> new problem, maybe I can figure out what has changed. If not, I'm
> surprised no-one has mentioned it before.
Oops. I mispoke in saying the xref header. I meant the References
header. For example, the post of yours that I'm replying to right now is
(from its Message-ID header) <jqgke9$m4j$2@online.de>. Its References
header ends with a reference to <jqftvh$540$1@online.de>, which is a
previous posting of yours. Therefore, that's what it looks like a
followup to. There is no reference to my
<1kl3yjv.ups13p1j6xppeN%nospam@see.signature> post anywhere in the
headers, although that's what you quoted from and appear to have
intended to follow-up to. That ID of mine appears in the citation of
your quote, but nowhere in the headers.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
|
|
0
|
|
|
|
Reply
|
nospam47 (9742)
|
6/3/2012 11:40:45 PM
|
|
Richard Maine <nospam@see.signature> wrote:
> Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de>
> wrote:
>
> > Have my followups always been like this?
>
> I don't think so, though I suppose I might have overlooked it before, it
> not being a horribly big deal. Maybe I'll try to search on some old
> postings to check, but I didn't do so before writing this.
Just went back and checked. No, all the ones I can still see look normal
enough, including even the ones in the "procedures as optional
arguments" thread that was also in the last few days. It just looks to
be in this thread that they are odd, but seems consistent in this
thread. Beats me as to why.
Probably some problem relating to communicating local data between posts
at the same level. :-)
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
|
|
0
|
|
|
|
Reply
|
nospam47 (9742)
|
6/3/2012 11:50:20 PM
|
|
On 6/3/12 2:39 PM, Ian Harvey wrote:
> On 2012-06-03 11:23 AM, glen herrmannsfeldt wrote:
>> Terence<tbwright@bigpond.net.au> wrote:
>>
>> (snip)
>>> It's not a transitive situation. The reverse may not be true (i.e
>>> things you
>>> can do with Common that you cannot do with modules (as expressed by a
>>> few
>>> postings above)..
>>
>> One thing you can do with COMMON that I hope you can't do with
>> modules, is EQUIVALENCE overlap. Consider:
>>
>> COMMON A(100),B(100),C
>> DIMENSION D(300)
>> EQUIVALENCE (A,D)
>>
>> Now, the first 100 elements of D are EQUIVLANCEd with A (as you
>> expect), the next 100 EQUIVALENCEd to B (surprise) and element 201
>> with C (double surprise). (The double surprise happens when you
>> add a new variable onto a COMMON, not realizing the EQUIVALENCE
>> already there.)
>
> Sincere apologies for dashing your hopes.
>
> MODULE sequence_association_is_mostly_evil
> IMPLICIT NONE
>
> TYPE seq_type
> SEQUENCE
> REAL A(100)
> REAL B(100)
> REAL C
> END TYPE seq_type
>
> REAL :: D(300)
> TYPE(seq_type) :: t
>
> EQUIVALENCE (t,D)
> END MODULE sequence_association_is_mostly_evil
>
> PROGRAM Just_because_you_can_does_not_mean_you_should
> USE sequence_association_is_mostly_evil
> IMPLICIT NONE
> D = 0.0
> t%C = 1.0
> PRINT *, D(201)
> END PROGRAM Just_because_you_can_does_not_mean_you_should
>
> I presume the number of use cases for this would be approaching the
> number of programmers that think that the concept of COMMON was
> fundamentally a good idea; and not just a necessary evil resulting from
> the underlying implementation on machines of the day.
Remember, SEQUENCE and MODULES were invented in the early to mid 80s.
Magic storage association was a big deal back then and SEQUENCE was
designed to make interaction with old FORTRAN programs, and new C
programs, possible. I'm positive the inventor of SEQUENCE didn't think
it was a good idea; he merely thought having it was better than not
having it.
Dick Hendrickson
|
|
0
|
|
|
|
Reply
|
dick.hendrickson (1286)
|
6/4/2012 12:23:33 AM
|
|
On 6/3/12 12:16 PM, Richard Maine wrote:
> Dick Hendrickson<dick.hendrickson@att.net> wrote:
>
>> Back when I was young and foolish I had a project with a ton of modules...
>
> Must have been a long wait from when you were young until f90 compilers
> were available.<ducks> :-)
>
Yeah, but not as long as the wait for F2008 compilers will be. ;)
Dick Hendrickson
|
|
0
|
|
|
|
Reply
|
dick.hendrickson (1286)
|
6/4/2012 12:24:41 AM
|
|
On 06/03/2012 03:38 PM, Phillip Helbig---undress to reply wrote:
> In article<jqfnfq$m2j$1@speranza.aioe.org>, dpb<none@non.net> writes:
> [...]
> I'll probably do something like
>
> SUB A
> USE COMMON_STUFF, ONLY: A, B
> END
> SUB B
> USE COMMON_STUFF, ONLY: A, B
> END
> SUB C
> USE COMMON_STUFF, ONLY: C
> END
> SUB D
> USE COMMON_STUFF, ONLY: C
> END
> SUB E
> USE COMMON_STUFF, ONLY: X, Y, Z
> END
> SUB F
> USE COMMON_STUFF, ONLY: X, Y, Z
> END
> SUB G
> END
> SUB H
> END
> SUB I
> END
> SUB J
> END
> MODULE COMMON_STUFF
> REAL :: A, B, C, X, Y, Z
> END
>
> rather than having a module for each pair of routines which need to
> share data.
It may complicate things even more, but since it was not yet mentioned yet:
module OO_approach
private
type, public :: f1_t
private
real :: A, B
contains
procedure :: sub_a
procedure :: sub_b
end type f1_t
contains
subroutine sub_a (f1)
class(f1_t), intent(...) :: f1
! can use f1%A and f1%B
end subroutine sub_a
subroutine sub_b (f1)
class(f1_t), intent(...) :: f1
! can use f1%A and f1%B
end subroutine sub_b
end module OO_approach
! ... then create objects of type f1_t and call sub_a and sub_b as
f1%sub_a and f1%sub_b
This is obviously overkill for the simple example. Like in the MODULE
implementation, the variables are declared outside the subroutines, but
you need extra typing.
But it has some advantages over both the COMMON and MODULE approaches:
there are no global variables (unless you choose to have an instance of
f1 as a global variable), so you can have several copies of A and B at a
given time. There is no way to access A and B except via an object of
type f1_t. You can specify intent for the passed object. You can count
on automatic deallocation of allocatable components in A and B. Etc.
Accessing local data of a function from outside always looks to me like
a poor-man's implementation of OO functionality, which could better be
implemented using the new OO syntax of Fortran. It requires F2003, but
this part is already available in many current compilers.
I would choose such a solution only if sub_a, sub_b and their associated
data can sensibly be grouped together (as seen by the logic of the
algorithm). But in that case, I'd prefer it over a MODULE or even
SUBMODULE solution.
-- Wolfgang
--
E-mail: firstnameinitial.lastname@domain.de
Domain: yahoo
|
|
0
|
|
|
|
Reply
|
seesig3208 (122)
|
6/4/2012 8:25:48 AM
|
|
In article <1kl4gcl.1p89n3d5vngowN%nospam@see.signature>,
nospam@see.signature (Richard Maine) writes:
> Oops. I mispoke in saying the xref header. I meant the References
> header. For example, the post of yours that I'm replying to right now is
> (from its Message-ID header) <jqgke9$m4j$2@online.de>. Its References
> header ends with a reference to <jqftvh$540$1@online.de>, which is a
> previous posting of yours. Therefore, that's what it looks like a
> followup to. There is no reference to my
> <1kl3yjv.ups13p1j6xppeN%nospam@see.signature> post anywhere in the
> headers, although that's what you quoted from and appear to have
> intended to follow-up to. That ID of mine appears in the citation of
> your quote, but nowhere in the headers.
OK, I'll investigate. I'm surprised no-one has noticed it before,
considering how many posts I have generated in the last 20 years (with
the same newsreader, and for the last 10 years via the same NNTP
server).
Is it more likely to be a problem with the news reader or the NNTP
server?
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/4/2012 8:30:22 PM
|
|
Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de>
wrote:
> In article <1kl4gcl.1p89n3d5vngowN%nospam@see.signature>,
> nospam@see.signature (Richard Maine) writes:
>
> > Oops. I mispoke in saying the xref header. I meant the References
> > header. For example, the post of yours that I'm replying to right now is
> > (from its Message-ID header) <jqgke9$m4j$2@online.de>. Its References
> > header ends with a reference to <jqftvh$540$1@online.de>, which is a
> > previous posting of yours. Therefore, that's what it looks like a
> > followup to. There is no reference to my
> > <1kl3yjv.ups13p1j6xppeN%nospam@see.signature> post anywhere in the
> > headers, although that's what you quoted from and appear to have
> > intended to follow-up to. That ID of mine appears in the citation of
> > your quote, but nowhere in the headers.
>
> OK, I'll investigate. I'm surprised no-one has noticed it before,
> considering how many posts I have generated in the last 20 years (with
> the same newsreader, and for the last 10 years via the same NNTP
> server).
>
> Is it more likely to be a problem with the news reader or the NNTP
> server?
I'd guess the reader to be more likely than the server, though I'd not
place money on it. I don't think the NNTP server normally does much with
the References header. I'd normally guess even more likely would be a
user mistake, except that it seems too consistent for that; the kinds of
mistakes I'm thinking of would not likely be that consistent.
As I noted in another followup, I'm only seeing it in this thread, but
it is quite consistent throughout this thread. I find that puzzling;
don't have a very good guess.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
|
|
0
|
|
|
|
Reply
|
nospam47 (9742)
|
6/4/2012 10:40:41 PM
|
|
On 6/4/2012 5:40 PM, Richard Maine wrote:
....
> As I noted in another followup, I'm only seeing it in this thread, but
> it is quite consistent throughout this thread. I find that puzzling;
> don't have a very good guess.
Hmmm....I hadn't noticed that before but that's same symptom here.
Peculiar. Sorry I brought it up. :)
--
|
|
0
|
|
|
|
Reply
|
none1568 (6651)
|
6/5/2012 12:17:15 AM
|
|
In article <1kl68m1.117l1cj18u0046N%nospam@see.signature>,
nospam@see.signature (Richard Maine) writes:
> I'd guess the reader to be more likely than the server, though I'd not
> place money on it. I don't think the NNTP server normally does much with
> the References header. I'd normally guess even more likely would be a
> user mistake, except that it seems too consistent for that; the kinds of
> mistakes I'm thinking of would not likely be that consistent.
I always use the REPLY/EDIT/EXTRACT function of my newsreader.
> As I noted in another followup, I'm only seeing it in this thread, but
> it is quite consistent throughout this thread. I find that puzzling;
> don't have a very good guess.
This post is just a test to see if the problem is still there.
|
|
0
|
|
|
|
Reply
|
helbig (4873)
|
6/5/2012 9:45:31 AM
|
|
On 6/5/2012 4:45 AM, Phillip Helbig---undress to reply wrote:
> In article<1kl68m1.117l1cj18u0046N%nospam@see.signature>,
> nospam@see.signature (Richard Maine) writes:
>
....
> This post is just a test to see if the problem is still there.
Yes, this shows up as a reply to yourself even though the reference to
Richard's reply is in the quoted text.
Puzzling, indeed...
--
|
|
0
|
|
|
|
Reply
|
none1568 (6651)
|
6/5/2012 12:52:35 PM
|
|
Dick Hendrickson <dick.hendrickson@att.net> wrote:
>> Back when I was young and foolish I had a project with a ton of
modules...
>Must have been a long wait from when you were young until f90 compilers
>were available. <ducks> :-)
>Richard Maine
From being young to F90? Going on 60 years
From first computer usage work to F90? About 40 years.
And 30 years from first Fortran use (late entry).
But the last 22 years seem to be just blah. :o{>
|
|
0
|
|
|
|
Reply
|
tbwright1 (218)
|
6/6/2012 5:58:40 AM
|
|
I'm using Outlook Express, and this application orders CLF new postings by
the posting that a response is applied to (not by date). So the logic is
very readable.
Google does something else - just sequentially by date and time
|
|
0
|
|
|
|
Reply
|
tbwright1 (218)
|
6/6/2012 6:02:50 AM
|
|
Was something cut out there? Or got lost? My original text said faster
coding, not faster .....
|
|
0
|
|
|
|
Reply
|
tbwright1 (218)
|
6/6/2012 6:05:56 AM
|
|
On 6-6-2012 8:03, Terence wrote:
> I'm using Outlook Express, and this application orders CLF new postings by
> the posting that a response is applied to (not by date).
....and apparently has problems with quoting the text you're responding to.
I'm pretty sure practically all news readers can sort by thread or by
date, at the user's choice, so that is nothing special.
The 'problem' with Phillip's postings is that somehow they don't refer
to the post he is replying to, but to a previous post upthread.
This somewhat breaks the "visual thread logic", but this is not to much
of a problem, because he properly quotes and attributes the posts he is
replying to.
The odd thing is that it didn't happen for his first couple of responses
in this thread, so somehow, somewhere some setting must have been changed.
Erik.
|
|
0
|
|
|
|
Reply
|
user195 (73)
|
6/6/2012 11:06:32 AM
|
|
No it doesn't. Express can leave the previous quote or allow me to remove
sections not relevant.
If I am responding to the previous selected quote (not the most recent by
date), but by theme order, then my resonse follows the text of that previous
one. One doesn't have to scroll down all that indented text to read the
reference or the response.
It works for me. Sorry if you are using another application which doesn't.
|
|
0
|
|
|
|
Reply
|
tbwright1 (218)
|
6/7/2012 8:40:37 AM
|
|
Yes:
"blocks can make coding clearer, shorter, and faster. "
(Describing the process of coding)
|
|
0
|
|
|
|
Reply
|
tbwright1 (218)
|
6/7/2012 8:45:15 AM
|
|
Terence <tbwright@bigpond.net.au> wrote:
(In entirety, I have not omitted a single word or citation)
> No it doesn't. Express can leave the previous quote or allow me to remove
> sections not relevant.
> If I am responding to the previous selected quote (not the most recent by
> date), but by theme order, then my resonse follows the text of that previous
> one. One doesn't have to scroll down all that indented text to read the
> reference or the response.
>
> It works for me. Sorry if you are using another application which doesn't.
I'd think the above a great job of irony, except that I (think I) know
better. It certainly is a perfect illustration of Erik's point using an
ironic method of exposition.
I'm moderately confident that Erik in turn was being slightly sarcastic
in saying that OutLook Express "apparently has problems with quoting the
text you're responding to". I suspect he knew that the problem was in
how Outlook Express was being used rather than in what it could do.
This actually has the opposite problem of the one that Phillip is
having. Phillip carefully cites things, but the References header is
wrong (in this thread). Fortunately the careful citation makes things
clear enough in spite of the odd headers. Here we have correct headers,
but complete lack of citation. That makes this much harder to follow.
Tying a little bit back to Fortran as a topic, we also have here an
illustration of part of why we have standards, both formal and informal.
One can pay attention to the standards, or one can take the attitude
that "it worked fine for this particular case for my
newsreader/compiler, so too sorry for anyone else."
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
|
|
0
|
|
|
|
Reply
|
nospam47 (9742)
|
6/7/2012 4:22:13 PM
|
|
|
79 Replies
53 Views
(page loaded in 0.776 seconds)
Similiar Articles: Finding environment variables usage - comp.unix.programmer ...Hi everybody, How can I find which environment variables a certain process is using? Any ideas? ... libraries used, and recursively check they are in the restricted ... Modifying MEX arguments in place? - comp.soft-sys.matlab ...That would be impossible if other variables were allowed to share only portions of the data block ... Ideas and suggestions are welcome. Petr PS: Here is the test that ... implementing neural networks online - comp.soft-sys.matlab ...By offline I mean having the I/O variables saved to the ... The two will share the same inputs and there will ... syntax of S-function really freak me out. Any suggestions? GLIMMIX with binary data - comp.soft-sys.sasHowever, I would make a couple of suggestions with your ... link=logit; random BirdID; If the reponse variable ... Could you please share some of your insight ... struct/union difference - comp.lang.c++.moderatedThe point at issue was that if two variables at class scope were to share storage, how should that be ... Can Do It!' see http://www.spellen.org/youcandoit For project ideas ... nitializing a static vector <> of integers (this static vector... it possible to have a vector of static pointer variables? ... methods - its a template! it is a generic way of sharing ... http://www.spellen.org/youcandoit For project ideas ... Single Reader, Single Writer FIFO - comp.programming.threads ...... Oh boy, you introduced false-sharing ... lock-free-algorithms/false-sharing---false Also, you need to declare the variables as ... If your main reader is truly restricted ... Static reflection - a base for runtime reflection? - comp.lang.c++ ...... am willing to learn more on that subject, share my thoughts. If you have good links on that topic, your own ideas ... name of qualifiers, name of parameter variables etc ... Question on GUI's? - comp.lang.java.guiany suggestions? > Ian I suppose there are multiple ways ... would take a look at using CardLayout for the variable ... mathworks ... for managing data can be used to share ... Semaphore tutorial? - comp.unix.programmer... describes how it affects the kernel's > semadj variable ... Multiple processes sharing a single mutex - comp.unix ... Tutorial - Microsoft Research - Turning Ideas into ... finding the closest number in an array - comp.soft-sys.matlab ...... idx=1. > > Any ideas? Probably simplest to code is to simply make the restricted test array another variable ... simply make the restricted test array > another variable ... Cannot execute command error - comp.text.tex... the network as the Q > drive is restricted and thus the profile paths cannot be changed. ... Execute a FORMULA in text variable - comp ... Can't shl_load() a library ... - comp.sys.hp.hpuxAny suggestions? I'm using HP11.0 and HP11.11. Any patches available for this particular problem. ... after setting > > this env variable ... synchronize.m for Timeseries - comp.soft-sys.matlab... say ts1 is a predictive signal of ts2 (a random variable). ... I just want them to share t... ... Synchronizing time ... LCD / 7 segment font suggestions - comp.fonts Synchronizing ... comp.soft-sys.sas - page 17Inbound attachment usage restricted by BP policy (Replaced ... d algorithm for decoding the Borland "real48" variables ... days so I thought I would see anyone had any ideas. Knowledge Sharing: Two-Dimensional Motivation Perspective and the ...... extrinsic rewards, OCB and demographic variables on knowledge sharing. ... Access to full text is restricted to subscribers. ... No references listed on IDEAS You can help add ... Proposed Changes in Accounting Treatment of Stock Options Prompt ...... entitle the holder to receive the appreciation in value of a share ... generally cannot be used under APB 25 without triggering variable accounting charges. Restricted Stock ... 7/28/2012 4:49:06 AM
|