This is now valid and returns a tuple with named values:
public (string city, string state) GetCityAndState()
{
return ("Lake Charles","Louisiana");
}
And you can get the return values without writing "Tuple<" once. error_type function(out data, out data2, ...);
instead. Given that C# has proper try/catch and other mechanisms of error handling I'd hope that this pattern won't repeat itself.Additionally, it allows restricting the scope of the variable, like in the TryParse examples. The output variable in something like "if (int.TryParse(someString, out var i))" is now scoped to the if block. It cannot be used in the else, nor inadvertently later in the parent scope.
(string first, string middle, string last) LookupName(long id)A tuple doesn't have behaviour, inheritance, encapsulation, or data hiding. Tuples are language-agnostic.
An OO language has little choice but to represent tuples as objects, but to say that tuples are objects is no more true than saying that a user's account is an object, a TCP connection is an object, or a window on screen is an object - it mistakes representation for referent, it confuses the map with the territory.
> ut to say that tuples are objects is no more true than saying that a user's account is an object, a TCP connection is an object, or a window on screen is an object - it mistakes representation for referent, it confuses the map with the territory.
No, it makes the map useful to navigate the territory by accepting the abstraction of objects as a useful thing; there's a reason to say "everything is an object", it's a powerful ability. I'm a Smalltalk'er, everything literally is an object with methods even if/while/for/foreach statements are modeled with objects.
That you find it confusing or meaningless doesn't matter to me, it's my reality tunnel and it works well.
This conversation, such that it is, is over: simultaneously insulting your co-conversant while explicitly and resolutely staying within your own perspective means there will be no communication, by your will. Good luck with that.
What do you think of the Try pattern, i.e.:
Result res;
if (TryThing(out res)) {
// Do stuff, use res
)
I always thought that was a good use for out, and C# itself uses it for TryGetValue in Dictionaries for instance.I'd call it a valuable exception to the rule.
Couldn't the generic parameter of Some<T> be a nonboxed value type, though? Some<T> could even be a struct, to avoid object allocation.
Edit: although that would get boxed so it could fit in a Maybe<T>, so yeah, I see what you're saying!
dictionary.WithValue(aKey, value => DoStuffWith(value));
The dictionary knows whether it has a value or not, I shouldn't be making decisions with if's about a dictionaries data when I can just hand some code to the dictionary and let it do the right thing.Your other example.
if (TryThing(out res)) {
// Do stuff, use res
}
I'd rather a simple extension to Object enabling this on any value including null... TryThing().IfPresent(thing => thing.DoStuff());
I'm an old Smalltalk'er, we're accustomed to building such control structures into the class library rather than trying to use an if statement for everything. Once you have a clean syntax for lambdas you have the ability to create a better experience than constantly writing procedural code using the common if/while/for/foreach constructs. In Smalltalk we'd do something like... dictionary at: aKey ifPresent: [:value | value doStuff ]
That's much better than asking if the key exists with an if, or accessing the dic at a key and doing a null check with an if statement on the value.C# still lacks quite a lot in comparison to Smalltalk, but it's slowly getting there year by year.
Just yesterday I fixed a threading bug caused by some semantics around passing by reference and locking.