Programming Language Classification
Last updated on 2024-05-25 | Edit this page
Overview
Questions
- How does Julia roughly compare to other programming languages?
Objectives
- State important global properties of Julia.
In this episode we will place Julia within the world of programming languages.
High-Level
Julia is a high-level language, that is, it abstracts away the details of the hardware that runs software written in the language. Other high-level languages are, for example, Java and Python.
Dynamic
Julia is dynamically typed by default. This puts it in the company of Python and distinguishes it from Java and C++.
Even though it is dynamically typed by default, it does allow programmers to specify the type of a variable, for example for method parameters or method return types. This is mainly necessary to make use of method dispatch based on argument types. It also helps to ensure that no unintended uses of functions (seem to) work. And, in some cases, it can improve performance.
We will give it a try and define two methods, one with and one without specifying the parameter type:
JULIA
> identity(x) = x
identity (generic function with 1 method)
> identity(2.0)
2.0
> identity(2)
2
> float_identity(x::Float64) = x
float_identity (generic function with 1 method)
> float_identity(2.0)
2.0
> float_identity(2)
ERROR: MethodError: no method matching float_identity(::Int64)
Closest candidates are:
float_identity(::Float64) at REPL[4]:1
Stacktrace:
[1] top-level scope
@ REPL[6]:1
Garbage Collected
Julia uses garbage collection for memory management.
Compiled
Julia is a compiled programming language. However, functions are compiled just-in-time for any given list argument types. For example, when we define a method, it does not get compiled.
Only when we call it for the first time, this happens.
And it only compiles the function for arguments of type
Int64
. We can look at the compilation results for different
argument types using the function code_native
:
JULIA
julia> code_native(foo, (Int64,))
.text
; ┌ @ REPL[1]:1 within `foo`
endbr64
movq %rdi, %rax
retq
nopl (%rax,%rax)
; └
julia> code_native(foo, (Float64,))
.text
; ┌ @ REPL[2]:1 within `foo`
endbr64
movabsq $.rodata.cst8, %rax
vmovsd (%rax), %xmm0 # xmm0 = mem[0],zero
retq
nopw %cs:(%rax,%rax)
; └
Since Julia always compiles and never evaluates, the compiler is sometimes called a just-ahead-of-time compiler.
High-performance
The intention behind developing Julia was to create a fast dynamic language. And so it comes as no surprise that high-performance software can be written in Julia. The language is by design particularly well suited for dealing with (large) arrays of numbers. This makes it a good language for writing code for numerical analysis, optimisation, and many forms of machine learning.
Benchmarks on the language’s website place its performance close to that of languages like C or Rust.
With CUDA.jl there is an officially supported library that allows to write code for Nvidia GPUs directly in Julia.