openlang

Calling procedures across sibling submodules

Each parent module and submodule lives in a separate file, as illustrated here. Is use association a way for submodule D to invoke a procedure from submodule C?

(File) module root_mod

|

|—(File) submodule C

| public module procedure taskC

|

|—(File) submodule D

use submodule C ? or use root_mod:submodule C

call taskC

The conversation continues 3

Follow the reasoning
  1. Permalink

    They can invoke one another after two adjustments:

    • Put interfaces for the child routines into the parent module

    • You don't need use, as every child shares that parent module

    A full working example follows:

    demo.f90:

      module root_mod
      implicit none
      interface
      module subroutine routine_c()
      end subroutine routine_c
      module subroutine routine_d()
      end subroutine routine_d
      end interface
      end module root_mod
    
      program demo
      use root_mod
      implicit none
      call routine_d()
      end program demo

    c.f90:

      submodule(root_mod) c
      implicit none
      contains
      module subroutine routine_c
      print *, "hello from routine_c"
      end subroutine routine_c
      end submodule c

    d.f90:

      submodule(root_mod) d
      implicit none
      contains
      module subroutine routine_d
      print *, "hello from routine_d"
      call routine_c()
      end subroutine routine_d
      end submodule d
  2. Permalink

    Sibling Fortran submodules don't know that the others exist. The hierarchy of submodules can, however, be extended as far as you need:

      module root1
      implicit none
      ...
      end module root1
    
      submodule (root1) layer1
      implicit none
      interface
      module subroutine task1() ! visible to descendants of layer1 but not to root1
      end subroutine
      end interface
      end submodule layer1
    
      submodule (root1:layer1) layer2
      implicit none
      contains
      subroutine perform_task()
      call task1()
      end subroutine
      end submodule layer2
    
      submodule (root1:layer1) layer3
      implicit none
      contains
      subroutine perform_task()
      call task1()
      end subroutine
      end submodule layer3

    Observe that both layer2 and layer3 define perform_task, because as siblings they cannot see one another's declarations.

Other sides of the same question

  1. Choosing enum entries randomly with GDScript in Godot 3.3 without listing each one?

    Here's the enum declaration I'm using in GDScript: I'd like to choose an enum variant randomly without listing every possible…

    Replies 2Latest activity gdscript
  2. Nim remainder syntax

    How is modulus expressed in Nim? cell % 7 == 0 gives undeclared identifier: '%' Neither a Google search nor looking through S…

    Replies 2Latest activity nim
  3. Returning results from an APL function

    How do I make my function return something once execution has finished? For instance, I have: ROUTINE N ? N ⍴ 12 //That gener…

    Replies 2Latest activity apl