I suspect that few members of fortran-lang.discourse.group use or are even aware of Ratfor.
As of now, Ratfor is a language whose usefulness is over, but now and then we come across packages of substantial size that are coded in Ratfor, and we have to decide what to do with them.
There are three main versions of Ratfor, in increasing order of readability/usability of the output Fortran code (the first two converters are C programs, the third is a Perl script):
- The original Ratfor from Bell Labs, which converts source code in Ratfor to Fortran 66. The output is not suitable for human maintenance or inspection.
- The newer Ratfor77, which outputs Fortran 77 source code. Of marginal interest in the year 2022.
- Ratfor90, which outputs Fortran 90 source code.
Ratfor90 appears from its description to be capable of producing F90 output that may be easier to understand and maintain than the F77 or F66 output of the older Ratfor converters. Unfortunately, after trying it on the Quantreg package (for use with R), I found that the conversion produces seriously buggy code. This is an unfortunate state of affairs, since some of the Quantreg source code, which is in R, cannot be converted to F90 except by hand conversion, and the conversion of the same Quantreg Ratfor to F77 or F66 source produces code that few would want to read.
Here is a demonstration of the bug in Ratfor90. The input test program in Ratfor:
subroutine sakj(x,p,nx)
integer nx,i
double precision x(nx),p(nx)
double precision sum0,qrange
sum0=0d0
for(i=1;i<nx;i=i+1) {
sum0=sum0+p(i)
if(sum0<.25) next
else { qrange=x(i);break }
}
sum0=1d0
for(i=nx;i>0;i=i-1) {
sum0=sum0-p(i)
if(sum0>.75) next
else { qrange=x(i)-qrange;break }
}
print '(2E12.4)',sum0,qrange
return
end
program tsakj
integer nx
parameter (nx = 11)
double precision x(nx),p(nx)
integer i
for(i=1; i<=nx; i=i+1)
x(i) = (i-1)*0.1d0
for(i=1; i < nx; i= i+1)
p(i) = i*0.1d0-0.05d0
p(nx) = 0.99d0
call sakj(x,p,nx)
end
and a manual translation to F90:
! manual translation of ts.r to f90
!
subroutine sakj(x,p,nx)
integer nx,i
double precision x(nx),p(nx)
double precision sum0,qrange
sum0=0d0
do i=1,nx-1
sum0=sum0+p(i)
if(sum0 < 0.25d0) cycle
qrange=x(i)
exit
end do
sum0=1d0
do i = nx,1,-1
sum0=sum0-p(i)
if(sum0 > 0.75d0) cycle
qrange=x(i)-qrange
exit
end do
print '(2E12.4)',sum0,qrange
return
end
program tsakj
integer nx
parameter (nx = 11)
double precision x(nx),p(nx)
integer i
do i = 1, nx
x(i) = (i-1)*0.1d0
end do
do i = 1, nx-1
p(i) = i*0.1d0-0.05d0
end do
p(nx) = 0.99d0
call sakj(x,p,nx)
end program
After converting using Ratfor77 and running the resulting Fortran program, the output is the same as from the manually generated F90 program:
0.1000E-01 0.8000E+00
The output after converting using Ratfor90:
0.1000E-01 0.1000E+01
Here is where the bug occurs. For the Ratfor code section
sum0=0d0
for(i=1;i<nx;i=i+1) {
sum0=sum0+p(i)
if(sum0<.25) next
else { qrange=x(i);break }
}
Ratfor90 outputs the following F90 code:
sum0=0d0
i=1
do
if(.not. (i<nx)) then
exit
end if
sum0=sum0+p(i)
if (sum0<.25) then
cycle
else
qrange=x(i)
exit
end if
i=i+1
end do
The serious error is that the statement i = i+1 is never reached, and p(1) and x(1) are used again and again where p(i) and x(i) should have been used. This makes Ratfor90 unusable for Ratfor code that contains FOR loops.