Engee documentation
Notebook

Notable differences from other languages

Although Julia syntax may seem familiar to MATLAB users, Julia is not a clone of MATLAB. There are important syntactic and functional differences between them. Listed below are some notable Julia differences that may confuse users who are used to MATLAB.

Differences from matlab

  1. The indexes of arrays in Julia are indicated in square brackets: A[i,j].
In [ ]:
Pkg.add(["LinearAlgebra"])
In [ ]:
A = [1 2 3; 4 5 6; 7 8 9]
i = 2
j = 3
element = A[i, j]
println(element)
6
  1. When an array in Julia is assigned to another variable, it is not copied. After assigning A = B, changing the elements of B will cause them to change to A.
In [ ]:
B = [1, 2, 3]
A = B
B[1] = 10
println(A)
[10, 2, 3]
  1. In Julia, the values passed to the function are not copied. If the function modifies the array, these changes will be visible to the caller.
In [ ]:
function modify_array(arr)
    arr[1] = 100
end

A = [1, 2, 3]
modify_array(A)
println(A)
[100, 2, 3]
  1. In Julia, arrays are not automatically incremented when using the assignment operator. Whereas in MATLAB, using the expression a(4) = 3.2, you can create an array a = [0 0 0 3.2], and using the expression a(5) = 7, increase it to a = [0 0 0 3.2 7], in Julia, the corresponding operator a[5] = 7 outputs an error occurs if the length of a is less than 5 or if the name a is used for the first time in this statement. Julia has push functions! and append!, which allow you to enlarge Vector type objects much more efficiently than a(end+1) = val in MATLAB.
In [ ]:
A = [1, 2, 3]
push!(A, 4)
println(A)

B = [5, 6, 7]
append!(B, [8, 9])
println(B)
[1, 2, 3, 4]
[5, 6, 7, 8, 9]
  1. The imaginary unit sqrt(-1) is represented in Julia by the constant im, not i or j, as in MATLAB.
In [ ]:
z = 2 + 3im
println(z)
println("Действительная часть: ", real(z)) 
println("Мнимая часть: ", imag(z)) 
2 + 3im
Действительная часть: 2
Мнимая часть: 3
  1. In Julia, numeric literals without a decimal separator (for example, 42) create integers, not floating-point numbers. As a result, some operations may result in an out-of-range error if they expect a floating-point number. For example, julia > a = -1; 2^a will return this error, since the result is not an integer (for more information, see the FAQ section on errors going out of scope).
In [ ]:
a = 42  # целое число
b = 42.0 # число с плавающей запятой
c = float(42) # явное преобразование к типу Float64
println(a)
println(b)
println(c)
42
42.0
42.0
  1. If Julia needs to return or assign multiple values, tuples are used, for example (a, b) = (1, 2) or a, b = 1, 2. Julia does not have the nargout function, which is often used in MATLAB to perform additional actions depending on the number of returned values. Optional and named arguments can be used for similar purposes.
In [ ]:
function get_values()
    return 1, 2
end

x, y = get_values()
println(x)
println(y)
1
2
  1. Julia has true one-dimensional arrays. Column vectors are of size N, not Nx1. For example, the expression rand(N) creates a one-dimensional array.
In [ ]:
v = [1, 2, 3] # одномерный массив
Out[0]:
3-element Vector{Int64}:
 1
 2
 3
  1. In Julia, the construction [x,y,z] always creates an array containing three elements: x, y, and z. — To concatenate by the first ("vertical") dimension, call the vcat(x,y,z) function or use a semicolon ([x; y; z]) as a separator. — To concatenate the second ("horizontal") dimension, call the hcat(x,y,z) function or use a space ([x y z]) as a separator. — To create block matrices (with concatenation over the first two dimensions), call the hvcat function or combine spaces and semicolons as separators ([a b; c d]).
In [ ]:
A = [1, 2, 3]
B = [4, 5, 6]
C = [7, 8, 9]

D = vcat(A, B, C) # вертикальная конкатенация
println(D)

E = hcat(A, B, C) # горизонтальная конкатенация
println(E)

F = [A; B; C] # разделитель ";"
println(F)

