« TestNG And What We'd Like Code To Be | Main | Coverage in Production: Learning From Your Code's Liveness »

November 29, 2010


Kim Gräsman

I think both are/were required for interop. COM had [in,out] (ref) and [out] only (out) -- the difference was significant due to COM's transparent cross-process or cross-machine marshalling. You didn't want to marshal a value both ways if one way was enough.

For what it's worth.

Michael Feathers

Yes, that makes sense. I forgot about COM's [out].


I'm writing Standard ML right now, and I have been comparing C#'s "bool foo.TryParse( string s, out foo result)" idea to ML's "foo.fromString s : option foo". I think, based on this article, you would suggest ML's approach over the C# approach? I have found both approaches awkward. I've been considering a continuation passing style approach: "void withFoo( string s, Action success, Action fail )", but I haven't decided if I like it better.

Amy Thorne

I'm curious to hear what you think is a good alternative to the TryParse pattern (http://msdn.microsoft.com/en-us/library/ms229009.aspx) used by some .NET Framework methods such as Int32.TryParse and Dictionary.TryGetValue. I think these are the main situations where I end up using something that uses out, but I'm not sure what the better alternative is.


How do you feel about using a Tuple when you want to return two values from a function?

A little bit awkward from C#, but I think easier to understand than ref/out. It works better when you have language support, like in F# or python

Nolan Egly

Several people have commented on combining success/fail with a return result. One frequently used pattern, especially for remote communication calls, is an OpResult.

// subst generic brackets for braces, it's getting stripped
public class OpResult[T] {
public T Result { get; private set; }
public bool WasSuccessful { get; private set; }
...constructor, etc...

WasSuccessful can be replaced with an IEnumerable of error strings if needed - whatever the situation might call for.

I presume what Michael is warning against (please correct me if I'm wrong of course) is a method that modifies multiple separate data structures, not a method that returns an operation success indicator and result data at the same time.


I think 'out' is just misleading in your argument. Its just the fall guy because it was the abused feature

you could of made a mess with any number of language features if you don't gel related things together into data structures.

not only do you have the returning problem, you have the passing around a bunch of related values. It all leads to nasty code.

its also fun when the related parameters / results are needed by different functions and are passed in different orders. Especially if they are all a common basic type (like a int) and then values get transposed and all kinds of fun occurs.

so "return back, not out"

is not a good rule, its more like one of those things you tell people who have abused a particular language feature to make them stop and think, but its a transient piece of advice that shouldn't become a "rule" or rule of thumb.

Johannes Link

The one situation where out is the better - i.e. more elegant - solution IMO is when dealing with the immutable (aka persistent) version of some usueful data abstractions. Consider the pop operation of an immutable stack; since the popped element and the new stack instance don't have any relation (except their common past), returning the new stack object in an out parameter seems more appropriate to me than creating a new abstraction just for this purpose. YMMV.

Erhan Hosca

can you please explain in a bit more detail why we shouldn't be using the TryParse pattern ?

The comments to this entry are closed.