I have read about functional programming languages such as Haskell but not used them. Fortran is an imperative language but does provide some support for functional programming, such as the built-in array operations and the ability to define PURE functions. Subroutines returning multiple variables could be replaced by functions returning derived types. There is a functional-fortran project. In a purely functional language you cannot redefine a variable. Although you can hardly program in Fortran without loops (which implies a changing loop variable), should you try to avoid redefining other variables? For example, if you want uniform random numbers between 0 and c, you could write
Is it worth it to define more intermediate variables to have fewer reassignments of variables? I may try to program in a style that avoids redefining variables when possible and see if I like the results.
It occurred to me that one way to set variables that cannot be changed is with ASSOCIATE, for example
integer, parameter :: n = 10
real :: xraw(n)
associate (xmult => 100.0)
associate (xscaled => xmult * (xraw - sum(xraw)/n))
write (*,"(*(f8.4))") xscaled
! xscaled = xscaled*5 ! illegal -- gfortran says Error: 'xscaled' at (1) associated to expression cannot be used in a variable definition context (assignment)
end program xassoc_ran
Another way, available since Fortran 90, is to define a subroutine where the fixed variables are declared as INTENT(IN) arguments.
I have been pretty pleased with the ability to program in Fortran using a functional style. All of my open source libraries are based heavily on it. If compilers were less buggy wrt associate I could probably get away without ever declaring a local variable, and you wouldn’t really notice it.
I’ll try and come back later and post some examples. Basically, in places where I only assign to a local variable once, if I try change that to an associate, there are a few different compiler errors that I occasionally run in to. The rhyme and reason to when it works and when it doesn’t has so far escaped me.
It would be convenient if each ASSOCIATE did not have to be paired with END ASSOCIATE. In this case the ASSOCIATE block would terminate at the end of the program unit. Then, in Fortran, you would have a simple way to define variables that cannot be changed, and you could use the type inference of ASSOCIATE to avoid declaring many variables. Currently if you use ASSOCIATE for each variable you define, you must clutter the end of the program unit with many END ASSOCIATE statements. For example, it would be nice if the program
associate (pi => 3.14)
associate (r => 10.0)
print*,"Radius, circumference =",r,2*pi*r
were valid without the two END ASSOCIATE statements. In this case, pi and r could be defined in the same ASSOCIATE statement since they are independent, but often the variable you want to define depend on variables that must be defined in previous ASSOCIATE statements.
Unfortunately, Fortran, as many other similar languages, is missing first class functions. And hence also lexical closures. And it cannot be overcome with syntactic sugar and overloading as in older C++.
But Fortran array operations are a good alternatives for applications of functions to lists in various ways.
Funny video, thanks. Since Fortran really never deletes anything (the compilers will still support deleted features), most of my ideas should be rejected – I just don’t know which ones It looks like my A0 edit descriptor suggestion (trim trailing spaces on output), analogous to I0, is going to be in Fortran 202x, but as AT, (T stands for TRIM). So some proposals from the general public are accepted. A0 was initially proposed 14 years ago, so one should be patient
It has been possible to use a named ASSOCIATE statement since Fortran 2003. Fortran 2003, page 160-161
R817 associate-stmt is [ associate-construct-name : ] ASSOCIATE
C810 (R820) If the associate-stmt of an associate-construct specifies an
associate-construct-name, the corresponding end-associate-stmt shall
specify the same associate-construct-name.
That’s fair! I can see the utility in having that functionality. One could define z in terms of x again though, and I think that would be less cumbersome than adding more associate lines; depends on the problem. If your associations are too complex to do that, perhaps additional local variables is a better choice anyway, to help identify more registers to hold variables.