question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Suggestion] Implement optional out parameters

See original GitHub issue

At the moment, the only way to implement optional out parameters is by writing overloaded functions that do nothing but provide a variable for the primary function to output into. If the user doesn’t care about a particular output parameter, why should they provide it?

For example, say I have the following function:

    public static void NearbyPointOnLine
    (
        Vector3 StartingPoint, 
        Vector3 EndingPoint, 
        Vector3 MyPosition, 
        out Vector3 ClosestPoint,
        out Vector3 RandomNearbyPoint,
        float RandomOffsetPercentage=0.0f
    )
    {
            // Find the closest point
            // Using values calculated above and the closest point, calculate a random point within the given range
    }

If the user doesn’t provide a RandomOffsetPercentage, they’d still get back the ClosestPoint in both ClosestPoint and RandomNearbyPoint. So the user could call NearbyPointOnLine(StartingPoint:LeftPoint, EndingPoint:RightPoint, MyPosition:this.position, ClosestPoint: out ClosestPoint); they can get the closest point without worrying about the random point.

The writer has to write boiler plate code to simulate optional parameters:

    public static void NearbyPointOnLine
    (
        Vector3 StartingPoint, 
        Vector3 EndingPoint, 
        Vector3 MyPosition,
        out Vector3 ClosestPoint
    )
    {
        Vector3 RandomNearbyPoint;
        NearbyPointOnLine(StartingPoint, EndingPoint, MyPosition, out ClosestPoint, out RandomNearbyPoint, 0.0f);
    }
    public static void NearbyPointOnLine
    (
        Vector3 StartingPoint,
        Vector3 EndingPoint,
        Vector3 MyPosition,
        out Vector3 RandomNearbyPoint,
        float RandomOffsetPercentage = 0.0f
    )
    {
        Vector3 ClosestPoint;
        NearbyPointOnLine(StartingPoint, EndingPoint, MyPosition, out ClosestPoint, out RandomNearbyPoint, 0.0f);
    }

This boiler plate could and should be done by the compiler; all this code could be reduced to just a few characters for the writer, and the compiler can expand it into the same override functions that the writer would otherwise write, but since the compiler is handling it, it wouldn’t have created the copy-and-paste bug that exists in the second boilerplate above. Alternatively, the compiler could be even smarter and create some temporaries in any calling functions to receive the output and discard it without creating new functions. Then there wouldn’t be the requirement of differing signatures as above: I could call NearbyPointOnLine(RightPoint, LeftPoint, this.Position, ClosestPoint: out ClosestPoint, RandomOffsetPercentage: 0.1f). However, since the writer must provide different signatures, RandomOffsetPercentage had to be dropped from the one that didn’t return the random point; this may have caused an issue during implementation of another function.

The writer could simply write public static void NearbyPointOnLine(Vector3 StartingPoint, Vector3 EndingPoint, Vector3 MyPosition, out Vector3 ClosestPoint=default(Vector3), out Vector3 RandomNearbyPoint=default(Vector3), float RandomOffsetPercentage=0.0f), then the user can use NearbyPointOnLine(LeftPoint, RightPoint, this.Position, out CenterPos), or NearbyPointOnLine(LeftPoint, RightPoint, this.Position, RandomNearbyPoint: out RandomPoint, RandomOffsetPercentage: 0.1f)

Alternatively, out parameters could act like return values, in that they are always optional; there is absolutely no requirement that the user make use of information given back to them from a function by a return value, so why should they be required to manually allocate out parameters that they are just going to discard? Thanks to named parameters, this is completely feasible. In the case of positional parameters, the user would have to provide the temporary variables to receive the out parameters up until they reach the desired values, just as they do now, but all following out parameters could be handled by the compiler; named parameters completely bypass this restriction. This may be too big of a semantic change for existing users (though it wouldn’t affect existing code; any existing boilerplate would already be more exact than an optional out parameter) so providing the function writer a way to explicitly state that their out parameters are optional (they’d be writing boiler plate code for it anyway) would provide the benefits of compiler generation with less confusion.

Bottom line: The compiler can do this better than the function writer, and it would be far more convenient for both the function writer and the user, resulting in less code and less bugs.

Issue Analytics

  • State:closed
  • Created 9 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
gaftercommented, Aug 15, 2016

We hope to improve things soon with the syntax M(out *) - that is, an explicit placeholder for omitted out parameters. That applies to all out parameters, and does not require updating the API to take advantage of the feature. Given that, I don’t think we’d ever want to do this too.

0reactions
ErzengelLichtescommented, Feb 5, 2015

I’d be in favor of removing out parameters entirely in favor of tuples, especially if we can have named tuples ((ClosestPoint: var closest) = NearbyPointOnLine(...)), but if out parameters exist at all (backcompat, no compiler magic for converting old outs into tuples) I would like to see optional outs for those who prefer out syntax over tuple syntax.

Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - Optional Output Parameters
An optional parameter passes in a specific value if the caller does not specify one -- with a ref parameter, the caller is...
Read more >
Different ways to make Method Parameter Optional in C# - ...
It is the simplest and easiest way to implement the optional parameter. In this way, you just simply define the optional parameters with...
Read more >
CA1021: Avoid out parameters (code analysis) - .NET
A public or protected method in a public type has an out parameter. By default, this rule only looks at externally visible types, ......
Read more >
Introduce optional parameters (private accessibility)
If the single purpose of an overloaded function is to call the 'implementation' function with default values for some arguments, Optional ...
Read more >
Are optional parameters helpful or a hindrance to ...
Optional parameters have, in my experience, been a good thing. I have never found them confusing (at least no more confusing than the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found