Added LDM Notes for November 1st, 2021
This commit is contained in:
parent
2246988f5d
commit
3514aabe7c
72
meetings/2021/LDM-2021-11-01.md
Normal file
72
meetings/2021/LDM-2021-11-01.md
Normal file
|
@ -0,0 +1,72 @@
|
|||
# C# Language Design Meeting for November 1st, 2021
|
||||
|
||||
## Agenda
|
||||
|
||||
1. [Order of evaluation for Index and Range](#order-of-evaluation-for-index-and-range)
|
||||
2. [Collection literals](#collection-literals)
|
||||
|
||||
## Quote of the Day
|
||||
|
||||
- "So 'The customer wants it therefore it's wrong' is your new motto?"
|
||||
|
||||
## Discussion
|
||||
|
||||
### Order of evaluation for Index and Range
|
||||
|
||||
https://github.com/dotnet/roslyn/issues/57349
|
||||
|
||||
We looked at an inconsistency in the order of evaluation between `Index` and `Range` operations, when those are applied to a type that does not have
|
||||
native methods that accept `Index` or `Range` types. The `Index` portion of the spec is fairly straightforward and we were easily able to determine
|
||||
the compiler had a bug with the lowering it performed. However, the specification is unclear about the `Range` translation: it does not clearly
|
||||
communicate the order of evaluation for the `receiver`, `Length`, and `expr` expressions that are cached. Our current behavior is inconsistent with
|
||||
the `Index` behavior, and likely confusing to users. After a bit of discussion, we unanimously agreed to standardize the order of evaluation to be
|
||||
consistent with the fully written out form of `expr.End.GetOffset(receiver.Length) - start`: ie `expr`, then `receiver`, then `Length`.
|
||||
|
||||
#### Conclusion
|
||||
|
||||
Codify the expected behavior as `expr` then `receiver` then `Length`.
|
||||
|
||||
### Collection literals
|
||||
|
||||
https://github.com/dotnet/csharplang/issues/5354
|
||||
|
||||
We took a first look at a proposal for a "collection literal" syntax in C#, doing a general overview of the proposed syntax form and gathering general
|
||||
feedback on the proposal. We hope to approach this proposal as a "one syntax to rule them all" form, that can achieve correspondence with the list
|
||||
pattern syntax form, support new types that collection initializers can't today (such as `ImmutableArray<T>`), and serve as a zero or even negative
|
||||
cost abstraction around list creation that is as good or better than hand-written user code.
|
||||
|
||||
There's some unfortunate bad interaction with existing collection initializers, however. They'll still exist, and they will be advantageous in some
|
||||
cases. Since the user is explicitly calling `new Type` on them, they have an obvious natural type, while collection literals will need some form of
|
||||
target-type for cases where there is no obvious natural type or if the user is trying to select between ambiguous overloads. They also probably wouldn't
|
||||
support this new splat operator, which also makes them worse in that case; even if we extended support for it, it's very likely that the new form would
|
||||
lower to a more efficient form with the pre-length calculation that it able to support.
|
||||
|
||||
We're unsure about some of the various axes of flexibility in this space. Some of them that we talked about are:
|
||||
* Existing collection initializers require the type to implement `IEnumerable` to be considered collection-like. Do we want to keep this restriction for
|
||||
the new form? It would lead to an odd non-correspondence with list patterns, since they are pattern-based and not interface-based. The proposal actually
|
||||
started more restrictive, but loosened to the current form after considering things like `HashSet<int> h = [1, 2, 3];` and deciding that was perfectly
|
||||
fine.
|
||||
* How specific do we want to make the lowering for various forms? Since it's a goal of the feature to be as optimal as possible here, if we prescribe
|
||||
too specific of lowering forms then we potentially make it difficult to optimize the implementation. We know from experience, though, that while we'll
|
||||
have a small window of opportunity just after ship to make changes to the way code is emitted, making changes years on will be dangerous and will likely
|
||||
have impacts on some user's code.
|
||||
* We think that a natural type for this syntax will have a lot of benefits, such as allowing it to be used for interfaces (`IEnumerable<int> ie = [1, 2];`)
|
||||
and it will be in line with the recent work we did around lambda expressions. However, unlike lambdas, we don't have a single list type in .NET that is
|
||||
unambiguously the natural type it should be. We'll need to dig into the pros and cons of the space and decide on how we want to approach this.
|
||||
|
||||
We also talked briefly about possible extensions of this space. One obvious one is dictionary literals. We think we can move ahead with collection
|
||||
literals for now, as long as we keep both dictionary literals and dictionary patterns, to be sure we're holding ourselves to the correspondence principle.
|
||||
Another area we should investigate is list comprehensions. We're not sure whether we want comprehensions, but we should at least look at the space and
|
||||
make sure we're comfortable that we'd never consider them or leave ourselves the space to be able to consider them in the future.
|
||||
|
||||
Finally, we want to look at other contemporary languages and see what they do for this space. For example, F# has dedicated syntax forms for each of it's
|
||||
main list/sequence types. Unlike C#, they have largely unified on a very few specific collection types. This allows them to have dedicated syntax for each
|
||||
one, but this approach isn't likely to work well in C# because we have a much wider variety of commonly-used collections, tuned for performance across a
|
||||
variety of situtations. Kotlin takes a different approach of having well-known methods to construct different collections, such as `listOf` or `arrayOf`.
|
||||
It's possible that, with `params Span`, we'd be able to achieve 90% of what we're trying to do without needing to build anything into the language itself.
|
||||
And then there are languages like Swift, Python, Scala, and others that actually have a dedicated literal for lists, with varying degrees of flexibility.
|
||||
|
||||
#### Conclusions
|
||||
|
||||
No conclusions today. A smaller group will begin a deep dive into the space to flesh out the various questions and components of this proposal, and come
|
||||
back to LDM with more research in the area.
|
|
@ -25,15 +25,17 @@ All schedule items must have a public issue or checked in proposal that can be l
|
|||
- Name shadowing in nested functions (Chuck): https://github.com/dotnet/csharplang/blob/main/proposals/csharp-8.0/shadowing-in-nested-functions.md
|
||||
- `params Span<T>` and implicit stack allocation of arrays (Chuck)
|
||||
|
||||
## Nov 1, 2021
|
||||
|
||||
- Collection literals (Cyrus): https://github.com/dotnet/csharplang/issues/5354
|
||||
- Order of evaluation with Ranges (Aleksey): https://github.com/dotnet/roslyn/issues/57349
|
||||
|
||||
# C# Language Design Notes for 2021
|
||||
|
||||
Overview of meetings and agendas for 2021
|
||||
|
||||
## Nov 1, 2021
|
||||
|
||||
[C# Language Design Notes for November 1st, 2021](https://github.com/dotnet/csharplang/blob/main/meetings/2021/LDM-2021-11-01.md)
|
||||
|
||||
1. Order of evaluation for Index and Range
|
||||
2. Collection literals
|
||||
|
||||
## Oct 27, 2021
|
||||
|
||||
[C# Language Design Notes for October 27th, 2021](https://github.com/dotnet/csharplang/blob/main/meetings/2021/LDM-2021-10-27.md)
|
||||
|
|
Loading…
Reference in a new issue