Replacement for obsolete "statement functions" in Fortran 95 and later? - function

Original Question
As I understand, as of Fortran 95 Statement functions have been declared obsolete in favor of internal functions. However, internal functions do not cover all use-cases, in particular when using statement functions as abbreviations with implied arguments for making the implementation of long formulas more readable. Is there any adequate replacement for this usecase?
Example
E.g., lets say we have an relation
Cᵢⱼ = ∫dx₁∫dx₂∫dx₃∫dy₁∫dy₂∫dy₃ (AᵢⱼBᵢⱼ +BᵢⱼAⱼᵢ)
E.g. compare an implementation using directly the internal representation of A,B with the index-order mandated by prior code, resulting in
do a1=1,NGRID1; do a2=1,NGRID2; ...; do aN=1,NGRIDN
x(i,j) = x(i,j) &
& + ARR_A(x1,x2,x3,i,y1,y2,y3,j)*ARR_B(x1,x2,x3,i,y1,y2,y3,j) &
& + ARR_B(x1,x2,x3,i,y1,y2,y3,j)*ARR_A(x1,x2,x3,i,y1,y2,y3,j)
end do; end do; ...; end do
to an implementation using statement functions as abbreviation,
A(i,j) = ARR_A(x1,x2,x3,i,y1,y2,y3,j)
B(i,j) = ARR_B(x1,x2,x3,i,y1,y2,y3,j)
...
do x1=1,NGRID1; do x2=1,NGRID2; ...; do y3=1,NGRIDN
x(i,j) = x(i,j) + A(i,j)*B(i,j) + B(i,j)*A(i,j)
end do; end do; ...; end do
In the second version it seems much easier to spot the mixed-uo order of the indices after noticing that there is an issue.
Using macros?
The only method to achieve similar semantics I found was using preprocessor macros. Typically, C-style macros are used, which here would lead to
#define A(i,j) ARR_A(x1,x2,x3,i,y1,y2,y3,j)
but this sacrifices scoping of the name. While this seems potentially useful, especially when the same abbreviation is used accross multiple functions, it seems potentially rather confusing. For a start, the compiler will give more useful error messages, when using statement functions incorrectly than it can for macros.
It also introduces the need to manually #undefine the name, if we want to reuse the same name in different contexts for different things.
Solution (1)
I had misunderstood how CONTAINS and internal functions work (see IanH's answer and its comments).
Short: Internal functions can be defined inside subroutines with CONTAINS, and work exactly like statement functions, except for a more verbose syntax.
The misunderstanding arose partly because it apparently is not allowed to define a subroutine inside a subroutine in this manner. Apparently it does work. No idea what I was doing wrong.

Internal procedures are pretty much a drop-in replacement for statement functions for this use case, with their usual benefits of more capability and less proneness to error, at the cost of some slight extra verbosity with their definition.
MODULE some_module ! Just for the sake of example.
...
CONTAINS
! The host of the internal procedure. This could
! also be an external procedure or a main program.
! It could also be a function.
SUBROUTINE some_subroutine
...
DO i = 1, 3
DO j = 1, 3
DO x1 = 1, 3
DO x2 = 1, 3
...
x(i,j) = x(i,j) + A(i,j)*B(i,j) + B(i,j)*A(i,j)
...
END DO
END DO
END DO
END DO
...
CONTAINS
! An internal procedure. For different use cases
! this could also be a subroutine.
FUNCTION A(i,j)
INTEGER, INTENT(IN) :: i,j
REAL :: A
A = ARR_A(x1,x2,x3,i,y1,y2,y3,j)
END FUNCTION A
FUNCTION B(i,j)
INTEGER, INTENT(IN) :: i,j
REAL :: B
B = ARR_B(x1,x2,x3,i,y1,y2,y3,j)
END FUNCTION B
...
END SUBROUTINE some_subroutine
...
END MODULE some_module
Note that the maximum array rank under the rules of Fortran 77/90/95/2003 is seven.

Related

Proper way to dynamically define LUA functions

I have been playing with Lua for the past week and I ended up writing this peace of code. I find it really useful that you can dynamically create new functions that "inherit" other functions, so programmers must have a name for it. My questions are:
What is this called?
Is there a better way to do this? (cycle over a data structure and create add-on functions that "improve" existing functions)
D = {
name = {
value = nil,
offset = 0,
update = function (self)
self.value = "Berlin"
end,
},
}
--Dynamic function definition
for i in pairs(D) do
D[i].upAndWrite = function(self)
self:update()
print("upAndWrite was here")
end
end
print(D.name.value)
D.name:upAndWrite()
print(D.name.value)
Result:
nil
upAndWrite was here
Berlin
I don't think that what you're doing have special name for it, it's just on-the-fly function creation.
There are few notes regarding your code:
Proper for loop
for i in pairs(D) do
…
end
In programming, variable i is generally used for counter loops, like in
for i=1,100 do
…
end
Here, pairs returns an iterator function and the idiomatic way to use it is
for k,v in pairs(D) do
…
end
Here k is a key (like i in your code) and v is a value (use it instead of indexing table like D[k] or D[i] in your code when you need to access the corresponding value).
There's no need to create functions on the fly!
Another important thing is that you create new function on each loop iteration. While this feature is very powerful, you're not using it at all as you don't store anything using upvalues and only access data through arguments.
A better way to do it would be creating function once and assigning it to every field:
-- Define D here
do
local function upAndWrite(self)
self:update()
print("upAndWrite was here")
end
for k,v in pairs(D) do
v.upAndWrite = upAndWrite -- Use our function
end
end
-- Perform tests here
What does on-the-fly function creation allow?
As mentioned above, you can utilize this very powerful mechanism of closures in certain situations. Here's a simple example:
local t = {}
for i = 1, 100 do
-- Create function to print our value
t[i] = function() print(i) end
-- Create function to increment value by one
t[-i] = function() i=i+1 end
end
t[1]() -- Prints 1
t[20]() -- Prints 20
t[-20]() -- Increment upvalue by one
t[20]() -- Now it is 21!
This example demonstrates one possible usage of upvalues and the fact that many functions can share them. This can be useful in a variety of situations together with the fact that upvalues can't be changed by side code (without use of debug library) and can be trusted in general.
I hope my answer covers what you wanted to know.
Note: Also, this language is called Lua, not LUA.
As a whole it doesn't have a name, no. There's lots of concepts that play into this:
First Class Functions aka. functions that can be assigned to variables and passed around just like numbers or strings.
Anonymous Functions aka. functions that are created without giving it a name explicitly. All functions in Lua are technically anonymous, but often they are assigned into a variable right after creation.
Metaprogramming aka. writing programs that write programs. A loop that creates functions (or methods) on an arbitrary number of objects is very simple, but I'd count it as metaprogramming.
Lua Tables; this may seem obvious, but consider that not all languages have a feature like this. Javascript has objects which are similar, but Ruby for example has no comparable feature.
If you're gonna use pairs, you might as well make use of both variables.
for key, object in pairs(D) do
function object:upAndWrite(self)
self:update()
print("upAndWrite was here")
end
end
Though that would create many closures, which means more work for the garbage collector, more memory usage and slower execution speed.
for key, object in pairs(D) do
print(object.upAndWrite) -- All the functions are different
end
It's a good first stage, but after refactoring it a bit you could get this:
do
local method = function(self) -- Create only one closure
self:update()
print("upAndWrite was here")
end
for key, object in pairs(D) do
object.upAndWrite = method -- Use single closure many times
end
end
Now there's only one closure that's shared among all the tables.
for key, object in pairs(D) do
print(object.upAndWrite) -- All the functions are the same
end

Lua - Should I use ":" when defining functions in tables if not using the "self" keyword?

This is more of a design philosophy question as I already know you shouldn't call a function with : (object-oriented syntactic sugar) if the function has been defined without the self keyword by using .. But the problem is that programmers using a library I have created tend to not read the documentation and run into the question of "how should I call your function?", so I end up always defining functions using the method below:
local tbl = {};
function tbl:Add(a, b)
return a + b;
end
I have installed Luacheck (in VS Code) and it often complains when I use this syntax and not use the self referential keyword. It says: [luacheck] unused argument "self". Is there any problem with this in terms of performance (or is there a way of disabling Luacheck in VS Code)?
I prefer writing functions in this style as opposed to the style below:
function tbl.Add(_, a, b)
return a + b;
end
It seems a pain to have to add a dummy variable at the start of the parameter list.
EDIT: Another problem is what if you had many tables that implement a function with the same name and want to iterate over them but some implementations do not use the self argument and others do? It would be very tedious and bad design to check what type of table it is to call the function correctly.
What is the preferred style? A bit confused in general about this warning. What are your thoughts? Thanks.
if you're not using the self argument you can just do
function tbl.Add(a, b)
return a + b;
end
no need to use a dummy variable.
You just need to be sure then that you also call it with a . and not a :
so
local someValue = tbl.Add(1, 3)
for example and not
local someValue = tbl:Add(1, 3)

How to use Eiffel functions?

So I'm just starting to learn Eiffel. One of the first exercises in the book I'm using says to make a function that does base^exp without using ^. I've copied my code below.
class
APPLICATION
inherit
ARGUMENTS
create
make
feature {NONE} -- Initialization
make
-- Run application.
do
create power(2;3)
printf("2 to the power of 3 is " + answer)
end
power(base : REAL; exp : INTEGER) : REAL
-- computers base raised to the bower of exp without using ^
local
remain : INTEGER
do
remain := exp
if remain = 0 then
result := 1
else
from
until
remain = 0
loop
result := result * result
remain := remain -1
end
end
end
end
How do I use this? Do I need it on the same level as feature{NONE}'s make? I know how I'm calling it is wrong, and I can't find anything in the chapter I just read, or online on how to pass parameters into it or how to use it's results.
There are several issues with the original code:
create is used to create an object, but you are not going to create anything, but to get a result of a computation of the function power by calling it. Therefore the keyword create is not needed.
You are using an entity answer to report the result of evaluation on a screen. However it is not declared anywhere. I believe the proper place would be a local variable declaration section.
The entity answer is not initialized to the result of the function power. This is usually done by an assignment instruction.
Feature arguments are separated by a comma, not by a semicolon.
From the original code it's unclear what is the type of the variable answer. Assuming it matches the type of the function power, before adding it to a string, it needs to be converted to a string. This is done by calling the feature out.
The standard feature for printing a string to a console is print, not printf.
Combining the critical points above, we get
make
-- Run application.
local
answer: REAL
do
answer := power(2, 3)
print ("2 to the power of 3 is " + answer.out)
end
After that the code can be compiled. Now less critical points:
It is a good style to put features to a dedicated feature clauses, so I would add a line like feature -- Basic operations before the feature power.
The implementation of the feature power has at least two problems. I'm not going to detail them here, but would give two hints instead:
by default numeric Result is initialized to 0, this needs to be taken into account for operations that use it without first assigning any other value
even though an argument base is passed to the function power it remains unused in the original version of the code

How to override a structure constructor in fortran

Is it currently possible to override the structure constructor in Fortran? I have seen proposed examples like this (such as in the Fortran 2003 spec):
module mymod
type mytype
integer :: x
! Other stuff
end type
interface mytype
module procedure init_mytype
end interface
contains
type(mytype) function init_mytype(i)
integer, intent(in) :: i
if(i > 0) then
init_mytype%x = 1
else
init_mytype%x = 2
end if
end function
end
program test
use mymod
type(mytype) :: x
x = mytype(0)
end program
This basically generates a heap of errors due to redundant variable names (e.g. Error: DERIVED attribute of 'mytype' conflicts with PROCEDURE attribute at (1)). A verbatim copy of the fortran 2003 example generates similar errors. I've tried this in gfortran 4.4, ifort 10.1 and 11.1 and they all produce the same errors.
My question: is this just an unimplemented feature of fortran 2003? Or am I implementing this incorrectly?
Edit: I've come across a bug report and an announced patch to gfortran regarding this issue. However, I've tried using a November build of gcc46 with no luck and similar errors.
Edit 2: The above code appears to work using Intel Fortran 12.1.0.
Is it currently possible to override the structure constructor in Fortran?
No. Anyway even using your approach is completely not about constructor overriding. The main reason is that structure constructor # OOP constructor. There is some similarity but this is just another idea.
You can not use your non-intrinsic function in initialization expression. You can use only constant, array or structure constructor, intrinsic functions, ... For more information take a look at 7.1.7 Initialization expression in Fortran 2003 draft.
Taking that fact into account I completely do not understand what is the real difference between
type(mytype) :: x
x = mytype(0)
and
type(mytype) :: x
x = init_mytype(0)
and what is the whole point of using INTERFACE block inside mymod MODULE.
Well, honestly speaking there is a difference, the huge one - the first way is misleading. This function is not the constructor (because there are no OOP constructors at all in Fortran), it is an initializer.
In mainstream OOP constructor is responsible for sequentially doing two things:
Memory allocation.
Member initialization.
Let's take a look at some examples of instantiating classes in different languages.
In Java:
MyType mt = new MyType(1);
a very important fact is hidden - the fact the object is actually a pointer to a varibale of a class type. The equivalent in C++ will be allocation on heap using:
MyType* mt = new MyType(1);
But in both languages one can see that two constructor duties are reflected even at syntax level. It consists of two parts: keyword new (allocation) and constructor name (initialization). In Objective-C syntax this fact is even more emphasized:
MyType* mt = [[MyType alloc] init:1];
Many times, however, you can see some other form of constructor invocation. In the case of allocation on stack C++ uses special (very poor) syntax construction
MyType mt(1);
which is actually so misleading that we can just not consider it.
In Python
mt = MyType(1)
both the fact the object is actually a pointer and the fact that allocation take place first are hidden (at syntax level). And this method is called ... __init__! O_O So misleading. С++ stack allocation fades in comparison with that one. =)
Anyway, the idea of having constructor in the language imply the ability to do allocation an initialization in one statement using some special kind of method. And if you think that this is "true OOP" way I have bad news for you. Even Smalltalk doesn't have constructors. It just a convention to have a new method on classes themselves (they are singleton objects of meta classes). The Factory Design Pattern is used in many other languages to achieve the same goal.
I read somewhere that concepts of modules in Fortran was inspired by Modula-2. And it seems for me that OOP features are inspired by Oberon-2. There is no constructors in Oberon-2 also. But there is of course pure allocation with predeclared procedure NEW (like ALLOCATE in Fortran, but ALLOCATE is statement). After allocation you can (should in practice) call some initializer, which is just an ordinary method. Nothing special there.
So you can use some sort of factories to initialize objects. It's what you actually did using modules instead of singleton objects. Or it's better to say that they (Java/C#/... programmers) use singleton objects methods instead of ordinary functions due to the lack of the later one (no modules - no way to have ordinary functions, only methods).
Also you can use type-bound SUBROUTINE instead.
MODULE mymod
TYPE mytype
PRIVATE
INTEGER :: x
CONTAINS
PROCEDURE, PASS :: init
END TYPE
CONTAINS
SUBROUTINE init(this, i)
CLASS(mytype), INTENT(OUT) :: this
INTEGER, INTENT(IN) :: i
IF(i > 0) THEN
this%x = 1
ELSE
this%x = 2
END IF
END SUBROUTINE init
END
PROGRAM test
USE mymod
TYPE(mytype) :: x
CALL x%init(1)
END PROGRAM
INTENT(OUT) for this arg of init SUBROUTINE seems to be fine. Because we expect this method to be called only once and right after allocation. Might be a good idea to control that this assumption will not be wrong. To add some boolean flag LOGICAL :: inited to mytype, check if it is .false. and set it to .true. upon first initialization, and do something else on attempt to re-initialization. I definitely remember some thread about it in Google Groups... I can not find it.
I consulted my copy of the Fortran 2008 standard. That does allow you to define a generic interface with the same name as a derived type. My compiler (Intel Fortran 11.1) won't compile the code though so I'm left suspecting (without a copy of the 2003 standard to hand) that this is an as-yet-unimplemented feature of the Fortran 2003 standard.
Besides that, there is an error in your program. Your function declaration:
type(mytype) function init_mytype
integer, intent(in) :: i
specifies the existence and intent of an argument which is not present in the function specification, which should perhaps be rewritten as:
type(mytype) function init_mytype(i)

Emulating namespaces in Fortran 90

One of the most troublesome issues with Fortran 90 is the lack of namespacing. In this previous question "How do you use Fortran 90 module data" from Pete, it has been discussed the main issue of USE behaving like a "from module import *" in Python: everything that is declared public in the module is imported as-is within the scope of the importing module. No prefixing. This makes very, very hard to understand, while reading some code, where a given identifier comes from, and if a given module is still used or not.
A possible solution, discussed in the question I linked above, is to use the ONLY keyword to both limit the imported identifiers and document where they come from, although this is very, very tedious when the module is very large. Keeping the module small, and always using USE : ONLY is a potentially good strategy to work around the lack of namespacing and qualifying prefixes in Fortran 9X.
Are there other (not necessarily better) workaround strategies? Does the Fortran 2k3 standard say anything regarding namespacing support?
For me this is the most irritating Fortran feature related to modules. The only solution is to add common prefix to procedures, variables, constants, etc. to avoid namespace collisions.
One can prefix all entities (all public entities seems to be more appropriate) right inside the module:
module constants
implicit none
real, parameter :: constants_pi = 3.14
real, parameter :: constants_e = 2.71828183
end module constants
Drawback is increased code verbosity inside the module. As an alternative one can use namespace-prefix wrapper module as suggested here, for example.
module constants_internal
implicit none
real, parameter :: pi = 3.14
real, parameter :: e = 2.71828183
end module constants_internal
module constants
use constants_internal, only: &
constants_pi => pi, &
constants_e => e
end module constants
The last is a small modification of what you, Stefano, suggested.
Even if we accept the situation with verbosity the fact that Fortran is not case-sensitive language force us to use the same separator (_) in entities names. And it will be really difficult to distinguish module name (as a prefix) from entity name until we do not use strong naming discipline, for example, module names are one word only.
Having several years of Fortran-only programming experience (I got into Python only a year ago), I was not aware of such concept as namespaces for a while. So I guess I learned to just keep track of everything imported, and as High Performance Mark said, use ONLY as much as you have time to do it (tedious).
Another way I can think of to emulate a namespace would be to declare everything within a module as a derived type component. Fortran won't let you name the module the same way as the namespace, but prefixing module_ to module name could be intuitive enough:
MODULE module_constants
IMPLICIT NONE
TYPE constants_namespace
REAL :: pi=3.14159
REAL :: e=2.71828
ENDTYPE
TYPE(constants_namespace) :: constants
ENDMODULE module_constants
PROGRAM namespaces
USE module_constants
IMPLICIT NONE
WRITE(*,*)constants%pi
WRITE(*,*)constants%e
ENDPROGRAM namespaces
Fortran 2003 has the new ASSOCIATE construct and don't forget the possibility of renaming USE- associated entities. But I don't think that either of these is much closer to providing a good emulation of namespaces than Fortran 90 already has, just (slightly) better workarounds.
Like some of the respondents to the question you link to, I tend to think that modules with very many identifiers should probably be split into smaller modules (or, wait for Fortran 2008 and use submodules) and these days I almost always specify an ONLY clause (with renames) for USE statements.
I can't say that I miss namespaces much, but then I've never had them really.
No one else summited this suggestion as an answer (though someone did in the comments of one answer). So I'm going to submit this in hopes it may help someone else.
You can emulate namespaces in the following way, and I would hope there would be no noticeable performance hit for doing so from the compiler (if so all object oriented Fortran programming is sufferings). I use this pattern in my production code. The only real downfall to me is the lack of derived type contained parameter variables, but I offer an option for that as well below.
Module Math_M
IMPLICIT NONE
PRIVATE
public :: Math
Type Math_T
real :: pi=3.14159
contains
procedure, nopass :: e => math_e
procedure :: calcAreaOfCircle => math_calcAreaOfCircle
End Type
Type(Math_T) :: Math
real, parameter :: m_e = 2.71828
contains
function math_e() result(e)
real :: e
e = m_e
end function math_e
function math_calcAreaOfCircle(this, r) result(a)
class(Math_T), intent(in) :: this
real, intent(in) :: r
real :: a
a = this%pi * r**2.0
end function math_calcAreaOfCircle
End Module Math_M
And the usage
Program Main
use Math_M
IMPLICIT NONE
print *, Math%pi
print *, Math%e()
print *, Math%calcAreaOfCircle(2.0)
End Program Main
Personally I prefer using $ over the _ for module variables, but not all compilers like that without compiler flags. Hopefully this helps someone in the future.