# Bug(s) in Ratfor90, Ratfor(?)

**URL:** <https://fortran-lang.discourse.group/t/bug-s-in-ratfor90-ratfor/3674>\
**Category:** Uncategorized\
**Created:** [June 6, 2022, 3:58pm UTC](https://fortran-lang.discourse.group/t/bug-s-in-ratfor90-ratfor/3674 "2022-06-06T15:58:19Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![mecej4](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mecej4/32/855_2.png) [@mecej4](https://fortran-lang.discourse.group/u/mecej4)\
**Post date:** [June 6, 2022, 3:58pm UTC](https://fortran-lang.discourse.group/t/bug-s-in-ratfor90-ratfor/3674/1 "2022-06-06T15:58:19Z")

</div>

I suspect that few members of fortran-lang.discourse.group use or are even aware of [Ratfor](http://www.econ.uiuc.edu/~roger/research/repro/ratfor.pdf).

As of now, [Ratfor](https://en.wikipedia.org/wiki/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):

1. 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.
2. The newer [Ratfor77](https://github.com/patrickbucher/ratfor77), which outputs Fortran 77 source code. Of marginal interest in the year 2022.
3. [Ratfor90](http://sepwww.stanford.edu/doku.php?id=sep:software: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](https://github.com/cran/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:

```auto
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:

```auto
! 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:

```auto
  0.1000E-01 0.8000E+00

```

The output after converting using Ratfor90:

```auto
  0.1000E-01 0.1000E+01

```

Here is where the bug occurs. For the Ratfor code section

```auto
        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:

```auto
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.

---

<div class="post-metadata">

**Author:** ![urbanjost](https://avatars.discourse-cdn.com/v4/letter/u/0ea827/32.png) [@urbanjost](https://fortran-lang.discourse.group/u/urbanjost)\
**Post date:** [June 6, 2022, 11:00pm UTC](https://fortran-lang.discourse.group/t/bug-s-in-ratfor90-ratfor/3674/2 "2022-06-06T23:00:47Z")

</div>

I was not directly involved, but when I was inquiring what happened to a large amount of RATFOR code  
at an organization I was previously associated with I was told that it had been processed into Fortran 77 (with ratfor77?, not sure) and been used as-is until relatively recently, when it was run through the commercial spag(1) utility from plusfort and maintenance resumed. They were happy with the results. plusfort might provide access for an Open Source project if you contact them. Fixiing ratfor90 might be relatively easy, though(?).

---

<div class="post-metadata">

**Author:** ![mecej4](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mecej4/32/855_2.png) [@mecej4](https://fortran-lang.discourse.group/u/mecej4)\
**Post date:** [June 7, 2022, 2:17am UTC](https://fortran-lang.discourse.group/t/bug-s-in-ratfor90-ratfor/3674/3 "2022-06-07T02:17:01Z")

</div>

Yes, using SPAG or VAST90 works for most of the Ratfor-converted F66 source files, but in a few cases the logic is too complicated for that to succeed.

One file in particular, [rqbr.r from Quantreg](https://github.com/cran/quantreg/blob/master/src/ratfor/rqbr.r), resulted in an F90 file that the compiler rejected because there were multiple GOTO statement from outside DO…END DO and IF…THEN…ENDIF constructs to labels inside the constructs. It is these longer source files with convoluted logic that often result in failure of the project as a whole, even if all the other sources are converted satisfactorily.

> [@urbanjost](#):
>
> Fixiing ratfor90 might be relatively easy, though(?)

Ratfor90 is a Perl script of about 2,000 lines. I don’t know Perl, and its slogan, “There is more than one way to do it”, is discouraging for me.

---

<div class="post-metadata">

**Author:** ![ashe](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@ashe](https://fortran-lang.discourse.group/u/ashe)\
**Post date:** [June 7, 2022, 2:43am UTC](https://fortran-lang.discourse.group/t/bug-s-in-ratfor90-ratfor/3674/4 "2022-06-07T02:43:35Z")

</div>

The problem is that Ratfor90 is blindly converting `next` to `cycle`. That doesn’t work inside a `for` loop because the _iteration-expression_ (i.e. the 3rd expression in the `for`) doesn’t get executed after the `cycle`. The `next` should get converted to a `goto` to the code for the  
_iteration-expression_.

BTW, this conversion also means that if, for example, you were to call a function named `ieee_next_after` it would get converted to `ieee_cycle_after`.

> [@mecej4](#):
>
> Ratfor90 is a Perl script of about 2,000 lines. I don’t know Perl, and its slogan, “There is more than one way to do it”, is discouraging for me.

It is certainly possible to have a well-written 2000-line Perl program, but I don’t think this is an example of one.

---

<div class="post-metadata">

**Author:** ![mecej4](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mecej4/32/855_2.png) [@mecej4](https://fortran-lang.discourse.group/u/mecej4)\
**Post date:** [June 7, 2022, 5:09am UTC](https://fortran-lang.discourse.group/t/bug-s-in-ratfor90-ratfor/3674/5 "2022-06-07T05:09:41Z")

</div>

> [@ashe](#):
>
> The problem is that Ratfor90 is blindly converting `next` to `cycle`.

Did you reach that conclusion by looking at the Fortran 90 output of the conversion, or at the relevant portion of the Perl conversion script itself? If the latter, and you know Perl well enough, can you suggest a fix for the issue?

Thanks for your explanation. But, given that Fortran does not have reserved keywords, translating **next** to **cycle** without regard for context would be asking for trouble, would it not? In fact, both **next** and **cycle** could be variable names in Fortran programs.

---

<div class="post-metadata">

**Author:** ![ashe](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@ashe](https://fortran-lang.discourse.group/u/ashe)\
**Post date:** [June 7, 2022, 1:36pm UTC](https://fortran-lang.discourse.group/t/bug-s-in-ratfor90-ratfor/3674/6 "2022-06-07T13:36:05Z")

</div>

> [@mecej4](#):
>
> > [@ashe](#):
> >
> > The problem is that Ratfor90 is blindly converting `next` to `cycle`.
> 
> Did you reach that conclusion by looking at the Fortran 90 output of the conversion, or at the relevant portion of the Perl conversion script itself?  
> If the latter, and you know Perl well enough, can you suggest a fix for the issue?

By looking at the script. But I didn’t see any obvious way to fix it.

If you have to use Ratfor90, I suggest rewriting to eliminate any occurrences of `next` inside a `for` loop.

> [@mecej4](#):
>
> Thanks for your explanation. But, given that Fortran does not have reserved keywords, translating **next** to **cycle** without regard for context would be asking for trouble, would it not? In fact, both **next** and **cycle** could be variable names in Fortran programs.

Worse than that, `next` is replaced by `cycle` even if it is **part** of a name (see my `ieee_next_after` example above).

---

<div class="post-metadata">

**Author:** ![mecej4](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mecej4/32/855_2.png) [@mecej4](https://fortran-lang.discourse.group/u/mecej4)\
**Post date:** [June 7, 2022, 2:39pm UTC](https://fortran-lang.discourse.group/t/bug-s-in-ratfor90-ratfor/3674/7 "2022-06-07T14:39:29Z")

</div>

> [@ashe](#):
>
> By looking at the script. But I didn’t see any obvious way to fix it.

OK, thanks.
