Simple way to implement a group of queues in Fortran? - templates

Suppose that I need to implement at least 5 queues in one procedure, each of it from a different defined type. How can achive this in a simple and short way?.
Another way to see the question is the way that came to me: after a lot of time of defining my own structures in fortran, I had to make a program in C++, and then I saw how easy is the use of templates... now, I want the same in my mother tongue....
seems that the knowledge is not always confortable
Thanks a lot!

Have you considered unlimited polymorphic pointers? See, for ex., pp 269 ff in "Modern Fortran Explained".

I have implemented the fortran template in Ruby, which is integrated in my CodeMate. The template syntax is similar to C++. I have implemented double linked list. The template definition snippets are as following:
...
template:list_t <type elem_t>
type list_t
integer :: num_elem = 0
type(elem_t), pointer :: head, tail
contains
...
procedure :: insert => list_insert
...
end type list
...
template:list_insert#list_t <type elem_t>
subroutine list_insert(this, elem, ...)
class(list_t), intent(inout) :: this
type(elem_t), intent(out), pointer :: elem
...
end subroutine list_insert
And the template instance is as following:
type(list_t<foo_t>) foo_list
where foo_t is a user-defined type that extends list_elem_t<foo_t>. The you can insert element into foo_list by
call foo_list%insert(elem, ...)
I think my solution to Fortran template is natural.

If you really want templates, there is Pyf95++. It brings templating and an STL for Fortran using a preprocessor. (for download here)
A generic linked-list that uses transfer() can be found in FLIBS.
(Otherwise with a bleeding edge compiler you can use unlimited polymorphism as suggested by Richard Lozes.)

Related

How do variable declarations within types work in Fortran?

I'm trying to learn Fortran, and I've found that there aren't very many tutorials out there (probably due to it being an old language). The ones I have found are vague and undescriptive, and as I've gone into more complex things it has become harder and harder to guess what said tutorials are saying.My current issue is with creating types. The tutorial contains examples such as:
module m_shapes
implicit none
private
public t_square
type :: t_square
real :: side
contains
procedure :: area ! procedure declaration
end type
contains
! Procedure definition
real function area(self) result(res)
class(t_square), intent(in) :: self
res = self%side**2
end function
end module m_shapes
This compiles fine, so I know it works.
When I try to do something similar like this:
program type_test
implicit none
type :: thingy(a)
real :: a
end type
end program
It doesn't compile with errors like "The component at (1) that appears in the type parameter list at (2) has neither the KIND nor LEN attribute"
The tutorial I found does not explain types well enough, and I've tried things like real,kind :: a = kind(0.0), but to no avail. Does anybody know what's wrong?
Thanks in advance.
You did not explain, what you actually want to do. Or your words are not nearly clear enough. We can tell you why your attempt produces the error, but I have no idea what you actually want to do.
Perhaps you just wanted
program type_test
implicit none
type :: thingy
real :: a
end type
end program
without the (a)? That declares a simple type with one component. But hard to guess if this is what you wanted and what you tried with the (a).
It does not declare any variable with that type. That is done using
type(thingy) :: var
The syntax
type :: thingy(a)
real :: a
end type
attempts to declare a parametrized derived type. These types can depend on a kind or length parameter. These parameters must be integers. If it is a kind parameter, it allows to declare variables of the type with varying values of these parameters. Then the kind of some components of the type (you know what kind is, right? Fortran 90 kind parameter ) get their kind according to the value of the parameter. If it is a length parameter, it allows the length of some array or string components of the derived type to be parametrized - set during the variable declaration.
These parameters that appear in the parenthesis must be integer components and must have the kind or len attribute.
For example
type :: param_type(k,l)
integer, kind :: k
integer, len :: l
real(kind=k), dimension(l) :: array
end type param_type
type(param_type(kind(1.), 10)) :: o_sp_10
type(param_type(kind(1.d0), 20)) :: o_dp_20
The values of the parameters are set during the declaration of those o_sp_10 and o_dp_20 objects. I do not want to go into more details.