G = [A B C] # разделитель пробел
println(G)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1 4 7; 2 5 8; 3 6 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1 4 7; 2 5 8; 3 6 9]
  1. In Julia, constructs a:b and a:b :c create AbstractRange objects. To create a complete vector, as in MATLAB, use the collect(a:b) method. However, you usually don't need to call collect. The AbstractRange object behaves like a regular array in most cases, but it is more efficient due to the "lazy" calculation of values. This pattern of creating special objects instead of full arrays is often used, including with functions such as range and iterators such as enumerate and zip. Special objects can usually be used as regular arrays.
In [ ]:
range = 1:5
vector = collect(range)
println(vector)
[1, 2, 3, 4, 5]
  1. Functions in Julia return the result of calculating the last expression or expression with the keyword return. You do not need to list the names of the returned variables in the function definition (for more information, see the return keyword).
In [ ]:
function sum(x, y)
    x + y
end

result = sum(2, 3)
println(result)
5
  1. In Julia, when calling a function without arguments, you must use parentheses, such as rand().
In [ ]:
function example()
    println("Функция без аргументов")
end

example()
Функция без аргументов
  1. In Julia, it is not recommended to put semicolons at the end of expressions. The results of expressions are not displayed automatically (except on the interactive command line), so there is no need to end lines of code with a semicolon. You can use the println function or the @printf macro to display certain data on the screen.
In [ ]:
a = 2
b = 3
c = a + b
println(c)
5
  1. In Julia, if A and B are arrays, logical comparison operations such as A == B do not return an array of boolean values. Instead, use A .== B or similar expressions for other logical operators such as < and >.
In [ ]:
A = [1, 2, 3]
B = [2, 2, 3]
result = A .== B
println(result)
Bool[0, 1, 1]
  1. In Julia, the operators &, | and ⊻ (xor) are executed bitwise, just like, respectively, and, or and xor in MATLAB. Their precedence is the same as that of bitwise operators in Python (but not the same as in C). They can be applied to scalar values or piecemeal to arrays, and can also be used to combine logical arrays. However, note the difference in the order of operations: parentheses may be required (for example, to select elements of A equal to 1 or 2, use the expression (A .== 1) .| (A .== 2)).
In [ ]:
a = 5
b = 3
result = a & b
println(result)

A = [true, false, true]
B = [false, true, true]
result = A .& B
println(result)
1
Bool[0, 0, 1]
  1. In Julia, collection elements can be passed to a function as arguments using the expansion operator (splat operator) ..., for example xs=[1,2]; f(xs...).
In [ ]:
function sum_elements(x, y, z)
    return x + y + z
end

values = [1, 2, 3]
result = sum_elements(values...)
println(result)
6
  1. The svd function in Julia returns singular values as a vector rather than a dense diagonal matrix.
In [ ]:
using LinearAlgebra
A = [1 2; 3 4]
U, S, V = svd(A)
println(S)
[5.464985704219043, 0.3659661906262575]
  1. Julia has a symbol ... it is not used to continue lines of code. Instead, the incomplete expression is automatically continued on the next line.
In [ ]:
a = 2 +
    3
println(a)
5
  1. Structs in Julia do not support dynamic field addition at runtime, unlike classes in MATLAB. Use Dict instead. Dictionaries in Julia are not ordered.
In [ ]:
struct MyStruct1
    field1::Int
end

s = MyStruct1(10)
println(s.field1)

# Используем словарь для добавления поля field2
s_dict = Dict(:field1 => s.field1, :field2 => 20)
println(s_dict[:field2])
10
20
  1. In Julia, each module has its own global scope or namespace, while in MATLAB there is only one global scope.
In [ ]:
module MyModule
    global_var = 10
    
    function my_function()
        println(global_var)
    end
end

MyModule.my_function()
10
WARNING: replacing module MyModule.
  1. In MATLAB, the idiomatic way to remove unnecessary values is to use logical indexing, as in the expression x(x>3) or in the operator x(x>3) = [] to change x in place. Julia provides higher-order functions filter and filter! for this purpose, which allow the expressions filter(z->z>3, x) and filter!(z->z>3, x) to be used as alternatives for x[x.>3] and x =x[x.>3]. The filter function! it allows you to use temporary arrays less often.
In [ ]:
A = [1, 2, 3, 4, 5]
filtered_A = filter(x -> x > 3, A)
println(filtered_A)

