Returning a reference from a factory

I know that reference and lifetimes are still being worked on, but I was wondering if it will be possible to return a reference from a factory function, e.g.:
fn some_factory() -> Reference[String]:
var build_string = "Hello" # initially lifetime is bounded to the local variable in the function scope
return Reference(build_string) # extend the lifetime since the string reference is returned outside the function scope

fn main():
var x = some_factory() # lifetime of the string is now bounded to lifetime of x
print(x) # prints "Hello"
# x containing the string is freed here
fn some_factory() -> Reference[String]:
var build_string = "Hello" # initially lifetime is bounded to the local variable in the function scope
return Reference(build_string) # extend the lifetime since the string reference is returned outside the function scope

fn main():
var x = some_factory() # lifetime of the string is now bounded to lifetime of x
print(x) # prints "Hello"
# x containing the string is freed here
I think that it's not possible in Rust, it would be nice to know if something like this will be possible in Mojo.
6 Replies
Ethan
Ethan•6mo ago
Shouldn't be possible. build_string is freed when out of scope
Nick!
Nick!•6mo ago
Why would you want to write such a function? You can just return a String itself; there is no need to return a reference to it.
Yinon Burgansky
Yinon Burgansky•6mo ago
If it is a large struct which should be heap allocated and we want to hint the compiler it should be passed around by reference and not by value. I think there is terminology issue. So IIUC reference is only used to solve the problem of ownership where there could be multiple references to the same object. Where here is about a memory allocation strategy, allocate it on the heap and pass it around by its memory address. To clarify the question, there are multiple concepts each with its own options: - Ownership, single or multiple references, mutable or immutable, deciding when to free an object. - Memory allocation strategy, heap or stack. - value semantics, by value or by reference (memory address). A struct can decide decide on its value semantics by default, but the struct size could change by compile time parameters passed from the outside, you might want to pass it by reference instead of by value, or to allocate it locally on the stack or globally in the heap depending on the use case. I would like to know how does Mojo plan to deal with the various legal combinations of these options?
Melody Daniel
Melody Daniel•6mo ago
Mojo🔥 roadmap & sharp edges | Modular Docs
A summary of our Mojo plans, including upcoming features and things we need to fix.
No description
Nick!
Nick!•6mo ago
@Yinon Burgansky The answer is: "it's complicated". Over time, I expect the Mojo docs will explain all of these concepts adequately. If you want to learn more about how to write programs while having detailed control over heap versus stack allocation, copying vs. reference-passing etc, I would recommend learning Rust. There are tons of high-quality tutorials on Rust, including how memory is managed. Mojo will handle memory quite similarly. (But not exactly the same.) As a side comment: the return type -> Foo doesn't imply that the return value will be stored on the stack, nor does it imply that the return value will be copied. If the type is @register_passable, then it will be returned in a register (which is not the stack). Otherwise, the function will receive a memory address (as an implicit argument) from the caller. This is the address that the return value will be written to. It could be on the stack, or on the heap. The function isn't able to tell the difference. So as I said, it's complicated 🥲. Over time, the Mojo docs will explain how all of this works.
Yinon Burgansky
Yinon Burgansky•6mo ago
Thanks, having the compiler optimize it automatically sounds great, which will hopefully make the code less verbose than rust.
Want results from more Discord servers?
Add your server