variable length array in derived type

I am mostly doing scientific programming in Python and do not have a whole lot of Fortran (90/95) experience. For one of my projects I want to define a derived type and overload a bunch of operators for that type. Critically, I'd like one of the variables of the derived type to an array of variable length; at least, I need two different lengths in different parts of the code. How can I best achieve this efficiently and avoiding code duplication?
My first approach was to use an allocatable array but that involved several allocate statements throughout the code including the overloaded operators. It also led to difficulties when using the code in an MPI application.
My current approach is two define a type of the same name in two separate modules and use one or the other in different parts of the code. The overloaded operators can be shared using a header file (mytype_operators.h in the example below).
module mod1
type mytype
real :: x1
real,dimension(1) :: x2
end type mytype
#include "mytype_operators.h"
end module mod1
module mod2
type mytype
real :: x1
real,dimension(10) :: x2
end type mytype
#include "mytype_operators.h"
end module mod2
Unfortunately, there is one module in the code with subroutines that I would like to use for both types. Currently I have two copies of that code; one with "use mod1", the other with "use mod2". Can I improve this and avoid the code duplication?
Your case is very suitable for using a Fortran feature introduced in the 2003 standard (and adopted much later by compilers) named parameterized derived types. First of all, you should check the compliance status of your compiler to know if it's fully supported.
This feature allows you to pass custom parameters when declaring or constructing a derived-type, so internal functionality will be adjusted accordingly. They are good for having different behaviour alternatives grouped in a single type name, possibly with considerable coding or storage differences. There are 2 types of parameters:
kind parameters behave much like the kind specifier of intrinsic types. Kind parameters of all variables must be known at compile time and are treated practically as constant values. The convenience is that you could change it easily (in code time) by altering just a value in the declaration or construction. This is commonly used for specializing the kind of components of intrinsic type.
len parameters behave much like the len specifier of intrinsic character type. You can define len parameters at compile time or runtime, and a len parameter of a variable cannot change unless you declared it allocatable. Moreover, you can have arguments with assumed len-parameters in procedures, and avoid code verbosity. This is commonly used as a "length" or "dimension" parameter for a derived type, because you can use them in the declaration of array bounds and character length.
In general, type parameters are used to mimic the functionality of intrinsic types in derived types, but you could also get "creative" and use it for other things, like the dimension-space of a transformation-matrix type; for a custom "union type" (like an enumeration); as the nature of a physical quantity in a "units of measurement" data-type (a real value annotated with "mass" unity is not directly compatible with a "temperature" one, but they can be handled pretty much the same way in the code); the "arity" of a tuple type...
module mod1
type :: mytype(n)
integer, len :: n
real :: x1
real, dimension(n) :: x2
end type mytype
contains
! your operations here...
end module mod1
And use it like this:
program test_pdt
use mod1
implicit none
type(mytype(10)) :: mt10
type(mytype(1)) :: mt1
integer :: i
mt10%x1 = 40.0
mt10%x2 = [(0.5 * i, i = 1, 10)]
mt1 = mytype(1)(20.0, [30.0])
call sub(mt10)
call sub1(mt1)
contains
subroutine sub(m)
! accepts values with any "n" parameter
type(mytype(*)) :: m
! you can also use them in declarations
integer, dimension(m%n + 1) :: y
type(mytype(m%n)) :: w
print *, m%n, w%n, size(y)
end
subroutine sub1(m)
type(mytype(1)) :: m ! only accepts values with n=1
print *, m%x1, m%x2, m%n
end
end
Warning:
This is feature, despite of having been announced many years ago, was just recently added to most compilers, and you should be aware that there are still some bugs in implementation. You should probably be fine with regular use, but I often face false syntax errors in some corner cases, and even ICE sometimes.

It is possible to have implicit kind in a Fortran procedure