filter!(x -> x > 3, A)
println(A)
[4, 5]
[4, 5]
  1. Extracting (or "dereferencing") all elements of an array of cells, for example vertcat(A{:}) in MATLAB, it is written in Julia using the expansion operator (splat operator), for example vcat(A...).
In [ ]:
A = [1, 2]
B = [3, 4]
C = [5, 6]
array_of_arrays = [A, B, C]
concatenated_array = vcat(array_of_arrays...)
println(concatenated_array)
[1, 2, 3, 4, 5, 6]
  1. In Julia, the adjoint function performs conjugate transposition; in MATLAB, adjoint provides an adjoint matrix (classical conjugation), that is, it performs the transpose of the matrix of algebraic complements.
In [ ]:
A = [1+2im 3+4im]
adj_A = adjoint(A)
println(adj_A)
Complex{Int64}[1 - 2im; 3 - 4im;;]
  1. In Julia, the expression (abc) is evaluated as a(bc), while in MATLAB it is calculated as (ab)c.
In [ ]:
a = 3
b = 2
c = 3
result = a^(b^c)
println(result)
6561

Differences from Python

  1. In Julia, the for, if, while, and so on blocks end with the end keyword, rather than indenting them, as in Python. There is no pass keyword.
In [ ]:
for i in 1:5
    println(i)
end
1
2
3
4
5
  1. In Julia, lines are indicated by double quotes, and three pairs of double quotes are used for multiline texts. Also, single quotation marks are used for characters.
In [ ]:
str1 = "Hello, World!"
str2 = """Это много-
строчный текст."""
char1 = 'c'
Out[0]:
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
  1. Julia uses the * operator for string concatenation, not +, as in Python. The ^ operator is used to repeat lines, not *.
In [ ]:
str1 = "Hello, "
str2 = "World!"
concatenated_str = str1 * str2
repeated_str = str2 ^ 3
println(concatenated_str)
println(repeated_str)
Hello, World!
World!World!World!
  1. In Julia, lists correspond to the Vector{Any} type or the more general Vector{T} type, where T is some type of elements. More efficient arrays, like NumPy arrays, can be represented by arrays Array{T}, where T is a specific type of elements.
In [ ]:
list1 = Any[1, "two", 3.0]
list2 = Vector{Int}(undef, 5)
array1 = Array{Int}(undef, 3, 3)
Out[0]:
3×3 Matrix{Int64}:
 3762813801648698725  3774918513298847538  7077182949550143800
 3762529018811868721  7364623875528025187      140502613063936
 3991368380935386977  3906925892200719205      140518684094896
  1. Indexing arrays in Julia starts from one, unlike in Python, where indexing starts from zero.
In [ ]:
array = [1, 2, 3, 4, 5]
println(array[1])  # Выведет 1
1
  1. When indexing slices in Julia, the last element is included, unlike in Python. a[2:3] in Julia is equivalent to a[1:3] in Python.
In [ ]:
array = [1, 2, 3, 4, 5]
println(array[2:3])  # Выведет [2, 3]
[2, 3]
  1. AbstractArray arrays with arbitrary indexes are allowed in Julia. Negative indexes that have a special meaning in Python are written in Julia as a[end] and a[end-1].
In [ ]:
array = [1, 2, 3, 4, 5]
println(array[end])  # Выведет 5
println(array[end - 1])  # Выведет 4
5
4
  1. To index to the last element in Julia, the end keyword is used. x[1:] in Python is equivalent to x[2:end] in Julia.
In [ ]:
array = [1, 2, 3, 4, 5]
println(array[2:end])  # Выведет [2, 3, 4, 5]
[2, 3, 4, 5]
  1. In Julia, range indexing has the format x[start:step:stop], and in Python - x[start:(stop+1):step]. Therefore, x[0:10:2] in Python is equivalent to x[1:2:10] in Julia.
In [ ]:
array = [1, 2, 3, 4, 5]
println(array[1:2:end])  # Выведет [1, 3, 5]
[1, 3, 5]
  1. Julia does not have a line continuation syntax. If the string contains a full-fledged expression, then it is considered completed. Otherwise, the line continues. Parentheses can be used to continue the expression.
