csharplang/meetings/2018/LDM-2018-05-21.md
2018-05-23 09:37:18 -07:00

4 KiB

C# Language Design Notes for May 21. 2018

Warning: These are raw notes, and still need to be cleaned up. Read at your own peril!

Target typed new

There's a PR for target typed new expressions

M(new (1));

We generally like it, and have been interested in a feature like this for a while, but we're a bit concerned about the ways in which use of it can be brittle. In the code above, adding another constructor to a type (which one of the overloads takes) can now cause an ambiguity, or cause a different overload to be picked.

It's roughly as "bad" as adding another implicit conversion.

We could consider restrictions. We could do it only in initializers, which is a common request. But that's still a harsh restriction. We would probably soon be back to considering the general version of the feature.

We could warn (or have an analyzer warn) if there is more than one possible target parameter type among overloads corresponding to a target-typed new argument.

We could also take a similar approach as we do to out vars. There we don't even take the parameter type into account for betterness purposes. We're ambiguous if two overloads differ only on the type of an out parameter, regardless of whether one is "better" than the other. If we do this similarly, then folks wouldn't easily get silent changes when overloads are added: instead they'd get ambiguity errors, and would be forced to put in a type name, or otherwise disambiguate.

Conclusion

We would like to pursue this feature. Let's schedule a design meeting to make sure we have the design ironed out. We like the more restrictive approach to overload resolution, similar to out vars.

Return/break/continue expressions

This is a convenience. However, it risks a syntactic conflict with other potential futures, especially "non-local returns" (allowing a lambda to return from its enclosing method) and "block expressions" (allowing statements inside expressions). While we can imagine syntaxes for those that do not conflict, we don't want to limit the design space for them at this point, at least not for a feature that is merely "nice to have".

Also, while we've been talking about this in analogy with throw expressions, that isn't quite right. throw is a dynamic effect, whereas return, break and continue are statically bound control transfers with a specific target.

Conclusion

We're grateful for the pull request, but do not want to go forward with the feature at this point.

Async streams

Async foreach task consumption

Just like foreach it will look for an interface or a pattern. Should the pattern require Task<T>, or be pattern-based all the way down?

Conclusion

Pattern all the way down. Same as with await.

Async foreach extension methods

foreach doesn't allow extension methods for GetEnumerator etc. We would like to change that, but there are obscure potential breaking changes there. Should foreach await allow extension methods?

Conclusion

Let's allow, and work to allow for synchronous foreach as well.

Async iterator lambdas

We don't do iterator lambdas today, and it's low priority to add it, though it's not really harmful.

Conclusion

We won't do it for async iterators either, until such time as we decide to do it for the synchronous ones.

When is it an iterator?

In synchronous iterators, the yield keyword is what makes it an iterator. The same for async iterators: the combo of the async modifier and the presence of the yield keyword makes it an async iterator. Whether you actually await is at most the subject of a warning, just as withe other async methods, and has no other bearing.

Pattern-based return type of async iterators?

Async methods no longer have to return Task and Task<T>, but can follow a pattern. We don't currently do a similar thing for iterators, but we should think about it, also for async iterators.

foreach await over dynamic

Block it. For synchronous foreach we resort to the nongeneric IEnumerable, but there is no nongeneric IAsyncEnumerable, and there won't be.