This is a common misconception. What happens is that the language is free to copy or not copy objects for which the user cannot distinguish whether copying happened. This allows the compiler various optimizations.
You may be interested in past discussions like
I have a simple question about memory management in Julia code. Coming from a C++ background with all that rvalue reference madness and move semantics stuff, I got my brain damaged, and I am having a hard time trying to reason about memory management again in other languages.
Consider the following cases:
Case 1
I have an immutable struct that requires a decent amount of memory (e.g. mesh with vertices, edges, triangles). By using composition, I define other concepts (e.g. path):
abstract ty…
This is a short summary based on what I understood from documentation, and this long thread , without mixing in (much of) scope rules, or any implementation details.
I will appreciate if somebody could check it’s validity.
Given that expr is either an expression evaluating to (returning) an object, or a literal object, either mutable or immutable, and not just a name ;
and
f(y) = do_with(y)
then:
x= expr makes the name/variable x bind to a new object (with new “reference” hence n…
From https://docs.julialang.org/en/latest/manual/types/#Mutable-Composite-Types-1:
In order to support mutation, such objects are generally allocated on the heap, and have stable memory addresses.
If I define:
mutable struct MyT
x::Int
end
and then use MyT inside a function, such as:
function f(x::Int)
q = MyT(x);
q.x += 1
return q.x
end
I would expect q to be allocated on the stack, because it is a local variable that does not change type and MyT is isbits. But it is not:
@btime f(1)…
but the bottom line is that deliberately leaving this unspecified and hidden from the user in normal circumstances is an important feature, and can be exploited by using immutables.
2 Likes