In [ ]:
a = (
    1 + 2 +
    3
)
println(a)  # Выведет 6
6
  1. In Julia, arrays are expanded by columns, while NumPy arrays are expanded by rows. When iterating through arrays in Julia, the loop order should be reversed compared to NumPy.
In [ ]:
A = [1 2; 3 4; 5 6]
for j in 1:size(A, 2), i in 1:size(A, 1)
    println(A[i, j])
end
1
3
5
2
4
6
  1. In Julia, the default values of function arguments are calculated every time a method is called, unlike in Python, where values are calculated only when a function is defined.
In [ ]:
function f(x = rand())
    return x
end;
In [ ]:
println(f())  # Выполните ячейку несколько раз
0.975434444871681
  1. In Julia, named arguments must be passed with names, unlike in Python.
In [ ]:
function foo(a; b = 1, c = 2)
    return a + b + c
end

println(foo(10, b = 3, c = 4))  # Выведет 17, нельзя вызывать как println(foo(10, 3, 4)), в случае с Python
17
  1. In Julia, the Int type corresponds to the machine integer type (Int32 or Int64), while in Python int can have any length.
In [ ]:
x = Int64(2) ^ Int64(64)
println(x)  # Выведет 0
0
  1. The imaginary unit in Julia is represented by the constant im, while in Python j is used.
In [ ]:
println(2im)  # Выведет 0 + 2im
0 + 2im
  1. In Julia, the exponentiation operator is denoted by ^, not **, as in Python.
In [ ]:
println(2 ^ 3)  # Выведет 8
8
  1. An empty value in Julia is denoted by a nothing constant of the Nothing type, while in Python a None object of the NoneType type is used.
In [ ]:
x = nothing
println(x)  # Выведет nothing
nothing
  1. In Julia, the * operator performs a matrix operation, while in Python, an element-by-element multiplication is performed. In Julia, the .* operator is used for element-wise multiplication.
In [ ]:
A = [1 2;
     3 4]
B = [5 6;
     7 8]
println(A * B)  # Выведет матрицу, [19 22; 43 50]

println(A .* B)  # Выведет матрицу, [5 12; 21 32]
[19 22; 43 50]
[5 12; 21 32]
  1. In Julia, the operator ' returns the conjugation of a vector, while the transpose operator .T in Python returns the original vector.
In [ ]:
x = [1 2 3]
println(x')  # Выведет [1; 2; 3]
[1; 2; 3;;]
  1. In Julia, a function can have several specific implementations (methods) that are selected based on the types of arguments. In Python, the function has a single implementation, and polymorphism is not supported.
In [ ]:
function square(x::Number)
    return x * x
end

function square(x::String)
    return string(x, x)
end

println(square(2))  # Выведет 4
println(square("hello"))  # Выведет "hellohello"
4
hellohello
  1. Julia does not have classes, instead structures are used that contain only data, but not methods.
In [ ]:
struct MyStruct
    x::Int
    y::Float64
end

function f(obj::MyStruct, z)
    return obj.x + obj.y + z
end

my_obj = MyStruct(1, 2.5)
println(f(my_obj, 3.5))  # Выведет 7.0
7.0
  1. Calling a class instance method in Python corresponds to calling a function in Julia.
In [ ]:
struct MyType
    x::Int
end

function f(obj::MyType, y)
    return obj.x + y
end

my_obj = MyType(10)
println(f(my_obj, 5))  # Выведет 15
15
  1. A structure in Julia can have only one abstract supertype, while Python classes can be inherited from several superclasses.
In [ ]:
abstract type Animal end

struct Dog <: Animal
    name::String
end

struct Cat <: Animal
    name::String
end

dog = Dog("Buddy")
cat = Cat("Whiskers");
  1. In Julia, is the ternary operator written as x > 0 ? 1 : -1, while Python uses the conditional expression 1 if x > 0 else -1.
In [ ]:
x = 10
result = x > 0 ? 1 : -1
println(result)  # Выведет 1
1
  1. In Julia, exception handling is performed using the try-catch-finally construct, unlike in Python, which uses try-except-finally.
In [ ]:
try
    # Код, который может вызвать исключение
catch ex
    # Обработка исключения
finally
    # Выполнение кода, который будет выполнен в любом случае
end

Conclusion:

This example demonstrates the main syntactic and functional differences that distinguish Julia from Matlab and Python.