Optional ref and out parameters, and pass-by-value for ref parameters #8156
Replies: 3 comments 6 replies
-
In general, i'm in support of this. |
Beta Was this translation helpful? Give feedback.
-
Is it really that much work to write |
Beta Was this translation helpful? Give feedback.
-
This feature would allow me to remove many passthrough overloads from my Geometry and LinearMath utilities. Is this one of those things that's stuck in the "lobby for a champion" state where it's generally liked but lacks an LDM driver because of higher priorities? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
The language currently does not let one specify default values for
ref
orout
parameters, and thus, ref/out parameters are always mandatory parameters.in
parameters, on the other hand, do allow default parameters, and the compiler treats omitted arguments the same way it would a constant literal argument passed to thein
parameter, by creating an unnamed temporary variable in the caller's stack frame and passing a ref to it.It would be very handy to be able to omit both
ref
andout
parameters from a method invocation, as would being able to pass a constant literal or evaluated expression as an argument for aref
parameter as you can for anin
. The semantics seem straightforward, as they're essentially the same as for the case of an omittedin
parameter: the compiler allocates space for the value in the caller's stack frame and, in the case of a defaulted or constant-literalref
parameter, assigns the value to that space. As an example, a dictionary that indexes on case-insensitive strings and maintains insertion order, and which allows inserting into an empty slot after a lookup fails:I'd suggest that when passing a constant literal or expression to a
ref
parameter, that theref
keyword be forbidden at the callsite, in order to avoid violating programmer expectations that usingref
results in a change of caller-visible state. For example, a getter-only (and non-ref) property or a readonly field on an object could reasonably be used as a pass-by-value source - imagine passing an array'sLength
field to aRead
method as an in/out parameter - it represents the size of the buffer on entry, and it is assigned the amount of data read prior to exit. Ifref
were allowed on a pass-by-value argument, then the following would be valid syntax:That looks like the code is able and expected to modify the length of the array itself! Instead, I'd recommend using the
in
keyword to specify an argument that is passed by value to aref
parameter, since overloads can't distinguish betweenin
andref
. That still isn't quite right, as a callsitein
usually means that the value is being received in areadonly
context, while this is being received as a liveref
. You could, similarly useout
for an optionalref
parameter, and the calling method would be responsible for initializing it to the default value.For optional
out
parameters, I'd suggest that the declaration syntax be an assignment of the discard_
identifier. That mirrors the syntax that you need to use today, in which you specifyout _
as the argument at the callsite. Callsite syntax isn't affected forout
parameters, as there is no concept of a "value" to pass in.Critically, the invoked method cannot tell the difference between an argument passed by copied-value or by true reference; the semantics and codegen of the called method does not change with the addition of optional parameters. As far as the called function is concerned, it has been passed a reference.
This change would promote code reuse, as functions can be called in one of several ways according to need, and from a codegen and performance performance standpoint, it's effectively free - these types of parameters tend to be used for things the method was going to be allocating local storage anyway, so it's just a form of caller-mediated stack setup.
Beta Was this translation helpful? Give feedback.
All reactions