meetings/2021/LDM-2021-01-13.md
https://github.com/dotnet/csharplang/issues/3428
Today, we started by looking at a long-standing request in various forms: the ability to create using directives that apply
to an entire project. This is of particular importance now as we solidify our work in relation to the .NET 6 themes, especially
around both beginner scenarios and general ease-of-use. A well-studied problem in teaching a programming language is avoiding
cognitive load, and usings are an ever-present cognitive load in C#, even in simple "Hello, World!" style applications. Either
the teacher says "Ignore the using thing for now" or they say "Ignore what the .s mean for now", with no ability to hold
off on introducing them. That's not to say teaching using isn't necessary, and necessary early in the teaching process; merely
that delaying that introduction from the first second of seeing C# to a day or week into the curriculum can be very helpful in
avoiding overloading newcomers and scaring them off.
While it's an important scenario, beginners aren't the only driving motivation here. .NET 6 is looking at making both beginner
and general scenarios better, and there's an argument that this will help general scenarios as well. Large-sized projects such
as dotnet/roslyn are the exception, not the rule; most .NET projects are smaller and don't have nearly so many moving and
interacting pieces. using boilerplate has a bigger impact on these projects, particularly as they tend to use many frameworks
and a custom project SDK (such as ASP.NET). That custom SDK, combined with a feature to allow the SDK to specify global usings
in some manner, can help ease these scenarios and remove unnecessary lines from most files in such solutions. Larger projects
like Roslyn may never use this feature, but Roslyn and projects like it are not the projects that much of our users are actually
writing.
Broadly, there are two possible approaches to this type of feature: CLI flags, specifiable for actual users via the project file,
and a syntax form that allows a user to specify a using should apply to all files. We have an existing proposal for the former
approach, 3428 (linked above), and some spitball ideas for what the latter could look like (perhaps something like
global using System;). Both have advantages:
dotnet run csfile in the future: where would the
syntax form live? An ethereal temp file, or a hardcoded part of the SDK?We seem to have unanimous agreement here that the design space is interesting, and we would like a feature to address the issues discussed above. We're much more split on the potential approaches, however, and need to explore the space more in depth.
https://github.com/dotnet/csharplang/issues/137
We're picking back up on the discussion from last week, which is around how restrictive we should be in permitted mixing and matching of multiple namespace statements and combination with traditional namespace directives. An important point to acknowledge is that, regardless of what decision we make here, Roslyn is going to have to do something to understand what multiple namespace directives in a file means because it will encounter that code at some point, regardless of whether it's valid or not, and will have to do its level best to make a guess as to what the user meant. There is a big difference between a compiler trying to make as much sense as it can of invalid code and the language having actual rules for the scenario, though. The scenario we're targeting specifically is files with one namespace in them (and most often, one type as well), and these scenarios make up roughly 99.8% of C# syntax files that lived on one LDT-member's computer. This includes the Roslyn codebase, which has several of these types of files specifically for the purposes of testing that we handle the scenario correctly. Measuring an even broader set of millions of C# files on GitHub shows literally 99.99% of files have just one namespace in them.
We also briefly discussed the interaction with top-level statements. On the one hand, we're concerned about the readability of combining these things, and that the namespace statement would be too easily missed. On the other hand, having just finished talking about beginner scenarios, it seems like it might be annoying that beginners couldn't be introduced to the simple form until they start splitting things apart into multiple classes. Users will likely police themselves here if it doesn't read well, and maybe restricting it is just adding an arbitrary restriction.
We allow one and only one file-scoped namespace per file. You cannot combine a file-scoped namespace with a traditional namespace directive in the same file. We did not reach a conclusion on the combination with top-level statements and will pick that up again soon.