Equivalent Julia and Fortran syntax

Since Fortran is the language I know best, and since Julia and modern Fortran are similar in some ways, I have made some notes on equivalent syntax in Julia and Fortran, also posted on GitHub. Below, the Julia syntax appears first and the Fortran syntax appears after “vs.”. Additions and corrections are welcome. An earlier version of this list was discussed at Fortran Discourse.

x = 1.0 vs. x = 1.0d0 (Julia uses 64-bit floats by default)

x = 1.0f0 vs. x = 1.0 (single precision)

true and false vs. .true. and .false.

const n = 3 vs. integer, parameter :: n = 3

const name = "Ed" vs. character (len=*), parameter :: name = "Ed"

const tf = true vs. logical, parameter :: tf = .true.

x = zeros(5) # array of Float64 intialized to zero

vs. Fortran

 real(kind=kind(1.0d0)), allocatable :: x(:)
 allocate (x(5),source=0.0d0)

[] vs. () to index array elements

& vs .and.

| vs. .or.

! vs. .not.

^ vs. ** for exponentiation.

x = rand() vs. call random_number(x) where x is a scalar

x = rand(n) vs. call random_number(x) where x is a vector of length n

x = rand(n1,n2) vs. call random_number(x) where x has shape [n1,n2]

sum(x) has the same meaning in Julia and Fortran

sum(x,dims=1) vs. sum(x,dim=1)

sum(x,dims=[1,2]) = sum(x) for 2-D array

If x is an array, sin.(x) vs. sin(x) and the same for other functions that accept scalar arguments.
Julia functions need a . before the argument(s) to broadcast. A user-defined Fortran function or subroutine
that accepts either scalar or array arguments is declared ELEMENTAL.

In general, Julia has a dims optional argument for array functions vs. dim in Fortran,

minimum(x) and maximum(x) vs. minval(x) and maxval(x)

max(2,3.1) vs. max(real(2),3.1) or max(2.0,3.1) – the Fortran max requires arguments of the same type.

Julia max.(x,y) for arrays x and y is similar to Fortran max(x,y), but Julia max(x,y) (without the .) for arrays x and y compares the first elements of the two arrays and returns the array with largest 1st element, looking at the 2nd elements etc. to break ties. Fortran has no simple equivalent.

size(x) returns tuple, size(x,dim) returns scalar. Fortran size(x) returns a scalar.
size(x) vs. shape(x)
length(x) vs. size(x)

x = [2,3] creates a 1-D array of integers
x = [2,3.1] creates a 1-D array of Float64, [2.0,3.1]. The integer value is coerced to Float64. In Fortran the elements of an array constructor must have the same type.

vec(x) converts x to 1-D array, vs. [x]

x .> 0 vs. merge(1,0,x>0) Note the . before >.
x[x .> 0] vs. pack(x,x>0)

* vs. // to concatenate strings

rstrip("foo ") vs. trim("foo ")

println(2," ",5) vs. print*,2,5 – Julia does not insert spaces between printed items by default.

print(2) vs. write(*,"(i0)",advance="no") 2 – Julia print does not append newline, unlike println

# vs. ! for comments

dog and Dog are distinct variables in Julia but not in Fortran

argmax(x) vs. maxloc(x,dim=1) for 1-D array x

sum([true,false,true]) vs. count([.true.,.false.,.true.])

For logical variables x and y, x == y vs. x .eqv. y

loops in Julia

for i in 1:3
    println(i," ",i^2)
end

vs. Fortran

do i=1,3
    print*,i,i**2
end do

If block in Julia

if someVar > 10
    println("someVar is totally bigger than 10.")
elseif someVar < 10    # This elseif clause is optional.
    println("someVar is smaller than 10.")
else                    # The else clause is optional too.
    println("someVar is indeed 10.")
end

vs. Fortran

if (someVar > 10) then
    print*,"someVar is totally bigger than 10."
