Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Good practice in naming derived types in fortran

I'd like to optimize the readability of my codes in Fortran by using OOP. I thus use derived types. what is the best practice to name the types and derived types?

For example, is it better to:

type a
    real :: var
end type
type(a) :: mya

or always begin type names by type_ like in type_a? I like this one but maybe better ideas can be foud.

Also, is it better (then why) to use short names that are less readable or longer names that end up quite difficult to read if the type has too many "levels". For example, in a%b%c%d%e, if a, b, c, d and e are 8 or more letters long as in country%hospital%service%patient%name, then once again readability seems to be a concern.

Advices from experts are really welcome.

like image 354
max Avatar asked Mar 24 '23 08:03

max


2 Answers

This not anything special to Fortran. You can use coding recommendation for other languages. Usually, type names are not designated by any prefix or suffix. In many languages class names start with a capital letter. You can use this in Fortran also, even if it is not case sensitive. Just be sure not to reuse the name with a small letter as a variable name.

One example of a good coding guideline is this and you can adapt it for Fortran very easily. Also, have a look on some Fortran examples in books like MRC or RXX. OS can be also useful.

I would recommend not to use too short component names, if the letter is not the same as used in the written equation. In that case it can be used.

Use the associate construct or pointers to make aliases to nested names like country%hospital%service%patient%name.

like image 200
Vladimir F Героям слава Avatar answered Apr 25 '23 13:04

Vladimir F Героям слава


In my experience, naming issues come up in OO Fortran more than other languages (e.g. C++) because of Fortran's named modules, lack of namespaces, and case-insensitivity, among other things. Case-insensitivity hurts because if you name a type Foo, you cannot have a variable named foo or you will get a compiler error (tested with gfortran 4.9).

The rules I have settled on are:

  • Each Fortran module provides a single, primary class named Namespace_Foo.
  • The class Namespace_Foo can be located in your source tree as Namespace/Foo_M.f90.
  • Class variables are nouns with descriptive, lower case names like bar or bar_baz.
  • Class methods are verbs with descriptive (but short if possible) names and use a rename search => Namespace_Foo_search.
  • Instances of class Namespace_Foo can be named foo (without namespace) when there is no easy alternative.

These rules make it particularly easy to mirror a C/C++ class Namespace::Foo in Fortran or bind (using BIND(C)) a C++ class to Fortran. They also avoid all of the common name collisions I've run into.

Here's a working example (tested with gfortran 4.9).

module Namespace_Foo_M
implicit none

type :: Namespace_Foo
  integer :: bar
  real    :: bar_baz
  contains
  procedure, pass(this) :: search => Namespace_Foo_search
end type

contains

function Namespace_Foo_search(this, offset) result(index)
  class(Namespace_Foo) :: this 
  integer,intent(in)   :: offset !input
  integer              :: index  !return value
  index = this%bar + int(this%bar_baz) + offset
end function

end module

program main
use Namespace_Foo_M !src/Namespace/Foo_M.f90

type(Namespace_Foo) :: foo

foo % bar = 1
foo % bar_baz = 7.3

print *, foo % search(3) !should print 11

end program

Note that for the purpose of running the example, you can copy/paste everything above into a single file.

Final Thoughts

I have found the lack of namespaces extremely frustrating in Fortran and the only way to hack it is to just include it in the names themselves. We have some nested "namespaces", e.g. in C++ Utils::IO::PrettyPrinter and in Fortran Utils_IO_PrettyPrinter. One reason I use CamelCase for classes, e.g. PrettyPrinter instead of Pretty_Printer, is to disambiguate what is a namespace. It does not really matter to me if namespaces are upper or lower case, but the same case should be used in the name and file path, e.g. class utils_io_PrettyPrinter should live at utils/io/PrettyPrinter_M.f90. In large/unfamiliar projects, you will spend a lot of time searching the source tree for where specific modules live and developing a convention between module name and file path can be a major time saver.

like image 24
wawiesel Avatar answered Apr 25 '23 12:04

wawiesel