unable to pass by value
i noticed i'm unable to pass variables by value, even primitives ,such as Int , are either borrowed or mutable refs "inout" or moved "owned"
11 Replies
@Honour why do you think
Int
is not being passed by value? I suspect it is, but not sure how to actually check.
Also see the @register_passable
decorator which you can use to make your own structs register- passable, which is a kind of accelerated pass by value.
The thing about Mojo is it's promoting the idea of "value semantics" which is very different than Python's reference semantics.
I keep returning to this section of the manual and it's pretty good:
https://docs.modular.com/mojo/programming-manual.html#argument-passing-control-and-memory-ownershipModular Docs - Mojo🔥 programming manual
A tour of major Mojo language features with code examples.
yeah it says value-semantics in the docs but then i created a
def
function with an Int argument and when i hover over it with the cursor the function signature says owned Int
which means it just transfers ownership rather than copy itif you have a variable a and copy it into variable b both own their respective copies
In the same way, you can pass copies to functions that take
owned
arguments
notice that this will compile:
had int been restricted to move only semantics you would have to write this:
and it would not compile, as it would be an attempt to use x after moveyeah value semantics has another name: copy semantics
lol
You can easily verify it with this example:
this does not compile
if you correct it by adding the ^ operator after x you will get this error:
a "move" is still a copy (sometimes). This is just semantics to allow you to protect objects that have some internal state, like a file descriptor - without shared mutable state reference semantics lead to
So a copyable type, a "value" is still safe to use where owned is required as it's inherently less restrictive than a move-only type.
I think it's clear to see why this would not be safe in the other direction
I hope this makes the difference a bit clearer.
note that this is just semantics, the compiler can do whatever optimisations it wants as long as it's safe, so you can't make assumptions about how these things are actually passed around.
yeah it says value-semantics in the docs but then i created a def function with an Int argument and when i hover over it with the cursor the function signature says owned Int which means it just transfers ownership rather than copy it@TeamPuzel I wonder if it's possible the LSP/tooltips disagrees vs what the compiler is actually doing? Docs say (note that def and fn work differently):
A Mojo def function receives a copy of all arguments—it can modify arguments inside the function, but the changes are not visible outside the function.Anyways, interesting question! If you think it's not actually a copy, that seems like at least a docs bug.
I can’t say anything about the tooltips because they’re broken for me, I don’t see any
But I think I heard of cases where the lsp disagreed
If you copy it makes sense it would be owned, is it different for an fn?
@TeamPuzel @guidorice perhaps you guys have misunderstood me . consider the code below
the compiler complains if you try to modify x inside the copy function because its not mutable, right??. The only way to provide mutability is with the
inout
keyword, but inout
automatically makes x
a mutable reference, which means modifying it also modifies the the original variable.
my point is that primitive types like int should copy by default or atleast allow the programmer to decide if they want a mutable reference
or a mutable copied value
Oh, okay
You want a mutable parameter that isn't a reference
There is a reason why it's probably not in mojo
GitHub
swift-evolution/proposals/0003-remove-var-parameters.md at main · a...
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - apple/swift-evolution
in Swift, in the very beginning you could have both
inout
and var
parameters
apparently that was confusing so var
was removed in one of the earliest proposals
It's still useful to have references to copyable types. inout
is irreplaceable whereas if you want a mutable copy var
paramers are only a convenience - you can just redeclare it:
Either way this is intended behavior