
# C# Language Design Meeting Notes for Oct. 30, 2019

## Agenda

1. Function pointer syntax
2. Enhancing Common Type Algorithm (again)

## Discussion

### Function pointer syntax

Proposal: https://github.com/dotnet/csharplang/issues/2917

While exploring syntax for function pointers, it turns out that parsing
the previously proposed syntax, namely

```C#
func*(int, int)
```

can feature exponential parsing behavior in the case of nested function
pointers.

An alternative is proposed using a generic-style syntax. E.g.,

```C#
func*<void>
cdecl*<int, void>
```

The proposed changes employ `*<` as being unambiguous in the language today. One suggestion is to
use the same trick, but with a minor modification: `func` would always be the first token, and
the calling convention would be the second token e.g.,

```C#
func cdecl*<int, void>
```

and the set of calling conventions would evolve as the set of CLR-supported
calling conventions evolve.

There are a couple features which aren't mentioned, and we're not sure if we
need to support them, and how we would do so.

Mainly, we don't know whether certain features, like attributes, require definitions of named
function pointers, instead of anonymous function pointer types. The runtime has proposed using
attributes to express configuration, like suppressing native/managed transition.

The current syntax doesn't have a place to put attributes, so if we wanted to support that
design, we would have to have some definition to place attributes. This would be similar to
delegate definitions, where you can define a delegate with a name and attributes, and then refer
to the delegate type by name.

However, the current runtime implementation doesn't support declaring tokens for the function
pointer, so there's no official mechanism to attach attributes to a function pointer. A follow-up
question is to ensure that the spec allows us to put the calling convention in the signature
during emit as part of the function pointer type.

We brainstormed a bunch of possible syntaxes (some more serious than others):

```C#
delegate managed *int(int, long)

delegate managed *List<T>(int, long)

delegate * List<T> managed(int, long)

delegate<managed> * List<T>(int, long)

delegate * managed List<T>(int, long)

delegate managed int *(int, long)

delegate managed*<int, long, void>

delegate *<int, long, void>

delegate* managed<int, long, void>
delegate*<int, long, void>
```

**Conclusion**

The new syntax is agreed to be unambiguous, as far as we can see. We agree on three
modifications:

    1. The optional calling convention should always have a prefix.
    2. Putting the `*` near the prefix is better, as it makes the function pointer
       more recognizable.
    3. `delegate` is a better prefix, as it is already a keyword.

Our final decision is

```C#
'delegate*' optional_calling_convention '<' type < type , ... > , return_type '>'
```

### Enhancing Common Type Specification follow-up

Proposal: https://github.com/dotnet/csharplang/issues/2823 

The previous proposal was to add target-typing as a fallback to existing features,
like the conditional expression, and do no more work on enhancing the common type
algorithm.

This would solve certain problems and not others. In the case where the conditional expression
has a common type, but that type is not the one you want (e.g., `b ? 1 : 2`, but you wanted the
result to be a `byte`), target typing would not solve this.

At the same time, not having all possible improvements doesn't seem to impact the
decision for nullable, specifically. We already have special language knowledge
and handling of nullable and when language algorithms fail to introspect and find
the "obvious" solution, this feels worse than more general failures.

**Conclusion**

None today. We ran out of time and would like to talk about it more.
