-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Language feature: Named variables in function return declarations #1999
Comments
I don't have strong feelings, but it feels "unrustic" to return a value by assigning to named return variable. Also, this might just be me, but I find the rust code you posted much more readable than the Go code you posted... |
This sounds like "structural records". Rust used to have them, and removed them in 0.6:
Adding them back was proposed in https://internals.rust-lang.org/t/pre-rfc-unnamed-struct-types/3872 . As far as I can tell this proposal was not explicitly rejected, the conversation just died out. It may be worth writing a formal RFC pull request. |
You could rephrase this as asking to place a pattern in return position and assign to it. And you might as well ask for patterns in argument position while you're at it. I donno if either really buys much, but it might look like
or maybe you could omit the |
One more advantage of this approach is that no need explicitly to maintain stack variables to return within function - those (if declared as proposed) are automatically created & managed on function calling & returning. Who programmed in Delphi definetely loved its "result" auto variable. |
Yes. In order that not to create this pattern within function. |
Yes, it's short but note the "&h -> h" l-value usage in the return calculation. |
I think Rust already requires the caller allocate the space for returned I think non-lexical lifetimes might enable this without adding complexity to the
as opposed to
|
It's an explicit creation of stack variables which will be returned when function finishes. The ability of returning stack variables as ref counted function results is very handy fetarure of Rust. With the proposal in simple cases it can be simplified even more. |
Wouldn't the "rustic" way of writing this actually use
|
Our collegue "burdges" has got the idea. |
Sorry, I'm still not convinced. For me this piece of code was genuinely confusing for a minute until I realized |
Yeah I realized it'd need an explicit name like I've no idea if this is a good idea, but I wanted to point out that destructuring can happen in the body without fancy new syntax in the |
This feature also involves empty return ("Go") or no return at all ("Delphi"). |
@IvankoB what do you mean by "empty return" and "no return at all"? Are they analogous to return |
I'm nervous about the underlying goal here because we should avoid mutability when possible. Also, can return values from the I think the question should be : After non-lexical lifetimes work, should Rust support initial assignments to destructured uninitalized data? If so, this might look like
which works even when
|
@burdges That's true but is it more readable than? That's unclear to me at the moment... fn foo(..) -> Range<Foo> {
let start = ...;
let mut end = ...;
// set and mutate end and set start
Range{ start, end }
} |
In "Go" it indicates to exit function immediately with return value set by last change within the function body if it took place otherewise the value on calling the function:
|
Since they're decladed in same scope as input arguments all their lifetimes can be managed alltogether. |
@IvankoB You can do an explicit return in rust too. fn foo() {
if (blah == blah) {
println!("Hey, you!");
return;
}
if(bar) {
baz();
} else {
fudge();
}
} For example, this is what the fn read_stuff(my_path: &str) -> Result<...> {
let mut f = File::open(my_path)?; // may return early
let mut str = String::new();
f.read_to_string(&mut str)?; // may return early
Ok(str)
} |
Ones declaring some return (= not procedures) as well ? |
Sure, you can do `return some_expr`
…On May 12, 2017 11:38 AM, "IvankoB" ***@***.***> wrote:
You can do an explicit return in rust too.
Ones declaring some return (= not procedures) as well ?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1999 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AIazwBGXrCslK4CJdzpPX9DOj7zSfIPPks5r5IsFgaJpZM4NXfu7>
.
|
Yes, I think field puns largely eliminate the need for this @mark-i-m Why should it matter if you make your pun before or after the meal? It's just interesting to see what non-lexical lifetimes enable. :) As an aside, I think structural records might be interesting for partially initializing
Anyways, I think one solid argument against Go style named returns, as proposed here, is simply that it's too much strangeness budget on too small and too questionable a feature. |
The example code might be smth like:
|
BTW, how do peole think abou allwing the syntax sugar:
for :
|
That example seems like it's missing a few pieces so I can't tell for sure what you're suggesting, but my guess is that you're trying to say we should allow |
The syntax sugar as combining "declaring + initalizing + borrowing" instead of separate "(declaring + initalizing)" and "borrowing" ? Why not BTW if Rust checks context & lifetimes thoroughly before compiling ? |
It's day 2 of learning Rust for me, and I must say that without naming the return value, how do you know what the value represents, or means? I find it baffling that you'd expect to name function parameters, but not return values. I'm not just coming from Go, but also Swift, and both languages allow the return of tuples. In Objective-C you can't return a tuple, but you can at least name the return value in your method, such as
The idea of having to guess what the return value represents doesn't instil much hope for writing semantically clear code. Looking at this Swift example, it is abundantly clear as to what the function accepts and returns. It's just as much, if not more so about the perspective from outside the function, than in. Put simply, it's a much clearer interface.
|
IMHO, the name of the function/method should communicate what it returns/does in a way that makes named return values redundant. Indeed, Also, rust has a strong commenting culture centering around doc comments... |
|
Ah, thanks for clarifying that :)
They are named: the name of the method/function describes the output/expected behavior. |
Are you one of the core developers of Rust? |
Why not just do:
|
Rather negates the whole point of tuples as return values though I would think. |
Is there some inherent need to return tuples from functions? |
Fairly unusual question. Is there a need? Only in so much as there is an inherent need to pass multiple parameters to a function. Just because you can’t find a use for a feature, doesn’t mean others shouldn’t too, or it should be removed. |
What feature is being removed here? I'm confused. |
I think named variables ala Go sound like a huge mistake because they discourage using ADTs correctly, and encourage excessive mutability as noted previously. In other words, if you want to return I think @rayascott's Swift example might be covered by the structural records suggestion #1999 (comment) which might look like this with named field puns:
I donno if this improves so much on @wesleywiser's version though. In fact, it's usually wise to consider if an intermediate data type might help in more ways, ala the builder pattern. Also, structural records have much better uses, so I'd hate for any serious interest in them to be sidelined by trying to make them work in every last position, including As an aside, if we write this using iterator methods then we encounter a
|
Lol, no... why? |
Actually the
so you could write
|
The idea is also to preallocate result variables so that they can be used in function body directly (without local declaration) - like the Delphi's "Result" variable. A kind of non-staic mutable variable. |
I've proposed structural records (#2584), which are not this proposal, but close enough so I think we can close this now. |
With visibility of function parameters, possibly with default return values, to achive functionality of Delphi's function "Result" auto variable or as shown in the below "Go" code:
Note the usage of return varibales "success" & "printer" within the function body. Very handy & clear.
The current "Rust" code for this function is as follows :
The text was updated successfully, but these errors were encountered: