Skip to content

Latest commit

 

History

History
108 lines (73 loc) · 4.21 KB

LDM-2020-01-22.md

File metadata and controls

108 lines (73 loc) · 4.21 KB

C# Language Design Notes for Jan. 22, 2020

Agenda

  1. Top-level statements and functions
  2. Expression Blocks

Discussion

Top-level statements and functions

#3117

Three main scenarios:

  1. Simple programs are simple -- remove the boilerplate for Main

  2. Top-level functions. Members outside of a class.

  3. Scripting/interactive. Submission system allows state preservation across evaluations.

Unfortunately, some of these proposals interact in difficult ways.

If you write

int x = ...;

is x now a global mutable variable for the entire program? Or is it a local variable in a generated Main method?

Proposal: Simple programs

The proposal is to prioritize (1) and (3) and remove boilerplate, while enabling use in scripting/interactive scenarios.

To address (1), we would allow a single file in the compilation to contain top-level statements, and any file to contain top-level local functions, which would be in scope in all files, but it would be an error to refer to them.

There's wide consensus that (1) is very useful. There's the case of small programs, where you really just want to write a few statements and not have to write the boilerplate of classes and Main. It's also a very large learning burden in that just to write "Hello, World" requires explaining methods, classes, static, etc.

(3) is also important partly because there are a number of products and scenarios currently using the scripting system. We should keep that in mind to make sure that we don't prevent a large number of use cases from ever using the new system.

We think (2) is interesting and worth considering. It may not be the highest priority, but we need to make sure we don't rule it out entirely. We also think that if we add (1) it seems likely that some people would want (2) much sooner.

If we do want to make space for (2) we should make sure to look at lookup rules very carefully. The C# lookup rules are very complicated and including new ones for top-level members could include subtle ways that change new code.

When we designed scripting we had experience that copying back-and-forth from interactive and the main program is very useful and important. Because the syntax used here is similar to local functions and it's not currently proposed that accessibility modifiers are legal, this would create a difference when copying code between standard C# and the interactive dialect, since presumably those declarations would now be illegal.

Block expressions

#3137

We're revisiting the earlier discussions and there is a proposal for how we could make blocks legal as expressions. The proposed precedence would be the lowest possible, so many ambiguities or breaking changes would be avoided.

Examples:

var x = { ; 3 };    // int x = 3
var x = { {} 3 };   // int x = 3

Note that a final expression is required, so the ' or {} are necessary as "starting statements".

The most notable restrictions are that you cannot branch out, meaning that return, yield break, and yield return, and goto would be illegal in this proposal.

Something which was brought up before is whether to use a "trailing expression" to produce a value, or introduce some sort of statement to produce the evaluation expression. If we used a break e; syntax, the above could look like

var x = { break 3; };

One problem is turning the block into a lambda, where break would have to be changed to return. On the other hand, if this code were introduced directly into the method, return would actually produce different, valid semantics. break e; would be an error in both contexts, instead of producing different code.

The precedence doesn't have agreement. Some people think that the precedence is still too high and that we should almost always require a parenthesized wrapper expression, except in specific cases where we think it's clear. Other people think that this is too low and they want to use them in more places.

Conclusion

We don't think we have enough information about the restrictions we're working under. One way to make progress would be to construct a list of the potential ambiguities in using the {} as an expression term.