else if (someVar < 10) then ! This elseif clause is optional.
    print*,"someVar is smaller than 10."
else                    ! The else clause is optional too.
    print*,"someVar is indeed 10."
end if

One-line if in Julia

 (i > 1) && println("i > 1") 

vs. Fortran

 if (i > 1) print*,"i > 1"

Exiting a loop early in Julia

 for i in 1:5
      println(i)
      if i^2 > 4
           break
      end
 end

vs. Fortran

 do i=1,5
      print*,i
      if (i**2 > 4) exit
 end do

Function definition in Julia

function power(i,a)
    return i^a
end

vs. Fortran

integer function power(i,a)
    power = i**a
end

Arrays of strings in Julia

 x = ["boy","girl","man"]

vs. Fortran

 character (len=4), allocatable :: x(:)
 x = [character (len=4) :: "boy","girl","man"]
 x = ["boy ","girl","man "] ! alternative with padding, since the character variables in a Fortran array 
                            ! must have the same length.

Module imports:
using Foo vs. use Foo
import Foo: bar vs. use Foo, only: bar

8 Likes

I think && and || are the corresponding here.*

count works in Julia the same way.

*I don’t know how to check if .and. and .or. in fortran are short-circuiting. But because of the precedence of the operations, the corresponding result of the operators is that .and. is && and .or. is ||:

program main
if ( 1 == 1 .and. 2 == 2 ) then
  write(*,*) "TRUE"
end if
end

gfortran -o if if.f90

./if
 TRUE

vs.

julia> (1 == 1 & 2 == 2)
false

julia> (1 == 1 && 2 == 2)
true

(after 20 years programming in Fortran the behaviour of & and | was surprising to me, and I still didn’t find any situation in which I could understand what they are useful for and use them).

1 Like

Fortran .and. does not short-circuit, so for example you cannot safely write, to avoid an out-of-bounds error for a 1-based array,

if (i > 0 .and. x(i) > 10) then
   print*,"x(i) bigger than 10"
end if

and must instead write

if (i > 0) then
   if (x(i) > 10) print*,"x(i) bigger than 10"
end if
2 Likes

Nice. But have people aware that

x = [1]
i = 1
( i > 0 & x[i] == 1 )

Will print false in Julia.

1 Like
julia> ((1 == 1) & (2 == 2))
true

so for

julia> (1 == 1 & 2 == 2)
false

it is the order of operations that leads to the surprising result.

1 Like

&& and || are logical operators, and their syntax has short-circuiting behaviour. & and | are bitwise operators, so it doesn’t make sense to use short-circuit behaviour.

2 Likes

Operator precedence and the fact that chains of == are short circuited:

f1() = ((1 == 1) & (2 == 2))
f2() = (1 == 1 & 2 == 2)
julia> @code_lowered f1()
CodeInfo(
1 ─ %1 = 1 == 1
│   %2 = 2 == 2
│   %3 = %1 & %2
└──      return %3
)

julia> @code_lowered f2()
CodeInfo(
1 ─ %1 = 1 & 2
│   %2 = 1 == %1
└──      goto #3 if not %2
2 ─ %4 = %1 == 2
└──      return %4
3 ─      return false
)
1 Like

All agreed. My point is that if one translates a Fortran code to Julia, replace the ands and ors with the short circuit versions. Otherwise you’ll get bugs that are hard to track.

The short circuit versions are the operators that are most likely to be used in Julia (with the bitwise having a niche which I never got into).

4 Likes

As noted on the first of these lines, sum(x) would be the preferred way to write the last example also in Julia.

1 Like

There is a GitHub-based site Julia starting with Fortran, in Japanese but which Google Translate effectively renders in English, at least within Google Chrome. It includes a Fortran and Julia grammar comparison , which could be the starting point for adding a Fortran section to Noteworthy Differences from other Languages · The Julia Language .

6 Likes