
# C# Language Design Notes for Jan. 22, 2020

## Agenda

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

## Discussion

### Top-level statements and functions

https://github.com/dotnet/csharplang/issues/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

```C#
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

https://github.com/dotnet/csharplang/issues/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:

```C#
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

```C#
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.