Taking a procedure such as
function c(a,b)
integer,parameter :: dp=kind(2.0e0)
real(kind=dp),intent(in) :: a,b
real(kind=dp) :: c
c=a+b
end function
Is there a way to call the same function in the same program with different kinds? For example:
program help
integer,parameter :: sp=kind(2.0d0),dp=kind(2.0e0)
print *, c(2.0_dp,3.0_dp)
print *, c(2.0_sp,3.0_sp)
end program
I know that I can write again the function c using sp parameters and give an interface that hide the two in one, but I'm looking for a solution that don't need to create another function... may be just modify the existing one?
No, there is no way to write a function that accepts arguments of the different kinds of real (or any of the other intrinsics). As you already know, the standard way to write code which is kind-indifferent is to write implementations for each of the kinds you are concerned with and to wrap them in an interface.
You could, if you prefer something more kludgy, write a routine for low-precision kinds which wraps a call to the matching routine for high-precision kinds and incorporates some kind adjustment. Personally I prefer the interface route to this.
Finally, you may well find that your compiler allows you to get away with passing arguments of the wrong kind to a routine, performing some automatic kind adjustment behind the scenes. This is non-standard and likely to be non-portable.

What's the difference (if any) between Standard ML's module system and OCaml module system?

My question is if there is any difference between Standard ML's module system and OCaml module system? Has OCaml all the support of functors , ascriptions etc... that SML has?
There are some differences feature-wise, as well as semantically.
Features SML supports but not OCaml:
transparent signature ascription
module-level let
symmetric sharing constraints
syntactic sugar for functors over types and values
Features OCaml 4 has but not SML:
higher-order functors
recursive modules
local modules
nested signatures
modules as first-class values
general module sharing (sig with module A = M)
module type of
Several SML implementations provide some of these as extensions, however: e.g. higher-order functors (SML/NJ, Moscow ML, Alice ML), local and first-class modules (Moscow ML, Alice ML), module sharing (SML/NJ, Alice ML), nested signatures (Moscow ML, Alice ML), and recursive modules (Moscow ML).
Semantics-wise, the biggest difference is in the treatment of type equivalence, especially with respect to functors:
In SML, functors are generative, which means that applying the same functor twice to the same argument always yields fresh types.
In OCaml, functors are applicative, which means that applying the same functor twice to the exact same argument (plus additional syntactic restrictions) reproduces equivalent types. This semantics is more flexible, but can also break abstraction (see e.g. the examples we give in this paper, Section 8).
Edit: OCaml 4 added the ability to optionally make functors generative.
OCaml has a purely syntactic notion of signatures, which means that certain type equivalences cannot be expressed by the type system, and are silently dropped.
Edit: Consider this example:
module F (X : sig type t end) = struct type u = X.t -> unit type v = X.t end
module M = F (struct type t = int end : sig type t end)
The type of M is simply sig type u type v end and has thus lost any information about the relation between its types u and v, because that cannot generally be expressed in the surface syntax.
Another notable difference is that OCaml's module type system is undecidable (i.e, type checking may not terminate), due to its permission of abstract signatures, which SML does not allow.
As for semantics, a much better and elaborate answer is given by Andreas Rossberg above. However, concerning syntax this site might be what you are looking for.
There is also the abstype facility in SML which is like the datatype facility, except that it hides the structure of the datatype. OCaml relies on module abstraction to do all the hiding that is necessary. Notice that this site does not mention this facility in SML.

Can we create custom attributes in fortran?

Expanding on my previous question here, I want to know if is possible to create custom attributes in fortran ?
something like this
real, custom_attribute, allocatable :: variable(:)
If that can be done, I am guessing the following can be done too
custom_type, custom_attribute, allocatable :: variable(:)
You can create user-defined "types". Probably you can accomplish your goal with this feature. See http://en.wikipedia.org/wiki/Fortran_95_language_features#Derived_data_types
No, there is no such thing as custom attributes in standard Fortran. However extending M. S. B.s answer, when using derived data types you can use parameterized derived types, which was introduced with Fortran 2003.
It allows you to define "kind" and "len" attributes for the derived data types.
This enables you to do something like: type(my_type(rk=selected_real_kind(15), extent=size(a))) :: b