From 3ffbddf8e9688cebfcfedd1d0a4917d820569722 Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Tue, 16 Mar 2021 13:51:13 -0700 Subject: [PATCH] Added LDM notes for March 15th, 2021. --- meetings/2021/LDM-2021-03-15.md | 76 +++++++++++++++++++++++++++++++++ meetings/2021/README.md | 16 ++++--- 2 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 meetings/2021/LDM-2021-03-15.md diff --git a/meetings/2021/LDM-2021-03-15.md b/meetings/2021/LDM-2021-03-15.md new file mode 100644 index 0000000..6a799c2 --- /dev/null +++ b/meetings/2021/LDM-2021-03-15.md @@ -0,0 +1,76 @@ +# C# Language Design Meeting for March 15th, 2021 + +## Agenda + +1. [Interpolated string improvements](#interpolated-string-improvements) +2. [Global usings](#global-usings) + +## Quote of the Day + +- "Need is a strong word... I'm just teasing, I'm just lobbing in a joke" + +## Discussion + +### Interpolated string improvements + +https://github.com/dotnet/csharplang/issues/4487 + +We looked at the open question around argument passing today. In the current form, the proposal treats the receiver specially, even +for reduced extension methods where the receiver is just sugar for the first argument. This special treatment of the receiver is +very limiting, as many API patterns exist today where destinations are conveyed as arguments to a method, not as the receiver of the +method, and we would like APIs to be able to continue having their same shapes. It's also inconsistent with how we treat extension +methods in the rest of the language: they're a sugar, and there is no semantic difference between calling them in reduced form or not. + +To address this, we looked at a couple of possible solutions: + +1. Don't pass anything. No receiver, no arguments. This is clean, but is not really an improvement on how it works today. It means that +the builder type would need to support storage of an arbitrary number of arguments of arbitrary types, and would preclude working with +ref structs and other types that can't be in generics today. +2. Require methods to have a `PrepFormat` or similar signature that is isomorphic to the original signature, with the builder parameters +as `out` variables instead. This would allow us to simply call that signature, and there would be no fancy mapping to consider. However, +this is pretty messy from a public API standpoint. We can apply `EditorDisplay` to such methods, but they'll still exist, need to be +documented, and generally get in the way. It also means that every method will need to have a second method, which possibly limits code +sharing abilities. +3. Put an attribute on either individual parameters or on the builder type, specifying that these parameters should be passed to the +builder creation method. The former version was proposed in the open questions section, but the latter came up in discussion and seems +like a better approach. It gives a central location, handles multiple potential builders in a method signature, and allows including the +receiver type as either a magic name like `this` or as a boolean flag. + +#### Conclusion + +We'll look at the attribute on the builder type solution. The next question we need to answer is around out-of-order execution for +arguments passed to builders. + +### Global usings + +https://github.com/dotnet/csharplang/issues/3428 + +Next, we looked at 2 open issues in global usings: the scope of the global using statements, and how name lookup treats these usings +with respect to regular using directives. Both of these questions really hinge on the overall view we want to take on how global usings +are represented. There are 2 views here: + +1. Global usings are effectively copy/pasted into the top of every file. They're just like regular `using` directives, and all the same +rules that apply to regular `using` directives at the top level apply to global usings as well. + * This has the advantage that, at the top level, a regular `using` directive will _never_ be changed by a global using directive. + Users can't introduce namespace ambiguities at the top level by introducing a global using directive that has a nested namespace with + the same name as a top-level namespace. + * It aligns with our prior art: both CSX and VB.NET work this way. + * This version has the disadvantage that, at the top level, global aliases could not be reused in a file-scoped using alias. They could + be used in an alias nested inside a namespace declaration, but not at the top level. While this is a niche scenario, it is likely that + someone will hit it at some point. + * If a name is imported in both a global `using` directive and a file-scoped `using` directive, that name is ambiguous. +2. Global usings are a new scope, that exists _above_ regular `using` directives at the top of a file. They are to file-scoped `using` +directives what file-scoped `using` directives are to `using` directives nested in a namespace. + * This would allow globally-defined aliases to be used in file-scoped directives. + * We would need to rationalize how these rules work for CSX. Do global using directives imported from a `#load` directive change the + meaning of `using` directives in the current file, or files that are subsequently `#load`ed? + * Name lookup would prefer the file-scoped `using` directives, only going to global directives if a name wasn't found. + * Has a bigger implementation cost: some PDB changes might be required in order to ensure that names mean the correct things and diverges + heavily from existing implementations. + +We think both worldviews here are consistent and reasonable, and would be fine with either mental model as an explanation to consumers of how +the feature works. However, worldview 1 is more consistent with past decisions and has less implementation concerns. + +#### Conclusion + +We'll go with worldview 1. The decisions for scoping and name lookup fall out from this. diff --git a/meetings/2021/README.md b/meetings/2021/README.md index 57c771f..d4a7d24 100644 --- a/meetings/2021/README.md +++ b/meetings/2021/README.md @@ -4,6 +4,8 @@ ## Schedule when convenient +- List pattern open questions (Fred): https://github.com/dotnet/roslyn/pull/49080#issuecomment-777026383 + ## Recurring topics - *Triage championed features and milestones* @@ -15,22 +17,24 @@ ## Mar 24, 2021 -- List pattern open questions (Fred): https://github.com/dotnet/roslyn/pull/49080#issuecomment-777026383 +- Interpolated string open questions (Fred): https://github.com/dotnet/csharplang/pull/4486 - `field` in auto-properties (Cyrus) ## Mar 22, 2021 - *Design review* -## Mar 15, 2021 - -- Interpolated string open questions (Fred): https://github.com/dotnet/csharplang/pull/4486 -- Review scoping and name lookup rules around Global Using directives. (Aleksey) https://github.com/dotnet/csharplang/blob/main/proposals/GlobalUsingDirective.md - # C# Language Design Notes for 2021 Overview of meetings and agendas for 2021 +## Mar 15, 2021 + +[C# Language Design Notes for March 15th, 2021](https://github.com/dotnet/csharplang/blob/master/meetings/2021/LDM-2021-03-15.md) + +1. Interpolated string improvements +2. Global usings + ## Mar 10, 2021 [C# Language Design Notes for March 10th, 2021](https://github.com/dotnet/csharplang/blob/master/meetings/2021/LDM-2021-03-10.md)