This is a simple cheatsheet and some performance comparison for scientific programmers who are interested in discover Julia. It is not an exhaustive list. This page is inspired from A Cheatsheet for Fortran 2008 Syntax: Comparison with Python 3.
| Fortran | Julia | |
| Top-level constructs | ||
| the main program | program my_program ... end program | function my_program() ... end my_program() |
| modules | module my_module ... end module my_module | module MyModule ... end |
| subroutines | subroutine my_subroutine ... end subroutine my_subroutine | function my_subroutine! ... end |
| functions | function f(x) result(res) res = ... end function f | function my_function(x) ... return res end |
| Generic interface | module cube_root_functions interface cube_root function s_cube_root(x) real :: s_cube_root real, intent(in) :: x end function s_cube_root function d_cube_root(x) double precision :: d_cube_root double precision, intent(in) :: x end function d_cube_root end interface end module cube_root_functions function s_cube_root(x) real :: s_cube_root real, intent(in) :: x s_cube_root = x ** (1.0/3.0) end function s_cube_root function d_cube_root(x) double precision :: d_cube_root double precision, intent(in) :: x d_cube_root = x ** (1.0d0/3.0d0) end function d_cube_root | cube_root( x :: Float32 ) :: Float32 = x^(1/3) cube_root( x :: Float64 ) :: Float64 = x^(1/3) |
| submodules | module main_module ... contains <submodule statements> end module main_module | module MainModule ... module SubModule ... end end |
| import statement | use my_module use my_module, only : fun1, var1 | using MyModule import MyModule: fun1, var1 |
| call subroutines and functions | call my_subroutine(args) my_function(args) | my_function(args) |
| abort a program | stop | exit() |
| inline comments | ! This is a comment | # This is a comment |
| include external source files | include 'source_file_name' | include("source_file_name") |
| Control flow patterns | ||
if construct | if <logical expr> then ... else if <logical expr> then ... else ... end if | if <logical expr> ... elseif <logical expr> ... else ... end |
case construct | select case <expr> case <value> ... case <value> ... case default ... end select | Not supported. Possible alternative is to use the ternary ? :syntax: function case(x) x == 1 ? println(1) : x + 1 == 3 ? println(2) : x == 3 ? println(3) : println("greater than 3") end |
do construct | do i = start_value, end_value, step ... end do | for i in start:step:end ... end |
do while construct | do while <logical expr> ... end do | while <logical expr> ... end |
| break from a loop | exit | break |
| leave this iteration and continue to the next iteration | cycle | continue |
| Data types | ||
| declaration | integer(kind=8) :: n = 0 real(kind=8) :: x = 0. | n = 0 n :: Int64 = 0 x = 0. x :: Float64 = 0. |
| named constants | integer, parameter :: answer = 42 real(8), parameter :: pi = 4d0 * atan(1d0) | const answer = 42 |
| complex number | complex :: z = (1., -1.) | z = 1 - 1im z = complex(1, -1) |
| string | character(len=10) :: str_fixed_length character(len=:), allocatable :: str_var_length | string = "this is a string" |
| pointer | real, pointer :: p real, target :: r p => r | p = Ref(r) |
| boolean | .true. .false. | true false |
| logical operators | .not. .and. .or. .eqv. .neqv. | ! && || |
| equal to | ==, .eq. | == |
| not equal to | /=, .ne. | !== |
| greater than | >, .gt. | > |
| less than | <, .lt. | < |
| greater than or equal to | >=, .ge. | >= |
| less than or equal to | <=, .ge. | <= |
| array declaration | real(8), dimension(3) :: a = [1., 2., 3.] | a = [1., 2., 3.] |
| string array declaration | character(len=20), dimension(3, 4) :: char_arr | char_arr = String[] push!(char_arr, new_string) |
| elementwise array operations | a op bop can be +, -, *, /, **, =, ==, etc.This is supported since the Fortran 90 standard. | Supported by using the broadcast operator `.`and the `f.(x)` syntax |
| first element | a(1) | a[1] (or a[begin] for general indexing) |
| slicing | a(1:5)a(5). | a[1:5] (or @view(a[1:5]) for non-allocating slicing)a[5]. |
| slicing with steps | a(1:100:2) | a[1:2:100] |
| size | size(a) | length(a) |
| shape | shape(a) | size(a) |
| shape along a dimension | size(a, dim) | size(a, dim) |
| Type conversion | ||
| to integer by truncation | int(x) | trunc(Int, x ) |
| to integer by rounding | nint() | round() |
| integer to float | real(a[, kind]) | float() |
| complex to real | real(z[, kind]) | real() |
| to complex | cmplx(x [, y [, kind]]) | complex() |
| to boolean | logical() | Bool() |
| Derived data types | ||
| definition | type Point real(8) :: x, y end type Point | struct Point x :: Float64 y :: Float64 end |
| instantiation | type(Point) :: point1 = Point(-1., 1.) | point1 = Point(-1., 1.) |
| get attributes | point1%x point1%y | point1.x point1.y |
| array of derived type | type(Point), dimension(:), allocatable :: point_arr | point_arr = Vector{Point} |
| type bound procedures (aka class method) | Assume that Circle has a type bound procedure (subroutine) print_area. type(Circle) :: c call c%print_area | Assume that Circle has a method print_area(c :: Circle). c = Circle() print_area(c) |
| Built-in mathematical functions | ||
| functions with the same names | abs(), cos(), cosh(), exp(), floor(), log(), log10(), max(), min(), sin(), sinh(), sqrt(), sum(), tan(), tanh(), acos(), asin(), atan() | Have the same name in Julia. |
| functions with different names | aimag() atan2(x, y) ceiling() conjg(z) modulo() call random_number() | imag() atan(x, y) ceil() conj() mod(), % Random.rand() |
| Built-in string functions | ||
| string length | len() | length() |
| string to ASCII code | iachar() | Int() |
| ASCII code to string | achar() | String() |
| string slicing | Same as 1D array slicing. | Same as 1D array slicing. |
| find the position of a substring | index(string, substring) | findfirst(substring, string) |
| string concatenation | "hello" // "world" | "hello" * "world" string("hello", "world") |
| Array constructs | ||
where construct | where a > 0 b = 0 elsewhere b = 1 end where | b[a .> 0] .= 0 b[a .<= 0] .= 1for i in eachindex(a) a[i] > 0 ? b[i] = 0 : b[i] = 1 end |
| Comprehension | integer, parameter :: n = 20 integer, parameter :: m = n*(n+1)/2 integer :: i, j complex, dimension(m) :: a a = [ ( ( cmplx(i,j), i=j,n), j=1,n) ] | a = [ complex(i,j) for j=1:n for i=j:n] |
forall construct | real, dimension(10, 10) :: a = 0 int :: i, j ... forall (i = 1:10, j = 1:10, i <= j) a(i, j) = i + j end forall | a = zeros(Float32, 10, 10) for i in 1:10, j in 1:10 if i <= j a[i, j] = i + j end end |
| CPU time | call cpu_time() | time = @elapsed begin ... end |
| command line arguments | call command_argument_count() call get_command() call get_command_argument() | For basic parsing, use ARGS |
| Input/output | ||
print fmt, <output list> | println() | |
| read from the command prompt | read fmt, <input list> | readline() |
| open a file | open(unit, file, ...) | f = open(file, 'r') |
| read from a file | read(unit, fmt, ...) <input list> | read(f) readlines(f) |
| write to a file | write(unit, fmt, ...) <output list> | write(f, ...) |
| close a file | close(unit, ...) | close(f) |
| file inquiry | inquire(unit, ...) | isfile("my_file.txt") |
| backspace in a file | backspace(unit, ...) | skip(f, -1) |
| end of file (EOF) | endfile(unit, ...) | seekend(f) |
| return to the start of a file | rewind(unit, ...) | seekstart(f) |
Update 16/10/2025: Since Julia 1.12 it is possible to build an application and execute it without the julia runtime. I added a Makefile to build this application in the directory julia-code. You must install JuliaC.
cd julia_code make time ./build/bin/app_exe 1 time ./build/bin/app_exe 1000Update 26/09/2025: @loiseaujc added a modern fortran version (gfortran-15 required). Check the PR #8 to see details.
Here an example of a Fortran to Julia translation. We use the Yee numerical scheme FDTD: Finite-Difference Time-Domain method and MPI topology. You can find a serial version and a parallel version using MPI library.
Test your MPI.jl installation with
$ cd julia_code $ julia --project -e "import Pkg; Pkg.instantiate()" $ mpirun -np 4 julia --project hello_mpi.jl Hello world, I am 0 of 4 Hello world, I am 3 of 4 Hello world, I am 1 of 4 Hello world, I am 2 of 4 On small program like this in Julia is really fast.
julia -O3 --check-bounds=no --startup-file=no maxwell_serial.jl: 14 secondsmake && time ./maxwell_serial_fortran: 31 seconds
make && time mpirun -np 9 ./maxwell_mpi_fortran: 7 secondsmpirun -np 9 julia --project -O3 --check-bounds=no --startup-file=no maxwell_mpi.jl: 5 seconds
Uncomment the plot_fields call in Julia programs or change idiag value in input_data for fortran.
gnuplot bz.gnu 