interface, subroutine procedure_name(arguments)
which would be equivalent to:
private :: dummy_procedure_name
interface procedure_name
module procedure dummy_procedure_name
end interface
subroutine dummy_procedure_name(arguments)
real, dimension(20) :: a
print *, a(1:10:2)
This operator even works with arrays of derived type:
type (something), dimension(20) :: b
print *, b(1:10:2)
However, it will not work with derived types which contain pointers to arrays. These are useful if one needs to specialize arrays in some way. For example, if one defines:
type something_else
real, dimension(:), pointer :: ptr
integer :: special_attribute
end type
type (something_else) :: special_array
one can refer to:
special_array%ptr(1:10:2)
but not to:
special_array(1:10:2)
C++ has subscript operators [] for this purpose, which are primitive versions of subsection operators (see, e.g, Lippman's C++ Primer, pp. 54-55).
Such a type is useful, for example, in describing a collection of
particles, where a pointer to the particle coordinates are stored
along with particle descriptors such as charge and mass. Since I
would like to encapsulate (make private) the components of
something_else, it would be useful to be able to say:
special_array(1:10:2)
and define that operation to mean:
special_array%ptr(1:10:2)
What I have in mind here is allowing user defined procedures to be equated to the operator '()'. This would be similar to how the multiply '*' operator is overloaded. In other words, I might have something like:
interface operator (())
module procedure do_something
end interface
contains
function do_something(a,i,j,k) result(r)
type (something_else) :: a, r
integer :: i, j, k
r%ptr = a%ptr(i:j:k)
r%special_attribute = a%special_attribute
end function do_something
As pointed out by
James B. White III, however, the fact that
array syntax exists for arrays of derived types (and presumably
could not be redefined), leads to some syntactical difficulties.
For example, how does one refer to a subsection of an element:
type (something_else) :: array_of_special_arrays(10)
array_of_special_arrays(1)(i:j:k)
Or a subsection of a subsection:
array_of_special_arrays(l:m:n)(i:j:k)
Things get even more complicated in multiple dimensions. Without such a feature, it is very clumsy to build a class of specialized arrays. In C++ this is reasonably straightforward since the subscript operators are primitive. But Fortran90 has a powerful array syntax, and incorporating this will take some care.
use module_name
private :: module_name
which would means that every name in the module is private.
Emulation of protected status is not possible, however, for components of a derived type. If they are public in the first module, they are public forever (unless the type name itself is made private). It is useful for efficiency reasons to allow a group of related modules to gain access to components. But for program safety and encapsulation one does not want universal access. Thus if the components of "something" are public in one module:
type something
real :: x
end type
then a second module which uses the first could do something like:
private, components :: something
which leaves the name "something" public, but its components are now private.
character*(:) c
allocate(c(len=4))
character*2, dimension(2) :: d = (/'22','3'/)
The only way to do this currently is to add trailing blanks:
character*2, dimension(2) :: d = (/'22','3 '/)
It is a nuisance to add trailing blanks all over the place.