Skip to content

Latest commit

 

History

History
70 lines (48 loc) · 5.21 KB

LDM-2023-04-03.md

File metadata and controls

70 lines (48 loc) · 5.21 KB

C# Language Design Meeting for April 3rd, 2023

Agenda

Quote of the Day

  • "These are now variadic tuple literals"

Discussion

Collection Literals

#7085
#5354

We started today by looking at open questions in collection literals, spending all of our time talking about the spread operator. We had a few questions we wanted answered about it:

  1. Is spread even an important thing to address in the initial collection literals proposal?
  2. How much is the compiler free to optimize the creation of these collection literals? Can intermediate literals be elided if a reasonable program wouldn't observe them?

For the first question, we universally agree that there is a concept to be explored there. There will be some syntax gremlins to iron out; some members believe that .. is perfectly natural, as it is the complement of slicing in list patterns and in accessing sub-ranges of existing collections, while other members believe that .. is bad here because it introduces confusion for collections of ranges. Despite that, we do think the space is worth exploring, and will do so.

Next, we thought about compiler optimizations of spreads. There's a lot of interesting side-points on optimizations here that can have a big impact on the collection literal, such as:

  • If the collection literal is not going to be added to later, then presizing makes sense. If it is going to be added to later, though, presetting the size can have negative impacts and force resizes where they might not otherwise be.
  • What is the order of evaluation of the creation of the list and the evaluation of the elements? For example, if the elements of the list are pre-evaluated, we could pre-size the collection more accurately; on the other hand, if we have to pre-evaluate the entire element set before calling the constructor of the containing type, could we end up having more stack/local usage and negatively impacting perf there?
  • What about intermediate collection literals? The proposal suggests using conditional expression spreads with empty collection literals for conditionally adding elements to the containing collection, but do those nested collection literals need to actually be created? Can they be inlined into the containing creation? And if we do that, does that mean that things like extract local can introduce silent perf impacts because intermediate collections are now considered real collections?

This last bullet brought up a new question that we then started delving into:

  1. Should list literals be thought of as more ephemeral until they're used? For example, if it's just being foreach'd over, we could just make it a stackalloc. Or, if it's assigned to a var variable that is eventually passed to a List location, we could say that it's not really a list until that point, but is instead a lightweight list-like thing.

This idea is both interesting (gives us lots of room to optimize the implementation for specific scenarios) and terrifying (what is the type of this variable? What does generic type inference do? Is it a quantum variable that needs to have the waveform collapse eventually?), and has lots of room to explore. We could say, for example, that var causes the type to collapse, and it's only when these are used as nested expressions in other expressions that they have this weird quantum state. We think this needs to be explored more, and the consequences and impacts on other systems thought through, before we go further down this road.

Finally, we also looked at the conditional expression used here. There are some older discussions on csharplang about making a conditional assignment as part of object initializers, we might be able to general purpose that to work in either of these cases. While we do think that the syntax originally proposed in the spec for collection literals should work and should ideally not produce excess allocations, it does feel ugly, and there's likely a feature to improve that for both collection literals and other types of initializers.

Conclusions

  1. We will continue trying to answer the spread questions and make an effort to include it in the initial feature.
  2. Leaning towards allowing optimization, but we need a better understanding of what optimizations are on the table and the consequences of them.
  3. We need more info about what the impacts of this change would be.

We'll come back after some more thinking on those topics has been done.

Fixed-size buffers

#7064
#1314

Finally today, we took an initial look through the first option proposed in 7064 for implementing safe fixed-size buffers. This is a more complicated proposal that builds off new runtime support for InlineArrayAttribute, allowing types defined with a specific pattern to be treated as if they are fixed-size buffers of an element type. Today was mostly an overview; next time we will go over the simpler version of the proposal (option 2) and discuss more about which option we want to go with.