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
program xassoc_ran
integer, parameter :: n = 10
real :: xraw(n)
call random_number(xraw)
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 associate
end associate
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
implicit none
associate (pi => 3.14)
associate (r => 10.0)
print*,"Radius, circumference =",r,2*pi*r
end associate
end associate
end
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.
As stated in your comment, it may appear redundant compared to what Fortran has long provided and you may thus receive the no āassociate statementā for you response!!
real, parameter :: pi = 3.14
So I suggest you put together all the use cases along with the needs and requirements, that can help it gain traction.
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
You donāt need to make end associate optional to avoid clutter. You can have multiple associations in one line, just by comma delimiting, and therefore only one āend associateā:
implicit none
associate (pi => 3.14, r=> 10.0)
print*,"Radius, circumference =",r,2*pi*r
end associate
end
EDIT: It seems I am still in the dark about F18 updates, I thought you couldnāt name associate statements. EDIT2: Again wrong about that!
Strange. I am (again) mistaken! It was the nvfortran compiler Iāve been using for my CUDA Fortran work. It claims to fully support F2003, but perhaps that is not the case.
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.