Videos related to this segment (click the title to watch)
01 JULIA1 - 2A: Types, objects, variables and operators (13:5)
01 JULIA1 - 2B: Object mutability and effects on copying objects (13:34)

0102 Types and objects

Some stuff to set-up the environment..

julia> cd(@__DIR__)
julia> using Pkg
julia> Pkg.activate(".") # If using a Julia version different than 1.10 please uncomment and run the following line (reproductibility guarantee will hower be lost) # Pkg.resolve() # Pkg.instantiate() # run this if you didn't in Segment 01.01 Activating project at `~/work/SPMLJ/SPMLJ/buildedDoc/01_-_JULIA1_-_Basic_Julia_programming`
julia> using Random
julia> Random.seed!(123)Random.TaskLocalRNG()

Types

julia> # 1 in not 1.0:
       a = 11
julia> b = 1.01.0
julia> typeof(a) # type is inferred !Int64
julia> typeof(b) # Convert type (cast)Float64
julia> a = 11
julia> b = convert(Float64,a)1.0
julia> typeof(b)Float64

Type hierarchy in Julia:

  • Any
    • AbstractString (We'll see what all these "abstract" mean....)
      • String
      • ...
    • AbstractArray
      • Array
      • ....
    • Number
      • Complex
      • Real
        • Rational
        • Integer
          • Unsigned
            • UInt64
            • ...
          • Signed
            • Int32
            • Int64
            • BigInt
            • ...
          • Bool
        • FixedPoints
          • ...
        • AbstractIrrational
          • Irrational
        • AbstractFloat
          • Float32
          • Float64
          • BigFloat
          • ...
    • ...

Complete Number hierarchy: https://upload.wikimedia.org/wikipedia/commons/d/d9/Julia-number-type-hierarchy.svg

Everythong is an object, i.e. of some "type":

julia> c = typeof(a)Int64
julia> typeof(c)DataType
julia> d = sinsin (generic function with 25 methods)
julia> typeof(d) <: Functiontrue
julia> typeof(+) <: Functiontrue

Operators are just functions:

julia> 1 + 23
julia> +(1,2) # this call the function "+"3
julia> import Base.+ # +(a,b,c) = a*b*c # Defining my new crazy addition operation with 3 arguments
julia> 10+20+30 # This call it60
julia> 10+20 # The addition with two parameters remains the same30
julia> 10+20+30+40 # Also this one remains with the standard addition..100
Warning

After you tested this singular interpretation of the summation function, please restart Julia or few things will continue to work: with great power comes great responsability, and if we change the meaning of such a inner feature of the language, repercussions will be deep.

Objects and variables

julia> k = 10    # "create" an object Int64 in memory and binds (assign) it to the `k` identifier (the variable name)10
julia> typeof(k)Int64
julia> sizeof(k) # bytes (1 byte is 8 bits)8
julia> bitstring(k)"0000000000000000000000000000000000000000000000000000000000001010"
julia> 0*2^0+1*2^1+0*2^2+1*2^310
julia> m = k # name binding: it binds (assign) the entity (object) referenced by a to the b identifier (the variable name)10
julia> m == k # are the two objects equal ?true
julia> m === k # are the two identifiers binding the same identical object in memory ?true

Mutability property of Julia objects

Mutable objects are stored in memory "directly", while for mutable objects it is its memory address to be stored:

julia> k = 1010
julia> v = [1,2]2-element Vector{Int64}: 1 2
julia> p = 'z''z': ASCII/Unicode U+007A (category Ll: Letter, lowercase)
julia> g = "hello""hello"
julia> ismutable(k)false
julia> ismutable(v)true
julia> ismutable(p)false
julia> ismutable(g)true

Three different ways to "copy" objects...

julia> a = [[[1,2],3],4] # First element of a is said to be "mutable", second one is not:2-element Vector{Any}:
  Any[[1, 2], 3]
 4
julia> ismutable(a[1])true
julia> ismutable(a[2])false
julia> b = a # binding to a new identifier2-element Vector{Any}: Any[[1, 2], 3] 4
julia> c = copy(a) # create a new copy of a and binds it to c2-element Vector{Any}: Any[[1, 2], 3] 4
julia> d = deepcopy(a) # copy all the references recursively and assign this new object to d2-element Vector{Any}: Any[[1, 2], 3] 4
julia> c == a # are the two objects equal ?true
julia> c === a # are the two identifiers binding the same identical object in memory ?false
julia> a[2] = 40 # rebinds a[2] to an other objects and at the same time mutates object a:40
julia> b2-element Vector{Any}: Any[[1, 2], 3] 40
julia> c2-element Vector{Any}: Any[[1, 2], 3] 4
julia> d2-element Vector{Any}: Any[[1, 2], 3] 4
julia> a[1][2] = 30 # rebinds a[1][2] and at the same time mutates both a and a[1]30
julia> b2-element Vector{Any}: Any[[1, 2], 30] 40
julia> c2-element Vector{Any}: Any[[1, 2], 30] 4
julia> d2-element Vector{Any}: Any[[1, 2], 3] 4
julia> a[1][1][2] = 2020
julia> b2-element Vector{Any}: Any[[1, 20], 30] 40
julia> c2-element Vector{Any}: Any[[1, 20], 30] 4
julia> d2-element Vector{Any}: Any[[1, 2], 3] 4
julia> a = 5 # rebinds a:5
julia> b2-element Vector{Any}: Any[[1, 20], 30] 40
julia> c2-element Vector{Any}: Any[[1, 20], 30] 4
julia> d2-element Vector{Any}: Any[[1, 2], 3] 4
Note

Consider these memory isues when we'll discuss calling a function by reference/value !

View this file on Github.


This page was generated using Literate.jl.