j3-fortran / fortran_proposals

Proposals for the Fortran Standard Committee
178 stars 15 forks source link

Allow a submodule to be USEd by another submodule #121

Open qolin1 opened 4 years ago

qolin1 commented 4 years ago

I have 3 submodules, called  AA, BB, and CC, and an ancestor module KK. I also have 2 vanilla modules XX and YY that hold data (no procedures). I would like to restrict access to XX and YY so they can only be used by descendants of KK. At present the only way to do this is to move the code defining that data from XX and YY so it appears in module KK. This works.

Suppose now that I would like to restrict access to this data within the submodules. Suppose I want AA and BB to have access to the data originally in XX, but disallow CC from such access. This can be achieved, but it requires an additional submodule to be created: let's call it sXX. sXX must be a direct descendant of KK; and AA and BB must be made descendants of sXX. The data that was in XX must appear in sXX. Again, this works.

Suppose now that I realize that AA should NOT have access to the data originally in module YY, but it must remain available to BB and CC. ...AFAICS, there is no way to arrange the tree of the submodules to achieve this. I can, of course, go back to the original setup, where XX and YY are vanilla modules, but this means they would be "public", available to all other code in the program.

What I propose, therefore, is to allow a submodule like sXX to be named on a USE statement in another submodule, providing they both have the same ancestor. AFAIK one cannot specify a submodule name on a USE statement, so relaxing this rule within a submodule set seems appropriate to me. This would allow data to be shared in a flexable way, while keeping it private inside the submodule set.

I guess there would need to be some rule requiring sXX to contain only data... or maybe not? Would it be useful to restrict access to procedures as well? Not sure of this...

certik commented 4 years ago

@qolin1 Would the proposal #86, if implemented, allow you to arrange the (sub)modules AA, BB and CC the way you want?

qolin1 commented 4 years ago

...Er, I'm not really sure, but I think the answer is no.

My understanding of #86 is that it allows additional functionality to be expressed via USE statements, in a situation where USE is already allowed.

But this proposal (#121) requests that USE statements be allowed in a situation where they are currently prohibited.

...Assuming I get the right end of the #86 stick...

certik commented 4 years ago

I am not sure I follow your reasoning. The #86 is to allow modules to be nested, and used, so it seems it would cover your use case also. To clarify this, would you mind posting an example code of the modules AA, BB, CC, XX, YY to show exactly what you are trying to achieve, and then let's discuss it.

qolin1 commented 4 years ago

Nesting is allowed in submodules already, but as I explained originally, it does not fix my case. #86 proposes the nesting of modules, but AFAICS that would not render them private to any other module: all public modules would remain public.

The submodule approach allows the data to be shared among submodule routines, while preserving its privacy.

Attached is example code demonstrating what I would like. Note that it doesn't compile.

test_121_desired.f90.txt

qolin1 commented 4 years ago

Closed in error, so repoened.

certik commented 4 years ago

Thanks for the code. Here is how you would do this if #86 is implemented:

module kk
   implicit none
   use kk%aa, only: aa_sub
   use kk%bb, only: bb_sub
   use kk%cc, only: cc_sub
end module kk

!------------------------------------------------------------------

module (kk) sXX
   implicit none
   real(8) :: xxa(100) = 99d0
end module

!------------------------------------------------------------------

module (kk) sYY
   implicit none
   real(8) :: yya(100) = 88d0
end module

!------------------------------------------------------------------

module (kk) aa
   contains
      module subroutine aa_sub
      use kk%sXX
      ! this routine should have access to XXA, but not YYA
      xxa(1) = 66.
  !!  yya(2) = 77.  ! ... should not be able to access YYA
      end subroutine
end module

!------------------------------------------------------------------

module (kk) bb
   contains
      module subroutine bb_sub
      use kk%sXX
      use kk%sYY
      ! this routine should have access to XXA and YYA
      xxa(2) = 77.
      yya(2) = 77.
      end subroutine
end module

!------------------------------------------------------------------

module (kk) cc
   contains
      module subroutine cc_sub 
      use kk%sYY
      ! this routine should have access to YYA, but not XXA
 !!   xxa(2) = 88. !  ... should not be able to access XXA
      yya(3) = 88.
      end subroutine
end module
qolin1 commented 4 years ago

OK, Looks good ... does this module nesting then achieve everything that submodules currently offer? Is it in fact a superset of submodules, aka "submodules done better" ?

qolin1 commented 4 years ago

Ah, and I forgot to ask: is any other code in the app allowed to USE kk%sYY ? Or is access to it restricted to modules within the KK nest?

klausler commented 4 years ago

OK, Looks good ... does this module nesting then achieve everything that submodules currently offer? Is it in fact a superset of submodules, aka "submodules done better" ?

No, they're quite distinct concepts. Submodules implement things declared by their ancestors, whose definitions are implicitly USE'd in the submodule. Nested modules declare things to be used by their containers, which would not be automatically USE'd.

qolin1 commented 4 years ago

OK so the killer feature of submodules is the separation of interface from implementation, and thus breaking the compilation cascade. It appears that nested modules does not allow this. Hence my original request to enhance submodules stands.

vansnyder commented 4 years ago

Submodules can have submodules. Would this solve the original problem?

qolin1 commented 4 years ago

No. Any given Submodule is only allowed to have exactly one parent (sub) module. The whole point of my proposal is to allow a (sub-)submodule to access entities outside of the direct line of submodule ancestry, while restricting those entities from being public to the rest of the program.

Great to make your acquaintance BTW, I love the stuff you have written on nuclear power.