Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia: Updating a Float64 within a function

Tags:

julia

I am trying to create a function to update a Float64 argument. The example below should be able to clarify what I am trying to achieve.

a=1.2

function fun!(a)
   a=3.4;
end

Unfortunately, a is updated only in local scope. Is there a way to do it? I thought that passing a pointer to the function could help, but I am not sure how to do it in Julia.

like image 859
merch Avatar asked Jan 02 '23 19:01

merch


2 Answers

You can't do this. A Float64 is not a mutable value, so you cannot mutate the value of a. You can only replace a by a separate Float64. This is what an immutable value is.

More lower level (and usually true, although there are exceptions): Float64s are represented by their actual bytes, while mutables are pointers to the actual bytes. The actual value of a mutable is its pointer. Mutating means changing values at the memory location that the pointer is pointing to, but this doesn't exist for the immutable.

like image 178
Chris Rackauckas Avatar answered Jan 22 '23 05:01

Chris Rackauckas


To complete the answer and if you have a C/C++ background:

  • mutable objects are generally allocated on the heap and have stable memory addresses. They are passed by reference
  • immutable objects are on the stack and are passed by copy

Also, AFAIK, the ! of fun! is only a name convention to draw attention it has nothing to do with julia internals. You can write fun is you want.

Examples:

v=ones(3);                         # [1 1 1]
isimmutable(v)                     # false -> v is passed by reference
foo(v::Array{Float64}) = v .*= 2;  # hence v can be modified
foo(v); 
v                                  # [2 2 2]

v=Int(1)                           # 1
isimmutable(v)                     # true -> v is passed by copy
foo(v::Int) = v *= 2               # use a local copy of v
foo(v)                             # returns 2, but it is a local copy
v                                  # 1 (unmodified because we worked with a copy)

Also see FAQ

Ref{} example:

Isaiah Norton comment

foo(r::Ref{Int}) = r[] *= 2

r=Ref{Int}(1)     # Base.RefValue{Int64}(1)
foo(r);
r                 # Base.RefValue{Int64}(2)
like image 30
Picaud Vincent Avatar answered Jan 22 '23 07:01

Picaud Vincent