mutable struct MyDiscreteWalker # capital letters for each word in type name -- camel case
x::Int64
end
mutable struct SomethingElse
x::Int64 # several fields
y::Float64
name::String
end
MyDiscreteWalker # refers to the *type*
MyDiscreteWalker
methods(MyDiscreteWalker) # which methods / versions of a function exist
Julia automatically created 2 constructors -- functions to create objects of that type
w = MyDiscreteWalker(3)
MyDiscreteWalker(3)
typeof(w)
MyDiscreteWalker
Complex(3, 4)
3 + 4im
3 + 4im # im is i (sqrt of -1)
3 + 4im
@which Complex(3, 4)
w
MyDiscreteWalker(3)
w isa MyDiscreteWalker # w is an **instance** of the type MyDiscreteWalker
true
methods(MyDiscreteWalker)
MyDiscreteWalker(x::Int64)
is a method that works only when it receives an argument x
of type Int64
MyDiscreteWalker(x)
will accept an x
of any type
Any
Any
3.0 isa Int64
false
typeof(3.0)
Float64
MyDiscreteWalker(3.0)
MyDiscreteWalker(3)
MyDiscreteWalker(3.1)
InexactError: Int64(3.1) Stacktrace: [1] Int64 at ./float.jl:710 [inlined] [2] convert at ./number.jl:7 [inlined] [3] MyDiscreteWalker(::Float64) at ./In[1]:2 [4] top-level scope at In[21]:1
Int64(3.0)
3
Int64(3.1)
InexactError: Int64(3.1) Stacktrace: [1] Int64(::Float64) at ./float.jl:710 [2] top-level scope at In[23]:1
trunc(Int64, 3.1)
3
floor(Int64, 3.1)
3
floor(3.1)
3.0
Int64(floor(3.1))
3
w = MyDiscreteWalker(3)
MyDiscreteWalker(3)
w
MyDiscreteWalker(3)
Problem set 3:
Collecting information into one packet that belongs together: encapsulation
mutable struct Agent
infection_status::Int
num_infected::Int
end
w = MyDiscreteWalker(3)
MyDiscreteWalker(3)
More common to use immutable structs:
struct ExampleImmutable
x::Int
y::Int
end
z = ExampleImmutable()
convert(Int64, 3.0)
3
convert(Int64, 3.1)
InexactError: Int64(3.1) Stacktrace: [1] Int64 at ./float.jl:710 [inlined] [2] convert(::Type{Int64}, ::Float64) at ./number.jl:7 [3] top-level scope at In[33]:1
Int64(3.0)
3
@which Int64(3.0)
methods(Int64)
@which convert(Int64, 3.1)
z = ExampleImmutable(1, 2)
ExampleImmutable(1, 2)
z.x
1
z.y
2
z.x = 10
setfield! immutable struct of type ExampleImmutable cannot be changed Stacktrace: [1] setproperty!(::ExampleImmutable, ::Symbol, ::Int64) at ./Base.jl:34 [2] top-level scope at In[45]:1
z.y = 10
setfield! immutable struct of type ExampleImmutable cannot be changed Stacktrace: [1] setproperty!(::ExampleImmutable, ::Symbol, ::Int64) at ./Base.jl:34 [2] top-level scope at In[46]:1
w = MyDiscreteWalker(3)
MyDiscreteWalker(3)
MyDiscreteWalker()
MethodError: no method matching MyDiscreteWalker() Closest candidates are: MyDiscreteWalker(!Matched::Int64) at In[1]:2 MyDiscreteWalker(!Matched::Any) at In[1]:2 Stacktrace: [1] top-level scope at In[48]:1
methods(MyDiscreteWalker)
MyDiscreteWalker() = MyDiscreteWalker(0) # outer constructor (lives outside definition of type)
MyDiscreteWalker
methods(MyDiscreteWalker)
w = MyDiscreteWalker()
MyDiscreteWalker(0)
function jump!(w::MyDiscreteWalker)
w.x += rand( (-1, +1) )
end
jump! (generic function with 1 method)
pos(w::MyDiscreteWalker) = w.x # getter function
pos (generic function with 1 method)
w.x # w.<TAB>
propertynames(w)
(:x,)
propertynames(z)
(:x, :y)
pos(w) # interface to my object; removes me from the internal details
0
function set_pos!(w, x) # setter function
w.x = x
end
set_pos! (generic function with 1 method)
jump(MyDiscreteWalker) = rand( (-1, +1) )
jump (generic function with 1 method)
function jump!(w::MyDiscreteWalker)
old_pos = pos(w)
set_pos!(old_pos + jump(w))
end
In this version of jump!
, I never refer to internal details of the object.
function walk!(w::MyDiscreteWalker, N)
for i in 1:N
jump!(w)
end
return w
end
walk! (generic function with 1 method)
w
MyDiscreteWalker(0)
walk!(10)
MethodError: no method matching walk!(::Int64) Closest candidates are: walk!(!Matched::MyDiscreteWalker, !Matched::Any) at In[64]:2 Stacktrace: [1] top-level scope at In[66]:1
walk!
walk! (generic function with 1 method)
methods(walk!)
aweirdfunction(10)
UndefVarError: aweirdfunction not defined Stacktrace: [1] top-level scope at In[69]:1
walk!(w, 10)
MyDiscreteWalker(4)
w # has been mutated / modified
MyDiscreteWalker(4)
mutable struct MyContinuousWalker
y::Float64
end
w = MyContinuousWalker(3)
MyContinuousWalker(3.0)
w isa MyContinuousWalker
true
jump!(w)
MethodError: no method matching jump!(::MyContinuousWalker) Closest candidates are: jump!(!Matched::MyDiscreteWalker) at In[53]:2 Stacktrace: [1] top-level scope at In[75]:1
methods(jump!)
jump(w::MyContinuousWalker) = randn()
jump (generic function with 2 methods)
jump!(w::MyContinuousWalker)
MethodError: no method matching jump!(::MyContinuousWalker) Closest candidates are: jump!(!Matched::MyDiscreteWalker) at In[53]:2 Stacktrace: [1] top-level scope at In[78]:1
methods(jump!)
function jump!(w) # takes argument w of *any* type
old_pos = pos(w)
set_pos!(w, old_pos + jump(w))
end
jump! (generic function with 2 methods)
jump!(1)
MethodError: no method matching pos(::Int64) Closest candidates are: pos(!Matched::MyDiscreteWalker) at In[54]:1 Stacktrace: [1] jump!(::Int64) at ./In[80]:2 [2] top-level scope at In[81]:1
w
MyContinuousWalker(3.0)
jump!(w)
MethodError: no method matching pos(::MyContinuousWalker) Closest candidates are: pos(!Matched::MyDiscreteWalker) at In[54]:1 Stacktrace: [1] jump!(::MyContinuousWalker) at ./In[82]:2 [2] top-level scope at In[84]:1
methods(pos)
pos(w::MyContinuousWalker) = w.y
pos (generic function with 2 methods)
function set_pos!(w::MyContinuousWalker, pos)
w.y = pos
end
set_pos! (generic function with 2 methods)
jump!(w)
2.1822730537401607
walk!(w, 10)
MethodError: no method matching walk!(::MyContinuousWalker, ::Int64) Closest candidates are: walk!(!Matched::MyDiscreteWalker, ::Any) at In[64]:2 Stacktrace: [1] top-level scope at In[91]:1
methods(walk!)
function walk!(w, N)
for i in 1:N
jump!(w)
end
return w
end
walk! (generic function with 2 methods)
walk!(1, 2)
MethodError: no method matching pos(::Int64) Closest candidates are: pos(!Matched::MyContinuousWalker) at In[86]:1 pos(!Matched::MyDiscreteWalker) at In[54]:1 Stacktrace: [1] jump!(::Int64) at ./In[89]:2 [2] walk!(::Int64, ::Int64) at ./In[93]:3 [3] top-level scope at In[94]:1
walk!(w, 10)
MyContinuousWalker(-3.3119507350317736)
w
MyContinuousWalker(-3.3119507350317736)
"A discrete walker is a kind of walker"
abstract type RandomWalker end
RandomWalker
RandomWalker
methods(RandomWalker)
mutable struct DiscreteWalker <: RandomWalker
x::Int64
end
mutable struct ContinuousWalker <: RandomWalker
y::Int64
end
pos(w::DiscreteWalker) = w.x
pos(w::ContinuousWalker) = w.y
pos (generic function with 4 methods)
function walk!(w::RandomWalker, N)
for i in 1:N
jump!(w)
end
return w
end
walk! (generic function with 3 methods)
w = DiscreteWalker(10)
DiscreteWalker(10)
w isa DiscreteWalker
true
w isa RandomWalker
true
[DiscreteWalker(1), DiscreteWalker(2)]
2-element Array{DiscreteWalker,1}: DiscreteWalker(1) DiscreteWalker(2)