Closed timotheecour closed 4 years ago
...or simply deprecate and eventually remove result
and let users type var result = ...; return result
which is explicit and doesn't introduce an implicit variable and a third return style that has few good use cases but costs confusion, compiler maintenance + extra compiler logic to make sure that usage of result is somewhat sane, macro difficulties etc.
The only advantage I see in result return value optimization. It seems to me (but I don't know the internals of the compiler) that if all code paths only assign to result.somefield
, it should be easy to optimize this and just create result
on the previous stack frame, thereby avoiding a copy when returning.
It may be the case that this is difficult to do in general, or that it is easy to do with other ways of returning. But the picture I have in my mind is that result
is a preallocated slot which lives before the current stack frame.
If result
does not help with RVO, I agree with @arnetheduck that its complexities dwarf its advantages.
Definite assignment analysis (DAA) has little to do with result
! And the motivation for it is like this:
var x: int # please check for me every branch assigns a value to 'x'
case selector
of caseA:
if cond:
x = 3
else:
# more complex logic here
# oops I forgot to assign to 'x'
of caseB:
x = 4
of caseC:
x = 8
Nim's case statement checks for exhaustiveness, DAA is a nice extension.
See https://docs.oracle.com/javase/specs/jls/se6/html/defAssign.html for the rules we could simply take over from Java. It works.
Before Nim got default(T)
certain patterns were hard to express without Nim's current implicit initialization but now that we have default(T)
we could make the next steps, if your code depends on result = default(T)
as the first statement of your proc, so write that down explicitly.
Closing because it misrepresents my proposal which is https://github.com/nim-lang/RFCs/issues/49
goal: discuss this topic here and not in unrelated issues like https://github.com/nim-lang/Nim/pull/14777#issuecomment-649000045
proposal
(var int, int)
currently work with iterators (in RT, not VM), but not with procs; when they do, the proposal should apply to the components that arevar
, so that onlyvar
components should be initalized before use (and initialization stays optional for other components)lent result
, the rules are the same as forvar result
example
rationale for P2,P3,P4
should not be controversial, it's just correctness (otherwise you get SIGSEGV at runtime); ditto with
lent result
rationale for P1
The analysis is simple, and behaves as if
result = default(typeof(result))
was the first statement.links