Full Code of dotnet/vblang for AI

main 0712f0b8c91d cached
61 files
1.0 MB
254.5k tokens
1 requests
Download .txt
Showing preview only (1,105K chars total). Download the full file or copy to clipboard to get everything.
Repository: dotnet/vblang
Branch: main
Commit: 0712f0b8c91d
Files: 61
Total size: 1.0 MB

Directory structure:
gitextract_tsofwn20/

├── .gitattributes
├── CODE-OF-CONDUCT.md
├── Language-Version-History.md
├── README.md
├── meetings/
│   ├── 2014/
│   │   ├── LDM-2014-02-10.md
│   │   ├── LDM-2014-02-17.md
│   │   ├── LDM-2014-03-12.md
│   │   ├── LDM-2014-04-01.md
│   │   ├── LDM-2014-04-02.md
│   │   ├── LDM-2014-04-16.md
│   │   ├── LDM-2014-04-23.md
│   │   ├── LDM-2014-07-01.md
│   │   ├── LDM-2014-10-01.md
│   │   ├── LDM-2014-10-08.md
│   │   ├── LDM-2014-10-15.md
│   │   ├── LDM-2014-10-23.md
│   │   └── README.md
│   ├── 2015/
│   │   ├── LDM-2015-01-14-VB.md
│   │   └── README.md
│   ├── 2016/
│   │   ├── LDM-2016-05-06-VB.md
│   │   └── README.md
│   ├── 2017/
│   │   ├── README.md
│   │   ├── vbldm-notes-2017.04.12.md
│   │   ├── vbldm-notes-2017.05.19.md
│   │   ├── vbldm-notes-2017.08.09.md
│   │   ├── vbldm-notes-2017.08.23.md
│   │   ├── vbldm-notes-2017.08.30.md
│   │   ├── vbldm-notes-2017.10.18.md
│   │   ├── vbldm-notes-2017.11.15.md
│   │   └── vbldm-notes-2017.12.06.md
│   ├── 2018/
│   │   ├── README.md
│   │   ├── vbldm-notes-2018.02.07.md
│   │   ├── vbldm-notes-2018.02.21.md
│   │   ├── vbldm-notes-2018.02.28.md
│   │   ├── vbldm-notes-2018.03.21.md
│   │   ├── vbldm-notes-2018.05.30.md
│   │   ├── vbldm-notes-2018.06.13.md
│   │   └── vbldm-notes-2018.12.19.md
│   ├── README.md
│   └── notes-template.md
├── proposals/
│   ├── README.md
│   ├── inactive/
│   │   └── README.md
│   ├── overload-resolution-priority.md
│   ├── proposal-DerestrictedOperators.md
│   ├── proposal-Implicit-default-optional-parameters.md
│   ├── proposal-template.md
│   └── rejected/
│       └── README.md
└── spec/
    ├── README.md
    ├── attributes.md
    ├── conversions.md
    ├── documentation-comments.md
    ├── expressions.md
    ├── general-concepts.md
    ├── introduction.md
    ├── lexical-grammar.md
    ├── overload-resolution.md
    ├── preprocessing-directives.md
    ├── source-files-and-namespaces.md
    ├── statements.md
    ├── type-members.md
    └── types.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
* text=auto


================================================
FILE: CODE-OF-CONDUCT.md
================================================
# Code of Conduct

This project has adopted the code of conduct defined by the Contributor Covenant
to clarify expected behavior in our community.

For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).


================================================
FILE: Language-Version-History.md
================================================
# Features Added in VB Language Versions

*NOTE:* See how to [specify the language version for your project here](https://docs.microsoft.com/dotnet/visual-basic/language-reference/configure-language-version)

## Visual Studio 2022, .NET 6

- [CallerArgumentExpression](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/caller-argument-expression.md): Note that this feature isn't gated under a language version. It's available for compilers that shipped starting with Visual Studio 2022 version 17.0.

## VB 15.0 (Visual Studio 2017)

- [Tuples](https://github.com/dotnet/roslyn/blob/master/docs/features/tuples.md)
- [Binary Literals](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.0/binary-literals.md)
- [Digit Separators](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.0/digit-separators.md)

## VB 15.3 (Visual Studio 2017 version 15.3)

- [Inferred tuple element names](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.1/infer-tuple-names.md)

## VB 15.5 (Visual Studio 2017 version 15.5)

- [Non-trailing named arguments](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/non-trailing-named-arguments.md)
- [Private Protected accessibility](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/private-protected.md)
- [Digit separator after base specifier](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/leading-separator.md)

## VB 17.13 (Visual Studio 2022 version 17.13)

- Recognizing 'unmanaged' constraint
- [Overload Resolution Priority](https://github.com/dotnet/vblang/blob/main/proposals/overload-resolution-priority.md)


================================================
FILE: README.md
================================================
# Visual Basic .NET Language Design

Welcome to the official repo for Visual Basic .NET language design.

* Full Language Specification: [Markdown](spec)
* List of proposals can be found in the [proposals folder](proposals).
* Archives of notes from design meetings, etc., can be found in the [meetings folder](meetings).

If you discover bugs or deficiencies in the above, please leave an issue to raise them, or even better: a pull request to fix them.

For *new feature proposals*, however, please raise them for [discussion](https://github.com/dotnet/vblang/labels/Discussion), and *only* submit a proposal as a pull request if invited to do so by a member of the Language Design Team (a "champion").

## Discussion

Discussion pertaining to language features takes place in the form of issues in this repo, under the [Discussion label](https://github.com/dotnet/vblang/labels/Discussion).

If you want to suggest a feature, discuss current design notes or proposals, etc., please [open a new issue](https://github.com/dotnet/vblang/issues/new), and it will be tagged Discussion.

GitHub is not ideal for discussions, but it is beneficial to have language features discussed nearby to where the design artifacts are. Comment threads that are short and stay on topic are much more likely to be read. If you leave comment number fifty, chances are that only a few people will read it. To make discussions easier to navigate and benefit from, please observe a few rules of thumb:

- Discussion should be relevant to Visual Basic .NET language design. Issues that are not will be summarily closed.
- Choose a descriptive title for the issue, that clearly communicates the scope of discussion.
- Stick to the topic of the issue title. If a comment is tangential, start a new issue and link back.
- If a comment goes into detail on a subtopic, also consider starting a new issue and linking back.
- Is your comment useful for others to read, or can it be adequately expressed with an emoji reaction to an existing comment?

## Design Process

Visual Basic .NET is designed by the Visual Basic .NET Language Design Team (LDT).

1. To submit, support, and discuss ideas please use the [Discussion label](https://github.com/dotnet/vblang/labels/Discussion).

2. Ideas that the LDT feel could potentially make it into the language should be turned into [proposals](proposals), based on this [template](proposals/proposal-template.md), either by members of the LDT or by community members by invitation from the LDT. The lifetime of a proposal is described in [proposals/README.md](proposals/README.md). A good proposal should:
    * Fit with the general theme and aesthetic of the language.
    * Not introduce subtly alternate syntax for existing features.
    * Add a lot of value for a clear set of users.
    * Not add significantly to the complexity of the language, especially for new users.  

3. A prototype owner (who may or may not be proposal owner) should implement a prototype in their own fork of the [Roslyn repo](https://github.com/dotnet/roslyn) and share it with the design team and community for feedback. A prototype must meet the following bar:
	* Parsing (if applicable) should be resilient to experimentation--typing should not cause crashes.
	* Include minimal tests demonstrating the feature at work end-to-end.
	* Include minimal IDE support (keyword coloring, formatting, completion).

4. Once a prototype has proven out the proposal and the proposal has been _approved-in-principle_ by the design team, a feature owner (who may or may not be proposal or prototype owner(s)) implemented in a feature branch of the [Roslyn repo](https://github.com/dotnet/roslyn). The bar for implementation quality can be found [here](https://github.com/dotnet/roslyn).

5. Design changes during the proposal or feature implementation phase should be fed back into the original proposal as a PR describing the nature of the change and the rationale.

6. A PR should be submitted amending the formal language specification with the new feature or behavior.

7. Once a feature is implemented and merged into shipping branch of Roslyn and the appropriate changes merged into the language specification, the proposal should be archived under a folder corresponding to the version of the language in which it was included, e.g. [VB 15.1 proposals](proposals/adopted/vb15.1)). Rejected proposals are archived under the [rejected folder](proposals/rejected).

## Language Design Meetings

Language Design Meetings (LDMs) are held by the LDT and occasional invited guests, and are documented in Design Meeting Notes in the [meetings](meetings) folder, organized in folders by year. The lifetime of a design meeting note is described in [meetings/README.md](meetings/README.md). LDMs are where decisions about future Visual Basic .NET versions are made, including which proposals do work on, how to evolve the proposals, and whether and when to adopt them.

## Implementation

The reference implementation of the Visual Basic .NET language can be found in the [Roslyn repository](https://github.com/dotnet/roslyn). Until recently, that was also where language design artifacts were tracked. Please allow a little time as we move over active proposals.

**DISCLAIMER**: An active proposal is under active consideration for inclusion into a future version of the Visual Basic .NET programming language but is not in any way guaranteed to ultimately be included in the next or any version of the language. A proposal may be postponed or rejected at any time during any phase of the above process based on feedback from the design team, community, code reviewers, or testing.


================================================
FILE: meetings/2014/LDM-2014-02-10.md
================================================
VB Language Design Meeting 2014-02-10

# Strict Module

C# lets you have "static class" but VB only has "Module" which lifts all its members into the namespace. Discussion on this was prompted by a comment of MVP Jan Záruba (Đonny) who said
> I use Partial Private Sub New to achieve the same effect as in C# with static class. The advantage of this compared to Module is that static class does not "pollute" namespaces with it's members (and I also cannot have generic module anyway)."

Đonny encountered a known and approved Roslyn breaking change, where VS2013 let you write "private partial sub new", but Roslyn doesn't. This is by design. But the question is, what could he and other users do?

Language designer Anthony D. Green looked into it:
> Today VB’s modules behave very much like F#’s modules when the AutoOpen attribute is applied. I’m proposing adding a modifier “Explicit” to modules which will go the other way. Additionally, we’d considered changing the codegen of VB Modules to exactly match those of C# (both abstract and sealed) so that they could be recognized by C# in Dev10. Unfortunately this turned out to be a breaking change due to a bug in the XmlSerializer. With my proposal we could consider changing the metadata representation to match C# and could also map C# static classes back to Explicit Modules. If C# does end up accepting the static import feature but retains the restriction to static classes it’ll be important to have a way for VB code to easily create such things – otherwise C# won’t be able to consume them (e.g. the Roslyn VB SyntaxFactory module).

## IL

C# static classes are currently emitted as `.class private abstract auto ansi sealed beforefieldinit`
VB modules are currently emitted as `[StandardModule] .class private auto ansi sealed`

## Language design

* How do you declare something whose name is hidden and whose members are lifted to the enclosing namespace?
** VB: <HideModuleName>
** C#: not available
** F#: not available
* How do you declare something where people have to qualify member access, unless they specifically import them all?
** VB: **NOT POSSIBLE, BUT DESIRABLE**
** C#: new C#/Roslyn feature, "static usings"
** F#: this is the default
* How do you declare something which *always* requires qualification to access members?
** VB: not available
** C#: this is the default
** F#: [<RequiresQualification>]

There's a clear VB parity gap here, which has been asked-for many times on user-voice and connect.

Anthony's proposal is for "static classes", no more, no less. The question is (1) whether to allow it, (2) whether to call it "explicit module" or "shared class" or something.

RESOLUTION: yes, we should allow it.

## Syntax

We need a new keyword or keyword pair. Here are the candidates we came up with.

**Strict Module**
MustQualify Module
Explicit Module
Opaque Module
MustQualifyMember Module
Closed Module
Protected Module
Private Module
Static Module
Greedy Module
Shared Module
Shared Class
Namespace Module

RESOLUTION: We'll use "strict module" as the best of a bad bunch. We're open to suggestions for better names.

## Semantics

The metadata we emit for "Strict Module" should be the same as the metadata for C# static classes.

Q. Generics? We could say "strict modules" can be generic. Note: you also can't have generic modules in VB. 
RESOLUTION: Strict modules CAN be generic; however generic modules CANNOT contain extension methods.

Q. Nesting? Currently VB modules can't be nested. C# static classes can be nested.
RESOLUTION: Strict modules cannot be nested.

Q. For C#/Roslyn new feature, when they import static types, will they also allow importing VB modules?
RESOLUTION: up to C#

Q. How about VB importing C# static classes?
RESOLUTION: Currently, VB can import C#'s static classes, and if they come with [StandardModule] then we auto-open. We will continue to do this. NOTE: THIS IS A BREAKING CHANGE: e.g. you will no longer be able to declare variables of type "Console". Doesn't seem a very bad breaking change.

Q. What about <HideModuleName>?
A. Intellisense will ignore this attribute on strict modules.


================================================
FILE: meetings/2014/LDM-2014-02-17.md
================================================
VB Language Design Meeting 2014-02-17

ROLL-UP OF PROPOSED FEATURES.

*Please don't reply to this post with comments on individual language features. That will get out of hand because there are so many of them. If you have comments on an individual feature, please create a new post for it. If the feature's also in C#, then cross-post to the "C# language design" topic.*

We spent this meeting on a complete roll-up of all the Dev14 ideas that have been floated and designed so far. This isn't a commitment that we will have time to finish designing or finish implementing them. It's just where we are at the moment.

The notes from this meeting are deliberately "RAW". I haven't spent time to type them up neatly. My goal is to get all language notes out in the open, where the public can see them, with as little process or hindrance as possible. I figure it's better to publish early and iterate (and fix typos), rather than publish late. If you see anything that seems wrong or you disagree with, please first seek clarification rather than taking these notes as Microsoft's definitive statement on anything.

You might notice that I've written the date in ISO format, "2014-02-17". This is in honor of a new VB language feature that has already been implemented, "year-first date literals".

# 1. Improved XML doc-comments.
*Approved. Already in Main. Parity with C#.*
These are now supported to the same extent as C#, e.g. crefs and paramrefs are parsed correctly by the language. (The IDE team also added a much richer IDE experience will full syntax colorization, quick-info and rename support.
![Image](http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-12-06-codeplex/5353.xml.png)

# 2. Comments after implicit line-contuations.
*Approved. Already in Main. VB-specific.*
Comments are allowed after implicit line-continuation characters. Here are examples which failed to compile before, but now work:

``` vb
Dim invites = {"Jim",   ' got to invite him!
               "Marcy", ' Jim's wife
               "Jones"}

Dim addrs = From i In invites     ' go through list
            Let addr = Lookup(i)  ' look it up
            Select i,addr
```

# 3. #Region anywhere
* Approved. Already in Main. Parity with C#.*

"#Region" is allowed within method bodies and can cross method bodies.

``` vb
Function Range(min%, max%) As IEnumerable(Of Integer)
    If min > max Then Throw New ArgumentException
#Region "validation"
    Return Helper(min, max)
End Function

Private Iterator Function Helper(min%, max%) As IEnumerable(Of Integer)
#End Region
    For i = min To max
        Yield i
    Next
End Function
```

# 4. Implement readonly props with readwrite props.
* Approved. Already in Main. Parity with C#.*

The following code used to give an error saying that C.p doesn't match I.p and hence can't implement it. But now it's okay. (Also, you can implement writeonly props with readonly props)

``` vb
    Interface I
        ReadOnly Property p As Integer
    End Interface

    Class C : Implements I
        Public Property p As Integer Implements I.p
            Get
            End Get
            Set(value As Integer)
            End Set
        End Property
    End Class
```

# 5. Overloads Overrides
* Approved. Already in Main. Interop with C#.*

Previously, VB libraries had to write both modifiers "Overrides Overloads" to play nice with C# users. Now, "Overrides" members are also implicitly Overloads.


# 6. Allow CObj in attributes
* Approved. Already in Main. Parity with C#.*

The following code used to give an error that CObj(...) wasn't a constant. But it is, so we no longer give the error.
``` vb
   <DefaultValue(CObj(1))>
```


# 7. TypeOf IsNot
* Approved. Already in Main. VB-specific.*

You used to have to write it the long way:
``` vb
   If Not TypeOf sender Is Button Then
```
Now you can write it more readably:
``` vb
   If TypeOf sender IsNot Button Then
```

You could already use the "IsNot" operator previously, but only for reference comparisons e.g. "If sender IsNot Nothing Then"...


# 8. Readonly autoprops
* Approved, but design-questions remain. This has been prototyped. Aligns with C# vNext "getter-only and initialized autoprops" feature.*

We all know that we want this, but we don't know exactly what we want... Here’s an example:
``` vb
   ReadOnly Property p As Integer = 15
   ReadOnly Property q As Integer

   Sub New(q As Integer)
      Me.q = q
   End Sub
```

It’s clear that “ReadOnly” means that the property itself only has a getter. That’s the only thing we’re agreed upon at the moment…

Outstanding questions:
1. Should the backing fields be visible in the designer, or hidden like they are now?
2. Is the backing field ReadOnly like C#, or mutable like a current autoprop?
3. Can you assign to a ReadOnly autoprop in the constructor (implicitly an assignment to the backing field) just like you can assign to a ReadOnly field in the constructor?

Note1: The CLR allows an assignment-to-readonly instruction at any time, but it has no effect after the constructor has finished. The CLR allows assignment-to-readonly by reflection at any time.

Note2: Why would you want to assign to a ReadOnly in the constructor rather than just in the property’s initializer? … Maybe it’s because you need some control-flow logic to figure out what to assign, e.g. a For loop. Maybe it’s because you assign based on arguments that were passed to the constructor – although this latter case is addressed by primary constructors.

Here is some previous public feedback on the topic: http://blogs.msdn.com/b/lucian/archive/2010/01/30/core9-readonly-auto-properties.aspx

Here are three mutually incompatible visions of the feature:

PROPOSAL “A”: ReadOnly autoprop is like ReadOnly field. We are minimizing the code you need to type to get readonly properties.
Backing field is hidden from intellisense, the backing field is ReadOnly, and you can assign to a ReadOnly autoprop in the constructor. (This is like C#’s current proposal, except C# proposal doesn’t allow assignment in the constructor).

PROPOSAL “B”: ReadOnly autoprop is like existing autoprop but without setter. We are sticking closely to the status quo, not doing anything special.
Backing field is hidden from intellisense, the backing field is ReadWrite, and you can’t assign to the autoprop in the constructor. (Note: this proposal is pretty weak unless there are primary constructors. Also, the existing VB snippets for readonly properties use mutable backing fields).

PROPOSAL “C”: Backing fields should become first-class and well-known. They’re VB’s answer to “{get; private set}” from C#.
Backing field is shown in intellisense, the backing field is ReadWrite, and you can’t assign to the autoprop in the constructor; but you can assign to the backing field.


MVP feedback: Bill McCarthy, Jan Zaruba, Joacim Andersson, Klaus Loffelman all voted in favor of proposal “C”. No one voiced any other preferences. We have implemented proposal "C" in the preview, and are open to further feedback.


# 9. International date literals
* Approved. Already in prototype. VB-specific.*

Design is merely to offer ISO syntax for the range of things that are covered by existing date literals for DateTime (so: no timezone, no milliseconds, no DateTimeOffset). The format for dates is YYYY-MM-DD, and they must have the full number of digits.
``` vb
   Dim d = #2013-06-12#
   Dim d = #2013-06-12 15:17:23#
```

Q0. What about the horrible hacks that Anthony discovered, about how the IDE compiler allows two-digit dates (but command-line doesn't), and … ???

Q1. Do you allow #2014-02-04 24:00# as well as #2014-02-05 00:00# ?
A1. The current DateTime constructor does not allow you to pass “24” for the hours. And the current VB literal doesn’t allow 24:00 as a time. So we should disallow this.

Q2. Do these always produce a datetime with .Kind = DateTimeKind.Unspecified?
A2. Yes, since current VB DateTime constants always do.

Q3. Do we intend to come up with a solution for declaring an optional parameter with value “DateTime.MaxValue”? Currently you can’t, because “DateTime.MaxValue” isn’t a constant, and there’s no way to write DateTime.MaxValue in the VB datetime literal format.
A3. No, no solution.

Q4. Can we have the existing DateTime separators, or merely the ISO separator (-) ?

Q5. Do we allow AM/PM or do we require 24 hour clock?


PROPOSAL “A”. This feature is just "existing DateTime literals but with four-digit year first"
Q4 = allow existing separators, Q5 = allow AM/PM

PROPOSAL “B”: This feature is about unambiguous universal (hyphen, year-first) notation for the date which was the part that SUFFERED, but just use existing time syntax for the rest. (votes in favor: Aleksey, Klaus, Lucian)
Q4 = require hyphen; Q5 = allow AM/PM

PROPOSAL “C”: This feature is "subset of ISO syntax for those things encompassed by current DateTime literals. (votes in favor: Neal, Dustin, Anthony) Everyone knows ISO syntax. They won’t need to stop to wonder whether #2010/10/11# means November 10th or October 11th (although there are no cultures in the world where it means November 10th).
Q4 = require hyphen, Q5 = disallow AM/PM

We could also accept AM/PM, but (1) the prettylister prints into ISO format, and (2) we give a warning.

RESOLUTION: proposal "A", based on discussion from 2014-02-04. Do you see what I did there? :)

# 10. Digit group separators
*Approved, but needs further language design decisions. Already in preview. Aligns with C# vNext feature "digit grouping"

We settled on spaces as separators per ISO recommendations, but C# preferred underscores (like Java), so we should revisit that difference.
``` vb
   Dim x = &B1110 0001 1010 1111
   Dim x = &B1110_0001_1010_1111_SB
```

Design: this is a token-level thing. You can’t have line-continuations (implicit or explicit). For spaces, we’d only allow a single space. Not sure what we’d do with underscores. You can put the separator anywhere you want, including after &H and &O and &B, except after the &.

Current experimental prototype allows space, underscore and backtick. Note: old calculators in the 1970s used backticks! No one likes the backtick (apart from Klaus).

PROPOSAL 1a: the only separator allowed is underscore.

PROPOSAL 1b: allow both space and underscore.

PROPOSAL 2: separator is allowed before the type suffix

PROPOSAL 3: not allowed more than one underscore in a row

Open question: should you be allowed a separator before the numeric-type-suffix? E.g.
   Dim x = &B 1110 S


# 11. Binary literals
*Approved. Already in preview. Aligns with C# vNext feature "binary literals" *

It will be nice for enum literals. F# has them. We would ask the debugger to consider displaying stuff in binary as well, but that’s lower priority.
``` vb
   Dim x = &B11100101
```

Note: Integer.TryParse is a language-neutral .NET Framework function, that should not be augmented just for sake of new language-syntax. So we wouldn't want to make it work with the above syntax.

# 12. Multiline strings
*Approved. Already in preview. Parity with C#. *

``` vb
   Dim x = "Hello
   World"
```
We will use the normal quotes. We are happy that the pretty-lister inserts them in pairs in Roslyn (so the remainder of the file doesn't blink on and off too much).

Note: the pretty-lister should not auto-indent the next line when you press ENTER. (C# doesn't either)

Q. Does a newline emit CRLF?
A. It's whatever is in the source file. That's how C# works.

We allow any characters up until an unpaired " (or all the other string-starting-and-closing quote characters are currently allowed).

Q. Do we allow multiline string literals in preprocessor directives?
A. No. Neither Roslyn nor Native allow implicit line continuations in preprocessor directives. (although they sadly allow explicit line continuations).


# 12. Select Case Typeof
*Approved, but needs further language design decisions. Already in preview. VB-specific.*

Anthony's basic idea, which is in the preview:
``` vb
Select Case sender
   Case 3 : ...
   Case < 4 : ...
   Case As UIElement : ...   ' now works
   Case b As Button : ...    ' now works
   Case t As TextBlock: ... ' now works
   Case As UIElement, As Integer : ...    ' okay in Design1
   Case 3, As String : ...                ' okay in Design1
   Case ex As Exception When ex.i<7 : ... ' not supported
   Case c As Control, d As DropDown : ... ' error.
   Case AsNot Integer: ...                ' not supported 
End Case
```

Questions arising from the prototyping effort:
* Value types
* When clauses - Should they apply to each clause or each Case? Should they be generalized to any kind of Case clause? Should they be removed? Should we add a Continue Select as an alternative?

**Design1**: "As String" is just a normal case, like the other cases in VB, and indeed you can combine them and jump into them. "x As String" is different: it must be the only condition on the Case line, and doesn't admit inbound jumps (similar to how For blocks don't admit inbound jumps). The scope of the variable declaration is just that case clause, and follows the same principles as other blocks which define variables like ForEach.
``` vb
   Case 3, As String : ...
   Case b As Button : ...
```

**Design2**: both "As String and "x As String cannot be comma-combined with other case clauses, and neither admits inbound jumps. The motive is to safeguard a possible future use of comma in pattern-matching. (Unfortunate, since VB doesn't have "case fall-through", and so likes to use comma to combine cases).

**Concern**: It feels like generics will be important. How to implement them though? Answer: this is impossible in the current CLR without reflection, and we wouldn’t want a language feature that depended on reflection. Therefore this scenario is out of consideration.
``` vb
   Case As IEnumerable(Of T) : fred(Of T)(Nothing)
```

Concern: We have to make sure that anything we support now will be compatible with a hypothetical future that allows richer pattern-matching. So let's design that hypothetical future right now even though we won't implement it. Pattern-matching is odd in a language without algebraic datatypes, because there's no inbuilt canonical way to decompose an object. Possibilities are (1) only do decomposition on types with primary constructors; (2) decompose based on property names; (3) like Scala a type has a canonical "Unapply" method which says how to decompose; it might be an extension method and might be overloaded by type or arity; (4) like F# have active patterns.

In our investigation of pattern-matching, we're heavily swayed by Martin Odersky's paper http://www.scala-lang.org/node/112


Anthony's advanced idea:
``` vb
Dim x = sender Matches Dim ui As UIElement When ui.Tag = "a"

Select Case sender
   Case Matches Dim b As Button : ...
End Select
```

```
Expr ::= … | expr Matches M [when boolean-expr]
M ::= * | Dim v | Dim v As T | MatchFunction(M, …)
```
Scope: the scope of each introduced "v" is the containing statement. So, it works in "If" and "Case", but it doesn't help with "Dim x = e Matches Dim v"

OPTION1: can we allow arbitrary Boolean expressions inside M? Still can't see it.

OPTION2: can we remove "Dim", and make the parentheses on MatchFunction compulsory? i.e.
```
expr ::= … | e match M1
M1 ::= M2 [where Boolean-expr]
M2 ::= * | Dim v | [Dim] v As T | MatchFunction(M1, …) 
```
OPTION3: Should we also we also allow `M2 ::= … | v As MatchFunction(M1, …)`


## TO RECAPTURE the basic question we're trying to address...
How difficult is it to match Tree(Leaf(2), Leaf(3))

## OPEN QUESTIONS:

(1) How exactly will MatchFunction bind? It would be nice to have a "matcher" object that we can dispatch on. It would be nice to dispatch on Integer.TryParse. Or maybe each active pattern should be explicitly indicated with an attribute (like extension methods).

(2) The whole idea here is to match against the runtime type of expr. How does that even work when invoking MatchFunctions? Overload resolution? It suggests putting overload resolution into the late-binder, which we don't like.



# 14. Await in Catch and Finally blocks
*Approved. Aligns with C# vNext feature*

We'll leave the design work to C# LDM, and do exactly the same.


# 15. Type inference for constructors of generic types.
*Approved. Aligns with C# vNext feature*

``` vb
   Dim x As New List({1,2,3})
   Dim x = New List({1,2,3})
```
We'll use just the same semantics as C#.

Note: it doesn't help common cases that I run into, e.g.
``` vb
Function f() As Tuple(Of Integer, String)
   If condition Then Return New Tuple(Nothing, Nothing)
   Return New Tuple(5, "hello")
End Function
```

But it's better than nothing, and brings more regularity into the language.


# 16. <field:attr> on autoprops
*Approved. Aligns with C# vNext feature "field target on autoprops" *
``` vb
   <field:attr> property x As Integer
   <field:attr> event e As Action
```
Stylistic guidance will be to use <field:NonSerializable> on events even though the field target isn't needed. No further semantic design work needed.


# 17. Allow scalar query expressions to clash names.
*Approved. Parity with C#*

There are two parts of the approved design....
``` vb
Dim args As String()
Dim q = From arg In args Select arg.ToString()
' BC36606: Range variable name cannot match the name of a member of the 'Object' class
```

Design1: Improve error message so it says “Inferred range variable name ‘ToString’ cannot conflict with blahblahblah”.

Design2: If the last Select is followed only by the innocuous clauses (Distinct, Skip, Take) and if the Select has only one item, then skip name generation entirely.

# 18. Introduce "Null" literal
* Rejected on 2014-01-06. It would have had parity with C# "inference is aware of null" feature. *

Here is the problem statement:

*“I don’t know what Nothing means.”* I wrote the following code, expecting that Nothing would mean a nullable integer, but it came back as the integer 0. 
``` vb
10:   Dim x = If(False, 0, Nothing)
```

*“Nothing doesn’t mean what I think it means.”* I wrote the following code, expecting that by specifying the type, it would know to use a nullable nothing. But it didn’t.
``` vb
20:   Dim x As Integer? = If(True, 0, Nothing)
```

*“No one else knows what Nothing means.”* MSDN articles always say “Use null (Nothing in VB),” but that’s not really correct. Nothing is more like default(T), and VB lacks null.


## PROPOSAL “B”: INTRODUCE NULL INTO THE LANGUAGE
The basic problem is that Nothing was a bad primitive from the get-go, and C#’s “null” was a better primitive. We should encourage people, as best-practice, to use “null”. It would work as follows.

Syntax: if we are parsing an expression and encounter the simple name “Null” and it doesn’t bind to any namespace, type or variable, and doesn’t have qualification or indexing or dictionary-lookup operators after it, then treat it as “Null”.

Semantics: Null is identical to Nothing, except for the following rules:

1. It is an error to interpret Null in a context expecting a non-nullable value type. So, “Dim x As Integer = Null” is an error, but “Dim x As Integer? = Null” is okay.

2. Even though Null has no inherent type of its own (i.e. Null doesn’t suggest its own type to dominant-type algorithm), nevertheless "Dim x = Null" infers type Object for x. This is similar to the existing rule that "Dim x = Nothing" infers Object even with Option Strict On.

3. If the compiler needs to determine dominant-type-of-set-of-expressions, and one of those expressions is a naked Null literal, then when gathering the set of inherent types of all those expressions, replace each non-nullable-value-type candidate “T” with Nullable(Of T).

Example: "Dim x = If(b,5,Null)" previously gathered only one inherent type "Integer" as a candidate for dominant-type-inference. From rule [3] it will instead gather “Integer?” as a candidate. Both expressions can be interpreted as Integer?, so that succeeds.

Example: “Dim x = {1,2,Null}” previously gathered only one inherent type “Integer” as a candidate for dominant-type-inference. From rule [3] it will instead gather Integer? as a candidate, and it works.

Example: “Dim x = {1, “hello”, Null}” previously gathered Integer and String as candidates. From rule [3] it will instead gather Integer?, String as candidates. There is no dominant type amongst these two, so it falls back to Warning: Object Inferred.

Example: “Dim x = {1L, 2, Null}” previously gathered Integer and Long. From rule [3] it will gather Integer? and Long?. The dominant type amongst these two is Long?, which is what it will pick.

Incidentally, the VB compiler up to VS2013 already recognizes syntactic “null” in the same way, in order to produce a special-case error:
![Image](http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-12-06-codeplex/5481.null.png)

We did consider “Nothing?” instead of “Null”. That has the slight advantage that Nothing is already a reserved word in VB. However, it looks strange, and will leave people even more confused. We also considered “Nuffink” :) and rejected it -- it’s not all dour-faced diligence in the VB LDM!


# 19. Smarter name resolution
* Approved. Already in Main. VB-specific. *

Full notes are recorded in the minutes of the VB LDM 2013-12-13. I haven't typed them up onto codeplex yet. If you want me to, please request them.

``` vb
Import NA     ' contains only the type NA.N1.T
Import NB     ' contains only the type NB.N1.U
Dim x As N1.T ' let this resolve to NA.N1.T

Dim x As ComponentModel.INotifyPropertyChanged
' In Console is okay, but in Winforms apps it is ambiguous
' between System.ComponentModel and System.Windows.Forms.ComponentModel
' Note: System.ComponentModel isn’t project-imported on most project types
' so the full qualification might be expected.

Threading.Thread.Sleep(1000)
' In Console and Winforms this is okay, but in WPF aps it is ambiguous
' between System.Threading and System.Windows.Threading
' Note: System.Threading isn’t project-imported on most project types
' so the full qualification might be expected.

Dim y As Xml.Linq.Xdocument
' If you import System.Security.Cryptography, this becomes ambiguous
' between System.Xml and System.Security.Cryptography.Xml
' Note: System.Xml isn’t project-imported on phone/silverlight,
' so the full qualification might be expected.

Diagnostics.Debug.WriteLine()
' In Silverlight/Phone this works, but in WinRT aps it is ambiguous
' between System.Diagnostics and Windows.Foundation.Diagnostics
' Note: System.Diagnostics isn’t project-imported on phone/silverlight,
' so the full qualification might be expected.
```

# 20. Partial modules and interfaces
* Approved. Aligns with C# vNext feature "allow partial anywhere" *
``` vb
   Partial Module Module1
   End Module
```
Partial methods inside will be allowed; they will just drop out. We can't think of any design gotchas. This was a request from the Roslyn implementors.


# 21. Params IEnumerable
* Approved. Aligns with C# vNext feature. *

``` vb
   Sub f(ParamArray x As IEnumerable(Of Integer))
```
No further design work needed.


# 22. Private Protected.
* Approved, but syntax needs to be settled. Aligns with C# vNext feature.*

Design option 1: like C#
``` vb
   Private Protected Sub f()

   Friend Property p As T
     Get
     Private Protected Set
   End Property
```

Design option 2: not like C#, but it is conceptually cleaner. VB should naturally be more verbose where verbosity is actively useful.
``` vb
   Protected And Friend Sub f()

   Friend Property p As T
     Get
     Protected Set
       ' means anyone in the assembly can see it,
       ' but only those who also derive can set it
   End Property

   Protected Property p As T
     Get
     Friend Set
       ' means it's a protected property, but
       ' only my assembly can set it
   End Property
```

RESOLUTION: Please see meeting notes from 2014-03, where we opted for "Design 3". (I haven't typed up those notes yet. If you'd like to see them, let me know -- lwischik).


# 23. TryCast for nullable value types
* Approved. Parity with C#.*

TryCast will allow a target type that's either Reference type or a nullable type. It will work exactly as in C#. Note that TryCast bypasses the latebinder.
``` vb
   Dim obj As Object = 1
   Dim x = TryCast(obj,Integer?)
```

# 24. Override events
* Approved in principle, but still needs design work. This is a parity issue for BCL and other frameworks*

Note: it is CLS-compliant for the BCL to do this. The only CLS restrictions around “abstract” are with generics.

Currently C# lets you
1.	Define an interface with an event. 
2.	Implement the interface by providing that event
3.	Define an abstract class with a MustOverride event
4.	Inherit from that class and override the event
5.	Define a class with an Overridable event
6.	(there’s a C# bug when you try to inherit from that class and override the event, but there are workarounds)

VB lets you do (1) and (2). This means that VB users are shut out from any library which uses (3) or (5): VB users are unable to inherit from the class.
In .NET4, the BCL folk have changed a few classes to include MustOverride events. For instance, Inherits System.Windows.Documents.Serialization.SerializerWriter. The only VB workaround is mock-type injection voodoo. (e.g. also the VS Editor folks, writing in C#, had done this themselves).

VB's lacuna was just an oversight.

Proposal at hand is (3) let you define an abstract class with MustOverride event, (4) let you inherit from that class and override the event, (5) let you define a class with an overridable event.


# 25. Allow MyBase in structures
* Approved, but low priority. VB-specific. *

The example is MyBase.GetHashCode(). It should behave like you'd expect, like C# does.

NB. Structure "GetHashCode" finds the first instance field and calls GetHashCode on it, using reflection 


# 26. Allow delegates in object initializers
* Approved in principle if C# goes ahead with the same feature, but needs further work on syntax*

``` vb
Dim x As New C With {.Name = "x", .Notify += delegate}
Dim x As New C With {.Name = "x", AddHandler .Notify, delegate }
Dim x As New C With {.Name = "x", .Notify = delegate }
Dim x As New C With {.Name = "x", .Notify := delegate }
```

We're not sure what syntax to use…
+= is the C# syntax and resonates with our proposal to add += for delegates, even though the feature only allows you to sign up a single delegate
= is the XAML syntax, and nice and short. If the constructor of C had already signed up a delegate, it'd be weird! It's also nice not to add new syntax.
:= is the named-argument syntax

NOTE: maybe there are problems to be solved at the same time for nested collection initializers, and of course lightweight-dynamic initialization. C# lets you use assignment for collection-initializers:
var x = new Order { .Items = {1,2,3} }
This gets the value of "Items" and then does a collection-initializer on it. We can't do this. But it shows there exists in C# a precedent where = really means Add.


# 29. Allow With and From together
* Approved, but low priority. VB-specific. *

This is just cleaning up the language. Design is that "With" comes first and "From" comes next.
``` vb
   Dim x As New List(Of Int) With {.Capacity=10} From {1,2}
```

# 30. Extern alias for assemblies
* Undecided.*

We have a design doc for this, but it's a lot of work, and seems low-priority.

# 31. Combine delegates with +=
* Approved in principle, but need design work. Parity with C#. *

``` vb
   m_ClickEventHandler += value
   m_ClickEventHandler -= handler
```
Semantics will be exactly as for C#. However we will not also allow "event += value" as a synonym for "AddHandler event, value".

STILL TO DO: figure out exact semantics for "+"
``` vb
m_ClickEventHandler = m_CLickEventHandler + value
```
STILL TO DO: figure out (for this as for all new features) how much should make it into the late-binder?


# 32. String interpolation
* Undecided *

``` vb
   Dim x = $"hello \{e.Name}"
```

We have detailed notes from this from VB LDM 2013-12-09. It's a complicated topic. If you'd like me to type up the notes, let me know. -- lwischik



# 42. Out parameters and implicit Out parameter declaration
* Approved in principle, but needs design work. Aligns with C# "out vars" feature.*

``` vb
   ' Callsite:
   If Integer.TryParse(s, Out [Dim] x [As Integer]) Then ...

   ' Declaration-site:
   Function TryParse(s As String, Out x As Integer) As Boolean
```

The declaration-site will be emitted as <Out> Byref. However if you merely write <Out> Byref then it will be treated as a ByRef rather than as an Out, because the compiler doesn't generally crack attributes in source code.

The declaration method will default-initialize all Out parameters on entry (this can be optimized away by the compiler). Warnings will be emitted for both use-before-assign and return-without-assign.

On the callsite, for back-compat, you don't need an "Out/Output" keyword to match an out parameter. However, you do need the keyword in order to declare the variable inline, and if you use the keyword then it is an error to pass it something that's not an lvalue.

Outstanding questions:

* What should the scope of "x" be? C# LDM is also wrestling with this, and the answers are sometimes unexpected.

* Should the pretty-lister insert "Out" as you type a function invocation?

* Callsite syntax: should it be "Out" or "Output"? Should we use rules similar to the existing "For" where you don't need Dim, and instead a new variable is implicitly declared if there's an "As" clause or if it doesn't bind an existing name?

* Is this synergy with "For" a step too far? Given that the scope of the out in statements will bleed outside. Shouldn't we help people avoid the dangerous situation?


# 34. Declaration expressions
* Rejected. This would have had parity with C# vNext feature. *

This is a generalization of Out Dim, to allow variables to be declared in any expression.

``` vb
Console.WriteLine(Dim x As Integer = GetValue(), x + 2)
Console.WriteLine(x+1)

If (Dim c = TryCast(x, String)) IsNot Nothing Then ...
var z = (var x=LengthyGetX(); var y = LengthyGetY(); x*x+y*y);

If (Let c = TryCast(x, String) in c) IsNot Nothing Then

var z = Let x = LengthGetX()
        Let y = LengthyGetY()
        Returns x*x + y*y

If (Let c = TryCast(x,String)) IsNot Nothing

var z = Let x = LengthGetX()
        Let y = x+LengthyGetY()
        Select x*x + y*y ' DO NOT want x to escape scope
```

"Select"? Yield? Returns? In?

``` vb
var z = Let x = LengthGetX(),
        y = x+LengthyGetY()
        Yield x*x + y*y ' DO NOT want x to escape scope

Integer.TryParse("15", Out x)
Console.WriteLine(x) ' REALLY DO WANT x to escape scope
```

C# is using the same mechanism for both "out vars" and the "let" construct. Maybe that's why C# scope isn't always obvious?

Q. Does the keyword "Let" cause ambiguities if we're using this inside query expressions? Note that "Let" is bad for query expressions.

Note: one thing that makes sense for C# is that C# already allowed assignment into expressions, and so assigning to a new-variable is a sensible extension. But VB has never allowed assignment in expressions, so it doesn't naturally go that far.

RESOLUTION: None of this feels naturally "VB"ish. We're happy if VB sticks merely to Out parameters and implicit declaration of Out arguments.


# 35. Expression sequences
* Rejected. Would have had parity with C# vNext feature. *

The C# goal is to allow multiple expressions. "An expression can be of the form (expr1; expr2; expr3) which has the end result "expr3" but it evaluates (and discards) the preceding expressions in the list."

VB proposal:
``` vb
Dim x = (Console.WriteLine("log") : 15)
Dim x = Do Console.WriteLine("log") In 15
```
an expression can have the form "Do statementlist In expr" which has the end result "expr" but it performs the preceding statementlist first.

``` vb
Dim z = Do Dim x = sideeffect() : Dim y = sideeffect() In x+y

Dim z = Do
                 Dim x = sideeffects()
           In 15

Dim x = Function()
                 Console.WriteLine("log") : Return 15
              End Function.Invoke()
```

RESOLUTION: If we don't have declaration expressions, then there's little value in expression-sequences. It might make sense to combine the two into a "Let" operator, but that doesn't feel very VBish.

# 37. Implicit Interfaces
* Tentatively approved, but still needs design work. Parity with C#. *

One typical scenario for it is code-generators and partial classes.

``` vb
Class C : implements IDisposable
   Sub Dispose() : End Sub
End Class
```

Proposal is to allow you to avoid use of "Implements" keyword. Note that C# also lets inherited members implement interface members. We might not do the same.

But would there be breaking changes? … yes if the base case implements stuff. Here's the example:

``` vb
Class A
   Sub Dispose() : End Sub
End Class

Class B : Implements IDisposable
   Sub Dispose() Implements IDisposable.Dispose
   End Sub
End Class

Class C : Inherits B : Implements IDisposable
   ' Q. does C implement IDisposable.Dispose over again, or rely on base class?
  ' Currently works fine, relying on B's implementation of IDisposable
  Sub Dispose() : End Sub
End Class

Class D  : Inherits A : Implements IDisposable
   ' Q. Does C implement IDisposable.Dispose via the base class, or not?
   ' Currently an error
End Class

Class E : Inherits B : Implements IDisposable
  Sub Dispose() : End Sub
   ' Q. does E implement IDisposable.Dispose via its method, or rely on base class?
  ' Currently works fine, but it does NOT use E's "dispose" to implement the interface
End Class
```

Proposal1: If existing VB fails to come up with a method that implements the interface member, THEN we look for an implicit implementation of it. (Worry: if someone modifies the base class to now implement the interface method, then the derived class will no longer be implicitly implementing it. But note that it's already the case that base-class-authors can do a whole load of things that mess up your code.) If something gets hijacked, then give a warning.

Problem: principle is that "adding interface-implementation to a base case should not be a breaking change". The above proposal would violate this principle. (Actually, the principle isn't fully upheld already. Consider a class "X"
``` vb
Sub f(dummy As Y) ' X has a narrowing conversion to Y
Sub f(dummy As I)
```
In the first release, it would implicitly pick the first overload. But if someone now changes X to implement I, then it would pick a different overload. So we don't believe that the principle is fully upheld. Maybe the principle is a smaller one. "If a new interface is added, and an existing class is changed to implement that interface, then it won't be a breaking change".


NB. Here's a "bridge-method" oddity:
``` vb
class B { public void Dispose(); }
class C : B, IDisposable {}
// in C#, the CLR likes interface implementations to be virtual, so C# compiler creates a bridge method.
```

Proposal2: we'll look up implicitly by name, and always prefer the most derived type. But we'll add a warning when you would be hijacking code that already compiles. It's a warning, one that won't arise in typical case. (Note: you'd already have had to use Overloads/Shadows)
Example:
``` c#
class A : IDisposable { Dispose }
class B : A {Dispose}
Class C : B, IDisposable {}
```
This code currently works, and does not hijack.
Proposal would change it so that C emits a warning and picks up the new one.


Proposal3: use new syntax, and copy the feature wholesale from C#.
``` vb
Class B
   Implicitly Implements I1
   Auto Implements I2 
   Implicitly I3
   Implicit I4
End Class
```
' As with C#, it will use explicit implements if they're present, and if absent then it will start looking in the most derived type. Hijacking will be impossible. NB. Vladimir points out that the C# implementation doesn't quite match the C# spec.

RESOLUTION: Yes. Use Proposal3. We will look for a keyword combination that seems nice.

Note: it's a weird situation that the more desirable syntax "Implicitly Implements" is more verbose than the less desirable traditional syntax "Implements". There may be IDE codespit ameliorations.

NB. Like in C#, a single method can implement the same named member from multiple interfaces. (currently can with the Implements keyword).

Q. How discoverable will it be?

Q. Currently VB requires explicit interface implementation to have exactly the same optional parameter defaults. Should we adopt C# rules here? or VB? Note that C# came from a history that the camel's nose was already in the tent. Oh, and what if there are multiple interfaces with different default values?

RESOLUTION: Stick with current VB rules, and if they complain, we can look into it then. And refactoring makes C# a bit dangerous. Note: we should match based on signature, and then give an error if the defaults don't match.


# 38. GetName operator
* Tentatively approved, but there are design issues. Parity with C# vNext "nameof" feature. *

Here are some sketch syntaxes we played around with...

``` vb
Dim name = nameof(Point.X)
Dim name = GetName(Point.X(Of ,).Y)  ' we prefer GetName

DIm name = nameof(System.Action)

Dim TextProperty As DependencyProperty = DependencyProperty.Register(GetName(Text), GetType(String), GetType(MyClass))

Public Property Text As String
   Get
     Return CStr(GetValue(TextProperty))
   End Get
   Set
      SetValue(TextProperty)
   End Set
End Property

Sub f(x As String)
   If x Is Nothing Then Throw New ArgumentException(GetName(x))
End Sub
```

The C# proposal is straightforward: the argument to nameof is an (optional type-or-namespace-followed-by-dot) and then an identifier. The result is the string of that identifier.

In VB we prefer "GetName" to "NameOf".


Q. Will it return the casing as you passed it to GetName, or will it return the casing as defined in metadata? What if there are two different casings in metadata? What if there are two different casings in metadata and they disagree with the argument to GetName? - Answer: it's an error. You'll have to fall back to a string literal.

Q. In VB can we refer to the constructor "New"? - No, there's never any need for it.

Q. Can "Point" be ambiguous? What if "Point" is a namespace, and member "X" exists in multiple modules inside that namespace?

Proposal1: "Point" (the prefix) must be unambiguous, but it's fine for "X" to refer to a method-group or a property-group or a unique thing. This is the current name lookup rules.

Q. Should we allow unbound generic types, similar to GetType?
A. Yes.

Q. Can we use type keywords like "Integer" and "Boolean"? (same question for C#).

Q. If we GetName() on an alias, does it refer to the underlying metadata name? Presumably yes! 


GENERAL FEEDBACK: Concern from Aleksey and IDE team about overloads and dealing with ambiguity. E.g. when you do find-all-references, or rename-refactor on an overloaded thing, then it's not clear which of the overloads "nameof(...)" operator is referring to (hence not clear whether it should be renamed). And the Roslyn APIs that return reference-counts -- how should they deal with it?

TWO WAYS TO SPEC THIS:
(1) GetName( BLARGH . Identifier ) where GetType(BLARGH) is valid
(2) GetName( current name lookup rules ) and the name lookup must be successful. (but need it also be unambiguous?)


# 39. Extension statics

This topic has been discussed offline. Let me (lwischik) know if you'd like me to type up the notes.

# 40. Expression-bodied function members
* Rejected. Would have had parity with C# vNext feature.*

In C# it'll look like this:
``` csharp
public int R => Math.Sqrt(X*X + Y*Y);  // readonly autoprop
int M(int i) => i+1;  // methods
static operator int(C x) => (int)x.field; // conversions
static operator +(C x,C y) => new C(x.field + y.field);
```

C#: all of these things are expressions, but statement-expression is a kind of expression, so they allow all statement-expressions as well (including void-returning statement expressions).

Is there anything to do in VB?

VB single-line lambdas:
``` vb
   Dim x = Function(y) y+15
   Dim z = Sub(y) Console.WriteLine(y)

Class C
  Public Square(x As Integer) x*x
End Class
```

Proposal 1: allow more things on a single line... We're already part way there (Roslyn now no longer requires "End" to start a line). It just requires allowing Sub() and other things to have a colon following them.

``` vb
   Dim lambda = Sub() : Return 5 : End Sub
   Sub method() : Console.WriteLine("oops") : End Sub
   Property p As Integer
     Get : Return _p : End Get
     Set : _p = value : End Set
   End Property
```

(Q. are there any ambiguities between multiline lambdas inside methods? Follow-up with Tomas/Anthony for more…)


Proposal 2: Invent a special-case syntax single-line functions, methods, operators and readonly autoprops.
``` vb
  Function f() As Integer : Return 15
  Sub g() : Console.WriteLine("hello")
  Sub ToDo() : Throw New NotImplementedException()
  Shared Operator +(x As C, y As C) As Integer : Return x.i + y.i
  ReadOnly Property p As Integer : Return 5
```
* Note: this prevents Proposal1, which is a bit of a shame! Unless you come up with the rule that "End Sub" is optional, like ; is in javascript.

Q. What if I put three statements? would I still need "end sub" ?
``` vb
   Sub g2() : x=15 : y=17
       Console.WriteLine(x+y) 

  Function f() As Integer = 15
  Sub g() = Console.WriteLine("hello")
  Shared Operator +(x As C, y As C) As Integer = x.i + y.i
  ReadOnly Property p As Integer = 5  ' doesn't work

  Function f() As Integer := 15
  Sub g() := Console.WriteLine("hello")
  Shared Operator +(x As C, y As C) As Integer := x.i + y.i
  ReadOnly Property p As Integer := 5

  Function f() As Integer 15
  Sub g() Console.WriteLine("hello")
  Shared Operator +(x As C, y As C) As Integer x.i + y.i
  ReadOnly Property p As Integer 5

  Function f() As Integer Return 15
  Sub g() Console.WriteLine("hello")
  Shared Operator +(x As C, y As C) As Integer Return x.i + y.i
  ReadOnly Property p As Integer Return 5
```
   

Proposal 3: Only solve it for autoprops, but use a new keyword:
``` vb
  Computed Property p As Integer = x
```

* This looks confusing! It looks more complicated than what it's actually doing.
* REJECTED proposal 3.


VB already has
``` vb
   Property p As Integer = GetFoo() + 17  ' this is done at initialization-time
```


RESOLUTION: We're proud not to do anything. None of the proposals buy that much, and none are that special.


# 41. Primary constructors.
* Rejected for VB. Would have had parity with C# vNext feature. *

The notes are offline. Let me (lwischik) know if you'd like me to type them up.


# 43. Literal type suffixes for Byte and SByte.
* Approved.*

``` vb
Dim x = 15L
Dim x = &HFACEL
```

Literals are NOT target-typed in VB. They are integers (unless with type suffix).

Byte is the only numeric type in VB which lacks a suffix. The reason it lacks it is because the obvious choice "B" is already taken by hex digit.

Byte is unusual - it's the only numeric type where the default is "unsigned". e.g. "Integer" means "Signed Integer" but "Byte" means "Unsigned Byte".

RESOLUTION: yes. Use "SB" and "UB". That will avoid the confusion of the previous paragraph. (other contenders were "Y and SY" like F#, or "Y and UY").


Q. Can you write "Dim x As Integer = &H00000000000000000000FACE ?
Likewise can you write "Dim x = &H0FUB"

Q. Can you have extra "1"s? e.g. Dim x As Signed Byte = &B111111111111110 SB ? The point is that leading 1s are not significant for signed binaries. 

Suspect the current rule is "any leading bits you specify had better be zero". That's a decent enough rule. We could get even more strict ("don't have more leading zeros") but that would be inconsistent.


This feature was triggered by a request of MVP Bill McCarthy, who wrote:

So If I want to force a binary number to Int16, I can use the type suffix:
``` vb
   Dim i As Int16 = &B 1000 0000 0000 0000S
```

Without the S this would fail as the literal would be an overflow for Int16.  First off, I think it would be nice if the S could be spaced, eg:
``` vb
   Dim i As Int16 = &B 1000 0000 0000 0000 S
```

And it'd be nice if there was an error correction suggestion that suggested the S suffix.

And finally, for signed bytes, could we perhaps have a SB suffix, eg:
``` vb
   Const  b as SByte = &B 1000 0000 SB
```

The following workaround just doesn't do it for me:
``` vb
   Const b As SByte = CSByte(&B 1111 1111 1000 0000S)
```

MVP Cory Smith wrote:
I do agree that if you specify the  SByte, it should attempt to do the appropriate conversion without requiring the following:
``` vb
   Dim s As SByte = CSByte(&B00010001)
```

Especially if this works:
``` vb
   Dim b As Byte = &B00010001
```

Here’s another option:
``` vb
   Dim s As SByte = 1
```

This works as well, so shouldn't any string literal work?  I'm just guessing that this was missed somewhere along the way and is an unintended bug in the current implementation.  My expectation would be that the implicit conversions for any literal would work like any other literal whether it is a number or a &B.

# 44. Dictionary member initializers
* Under discussion. Parity with C# vNext feature.


Currently VB lets you write dictionary-lookup expressions
``` vb
   Dim x = y!name   ’ becomes this C# thing y[“name”]
```

C# is considering the following:
``` cs
var expr = new Exception("oops");
var x = new JSON{
     $foo = 15,
     ["bar"] = 17,
     [expr] = 9 }
```

Proposal is to allow such things in VB object initializers. Here are possibilities...
``` vb
1: Dim x = New C With { .member = "hello" } ' existing members
2: Dim x = New C With { !name = “hello” }  ' dictionaries

3: Dim x = New C With { (expr) = "hello" } ' dictionaries
4: Dim x = New C With { !(expr) = "hello" } ' a bit goofy? only consider this if second form turns out ambiguous
5: Dim x = New C With { .(expr) = "hello" }

6: Dim x = New C With { .Item(3) = "hello" } ' It's what you'd write if it were in a With block.

Dim $temp = new C
$temp("name") = ...
$temp(expr) = ...
```

Option 4:  ! means default-property-access always. We could backport ! to generally mean "default property access" everywhere, including expressions and With blocks.

CON4: !x=3 and !(x)=3 now mean different things

PRO: People ask for a way to indicate indexing rather than invocation. They've often asked for []

Option 3: we currently have a.member, a!name, a(index) so everything that comes after the "a" is valid also inside the initializer. NB. requires the thing to be an LVALUE, i.e. no xml-members, no invocation.

CON: Can't use this in a With block on the right hand side, e.g. "With d : Dim a = .y : Dim b = (z) : End With"

Option 5: We are omitting the default property name.


RESOLUTION: We like 1, 2 and 4.
RESOLUTION: 6 is also fine, for uniformity, but is lower priority.



Q. Should we allow .$ as an alias for ! in VB?
A. No. Let's leave it to the intellisense to help people find it



# 46. Dictionary literals
* Haven't got to this. Don't think it's worth it.*

Currently VB has excellent support for array literals. But people want dictionary literals, and are forced to use anonymous-types with reflection. For instance, they write

``` vb
   InitializeMvc(New With { .arg1=“hello”, .arg2=“world”})
   Dim s = “hello \{name}”.Format(New With {.name=“fred”})
```

The first example is a typical MVC idiom, where anonymous types are used instead of named arguments, for cases where named arguments aren’t flexible enough. The second example is similar how Python does string interpolation. Both cases require reflection to get at the members of the anonymous object, which is a pain.

Look at how array literals work...
``` vb
Sub f(Of T)(x As IEnumerable(Of T))
f( {1,2,3} ) ' today this picks up Integer as a hint for T
```

Proposal is to allow a new form of dictionary literal:
``` vb
   Dim x = New With { arg1 := “hello”, arg2 := “world”}
```

Typical scenario is, as above, where the keys of the dictionary are strings that should be compared with the normal InvariantCulture comparison (since they’re used like parameter names rather than human-language strings). It’s not clear however what the type of the dictionary should be, and how it will work with type inference. For instance,

``` vb
   Sub f(x As Dictionary(Of String, Object))
   ...
   Dim y = New With { arg1 := 1, arg2 := 2 }
   f(New With { arg1 := 1, arg2 := 2 })
```

We’d expect “y” to be inferred as Dictionary(Of String,Integer) or IDictionary or ReadOnlyDictionary or something like that. However, we’d expect the call to “f” to be compatible with the parameter type.

Here are some sketched syntaxes to see if they look any good...

``` vb
Dim x = New With { arg1 := "hello" }
Dim x = { arg1 := "hello" }
Dim x = { (1+2) := "hello" }
Dim x = { arg1 = "hello" }
With fred
   Dim x = { !arg1 = "hello" }
End With

InitializeMvc( { !arg1 := "hello", … } )
```

Q. If we have dictionary literals, what would they generate?

A. If type context implements IDictionary<U,V> then use U for key and V for value, otherwise infer from dominant type of expressions - all like we do with array literals.

Q. What is the compile-time type of the dictionary-literal expression?
A. IDictionary<U,V>

Q. What is the run-time type of it?
A. Dictionary<U,V>


# 46. Fix the ternary If operator
* Under consideration. 

The basic problem is that when people see a ternary If operator with a type context
``` vb
   Dim x As Integer? = If(True, 0, Nothing)
```
then they expect it to mean this:
``` vb
   Dim x As Integer? : If True Then x = 0 Else x = Nothing
```
Proposal is that we should fix this for them as follows. When interpreting If(x,y,z) in a context in which the desired type is known, then interpret both y and z in the context of that type.

Note that it will be a breaking change. We decided in LDMs in years past that this would nevertheless be good for the language.

We must seek wider input on what people think about this. Once Roslyn goes open-source, it'll be great to open up to general public feedback.


# 47. More nullable support
* Approved. VB-specific. Completes the nullable story.

``` vb
Dim y = CInt?(5)
```

The issue is about Intrinsic nullable conversion operators (e.g. CInt?(<expression>))

Should we add them? If so, what does `CInt?(5)` mean?

Proposal 1: `If(<a string> Is Nothing, Nothing, CInt(<a string>)`
Proposal 2: `If(Integer.TryParse(<a string>, result), result, Nothing)?`
Proposal 3: `CType(s, Integer?)`

RESOLUTION: Yes, proposal 3.


# 50. Allow As clause on Select clause range variables.
* Under consideration. VB-specific.

Proposal: allow an “As Clause” on query Select clause range variable declarations. Maybe also on Anonymous-type member declarations too.

For example,
``` vb
Dim x = From y As String In list
               Let q As Integer = foo()
               Select x As String = foo()
```

Currently you can specify "As" in Let clause, and it does an implicit conversion.

PROPOSAL: allow you to specify "As" in Select when introducing a new variable ("range variable") with an initializer.

Q. Can you use it after Aggregate? after GroupBy?

RESOLUTION: Anthony will flesh out the other LINQ places where As would go.


# 51. More implicit line continuations
* Still under design. VB-specific.

Proposal: allow implicit line-continuations in these places:
* Before “Then” in If … Then statements
* Before “Implements” and “Handles” clauses
* Others?

Here are some examples...

``` vb
If x
Then Return 15

If x
Then
   Return 15
End If

If x AndAlso
   y AndAlso
   z
Then
  Return 15
End If
```

We generally like the implicit LC before the Then token. The prettylister would put "Then" aligned with the "If" and "EndIf".  But if you omit the Then token (an omission only allowed with multiline ifs), then what? ...? Needs more investigation.


# 52. Allow Handles to be combined with Implements
* Not yet considered


# 53. Negative binary literals
* Not yet considered

Proposal: If the type of the literal is a signed and has all bits explicitly specified we can create a negative number just like we do for hex literals today so
``` vb
&B 1000 0000 SB = -128
```


# 54. ?. operator, which does null-check before proceeding
* Approved, but needs more design-work

We want to write
``` vb
  Dim x = customer?.Name
```
which would mean something like
``` vb
   Dim x As String = If(customer Is Nothing, Nothing, customer.Name)
```
except it would put "customer" into a temporary variable (to avoid evaluating it twice, and to avoid race conditions)


This is a huge topic. I will write up a separate set of notes. There is big debate about what happens if you have several things in sequence, e.g.
``` vb
Dim x = customer?.Name.Length
```

Proposal1: If you used ?. somewhere in the sequence, then you *MUST* continue to use it for every subsequent dot, otherwise it's a compile-time error. This boils down to ?. being a LEFT-ASSOCIATIVE operator, with everything that entails.

Proposal2: In the above example, you are allowed to write "Name.Length", with the intended meaning that you the programmer KNOW that if customer is non-null then (because of invariants in your code) you know that customer.Name is also non-null, and you wish to avoid the runtime cost of doing a null-check on it. This boils down to ?. being a RIGHT-ASSOCIATIVE operator, with everything that entails.


We also in VB expect to allow `x?(y)` which does a null-check on x prior to indexing or invoking it. (C# would only `x?[y]` or `x?.Invoke()` -- it would not allow `x?()` for conditionally invoking delegates).


Q. Which language operators should have "null-checking" versions of them? We've already seen the null-checking member-access operator `x?.y` and the null-checking indexing-or-invoking operator `x?(y)`. Are there any others?

We had wondered if there is ever need for a null-checking conversion operator, i.e. one that does a null-check prior to doing the conversion. Normally it's not needed, since users who write their own user-defined-conversions can roll the null-check into those. So the question is whether it's needed for intrinsic conversions. The only intrinsic conversion that might benefit from a null-check is `Integer? -> String`. This is the only intrinsic conversion which can throw a NullReferenceException.

PROPOSAL 1: Allow null-checking conversion operator, for this one case.

PROPOSAL 2: Change behavior of `Integer? -> String` intrinsic conversion, so it gives you an empty string if the input is null.

RESOLUTION: Rejected proposal 1 because it's too niche. Proposal 2 is decent, but low priority.


---
---

On Apr 4, 2014 at 5:16 PM @AdamSpeight2008 wrote:

Re: __46. Dictionary literals__

Instead of a Dictionary literal, I think it could be better to implement a Key-Value Pair literal instead.  (Think JSON)
A Key-Value Pair Literal  ```{ "A" : 1 }```  
This re utilises the Expression / Statement Continuation Character in VB.net and Array Literals.

In C#  ```:``` is only used in _(as far I can tell)_

```
 cond ? trueExpr : falseExpr  ' Inline IF
 class B : A                  ' Inheritance
```

both of which are contextually different so I can't see another contextual definition being a problem.

This would in essence make a Dictionary Literal just a collection of Key-Value Pairs. Eg

```vb
Dim myDict = { { "A" : 1 } , {"B" : 2 } , { "C" : 3 } }
```

Is then translated into the following code.
```
Dim myDict As New Dictionary(Of String, Integer)(  { ( "A" : 1 ) , ( "B" : 2 ) , ( "C" : 3 ) } 
```

This then only needs a overload for the constructor that takes an ```IEnumerable(Of IKeyValuePair(Of K, V))```.

The compiler could also check at compile-time that the dictionary initialisation is valid. Eg Are the Keys Unique.

---

On May 14, 2014 at 9:51 PM @AdamSpeight2008 wrote:

Allow ```With``` on the ```Case Else``` clause
would permit the following style of coding

```vb
            Select Case flags 
              Case CharFlags.White       : ' stay in FollowingWhite
              Case CharFlags.CR          : state = AccumulatorState.CR
              Case CharFlags.LF          : state = AccumulatorState.Done
                                           terminatorLength = 1
                                           Exit While
              Case Else When (flags And (CharFlags.Complex Or CharFlags.IdentOnly)) <> 0
                                         : state = AccumulatorState.Bad
                                           Exit While
              Case Else                  : state = AccumulatorState.Done
                                           Exit While
            End Select
```

rather than current (less elegant work around)
```vb
            Select Case flags 
              Case CharFlags.White       : ' stay in FollowingWhite
              Case CharFlags.CR          : state = AccumulatorState.CR
              Case CharFlags.LF          : state = AccumulatorState.Done
                                           terminatorLength = 1
                                           Exit While
              Case Else
                 If (flags And (CharFlags.Complex Or CharFlags.IdentOnly)) <> 0 Then
                    state = AccumulatorState.Bad
                    Exit While
                 End If
                 state = AccumulatorState.Done
                 Exit While
            End Select
```

Also allow the ```When``` to the preceded with an implicit line continuation. So that if can be placed /  aligned underneath the relevant ```Case``` clause.
This will improve the readability and formatting.

```vb
              Select Case baseCorTypeId 
                Case SpecialType.System_Enum                                   :  result = TypeKind.Enum ' Enum
                Case SpecialType.System_MulticastDelegate                      :  result = TypeKind.Delegate   ' Delegate
                Case SpecialType.System_Delegate
                  When Me.SpecialType <> SpecialType.System_MulticastDelegate  :  result = TypeKind.Delegate ' Delegate
                Case SpecialType.System_ValueType
                   When Me.SpecialType <> SpecialType.System_Enum              :  result = TypeKind.Structure ' Struct 
                Case baseCorTypeId
                    When Me.Arity = 0 AndAlso
                         Me.ContainingType Is Nothing AndAlso
                         ContainingPEModule.Module.HasAttribute(Me.m_Handle, AttributeDescription.StandardModuleAttribute)
                                                                               :  result = TypeKind.Module
              End Select 
```

_Note: The code is from my roslyn fork_

---

On May 17, 2014 at 1:51 PM @AdamSpeight2008 wrote:

The ```When``` clause should bind to each ```caseClause``` and not the entire collection of ```caseClause``` of that ```caseStatement```

__Composition__
``` 
 Case  caseClause_1 , caseClause_2   When BoolExpr   :  caseActionExpr
      | caseClause | | caseClause | | whenClause  |    |              |
      +------------+ +------------+-+-------------+    +--------------+
                     | caseClauseWithCondition    |
                     +----------------------------+
|----------------------------------------------------------------------|
| caseStatement                                                        |
+----------------------------------------------------------------------+

```

__Usage example__

```vb
Select Case x
  Case Is < 0  : Throw someException
  Case 0 When a_Cond,
       1 When b_Cond     : Return "Result A" 
  Case 2 When a_Cond     : Return "Result B"
  Case Else When b_Cond  : Return "Result C"
  Case Else
    Return "Other"
End Select

End Select
```

would be functionally equivalent to the following ```If ... ElseIf ... Else ... End If``` construct 
```
If ( x = 0 ) Then
  Throw SomeException
ElseIf ( (x = 0) AndAlso ( a_cond ) ) OrElse
       ( (x = 1) AndAlso ( b_cond ) ) Then
  Return "Result A"
ElseIf ( (x = 0) AndAlso ( a_cond ) ) Then
  Return "Result B"
Else
  If ( b_cond ) Then
    Return "Result C"
  Else 
    Return "Other"
  End If
End If
```

---



================================================
FILE: meetings/2014/LDM-2014-03-12.md
================================================
# ProtectedAndFriend, ProtectedOrFriend

## BACKGROUND

The CLI includes two access modifiers "FamilyAndAssembly" (which allows access to derived types that are in the same assembly) and "FamilyOrAssembly" (which allows access to types if they are derived, and also allows access to types if they are in the same assembly). The concepts are explained well here: http://stackoverflow.com/questions/22856215/what-is-the-meaning-of-the-planned-private-protected-c-sharp-access-modifier

## REQUEST
VB and C# already have syntax for FamilyOrAssembly ("Protected Friend"). Please add syntax to allow VB to express FamilyAndAssembly.

## RESOLUTION
VB will add two new access modifiers, which are exact transliterations of the CLI keywords...

``` vb
ProtectedAndFriend
ProtectedOrFriend
```

The pretty-lister will not turn "Protected Friend" into "ProtectedOrFriend". However, if the user types "private protected" (or whatever syntax C# chooses) then it will pretty-list the entire file into C#. JOKE. No it won't. But it may pretty-list the C# syntax into "ProtectedAndFriend".

Here are some code samples:

``` vb
   ProtectedAndFriend Sub f()

   Friend Property p As T
     Get
     Protected Set
       ' means anyone in the assembly can see it,
       ' but only those who also derive can set it
   End Property

   Protected Property p As T
     Get
     Friend Set
       ' means it's a protected property, but
       ' only my assembly can set it
   End Property
```

## DISCUSSION
Alex wrote, "Around Private Protected, I really feel like we make a mistake if we choose our VB syntax with the arbitrary choice that C# made so that it could look like C++.  We should embrace this as one of those times where VB’s trend towards verbosity leads naturally to a design whose meaning is obvious at first glance. We don’t want to get stuck in a design rut where we’re OK with C# being clearer than VB where terseness pays off, but not vice versa where verbosity pays off – by definition, then, VB will always be less clear than C#."

Neal observed that the sense of "And/Or" is confusing. It might be a logical And of the permissions, or a logical And of the restrictions. Nevertheless, the CLI has chosen a canonical sense, and we're copying it.

## OTHER DESIGNS CONSIDERED

``` c#
private protected
protected if internal
internal && protected  // also "internal || protected"
internal and protected  // also "internal or protected"
internalAndProtected  // also "internalOrProtected"
```
``` vb
ProtectedAndFriend  ' also "ProtectedOrFriend"
Protected And Friend  ' also "Protected Or Friend"
ProtectedFriend   ' rejected because it's just one space away from "Protected Friend"
FamilyAndAssembly  ' also "FamilyOrAssembly"
Private Protected
Protected OnlyIn Friend
Protected But Friend
Protected If Friend
Protected When Friend
Protected Xor Friend  ' just a joke... :)
```


# Faster CInt(Double)

## Background

``` c#
double d = 10.5;
int x = (int)d;
```
``` vb
Dim x = CInt(d)
```

The VB version is slower than C#. Indeed, any time we call CInt, the compiler always codegens a call to Math.Round. Even CInt(Math.Round(x)) gets compiled into Math.Round(Math.Round(x)).

## Request
Please allow us to write fast integer casts in VB.

## Resolution

**Part 1**: Any time the compiler generates an implicit call to Math.Round (i.e. as part of `CInt, CLong, CULong, CUint`), and if the argument of that implicit call is one of a list of math functions known to return a whole number, then omit the outer call to Math.Round. The list of known math functions is: `Round(d), Round(d,MidpointRounding), Truncate(d), Floor(d), Ceiling(d), VisualBasic.Fix(d), VisualBasic.Int(d)`.


**Part 2**: If the user writes `CInt(Math.Truncate(d))` then we will emit `conv.i4` or `conv.ovf.i4` dependent on the current project-level "check-overflow" settings. (TODO: verify that `conv.i4` has exact same semantics as `CInt(Math.Truncate)`, including negative values, superlarge doubles and exceptions, NaN, Infinity). Also do likewise for `conv.i1, conv.i2, conv.i4, conv.i8` and for their unsigned versions, and for both checked and unchecked versions.


## Discussion

This is a compiler optimization, pure and simple. It adds no new syntax or concepts or library functions. We identify targeted scenarios and generate optimal IL in those cases where semantics would not be affected. This seemed the cleanest approach. Specifically, it seemed better than adding any of the following syntaxes:
``` vb
DirectCast(d, Integer)
(Integer)d
VB.FastCast(d)
d As Integer
```

Will it be better to special-case just one of these combinations? e.g. conv.i4 on CInt(Truncate(double))? Or is it better to just do all of them? Default answer: "yes do all of them", and only scale back if the compiler-dev comes back and says it's too hard.

There are other possible concerns, e.g. what happens if it turns out that the semantics of conv.i4 are actually different from ALL of the Math.Round-like functions? What if it turns out that it's really hard to implement every case? What if expression-trees throw a wrench in the works? Well, when devs set about implementing the feature, then we can come back to check.



================================================
FILE: meetings/2014/LDM-2014-04-01.md
================================================
# Null propagating operator ?.

The `?.` operator is the second-highest voted request on UserVoice
http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/3990187-add-operator-to-c

We've discussed it in C# and VB Language Design Meeting. Mads has written up detailed notes [here](https://roslyn.codeplex.com/discussions/540281) and [here](https://roslyn.codeplex.com/discussions/540514). Some questions still remain, so I'm starting a thread for general discussion of this feature.

The core idea is to save you having to write code like this all the time, with null-checks:
``` cs
var temp = GetCustomer();
string name = (temp == null) ? null : temp.name;
```

Instead you'd write this:
``` cs
var temp = GetCustomer()?.name;
```

## How does ?. behave in sequences?

Q. How does it behave if you have several of these things in sequence? There are two possibilities on the table:
* *Left-associative*
* *Right-associative*



``` cs
class Customer1
{
    public readonly ExtraRef extraRef = new ExtraRef();
}

class ExtraRef
{
    public readonly string name = "fred";
}

Customer1 GetCustomer1()
{
    return (RND.Next() > 0.5) ? null : new Customer1();
}

int? len1a = GetCustomer1()?.extraRef?.name?.Length;
int? len1b = GetCustomer1()?.extraRef.name.Length;
```

What do you expect about `len1a` and `len1b`? [**edit** - initially I wrote the following out wrong. I've fixed them.]

* len1a - this is the same for both *left-associative* and *right-associative* -- it performs a null-check on GetCustomer1(), and if that succeeds, then it will perform null-check on extraRef and name.
* len1b - under *left-associative* it is a **compile-time error**. But under right-associative, it performs a null-check on GetCustomer1(), and then **skips** the null-check on extraRef and name.

Note: I constructed this example so that, if GetCustomer1() returns non-null, then I as the programmer know (from readonliness) that extraRef and name will both be non-null. The question is, is there some way to communicate this fact to the compiler, to avoid superfluous null-checks? **Left-associative says there isn't; right-associative says there is.**

(I benchmarked about a 5% perf overhead of doing those extra null-checks in the case where GetCustomer1() returns non-null)


``` cs
class  Customer2
{
    public readonly ExtraStruct extraStruct = new ExtraStruct {age=29};
}

struct ExtraStruct
{
    public int age;
}

Customer2 GetCustomer2()
{
    return (RND.Next() > 0.5) ? null : new Customer2();
}

int? age2a = GetCustomer2()?.extraStruct?.age;
int? age2b = GetCustomer2()?.extraStruct.age;
```

What do you expect about `age2a` and `age2b` ?

* age2a (how you must write it under *left-associative*) - this performs a null-check on GetCustomer2() and if this succeeds then, thanks to **compiler-optimization** and despite what's written, it knows it can skip the null-check on extraStruct.
* age2b (how you must write it under *right-associative*) - this performs a null-check on GetCustomer2() and if this succeeds then, **because of how you wrote it**, it skips the null-check on extraStruct.

Here, extraStruct is a structure and can never be null. So it doesn't make sense to null-check it. Should this fact be expressed as a compiler optimization in `age2a`? Or should it be expressed in syntax in `age2b`?


``` cs
var x = GetCustomer1()?.extraRef?.name?.Length
==>
var explainingVariable = GetCustomer1()?.extraRef;
var x = explainingVariable?.name?.Length;
```

* Is this a valid refactoring?
  * *left-associative* : it is a valid refactoring 
  * *right-associative* : it's an invalid refactoring
* How would you add parentheses to make the order explicit?
  * *left-associative* : `x = ((GetCustomer1()?.extraRef)?.name)?.Length`
  * *right-associative* : `x = GetCustomer1()?.(extraRef?.(name?.Length))`

You can see why we call them left-associative vs right-associative. It has to do with how you'd put parentheses into the expressions if you were writing them out explicitly.

Incidentally, there are other places where you can't just introduce an explaining variable. For instance, in `var y = a * b + c * d`, you can't just introduce an explaining variable for the first three parts `var ev = a * b + c; var y = ev * d;`. In this case though it's because of precedence, not because of associativity.

[NOTE: that &#43; is meant to be a PLUS sign. I don't know what's up with the markdown...]

Eric Lippert wrote a great blog on the associativity of the ?? operator: http://blog.coverity.com/2013/10/23/null-coalescing-bugs/#.Uzurzo1OV3Q


## Some other idioms with ?.

``` cs
// Call Dispose only if x is non-null:
x?.Dispose(); 


// Trigger an event only if it's non-null
// (not needed in VB, since this is already built into RaiseEvent statement)
event EventHandler OnFired;
void Fire()
{
    OnFired?.Invoke(this, new EventArgs());
}
```


## Codegen for ?.

I asked some CLR experts about what assembly code would be generated by the JIT for the ?. operator, and filled in some details from my hazy memory of OS architecture...

The question was, where does NullReferenceException currently get generated? When you do `GetCustomer1().extraRef`, and GetCustomer1() happens to return null, and so it fires a NullReferenceException, does that happen because the JIT implicitly generates a null-check?

No. The answer is that the NullReferenceException is generated at a lower level. More specifically, in between CPU and RAM there’s a chip called "Memory Management Unit (MMU) / Page Table". Every single time a thread accesses an address in the process’s virtual address-space, the MMU looks up the address in that page table to find where the address is in physical memory. If the virtual address isn’t yet mapped to a page of memory, then the MMU generates a page-fault which the OS has to handle, e.g. by paging in from disk. The CLR reserves addresses at the bottom of virtual address space but never actually pages them in. If ever an instruction tries to look up any address there, then the MMU generates a fault, and the CLR responds to it by generating a NullReferenceException.

The codegen for `x?.y` would probably be something like this...
```
mov rax, X
test rax, rax
beq :lbl
mov rax, [rax + k]
:lbl 
```

[Note: that &#43; is meant to be a PLUS sign. I don't know what's up with the markdown...]




================================================
FILE: meetings/2014/LDM-2014-04-02.md
================================================
# String interpolation
String interpolation is one of the top ten requests on uservoice - http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2312991-string-interpolations-in-c

We've been discussing the feature back and forth in C# and VB language design meetings. This thread starts with a summary of the points raised from the Visual Basic Language Design Meeting of 2013-12-09, combined with comments from MVPs, but I'm hoping that everyone who's interested in the topic can add their thoughts and suggestions to the thread. (I switch back-and-forth between C# and VB syntax, which is how we did our discussions...)

So far the consensus seems to be a resounding "meh" because the proposed designs seem to miss the mark, and the feature isn't as important as other potential new features. Here's a writeup of all our notes so far, so we can have a wider discussion with the general public.

## Examples
Here are some examples in C# and VB:

``` cs
var x = "It measures \{distance:0.00}m";
```
``` vb
Dim filepath = $"{drive}:\{path}\{file}.{ext}"
Dim query = $"{url}?arg1={x}&arg2={y}"
Dim csv_line = $"{name},{dollars}{vbCrLf}"
```

String interpolation would be syntactic sugar for a call to String.Format:

``` cs
var x = "It measures \{distance:0.00}m";
==>
var x = String.Format("It measures {0:00}m ", distance);
```

## Motivation

Why string interpolation? Isn't String.Format already good enough? More generally, what is the real problem that string-interpolation tries to solve? Here are some possible answers, both good and bad. I think we haven’t yet got a crisp good answer to this question. Some possible answers:

1. It is a full replacement from String.Format, with culture and everything, to solve the mess that you find when there are too many positional arguments (see examples below)
2. It provides a quick-and-dirty way to do string concatenation in the invariant-culture for use in composing strings together to pass to other APIs
3. It provides an easy way to stick in identifiers
4. It is an easier way to teach Coding 101 – don’t want to start beginners on String.Format
5. All the other cool languages have it. (bad reason)


## Motive 1: a replacement for String.Format
Proposal: "String interpolation is a replacement for String.Format, for cases where the "positional" arguments {…} of String.Format are confusing to read." As a motivating example, the following code has a few bugs (missing space before {5}, and the orders have got mixed up) and it's not really human-readable…

``` vb
Dim x = String.Format("Robot {1} reporting{0}  {3} levels are {2}{0}" &
                      "{5} levels are {4}",
                      vbCrLf, name, coolant.name, coolant.level,
                      reactor.name, reactor.level)
```

Isn't normal string concatenation already good enough? Again, sometimes it's confusing. The bug here is that there's a missing vbCrLf at the end of the second line:

``` vb
Dim z = "Robot " & name & " reporting " & vbCrLf &
        "  " & coolant.name & "levels are " & coolant.value &
        "  " & reactor.name & " levels are " & reactor.value
```

One curious proposal is to allow string concatenation just by omitting the & in VB (or + in C#), just as is currently the case in C for string literals. But this seems pretty limited -- wouldn't allow for format specifiers, would only work for expressions with string literals before and after them, might close the language off to context-specific keywords in the future, and doesn't look very readable.


String interpolation could be neater and easier to debug than either String.Format or concatenation...
``` vb
    Dim y = $"Robot {name} reporting
{coolant.name} levels are {coolant.level}
{reactor.name} levels are {reactor.level}"
```

However, this example is fishy. Most professional programmers won't be writing user-facing strings in code. Instead they'll be storing those strings in resources (.resw, .resx or .xlf) for reasons of localization. So there doesn't seem much use for string interpolation here.


## Motive 2: a quick-and-dirty way to do construct strings for APIs.
``` vb
Dim filepath = $"{drive}:\{path}\{file}.{ext}"
Dim query = $"{url}?arg1={x}&arg2={y}"
Dim csv_line = $"{name},{dollars}{vbCrLf}"
```

These examples seem to work nicely with string interpolation, but we'd be opening up potential security holes when people construct strings without sanitizing them first. That's a worry.

Some open questions about string interpolation...

## Q. Default culture?
What should the default culture be for string interpolation?
* String.Format uses CultureInfo.CurrentCulture by default
* It feels like InvariantCulture would be a better bet if users are typically using string-interpolation as a way to construct strings to pass to APIs.
* CurrentCulture would be make more sense only if (1) people use it mainly for UI strings, (2) and they’re not localizing their UI by storing strings in .resw
* CurrentCulture also makes sense if the feature feels really close to String.Format.

## Q. Specify culture?
Should users be able to specify the culture to be used?
* The Javascript proposal (next post) would allow this, since you could call
``` vb
Dim s = FmtInvariantCulture`hello {x}`
Dim s = FmtCurrentCulture`hello {x}`
```
* If we want to use a prefix for string interpolation `var x = $"hello";`, then that provides a place where culture could be specified `var x = ${culture}"hello";`
* Alternatively, culture could be specified at the end, e.g.
``` cs
var x = "hello \{x}"(CultureInfo.CurrentCulture);
```
``` vb
Dim x = $"hello {x}"(CultureInfo.CurrentCulture)
```
* MVP Bill McCarthy suggested this interesting syntax:
``` vb
Dim x = $"hello {x}" Using CultureInfo.CurrentCulture
```

## Q. Perf of String.Format ?
What kind of compiler optimizations would be used?
* If the compiler sees that it can optimize away the call to String.Format, and use instead something more lightweight (that still has the same semantics), then it would:
``` cs
var x = "It measures \{distance}m";
==> var x = String.Format("It measures {0}m ", distance);
==> var x = String.Concat("It measures ", distance.ToString(), "m");
```
* Will there be compiler folding? e.g.
``` cs
var x = "hello \{a}" + "world \{b}";
==> var x = "hello \{a}world \{b}";
==> var x = String.Format("hello {0}world {1}", a, b);
```
* Will the compiler do compile-time evaluation if the arguments that go in the hole are constant and which don’t depend on the current culture? It seems risky to take a dependency on the internal behavior of String.Format…

## Q. Prefix syntax?
On an interpolated string, should it have a prefix?
``` cs
var x = "It measures \{d}m";
var x = $"It measures {d}m";
```
* For C# we were leaning towards the first form, where the presence of `\{.}` inside a string implies it is to be interpolated. For VB that's impossible, so we were pushed towards the second form where the prefix implies that the string will be interpolated.
* MVPs raised the issue that, if you wanted to do a global search to find all interpolated strings in a codebase, the prefix form makes it easier. If you merely searched for \{ then you'd get false-positives from double-escaped \\{, and from \{ in XML doc-comments.
* For choice of prefix, we considered the following, and preferred $
``` vb
Dim x = @"hello"   ' bad, since confusing with C# verbatim strings
Dim x = #"hello"   ' used in a few other languages
Dim x = $"hello"   ' used in Nemerle. Fits with the VB heritage
```

## Q. Hole syntax?
In an interpolated string, what syntax to use for marking an expression hole? And then how do you escape that syntax if you want to use it literally? For VB we considered the following:
``` vb
Dim brace  = $"hello {name} "" {{ {vbCrLf}"    ' PHP, Python, String.Format
Dim escape = $"hello \{name} \" \\ \n"         ' C# proposal
Dim hash   = $"hello #{name} "" ## ${vbCrLf}"  ' Ruby, Coffeescript
Dim $brace = $"hello ${name} "" $$ ${vbCrLf}"  ' Dart
Dim $paren = $"hello $(name) "" $$ $(vbCrLf)"  ' Nemerle
Dim $dollar= $"hello $name "" $$ $vbCrLf"      ' PHP, Perl, Dart, Nemerle
```
* `brace` is strongly reminiscent of String.Format, which is good. And {{ is how you already escape out of String.Format. The "vbCrLf" is reasonable way to get a newline. We preferred this option for VB.
* `escape` has the nice feature that it opens the door for escape characters, and is like C#. But it feels wrong to have to have that redundant extra character.
* `hash` doesn’t have much going for it.
* `$brace` re-uses $ in a reasonable way but the way to escape $ is pretty ugly
* `$paren` is a Nemerle variant of `$brace` with the same disadvantages
* `$dollar` would be a nice shortcut for the common case of just wanting to include an identifier, and is something allowed by string-interpolation in a lot of other languages. However it only combines well with `$brace` and `$paren`.


## Q. Expressions in holes?
What kinds of expressions should be allowed in the "holes"? Just identifiers? Or qualified identifiers? How about indexers? Invocations? Arbitrary expressions?
``` cs
var x = "This is \{arg[0]} and \{arg[1]}";
var y = "This is \{Lookup(x)} ";
var x = "Welcome \{user.Name} to \{user.Activity}";
```
* MVPs justifiably observed that it would be bad practice to use complex expressions inside the holes.
* But it's hard to draw a clear compiler-enforced line between "things that are okay in holes" and "things that aren't". For instance, indexers and method-invocations are probably good. So to keep things plain and regular, the compiler should probably to allow all expressions.
* There's a good precedent for this. With the async/await feature, we wanted to allow things like `var x = await t` and also `using (var x = await t)`. And so we allowed await in all expression contexts, even though it's bad practice to use them in confusing places like `x[await t1] += await t2;`
* In practical terms, it's very hard (in terms of implementing the lexer+parser) to allow arbitrary expressions inside a hole. VB already does this for expression holes in XML-literals, so could use the same codebase for expressions in interpolated-string-holes. But C# doesn't yet do this anywhere.
* Should it allow format-specifiers like the :0.00 used in the first example? That might complicate the lexing/parsing. But we don't see any ambiguity problems.


## Q. C# verbatim string?
Can you use string interpolation in a C# verbatim string?


## Q. VB implicit line continuations?
How does it work with VB implicit line continuations? e.g.
``` vb
Dim x = $"hello { 3
         + 4 } world"
```
Answer: it works exactly the same as always: implicit line continuations happen before or after specific characters. The fact of being inside a hole in an interpolated string doesn’t change that. So the above code won’t work, since implicit line continuation isn't allowed before +.

Also, { allows an implicit line-continuation after it as always, and } at the end of a hole allows an implicit line continuation before it as always. Note for precedent that `Dim x = New With { .x=15}` also allows an implicit LC after the `{`, and XML expression holes allow an implicit LC after the `<%=`.

## Q. VB Case statement?
Can you use interpolated strings as a VB Case expression? e.g. `Select Case x : Case $"hello {a}`
Answer: Yes. VB case statements always allow computed values here. C# never does.

## Q. Const?
Is an interpolated string const? `Const x as String = $"hello"`

Answer: No, never, not even for the ones that are clearly recognizable as constants. The rule is that string interpolation is semantically shorthand for String.Format (notwithstanding any under-the-hood compiler optimizations).

## The Python alternative
There's an idiom used in Python today, that some people in VB/C# are also adopting. Here's how it would look in .NET:

``` vb
Dim args = New With {.Name = "Jones", .Address = "1256 92nd St"}
Dim str = "Mr {Name} lives at {Address}".FormatEx(args)
```

The idea here is that it's all the positional format-arguments {0}, {1} in String.Format that are difficult to read. So we could do them using named arguments {Name}, {Address}. You would write an extension method on String which takes an object. At runtime your method parses the string to find curly braces (just like String.Format does), and it uses reflection to look for corresponding members in the "args" object.

(You'd have to be careful that the folks doing localization of your strings don't try to localize {Name} or {Address} !)

With the proposed "dictionary" features of C# and VB vNext, you could write FormatEx using dictionary arguments rather than reflection:
``` vb
Dim args = New Args With {!Name = "Jones", !Address = "1256 92nd St"}
Dim str = "Mr {Name} lives at {Address}".FormatEx(args)
```

This Python-style approach would also solve the culture problem -- because you can easily pass Culture to your extension method.

## The Javascript alternative
There's a string-interpolation proposal on the table for the next version of EcmaScript that's designed specifically to solve the security worries of string interpolation. It also solves Culture.
http://wiki.ecmascript.org/doku.php?id=harmony:quasis

It would look something like this if we translated it into .NET:
``` vb
Dim x = c.Fmt`Mr {name} at {address}`
==>
Dim x = c.Fmt({"Mr ", " at ", ""}, name, address)
```
The idea here is that at compile-time the interpolated string gets broken up into pieces, and then at runtime it gets passed as an argument to the specified function or delegate. The advantage, as compared to the Python approach, is that there's less runtime overhead.



We had discussed something sort-of-related for C#. "There are many different APIs which work the same way: let's come up with a proposal for string-interpolation which works with all of them". It would expand an interpolated string into a *comma-separate sequence of expressions* :
``` vb
$"hello {a} in {b}"
==>
"hello {0} in {1}", a, b
```

This would enable it to be used for a wide variety of APIs, e.g.
``` vb
1: Console.WriteLine($"hello {a} in {b}")
2: Dim x = String.Format($"hello {a} in {b}")
3: Diagnostics.WriteLine($"hello {a} in {b}")
```
However it would prevent another idiom,
``` vb
4: Dim x = $"hello {a} in {b}"
```

The pain of losing [4] is severe. And the other cases above all boil down to a call to String.Format, so we're not losing much by saying that string-interpolation is always translated into a call to String.Format. Indeed, we think that most of the time people take parameters `(fmt as string, ParamArray args as Object())`, then they just pass it down straight to String.Format. True there are just a few cases where they don't... for instance, the Roslyn codebase has a function where it modifies the format and args before passing them to String.Format. The pain of losing these scenarios seemed less than the pain of losing [4].



================================================
FILE: meetings/2014/LDM-2014-04-16.md
================================================
# #Warning Disable

## REQUEST

Please add `#pragma` to VB so we can suppress warnings. This will be especially useful for Roslyn Diagnostics, where people will find many more warnings in their code.

## RESOLUTION

Add two new preprocessor directives:

``` vb
#Disable Warning 40008, BC42358, "BC42356"
#Enable Warning 40008, BC42358, "BC42356"
```

## ALTERNATIVE SYNTAXES CONSIDERED

``` vb
#pragma disable <id>
#pragma enable <id>

#Disable <id>  ' sounds like you're disabling code, not warnings
#Enable <id>

#Ignore <id>
#End Ignore  ' block structure is worse than toggles

#Disable Warning <id>
#Enable Warning <id>
```


## DISCUSSION

The tradition in VB and its rich history of quick-fixes is that you resolve warnings by FIXING YOUR CODE, e.g. by doing whatever the quickfix says, adding an explicit cast, adding a return statement, ...

Q. Do people really use #pragma much in C# today? Hard to say. With new Roslyn diagnostics, will *more* people start using #pragma in C# ? Will people write Roslyn diagnostics that have a much higher false-positive rate than existing rules, for people who wish to be more careful, safe in the knowledge that it's easy to suppress?

Q. Is there a downside to adding #pragma to VB for suppressing warnings? - no, not really

Q. Should we add a feature which suppresses the warning merely for the next line, rather than for the rest of the file? -- This isn't feasible in C# where lines don't really exist semantically. It is feasible for VB. Disadvantage: would confusing for LINQ, and not refactoring-safe. Advantage: if the lightbulb/quickfix appears for a warning, and when you chose the option to "suppress warning" then it only has to insert a single line to "suppress-warning-on-next-line", rther than having to insert `#ignore` before and `#restore` after. Conclusion: No we won't add this next-line-suppression feature.

Q. Is it good to disable/enable on a "block" basis like `#Ignore / #End Ignore` ? Or on a toggle basis like `#Disable Warning / #Enable Warning` ? Well, with blocks you can't do overlapping regions. And you can't easily disable warnings for an entire method but then re-enable them for a small critical region inside (even though that's a weird scenario). We believe overall that toggles are nicer. They have a lot of engineering, thought and experience behind them.

Q. For the `<id>`, should quotation marks be obligatory? - No. You can use any identifier or integer. It's only if the warning-id has spaces or other weird characters that you'd need quotation marks.

Q. Should we allow pure integers for the `<id>`, with the expectation that they disable intrinsic VB compiler warnings? All user-defined warnings (that come through Roslyn diagnostics) would have error codes that aren't pure integers. -- Yes, let's allow integers, just like C#, and just like the VB command-line. It will be a common case.

Q. Will the Roslyn diagnostics APIs allow people to define error codes that are just pure numbers, even though they'll be impossible to disable them? -- No real need. Diagnostic-authors will learn soon enough not to do this.

Q. Should we allow you to disable/enable command-separated lists of warnings in a single `#Disable Warning / #Enable Warning` directive? -- Yes.

Q. Preprocessor directives look ugly because they're always left-aligned. Can we make it so preprocessor directives can be indented? There's a uservoice request for it. -- Not discussed; left for another day.


# Back-compat break with interface implementations

We also discussed another topic to do with ambiguity between unrelated interfaces. Discussion is in this thread:
https://roslyn.codeplex.com/discussions/570975


# Update: VB LDM 2014.07.01

We re-visited #Disable Warning. The summary for VB is:

* Use the syntax `#Disable Warning id1, id2, ...`
* The warning IDs must parse as per the same rules of VB identifiers, and are case-insensitive. That rules out plain numbers `#Disable Warning 4008` (instead you must disable BC4008) and it rules out strings `#Disable Warning "Don't Use Capitals!"`. That means you can't disable warnings that have fancy error codes with punctuation and so on.
* This will guide users to the thought that they can right-click, find all references, and opens up the mental door to other refactorings/tooling
* We will restrict what identifiers can be produced at the production side too, when authoring analyzers
* We used to give BC2026 “that warning can’t be configured” when you try to nowarn or warnaserror on non-existent warnings (and also on certain named warnings e.g. 2026). But that wouldn’t work for diagnostic warning codes. So let’s no longer emit BC2026 ever. Instead, if you try to disable or enable a non-existing warning, simply do nothing.
* Stretch goal: the IDE could grey out all identifiers that have been disabled but are never actually generated by the code

C# will be mostly similar, but
* C# will support disabling warnings/errors by number as well as by identifier, and is case sensitive. It has to support disabling numbers for back-compat. If you disable warning number 4008, that's equivalent to disabling identifier CS4008.
* As with VB, we stop validating whether the warning code is a legal compiler warning ID (both on the command-line and inside #pragma) - CS1691 will no longer be reported for C#.
 
Things that fall out for free:
* No changes required to disallow Hexadecimal, Octal, Long etc. literals
* No need to worry about making BC2026 unerrorable
 
For the future:
* Update lightbulb suppression to always generate #pragma / #disable with identifiers. (Do we need to check that the id will be a legal identifier before spitting the code?)
* Fix /nowarn and /warnaserror command-line switches to support custom diagnostics
* Implement grey out for “unused” ids in #pragma, #Disable (plus corresponding code fix)
* Have some way for users to get from a reported warning id / from a warning id used in #pragma or #Disable to a description of the diagnostic
* Support for qualified identifiers that use dots (only if customers ask for it)



================================================
FILE: meetings/2014/LDM-2014-04-23.md
================================================
(this discussion happened in VB language design meeting, but it strongly concerns C# also).


# Better support for immutable data, with pattern-matching

## Request

Please make it easier for me to declare immutable data-types, and make it easier to code over them via pattern-matching. Easier immutable datatypes will make my code have fewer defects, and pattern-matching over immutable data (like in F#, Scala and other functional languages) will allow clean readable maintanable coding idioms.

For instance, I have a method and want to return 2-3 return values. Here's the ugly code I write now:
``` cs
// Ugly 1: use out params (but doesn't work with async)
void Lookup(out string name, out int x, out int y) {...}
...
Lookup(out name, out x, out y); Console.WriteLine(name);


// Ugly 2: use a tuple (but my consumer has a hard time knowing which element is what)
Tuple<string,int,int> Lookup() {...}
...
var r = Lookup(); Console.WriteLine(r.Item1);


// Ugly 3: declare a custom datatype
class LookupResult(string name, int x, int y)
{
   public string Name {get;} = name;
   public int X {get;} = x;
   public int Y {get;} = y;
}
LookupResult Lookup() {...}
...
var r = Lookup(); Console.WriteLine(r.Name);
```

What I'd like is to write all this much more simply:
``` cs
class LookupResult(string name, int x, int y);
LookupResult Lookup() {...}

var r = Lookup(); Console.WriteLine(r?.name);
```

Even better, I'd like to deconstruct the returned value using pattern-matching:
``` cs
if (Lookup() matches LookupResult(var name, var x, var y)) { ... }
```


## Background

We have been guided in our thoughts by the paper "Matching Objects with Patterns" by Emir, Odersky and Williams. There's a link to it on this Scala webpage: http://www.scala-lang.org/old/node/112

The Roslyn compiler currently has "primary constructors" in C#, and a form of "typecase" in VB:

``` cs
class C(int x, int y)
{
    public int X { get; set; } = x;
    public int Y { get; set; } = y;
}
```
``` vb
Function GetArea(shape As Shape) As Double
    Select Case shape
        Case r As Rect : Return r.X * r.Y
        Case c As Circle : Return Math.PI * c.Radius * c.Radius
    End Select
End Function

' Once we add Out expressions to VB, you can get more pattern-matchey
Function Eval(expr As Expr) As Integer
    Select Case expr
        Case e As PlusExpr When e.Matches(0, Out rhs)
            Return Eval(rhs)
        Case e As PlusExpr When e.Matches(Out rhs, 0)
            Return Eval(rhs)
        Case e As PlusExpr When e.Matches(Out lhs, Out rhs)
            Return Eval(lhs) + Eval(rhs)
        Case e As IntExpr
            Return e.Val
    End Select
End Function
```

**Question: how will the two features work together?** Will there be a "sweet spot" where their designs mesh together well, and mesh with additional features in future versions of the languages, to produce a nice pattern-matching design? Something as nice as what F# or Scala have?

**Urgent question: do we need to make changes to the CURRENT design of primary constructors and Select Case** so that we don't block off a future world of pattern-matching?


## PROPOSAL: Records, and Plain Old CLR Objects

Here is a coherent set of proposals that combine construction and deconstruction into one neat easily-written proposal, to support the scenario in the "Request".


Imagine something called a *"Record"*, a type with an ordered list of named data members. Not saying there should be a new kind of type called a "record type" alongside classes and structs... indeed it might be best not to have a new kind of type, since we might want record-like classes and structs.

**PROPOSAL 1:** a record can be defined using primary-constructor syntax, and it is syntactic sugar for an expanded form as follows...
``` cs
class Point(int X, int Y);

==>

class Point(int X, int Y)
{
   public int X { get; } = X;
   public int Y { get; } = Y;
}
```

The rule is: "When you write a record, it automatically generates properties for the *PRIMARY PROPERTIES*, unless you have provided those properties yourself". The term "Primary Properties" refers to the parameters in the primary-constructor syntax. Thus, if you didn't want it to auto-generate a property, you'd have to provide your own version of that property, as in the example below. (There's no way to say that you *don't* want the property with this syntax: if you don't want the property, then don't use the feature at all).
```cs
class Point(int X, int Y) { public int X => 15; }

==>

class Point(int X, int Y)
{
   public int X => 15;
   public int Y {get; set;} = Y;
}
```

**PROPOSAL 2:** Just as we've seen the compiler auto-generate properties if you failed to provide them yourself, it will also auto-generate a default implementation of Equals and GetHashCode if you fail to provide them yourself. This default implementation will do element-wise calls to Equals and GetHashCode on the primary properties.

(By default, Proposal 1 uses immutable properties, and so Equals/GetHashCode will terminate. It's bad practice to for GetHashCode to calculate based on mutable properties.)


**PROPOSAL 3:** In addition to auto-generated properties, Equals, GetHashCode, we also auto-generate a MAtch operator (unless one is provided by the user)...

``` cs
class Point(int X, int Y)
{
  public int X {get;} = X;
  public int Y {get;} = Y;
  public static bool operator Matches(Point self, out int X, out int Y) {X=self.X; Y=self.Y; return true;}
}
```

In addition to this, we introduce a new *MATCH* operator into the language:

``` cs
<expr> matches T(args)
```
Operational semantics:

1. Evaluate "var tmp1 = <expr>"
2. Look in type "T" for an overload of "Matches" whose 2nd...last parameters match the arguments
3. Evaluate "var tmp2 = tmp1 As TFirst" where TFirst is the type of the first parameter of that overload
4. If this is null, then the match operator returns false
5. Otherwise, the result invoke the Match operator, passing it (tmp2, args) as arguments.

You'd use the match operator like this:
``` cs
if (f() matches T(var name, var x, var y)) { ... }
```
Note that this would have different rules from the way out vars are currently conceived. These out be definitely assigned only if the "e matches T(args)" returns true. Incidentally, note that the T's Match operator is not necessarily invoked... e.g. if f() returns null, then it won't be called!



**PROPOSAL 4:** You could also treat the typename as a method, e.g.
``` cs
var p = Point(2,3);
==>
var p = new Point(2,3);
```
All this does is remove the need for the word "new" for these record types. It might seem pointless, but it unifies the way you write construction and deconstruction...
``` cs
var p = Point(2,3);
if (p matches Point(out x, out y)) { ... }
```


## Discussion

There were questions raised, heated discussions, and no agreed-upon answers.


Q. If we go with primary constructors as they're currently envisaged (where the primary parameters *don't* define fields, and instead only exist at construction-time), then will we still be able to support this vision of pattern-matching?

A. Not directly. But we could support this vision through a new modifier "record", e.g. `record class Point(int x, int y)`



Q. What is the difference between putting all this "record" stuff (auto-generated properties, Equals, GetHashCode, Match operator) into the existing primary constructor syntax, vs putting them in via a new modifier "record" ?

A1. It's a language-cleanliness problem. It would feel goofy for the primary constructor syntax to mean such different things depending on whether the "record" modifier is present.

A2. Case is different. The convention in C# will be to use lower-case for primary constructor parameters, since users will write out the properties manually and use upper-case for that. But with records, the convention will probably be to use uper-case for the primary properties.



Q. It feels wrong for primary-constructors to be so closely tied to immutable data and pattern-matching. Primary constructors have many other uses even when you don't want the rest, e.g. for coding visitor-patterns. Can we add all the features (primary constructors, Matches, Equals/GetHashCode, auto-generated properties) individually and orthogonally over time? And then use "concise declaration" (via whatever syntax) as the thread that ties everything together and delivers the smooth end-to-end use-case?

A. Maybe our goal should be to make a concise story for the desired use-case, rather than to add orthogonal features?


Q. Is it important that users can declare Match operators today, right from the first version of primary constructors? (granted, this would be pretty much useless on its own: the Match operator only becomes useful in conjunction with all the other features).



Q. How would these "record types" work with serialization? People commonly use Plain Old CLR Objects (POCO) when they want DataContract serialization. But there's no clear way with this proposal to attribute the individual properties.



Q. What's needed to ship in the first version of primary-constructors so as to allow this kind of evolution over time? Are there any conflicts with the current proposals (of primary-constructors and SelectCase) that would prevent such evolution?

A. Neal and Mads will meet, discuss this question, and take it to C# LDM next week.



================================================
FILE: meetings/2014/LDM-2014-07-01.md
================================================
# #Warning Disable

## REQUEST

Please add `#pragma` to VB so we can suppress warnings. This will be especially useful for Roslyn Diagnostics, where people will find many more warnings in their code.

## RESOLUTION

Add two new preprocessor directives:

``` vb
#Disable Warning 40008, BC42358, "BC42356"
#Enable Warning 40008, BC42358, "BC42356"
```

## ALTERNATIVE SYNTAXES CONSIDERED

``` vb
#pragma disable <id>
#pragma enable <id>

#Disable <id>  ' sounds like you're disabling code, not warnings
#Enable <id>

#Ignore <id>
#End Ignore  ' block structure is worse than toggles

#Disable Warning <id>
#Enable Warning <id>
```


## DISCUSSION

The tradition in VB and its rich history of quick-fixes is that you resolve warnings by FIXING YOUR CODE, e.g. by doing whatever the quickfix says, adding an explicit cast, adding a return statement, ...

Q. Do people really use #pragma much in C# today? Hard to say. With new Roslyn diagnostics, will *more* people start using #pragma in C# ? Will people write Roslyn diagnostics that have a much higher false-positive rate than existing rules, for people who wish to be more careful, safe in the knowledge that it's easy to suppress?

Q. Is there a downside to adding #pragma to VB for suppressing warnings? - no, not really

Q. Should we add a feature which suppresses the warning merely for the next line, rather than for the rest of the file? -- This isn't feasible in C# where lines don't really exist semantically. It is feasible for VB. Disadvantage: would confusing for LINQ, and not refactoring-safe. Advantage: if the lightbulb/quickfix appears for a warning, and when you chose the option to "suppress warning" then it only has to insert a single line to "suppress-warning-on-next-line", rther than having to insert `#ignore` before and `#restore` after. Conclusion: No we won't add this next-line-suppression feature.

Q. Is it good to disable/enable on a "block" basis like `#Ignore / #End Ignore` ? Or on a toggle basis like `#Disable Warning / #Enable Warning` ? Well, with blocks you can't do overlapping regions. And you can't easily disable warnings for an entire method but then re-enable them for a small critical region inside (even though that's a weird scenario). We believe overall that toggles are nicer. They have a lot of engineering, thought and experience behind them.

Q. For the `<id>`, should quotation marks be obligatory? - No. You can use any identifier or integer. It's only if the warning-id has spaces or other weird characters that you'd need quotation marks.

Q. Should we allow pure integers for the `<id>`, with the expectation that they disable intrinsic VB compiler warnings? All user-defined warnings (that come through Roslyn diagnostics) would have error codes that aren't pure integers. -- Yes, let's allow integers, just like C#, and just like the VB command-line. It will be a common case.

Q. Will the Roslyn diagnostics APIs allow people to define error codes that are just pure numbers, even though they'll be impossible to disable them? -- No real need. Diagnostic-authors will learn soon enough not to do this.

Q. Should we allow you to disable/enable command-separated lists of warnings in a single `#Disable Warning / #Enable Warning` directive? -- Yes.

Q. Preprocessor directives look ugly because they're always left-aligned. Can we make it so preprocessor directives can be indented? There's a uservoice request for it. -- Not discussed; left for another day.


# Back-compat break with interface implementations

We also discussed another topic to do with ambiguity between unrelated interfaces. Discussion is in this thread:
https://roslyn.codeplex.com/discussions/570975

# Update: VB LDM 2014.07.01

We re-visited #Disable Warning. The summary for VB is:

* Use the syntax `#Disable Warning id1, id2, ...`
* The warning IDs must parse as per the same rules of VB identifiers, and are case-insensitive. That rules out plain numbers `#Disable Warning 4008` (instead you must disable BC4008) and it rules out strings `#Disable Warning "Don't Use Capitals!"`. That means you can't disable warnings that have fancy error codes with punctuation and so on.
* This will guide users to the thought that they can right-click, find all references, and opens up the mental door to other refactorings/tooling
* We will restrict what identifiers can be produced at the production side too, when authoring analyzers
* We used to give BC2026 “that warning can’t be configured” when you try to nowarn or warnaserror on non-existent warnings (and also on certain named warnings e.g. 2026). But that wouldn’t work for diagnostic warning codes. So let’s no longer emit BC2026 ever. Instead, if you try to disable or enable a non-existing warning, simply do nothing.
* Stretch goal: the IDE could grey out all identifiers that have been disabled but are never actually generated by the code

C# will be mostly similar, but
* C# will support disabling warnings/errors by number as well as by identifier, and is case sensitive. It has to support disabling numbers for back-compat. If you disable warning number 4008, that's equivalent to disabling identifier CS4008.
* As with VB, we stop validating whether the warning code is a legal compiler warning ID (both on the command-line and inside #pragma) - CS1691 will no longer be reported for C#.
 
Things that fall out for free:
* No changes required to disallow Hexadecimal, Octal, Long etc. literals
* No need to worry about making BC2026 unerrorable
 
For the future:
* Update lightbulb suppression to always generate #pragma / #disable with identifiers. (Do we need to check that the id will be a legal identifier before spitting the code?)
* Fix /nowarn and /warnaserror command-line switches to support custom diagnostics
* Implement grey out for “unused” ids in #pragma, #Disable (plus corresponding code fix)
* Have some way for users to get from a reported warning id / from a warning id used in #pragma or #Disable to a description of the diagnostic
* Support for qualified identifiers that use dots (only if customers ask for it)
 



================================================
FILE: meetings/2014/LDM-2014-10-01.md
================================================
There were two agenda items...
1. Assignment to readonly autoprops in constructors (we fleshed out details)
2. A new compiler warning to prevent outsiders from implementing your interface? (no, leave this to analyzers)

# Assignment to readonly autoprops in constructors

```cs
public struct S {
   public int x {get;}
   public int y {get; set;}
   public Z z {get;}

   public S() {
      x = 15;
      y = 23;
      z.z1 = 1;
   }
}

public struct Z { int z1; }
```

_What are the rules under which assignments to autoprops are allowed in constructors?_

__Absolute__ We can't be more permissive in what we allow with readonly autoprops than we are with readonly fields, because this would break PEVerify. (Incidentally, PEVerify doesn't check definite assignment in the constructor of a struct; that's solely a C# language thing).

__Overall principle__ When reading/writing to an autoprop, do we go via the accessor (if there is one) or do we bypass it (if there is one) and access the underlying field directly?
_Option1:_ language semantics say the accessor is used, and codegen uses it.
_Option2:_ in an appropriate constructor, when there is a "final" autoprop (either non-virtual, or virtual in a sealed class), access to an autoprop _means_ an access to the underlying field. This meaning is used for definite assignment, and for codegen. Note that it is semantically visible whether we read from an underlying field vs through an accessor, e.g. in `int c { [CodeSecurity] get;}`
_Resolution: Option1_. Under Option2, if you set a breakpoint on the getter of an autoprop, gets of it would not hit the breakpoint if they were called in the constructor which is weird. Also it would be weird that making the class sealed or the autoprop non-virtual would have this subtle change. And things like Postsharper wouldn't be able to inject. All round Option2 is weird and Option1 is clean and expected.

__Definite Assignment__. Within an appropriate constructor, what exactly are the rules for definite assignment? Currently if you try to read a property before _all_ fields have been assigned then it says CS0188 'this' cannot be used before all fields are assignment, but reading a field is allowed so long as merely that field has been assigned. More precisely, within an appropriate constructor, for purposes of definite assignment analysis, when does access of the autoprop behave as if it's an access of the backing field?
_Option1_: never
_Option2_: Only in case of writes to readonly autoprops
_Option3_: In the case of writes to all autoprops
_Option4_: In the case of reads and writes to all autoprops
_Resolution: Option4_. This is the most helpful to developers. You might wonder what happens if it's a virtual autoprop and someone overrides getter or setter in derived types in such a way that would violate the definite assignment assumptions. But for structs there won't be derived types, and for classes the semantics say that all fields are assigned to default(.) so there's no difference.

__Piecewise initialization of structs__. In the code above, do we allow `z.z1 = 15` to assign to the _field_ of a readonly struct autoprop?
_Option1:_ Yes by threating access to "z" for purposes of definite assignment as an access of the underlying field.
_Option2: _ No because in `z.z1` the read of `z` happens via the accessor as per the principle above, and thus returns an rvalue, and hence assignment to `z.z1` can't work. Instead you will have to write `z = new Z(...)`.
_Resolution: Option2_. If we went with Option1, then readonly autoprops would end up being more expressive than settable autoprops which would be odd! Note that in VB you can still write `_z.z1 = 15` if you do want piecewise assignment.

__Virtual__. What should happen if the readonly autoprop is virtual, and its getter is overridden in a derived class?
_Resolution:_ All reads of the autoprop go via its accessor, as is already the case.

__Semantic model__. In the line `x = 15` what should the Roslyn semantic model APIs say for the symbol `x` ?
_Resolution:_ they refer to the property x. Not the backing field. (Under the hood of the compiler, during lowering, if in an appropriate constructor,  for write purposes, it is implicitly transformed into a reference to the backing field). More specifically, for access to an autoprop in the constructor,
1. It should _bind_ to the property, but the property should be treated as a readable+writable (for purposes of what's allowed) in the case of a readonly autoprop.
2. The definite assignment behavior should be as if directly accessing the backing field.
3. It should code gen to the property accessor (if one exists) or a field access (if not).

__Out/ref arguments in C#__. Can you pass a readonly autoprop as an out/ref argument in C#?
_Resolution: No_. For readonly autoprops passed as _ref_ arguments, that wouldn't obey the principle that access to the prop goes via its accessor. For passing readonly autoprops as _out_ arguments with the hope that it writes to the underlying field, that wouldn't obey the principle that we bind to the property rather than the backing field. For writeonly autoprops, they don't exist because they're not useful.

__Static readonly autoprops__ Should everything we've written also work for static readonly autoprops?
_Resolution: Yes._ Note there's currently a bug in the native compiler (fixed in Dev14) where the static constructor of a type G<T> is able to initialize static readonly fields in specializations of G e.g. `G<T>.x=15;`. The CLR does indeed maintain separate storage locations for each static readonly fields, so `G<int>.g` and `G<string>.g` are different variables. (The native compiler's bug where the static constructor of G could assign to all of them resulted in unverifiable code).

__VB rules in initializers as well as constructors__. VB initializers are allowed to refer to other members of a class, and VB initializers are all executed during construction time. Should everything we've said about behavior in C# constructors also apply to behavior in VB initializers?
_Resolution: Yes_.

__VB copyback for ByRef parameters__. In VB, when you pass an argument to a ByRef parameter, then either it passes it as an lvalue (if the argument was a local variable or field or similar) or it uses "copy-in to a temporary then invoke the method then copy-out from the temporary" (if the argument was a property), or it uses "copy-in to a temporary then invoke the method then ignore the output" (if the argument was an rvalue or a constant). What should happen when you pass a readonly autoprop to a ByRef parameter?
_Option1:_ Emit a compile-time error because copyback is mysterious and bites you in mysterious ways, and this new way is even more mysterious than what was there before.
_Option2:_ Within the constructor/initializers, copy-in by reading via the accessor, and copy-back by writing to the underlying field. Elsewhere, copy-in with no copy-out. Also, just as happens with readonly fields, emit an error if assignment to a readonly autoprop happens in a lambda in a constructor (see code example below)
_Resolution: Option2_. Exactly has happens today for readonly fields. Note incidentally that passing a readonly autoprop to a ByRef parameter will have one behavior in the constructor and initializers (it will do the copy-back), and will silently have different behavior elsewhere (it won't do any copy-back). This too is already the case with readonly fields. On a separate note, developers would like to have feedback in some cases (not constants or COM) where copyback in a ByRef argument isn't done. But that's not a question for the language design meeting.

__VB copyin for writeonly autoprops__. VB tentatively has writeonly autoprops for symmetry, even though they're not useful. What should happen when you pass a writeonly autoprop as a ByRef argument?
_Resolution: Yuck._ This is a stupid corner case. Notionally the correct thing is to read from the backing field, and write via the setter. But if it's easier to just remove support for writeonly autoprops, then do that.

```vb
Class C
    ReadOnly x As Integer = 15

    Public Sub New()
        f(x)
        Dim lamda = Sub()
                        f(x) ' error BC36602: 'ReadOnly' variable
                        ' cannot be the target of an assignment in a lambda expression
                        ' inside a constructor.
                    End Sub
    End Sub
    Shared Sub f(ByRef x As Integer)
        x = 23
    End Sub
End Class
```

We discussed a potential new error message in the compiler.

__Scenario:__ Roslyn ships with ISymbol interface. In a future release it wants to add additional members to the interface. But this will break anyone who implemented ISymbol in its current form. Therefore it would be good to have a way to prevent anyone _else_ from implementing ISymbol. That would allow us to add members without breaking people.

Is this scenario widespread? Presumably, but we don't have data and haven't heard asks for it. There are a number of workarounds today. Some workarounds provide solid code guarantees. Other workarounds provide "suggestions" or "encouragements" that might be enough for us to feel comfortable breaking people who took dependencies where we told them not to.

__Counter-scenario:__ Nevertheless, I want to _MOCK_ types. I want to construct a mock ISymbol myself maybe using MOQ, and pass it to my functions which take in an ISymbol, for testing purposes. I still want to be able to do this. (Note: MOQ will automatically update whenever we add new members to ISymbol, so users of it won't be broken).


__Workarounds__

1. Ignore the problem and just break people.
2. Like COM, solve it by adding new incremental interfaces ISymbol2 with the additional members. As Adam Speight notes below, you can make ISymbol2 inherit from ISymbol.
3. Instead of interfaces, use abstract classes with internal constructors. Or abstract classes but never add abstract methods to it; only virtual methods.
4. Write documentation for the interface, on MSDN or in XML Doc-Comments, that say "Internal class only; do not implement it". We see this for instance on ICorThreadpool.
5. Declare a method on the interface which has an internal type in its signature. The CLR allows this but the language doesn't so it would have to be authored in IL. Every type which implements the interface would have to provide an implementation of that method.
6. Write run-time checks at the public entry points of key Roslyn methods that take in an ISymbol, and throw if the object given was implemented in the wrong assembly.
7. Write a Roslyn analyzer which is deployed by the same Nuget package that contains the definition of ISymbol, and have this analyzer warn if you're trying to implement the interface. This analyzer could be part of Roslyn, or it could be an independent third-party analyzer used by many libraries.


__Proposal:__ Have the compiler recognize a new attribute. Given the following code
```cs
[System.Runtime.CompilerServices.InternalImplementationOnly] interface I<...> {...}
```
it should be a compile-time warning for a type to implement that interface, directly or indirectly, unless the class is in the same assembly as "I" or is in one of its InternalsVisibleTo friends. It will also be a compile-time error for an interface to inherit from the interface in the same way. Also, we might ask for the .NET Framework team to add this attribute in the same place as System.Runtime.CompilerServices.ExtensionAttribute, and CallerMemberNameAttribute. But doing it isn't necessary since the compiler will recognize any attribute with that exact fully-qualified name and the appropriate (empty) constructor. 

Note that this rule would not be cast-iron, since it won't have CLR enforcement. It would still be possible to bypass it by writing IL by hand, or by compiling with an older compiler. But we're not looking for cast-iron. We're just looking for discouragement strong enough to allow us to add members to ISymbol in the future. (In the case of ISymbol, it's very likely that people will be using Roslyn to compile code relating to ISymbol, but that doesn't apply to other libraries).


__Resolution:__ Workaround #7 is a better option than adding this proposal to the language.


================================================
FILE: meetings/2014/LDM-2014-10-08.md
================================================
# Back-compat break with interface implementations

## High-level summary

* _On the declaration side,_ C# users always used to be able to declare overloads of ambiguous interface methods. We are adding this ability also to VB for VS2015.
* _On the consumption side,_ C# language is more "hide-by-name" while VB supports both "hide-by-name" and "hide-by-sig".
* In such cases VB used to try to emulate the C# behavior when meta-importing such declarations. Now it will follow the more VB behavior.
* _This will cause some small breaking changes_. The breaking cases are limited to where...
* (1) Library code was authored in C#
* (2) In that library an interface ID inherits from two others IA,IB and declares a more general overload of a method in each of them
* (3) VB consumers of that library used to pick the more general overload (copying C#'s hide-by-name behavior). But now they will pick the more specific overload (using VB's hide-by-sig behavior)
* (4) If there were ambiguous specific overloads then it will be a break for VB consumers of the C# library.


## Background

``` vb
Interface A
  Sub M(x As Integer)
End Interface

Interface B
  Sub M(x As String)
End Interface

Interface C : Inherits A,B
  Overloads Sub M(x As Char)
End Interface

Interface D : Inherits A, B
End Interface
```

DECLARATION: Declaration C" had been illegal in VB up to VS2013; you could only declare M in C with 'Shadows, or meta-import it from C#. But VB Roslyn made a change... it now lets you *declare* such things.

CONSUMPTION: We never came up with a policy around CONSUMPTION of such things.

* VS2013: In the type "C" if you try to access "M", the compiler doesn't see "M" from A and B. It only sees it from C. Note: you can meta-import C, but can't declare it.
* VS2013: In the type "D" if you try to access "M", the compiler gives a name-lookup ambiguity error prior to even attempting overload resolution.
* Roslyn as of May 2014: In both "C" and "D" if you try to access "M", the compiler gives name-lookup ambiguity error prior to even considering overload resolution.

## Request

We'd like to be able to invoke "M" in both "C" and "D". But we'd also like to preserve backwards compatibility. It's a conundrum.


Note that there's a similar issue with Modules:
``` vb
Module Module1
  Function Sin(d As Double) As Double

Modle Module2
  Function Sin(s As Single) As Single

' this callsite is in a place that imports both modules' containing namespaces
Dim x = Sin(1.0) ' VB currently makes this an ambiguity. 
```
VB makes this invocation of Sin an ambiguity. But when you do the equivalent in C# using "static using", it gathers together all candidates from all usings, and then performs overload resolution on them. This case seems very minor. Not worth worrying about.

## VB LDM 2014.04.16

PROPOSAL1: revert change that enabled declaration in C. (but doesn't help consumption of meta-imported C, nor consumption of D).

PROPOSAL2: silently treat it as shadowing at the callsite, consistent with native compiler. (but doesn't help consumption of D).

_PROPOSAL3: Allow at lookup, i.e. merge them all, and leave it to overload resolution. (This is the proposal that we picked)._ This is a small breaking change. It will break code which used to meta-import "C", and invoked "M" in it, and always got the version of "M" in "C". Now with this change, it might get the version of "M" from "A" or "B". We think this is a minor breaking change, because (1) it only applied to meta-import situations, (2) it will now behave as the author intended. Note that this requires a change to VB spec 4.3.2.

PROPOSAL4: combination of 1 and 2, i.e. completely duplicate behavior of native compiler.

## VB LDM 2014.10.08

We revisited the previous conclusion in the light of implementation. The related bug numbers are:
https://roslyn.codeplex.com/workitem/34
Internal vstfdevdiv bug 527642

The issue is that the C# language has hide-by-name lookup rules, and because of this it doesn't matter whether it meta-exports its signatures as "hide-by-name" or "hide-by-sig"; that difference is ignored. It happens to export them as "hide-by-sig".


Here's a representative example of the kind of breaks we'll now get under PROPOSAL3. There is a library that was authored in C#:
```cs
interface IA {void m(int x);}
interface IB {void m(int x);}
interface ID : IA,IB {void m(object x);}
```
C# users of the library are able to use it fine:
```cs
ID d = null;
d.m(1);  // picks the "object" overload
```
However VB users of the library will now experience a break
```vb
Dim x As ID = Nothing
x.m(1) ' VS2013 used to pick 'Object' but under Proposal3 will now give an ambiguity error
x.m(CObj(1)) ' this is the workaround to use in this case
```

The breaking cases are limited to where C# had ambiguous methods in unrelated interfaces, and overrode them with a more general overload in the derived interface ID. We imagine this breaking case will be uncommon.



There's a more common related scenario which WILL CONTINUE to work just fine. Let's walk through it:
```cs
interface IJson {string GetName();}
interface IComponent {string GetName();}
interface IPatient : IJson,IComponent {}
```
I am a C# author. I am taking in two libraries that provide IJson and IComponent. They are unrelated by they happen to have a method which shares a signature and has more or less the same behavior. I write it as above. However, within my C# use of my library, I discover a problem straight away: `IPatient y = ...; y.GetName();` This code will give a compile-time ambiguity error because it doesn't know which unrelated overload of GetName to use. So I fix up my C# library as follows, to silence up the compiler:
```cs
interface IPatient : IJson,IComponent {new string GetName();}
```
With this change, the same C# code `IPatient y = ...; y.GetName();` will work just fine. The reason it works in C# is because C# language uses hide-by-name lookup rules, and finds IPatient.GetName, and is happy with that.
```vb
Dim y As IPatient = Nothing
y.GetName() ' correctly picks IPatient.GetName
```
Fortunately the VB consumers of the library will also work great. In VS2013 it worked because VB faked up hide-by-name semantics on meta-import and so got the derived class. Under Proposal3 it will work because VB honestly uses hide-by-sig semantics and in this case (unlike ID.m(object) above) the hide-by-sig semantics pick the correct method.


How did VS2013 VB fake up "hide-by-name" semantics? Well, upon meta-import, it did a "shadowing trick": if it encountered an interface like C, it knew that such an interface could not have been declared by VB, and therefore it must have been declared in C#, and C# language had hide-by-name (shadowing) semantics, and so VB ignored the "hide-by-sig" attribute on the metadata and imported it as hide-by-name.


We went back on our resolution. We decided to forbid declaration of interfaces like "C". By forbidding it, we open the door to pulling the same "shadowing" trick as VS2013 did on meta-import. Actually the Roslyn compilers have a cleaner design and can't pull the trick on meta-import; however they can pull it on name lookup.

In other words, we resolved to go for PROPOSAL4.

## VB LDM 2014.10.08

Gosh this is difficult. In trying to replicate the behavior of VS2013, Aleksey discovered some pretty weird bugs in the way VS2013 applied its shadowing heuristics.

```vb
' BUG NUMBER 1 IN VS2013

Interface IA(Of T)
    Sub M1(x As T)
End Interface

Interface IB
    Inherits IA(Of Integer), IA(Of Short)
    Overloads Sub M1(x As String) ' VS2013 doesn't report an error
End Interface

Interface IC1
    Sub M1(x As Integer)
End Interface

Interface IC2
    Sub M1(x As Short)
End Interface

Interface ID
    Inherits IC1, IC2
    Overloads Sub M1(x As String) ' VS2013 reports error BC31410 "Overloading methods declared in multiple base interfaces is not valid"
End Interface

Module Module2
    Sub Test(x As IB)
        x.M1(1) ' VS2013 reports error BC30685: 'M1' is ambiguous across the inherited interfaces 'IA(Of Integer)' and 'IA(Of Short)'
    End Sub

    Sub Test(x As ID)
        x.M1(1) 'ID
    End Sub
End Module  
```
What's strange in this bug number 1 is that you expect the declaration error BC31410 to be reported in both cases IB and ID. However VS2013 only reports a declaration error for ID. Instead it reports a consumption error for IB.

```vb
' BUG NUMBER 2 IN VS2013

Interface IA
    Sub M1()
End Interface

Interface IB
    Inherits IA
    Overloads Sub M1(x As Integer)
End Interface

Interface IC1
    Inherits IA, IB
    Overloads Sub M1(x As String) ' VS2013 reports error BC31410 "Overloading methods declared in multiple base interfaces is not valid."
End Interface

Interface IC2
    Inherits IB, IA
    Overloads Sub M1(x As String) ' VS2013 reports error BC31410 "Overloading methods declared in multiple base interfaces is not valid."
End Interface

Interface IC3
    Inherits IB
    Overloads Sub M1(x As String) ' VS2013 reports no error
End Interface
```
What's strange about this is that interfaces IC1, IC2 and IC3 are semantically equivalent: whether or not you explicitly declare that you inherit from IA is irrelevant, since it's implied. So the compiler shouldn't be reporting a declaration error in IC1/IC2, just as it doesn't report a declaration error in IC3.

This means that we have to refine our idea of Proposal 4:

PROPOSAL4a: disallow declaration C by reimplementing all the weird quirks of VS2013, and use implicit shadowing upon name lookup. We rejected this as too difficult: Roslyn has very different code paths, so there's a high risk that we'd get different behavior from VS2013.

PROPOSAL4b: disallow declaration C in a clean way without any of the weird quirks of VS2013.

The question is: out of Proposal3 and Proposal4b, which will be the most painful break?

Proposal4b will hurt people who declare things that used to be okay under the old quirky rules but are no longer okay. We haven't discovered many cases yet.

Proposal3, as we said before, will hurt people who invoked x.m(1) in the case identified above. Their workaround is to change the callsite with an explicit cast. There is precedent for this: the overload resolution rules between VB and C# are different, and VB people have to put explicit casts in other callsites.

COM is an interesting case where you generally have IFoo1 and IFoo2 where IFoo2 duplicates (doesn't inherit) the methods of IFoo but also adds a few others. However we don't see this as a problem. It's very nontypical to declare a third interface IBar which inherits both IFoo1 and IFoo2 in COM scenarios.

In the light of this new evidence, we prefer Proposal3. It will be a better cleaner future for the VB language to declare things like this. And it puts the pain on callsites to ambiguous interfaces, rather than producers of them; it's generally easier to fix callsites. As for the breaking changes, some of them will be silently picking more appropriate overloads, which is generally the right thing to do and more intuitive. Only in rare and contrived cases (where C# author overrides two ambiguous specific methods with a less specific methods) will there be a compile-time failure.

Note that the VS2015 CTP4 (already shipped by the time we had this LDM) lets you declare things like "C" but there's not even any overload resolution at the callsite. That will give us lots of opportunity to hear from customers whether they're suffering from the fact that we no longer do implicit shadowing. If we hear pain, then we can re-visit.



================================================
FILE: meetings/2014/LDM-2014-10-15.md
================================================
We've been reconsidering some details about the "nameof" operator. This was prompted by a few questions:

* _Why can't I write "nameof(this.p)"? My convention is to always put 'this' in front of my fields and properties._
* _Why does the IDE throw an exception when I rename symbols that appear in nameof expressions? Why is it so hard to write analyzers that work correctly in the face of nameof?_

A revised spec is below. The chief difference from the original spec ([part1](https://roslyn.codeplex.com/discussions/552376) and [part2](https://roslyn.codeplex.com/discussions/552377)) is that now the argument of nameof(.) is just an expression, like any other expression in the language (in CTP4 it had been an unusual hybrid similar in some ways to the argument of typeof). The common cases of nameof will still be written the same as what's in CTP4, but some edge cases will be different.

There's one chief open design question remaining, detailed below.

Please let us know what you think!


# nameof operator: revised spec

The nameof(.) operator takes one expression argument (note that in C#, types are expressions). There are two principles: in essence, (1) the expression must "have a name", and (2) it must resolve to one single symbol.

## Bread and butter cases
```cs
// Validate parameters 
void f(string s) {
    if (s == null) throw new ArgumentNullException(nameof(s));
}
```

```cs
// MVC Action links
<%= Html.ActionLink("Sign up",
             nameof(UserController),
             nameof(default(UserController).SignUp()))
%>
```

```cs
// INotifyPropertyChanged
int p {
    get { return this._p; }
    set { this._p = value; PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.p)); }
}
```

```cs
// XAML dependency property
public static DependencyProperty AgeProperty = DependencyProperty.Register(nameof(default(C).Age), typeof(int), typeof(C));
```

```cs
// Logging
void f(int i) {
    Log(nameof(f(i)), "method entry");
}
```

```cs
// Attributes
[DebuggerDisplay("={" + nameof(default(C).getString()) + "()}")]
class C {
    string getString() { ... }
}
```

_I'm sorry. Markdown keeps turning my plus symbols into ampersand hash 43. I don't know how to stop it._

I call out the last two cases. If we decided to break principle (2), then we could allow method-groups, and hence omit the argument lists for these two cases. We could reasonably choose either to keep principle (2) or to break it, and there are pros and cons to both sides. More details in the post below.

# Implementation
```cs
class NameOfExpressionSyntax : ExpressionSyntax { readonly ExpressionSyntax argument; }
```
For source code that compiles without errors, semanticModel.GetSymbolInfo(argument) will return a single symbol. For erroneous code it might also return 0 or many candidates.

(Under the alternative option, where principle (2) is violated, then we would make GetSymbolInfo return no single preferred symbol, and instead always return a candidate list. Analyzers would now have to deal with this case for successful user code as well as for erroneous user code.)

# C# Syntax
```
expression: … | nameof-expression

nameof-expression:
    nameof ( nameof-expression-argument )

nameof-expression-argument:
    simple-name                  x
    member-access                e.x, e.x<int>, e?.x,
                                 int.TryParse, a::b.c
    invocation-expression        e(args)
    base-access-named            base.x
```

It is helpful to list what is not allowed as the nameof argument. In general, nameof accepts expressions that have names (including type expressions that have names). All other arguments produce compile-time error "This expression does not have a name". Here are the expressions that are not allowed:
```
    assignment                   x += 15
    query-expression             from y in z select y
    lambda-expression            () => e
    conditional-expression       a ? b : c
    null-coalescing-expression   a?? b
    binary-expression            ||, &&, |, ^, &, ==, !=,
                                 <, >, <=, >=, is, as, <<,
                                 >>, +, -, *, /, %
    prefix-expression            +, -, !, ~, ++, --,
                                 (cast)e, *, &
    postfix-expression           ++, --
    array-creation-expression    new C[…]
    object-creation-expression   new C(…)
    delegate-creation-expression new Action(…)
    anonymous-object-creation-expression new {…}
    typeof-expression            typeof(int)
    checked-expression           checked(…)
    unchecked-expression         unchecked(…)
    default-value-expression     default(…)
    anonymous-method-expression  delegate {…}
    pointer-member-access        e->x
    sizeof-expression            sizeof(int)
    literal                      "hello", 15
    parenthesized-expression     (x)
    element-access               e[i]
    this-access                  this
    base-access-indexed          base[i]
    await-expression             await e
    nameof-expression            nameof(e)
    vb-dictionary-lookup         e!foo 
```

Note that there are some types which are not counted as expressions by the C# grammar. These are not allowed as nameof arguments (since the nameof syntax only allows expressions for its argument). It is a pleasant coincidence that none of these types even have names, so they wouldn't be useful as a nameof argument anyway. Even keywords like "int" and "bool" are not names; they are keywords. There's no need to spell out that the following things are not valid expressions, since that's already said by the language syntax, but I'm going to spell it out anyway. 
```
    predefined-type              int, bool, float, object,
                                 dynamic, string, void
    nullable-type                Customer?
    array-type                   Customer[,]
    pointer-type                 Buffer*, void* 
```           

# Semantics

The nameof expression is a constant. In all cases, nameof(…) is evaluated at compile-time to produce a string. Its argument is not evaluated at runtime, and is considered unreachable code (however it does not emit an "unreachable code" warning).

_Name lookup._ The same rules of "simple name lookup" and "member access" apply to nameof arguments as they do to the rest of the language.

_Accessibility._ The same rules of accessibility apply to nameof arguments as they do to all other expressions.

_Error in binding._ The same rules of binding apply to nameof as to all other expressions. If binding to the argument/type would result in an error, e.g. to obsolete methods, then that is still an error for purposes of nameof.

_Definite assignment._ The same rules of definite assignment apply to nameof arguments as they do to all other unreachable expressions.

_VB invocation / indexing._ In VB, e(…) might be either an method invocation, a delegate invocation, an array indexing, a property access, a default property access, or an invocation of a parameterless function "e" followed by indexing. Which one of these it is, is determined by symbol resolution. After symbol resolution, as with C#, only method invocations are allowed as nameof arguments.

_Result of the nameof operator._ This depends on the form of the nameof argument…

__nameof(simple-name)__, of the form I<A1…AK>
__nameof(member-access)__, of the form E.I<A1…AK>
__nameof(base-access-named)__, of the form base.I<A1…AK>

These cases are all resolved using the rules for simple name lookup $7.6.2 or member access $7.6.4. If they succeed in binding, they must bind to one of:

* A method-group. This produces an error "To specify the name of a method, you must provide its arguments".
* A variable, value, parameter, constant, enumeration-member, property-access, field, event, type-parameter, namespace or type. In this case the result of the nameof operator is simply "I", which is generally the name of the symbol that the argument bound to. There are some caveats…

If "I" identified an alias e.g. "using I = X.Y.Z; nameof(I)", then the result of nameof is still "I", even though the expression bound to the type X.Y.Z.

Also "I" undergoes the standard identifier transformations prior to being returned from nameof. In C# these are detailed in $2.4.2 of the C# spec: first any leading @ is removed, then Unicode escape sequences are transformed, and then any formatting-characters are removed. This of course still happens at compile-time. In VB, any surrounding [] is removed.

Also in VB the result has the capitalization that was used in the argument. This might be different from the capitalization of the symbol that the argument bound to.


__nameof(invocation-expression)__, of the form F(args)

The invocation expression must be either a method-invocation because F was a method-group, or a delegate-invocation because F was a value of delegate type.

* If a method-invocation, then F must have had the form E.I<A1…AK> or I<A1…AK> or base.I<A1…AK> from other rules in the language, and must have bound to a method-group. F(args) must bind to a unique method by the normal rules of overload resolution. The result of the nameof operator is simply I, subject to the same transformations as above.

* If a delegate-invocation, it is a compile-time error "This expression does not have a name."

# Examples

```cs
void f(int x) {
   nameof(x)
}
// result "x": Parameter (simple name lookup)
```

```cs
int x=2; nameof(x)
// result "x": Local (simple name lookup)
```

```cs
const x=2; nameof(x)
// result "x": Constant (simple name lookup)
```

```cs
class C {
   int x;
   … nameof(x)
}
// result "x": Field (simple name lookup)
```

```cs
class C {
   void f() {}
   … nameof(f)
}
// result: error "To specify the name of a method, you must provide its arguments": Method-group (simple name lookup)
```

```cs
class C {
   void f() {}
   … nameof(f())
}
// result "f": Invocation-expression that resolves successfully
```

```cs
class C {
   void f(){}
   void f(int i){}
   … nameof(f(1))
}
// result "f": Invocation-expression that resolves successfully
```

```cs
Customer c; … nameof(c.Age)
// result "Age": Field (member access)
```

```cs
Customer c; … nameof(c._Age)
// result error "_Age is inaccessible due to its protection level: Private field (member access)
```

```cs
nameof(Tuple.Create)
// result error "To specify the name of a method, you must provide its arguments": Method-group (member access)
```

```cs
nameof(Tuple.Create(1,2))
// result "Create": Invocation-expression that resolves successfully, including with generic type inference
```

```cs
nameof(System.Exception)
// result "Exception": Type (member access)
```

```cs
nameof(List<int>)
// result "List": Type (simple name lookup)
```

```cs
nameof(List<>)
// result error "type expected": Unbound types are not valid expressions
```

```cs
nameof(List<int>.Length)
// result error "List<int> doesn't contain a member Length": Member access, is unable to find an static member named Length on this type
```

```cs
nameof(default(List<int>))
// result error "This expression doesn't have a name": Not one of the allowed forms of nameof
```

```cs
nameof(default(List<int>).Length)
// result "Length": Property access (member access)
```

```cs
nameof(int)
// result error "Invalid expression term 'int'": Not an expression. Note that 'int' is a keyword, not a name.
```

```cs
nameof(System.Int32)
// result "Int32": Type (member access)
```

```cs
using foo=System.Int32;
nameof(foo) 
// result "foo": Alias (simple name lookup)
```

```cs
nameof(System.Globalization)
// result "Globalization": Namespace (member access)
```

```cs
nameof(x[2])
nameof("hello")
nameof(1+2)
// error "This expression does not have a name": Not one of the allowed forms of nameof
```

```vb
NameOf(a!Foo)
' error "This expression does not have a name": VB-specific. Not one of the allowed forms of NameOf.
```

```vb
NameOf(dict("Foo"))
' error "This expression does not have a name": VB-specific. This is a default property access, which is not one of the allowed forms.
```

```vb
NameOf(dict.Item("Foo"))
' error "This expression does not have a name": VB-specific. This is an index of a property, which is not one of the allowed forms.
```

```vb
NameOf(arr(2))
' error "This expression does not have a name": VB-specific. This is an array element index, which is not one of the allowed forms.
```

```vb
Dim x = Nothing
NameOf(x.ToString(2))
' error "This expression does not have a name": VB-specific. This resolves to .ToString()(2), which is not one of the allowed forms.
```

```vb
Dim o = Nothing
Dim b As Func(Of Object, Object, Boolean) = AddressOf o.Equals
' result "Equals". Warning "Access of static member of instance; instance will not be evaluated": VB-specific. VB allows access to static members off instances, but emits a warning.
```

```cs
[Foo(nameof(C))]
class C {}
// result "C": Nameof works fine in attributes, using the normal name lookup rules.
```

```cs
[Foo(nameof(T))]
class C<T> {}
// result error "T is not defined": A class type parameter is not in scope in an attribute on that class
```

```cs
[Foo(nameof(T))] void f<T> { }
// result error "T not defined": A method type parameter is not in scope in an attribute on that method
```

```cs
void f([Attr(nameof(x))] int x) {}
// result error "x is not defined": A parameter is not in scope in an attribute on that parameter, or any parameter in the method
```

```vb
Function f()
  nameof(f)
End Function
' result "f": VB-specific. This is resolved as an expression which binds to the implicit function return variable
```

```vb
NameOf(New)
' result error "this expression does not have a name": VB-specific. Not one of the allowed forms of nameof. Note that New is not a name; it is a keyword used for construction.
```

```vb
Class C
  Dim x As Integer
  Dim s As String = NameOf(x)
End Class
' result "x": VB-specific. Field access (simple name lookup)
```

```cs
class C {
   int x;
   string s = nameof(x);
}
// result error "cannot reference non-static field": C#-specific. Normal  name referencing error
```

```cs
class C {
   int x;
   string s = nameof(C.x);
}
// error "C doesn't contain a member named x": Normal member access rules, with static/instance mismatch
```

```cs
class C {
   int x;
   string s = nameof(default(C).x);
}
// result "x": This is the C# idiom for getting the name of an instance variable.
```

```cs
struct S {
   int x;
   S() {var s = nameof(x); …}
}
// result "x": Field access (simple name lookup). Nameof argument is considered unreachable, and so this doesn't violate definite assignment.
```

```cs
int x; … nameof(x); x=1;
// result "x": Local access (simple name lookup). Nameof argument is unreachable, and so this doesn't violate definite assignment.
```

```cs
int x; nameof(f(ref x));
// result "f": Invocation expression. Nameof argument is unreachable and so can be used as a ref argument prior to definite assignment.
```

```cs
var @int=5; nameof(@int)
// result "int": C#-specific. Local (simple name lookup). The leading @ is removed.
```

```cs
nameof(m\u200c\u0065)
// result "me": C#-specific. The Unicode escapes are first resolved, and the formatting character \u200c is removed.
```

```vb
Dim [Sub]=5 : NameOf([int])
' result "int": VB-specific. Local (simple name lookup). The surrounding [.] is removed.
```

# Chief Open Design Question

Principle (2) says the nameof argument must resolve to one single symbol. Is this a principle worth sticking to? It could go either way. Let's examine the issues, starting with some concrete examples...

```cs
// Logging
void f(int i) {
    Log(nameof(f(i)), "method entry");
}
```

```cs
// Attributes
[DebuggerDisplay("={" + nameof(default(C).getString()) + "()}")]
class C {
    string getString() { ... }
}
```

If we decided to break principle (2), then we could allow method-groups, and hence omit the argument lists for these two examples. We could reasonably choose either to keep principle (2) or to break it, and there are pros and cons to both sides.

## Comparison: code
```cs
void M(int i) {
}
void M(string s) { 
    var x = nameof(M);    // error with principle (2); okay without it
    var x = nameof(M(s)); // okay
    var x = nameof(M(s)); // okay
}
```

## Comparison: logging code
```cs
// Logging
void f(int i) {
    Log(nameof(f(i)), "method entry"); // with principle (2) you have to supply arguments
    Log(nameof(f), "method entry"); // without it, you can omit arguments
}
```

## Comparison: attributes
```cs
// Attributes
[DebuggerDisplay(nameof(default(C).getString())] // with principle (2) you supply parentheses
[DebuggerDisplay(nameof(default(C).getString)] // without it, you can omit them
class C {
    string getString() { ... }
}
```

## Comparison: IDE behavior

With principle (2), IDE refactoring behavior will be understandable, e.g. if you rename M then you can anticipate how it will be renamed inside nameof arguments. It's easy to understand+predict what HighlightAllReferences and GoToDef and FindAllReferences will do.

Without principle (2), IDE refactoring becomes less predictable. What will happen if you rename-refactor the second "M" in _Comparison:Code_? Would it rename the first one as well, and also the nameof argument? It's also not clear how CodeLens and other tools would count nameof(M). Would it count it as a reference to all overloads of M? There are probably similar issues all over the IDE.

## Comparison: typing burden

With principle (2), you always need to specify which overload of M you're referring to, even though they have the same name. (In mitigation, it's often quite easy to specify which overload. As in the logging case, you typically do it within the method you wish to name, and so you typically have parameters to hand).

## Comparison: conceptual burden

Without principle (2), nameof will be the _only_ part of the language where "method-group" is a valid expression. Everywhere else it must be resolved to a single method.

## Comparison: analyzer burden

With principle (2), it will be easier to write analyzers. They won't blow up in untested corner cases involving nameof.



================================================
FILE: meetings/2014/LDM-2014-10-23.md
================================================
# nameof operator: spec v5
The nameof(.) operator has the form nameof(expression). The expression must have a name, and may refer to either a single symbol or a method-group or a property-group. Depending on what the argument refers to, it can include static, instance and extension members.

This is v5 of the spec for the "nameof" operator. [[v1](https://roslyn.codeplex.com/discussions/552376), [v2](https://roslyn.codeplex.com/discussions/552377), [v3](https://roslyn.codeplex.com/discussions/570115), [v4](https://roslyn.codeplex.com/discussions/570364)]. The key decisions and rationales are summarized below. _Please let us know what you think!_


# Rationale

Question: why do we keep going back-and-forth on this feature?

Answer: I think we're converging on a design. It's how you do language design! (1) make a proposal, (2) _spec it out_ to flush out corner cases and make sure you've understood all implications, (3) _implement the spec_ to flush out more corner cases, (4) try it in practice, (5) if what you hear or learn at any stage raises concerns, goto 1.

* _v1/2 had the problem "Why can't I write nameof(this.p)? and why is it so hard to write analyzers?"_
* _v3 had the problem "Why can't I write nameof(MyClass1.p)? and why is it so hard to name method-groups?"_
* _v4 had the problem "What name should be returned for types? and how exactly does it relate to member lookup?"_

This particular "nameof v5" proposal came from a combined VB + C# LDM on 2014.10.22. We went through the key decisions:

1. __Allow to dot an instance member off a type? Yes.__ Settled on the answer "yes", based on the evidence that v1/v2 had it and it worked nicely, and v3 lacked it and ended up with unacceptably ugly "default(T)" constructions.
2. __Allow to dot instance members off an instance? Yes.__ Settled on the answer "yes", based on the evidence that v1/v2 lacked it and it didn't work well enough when we used the CTP, primarily for the case "this.p"
3. __Allow to name method-groups? Yes.__ Settled on the answer "yes", based on the evidence that v1/v2 had it and it worked nicely, and v3 lacked it and ended up with unacceptably ugly constructions to select which method overload.
4. __Allow to unambiguously select a single overload? No.__ Settled on the answer "no" based on the evidence that v3 let you do this but it looked too confusing. I know people want it, and it would be a stepping stone to infoof, but at LDM we rejected these (good) reasons as not worth the pain. The pain is that the expressions look like they'll be executed, and it's unclear whether you're getting the nameof the method or the nameof the result of the invocation, and they're cumbersome to write.
5. __Allow to use nameof(other-nonexpression-types)? No.__ Settled on the answer "only nameof(expression)". I know people want other non-expression arguments, and v1/v2 had them, and it would be more elegant to just write nameof(List<>.Length) rather than having to specify a concrete type argument. But at LDM we rejected these (good) reasons as not worth the pain. The pain is that the language rules for member access in expressions are too different from those for member access in the argument to nameof(.), and indeed member access for StrongBox<>.Value.Length doesn't really exist. The effort to unify the two concepts of member access would be way disproportionate to the value of nameof. This principle, of sticking to existing language concepts, also explains why v5 uses the standard language notions of "member lookup", and hence you can't do nameof(x.y) to refer to both a method and a type of name "y" at the same time.
6. __Use source names or metadata names? Source.__ Settled on source names, based on the evidence... v1/v2/v3 were source names because that's how we started; then we heard feedback that people were interested in metadata names and v4 explored metadata names. But I think the experiment was a failure: it ended up looking like _disallowing_ nameof on types was better than picking metadata names. At LDM, after heated debate, we settled on source names. For instance `using foo=X.Y.Z; nameof(foo)` will return "foo". Also `string f<T>() => nameof(T)` will return "T". There are pros and cons to this decision. In its favor, it keeps the rules of nameof very simple and predictable. In the case of nameof(member), it would be a hindrance in most (not all) bread-and-butter cases to give a fully qualified member name. Also it's convention that "System.Type.Name" refers to an unqualified name. Therefore also nameof(type) should be unqualified. If ever you want a fully-qualified type name you can use typeof(). If you want to use nameof on a type but also get generic type parameters or arguments then you can construct them yourself, e.g. nameof(List<int>) + "`2". Also the languages have no current notion of metadata name, and metadata name can change with obfuscation.
7. __Allow arbitrary expressions or just a subset?__ We want to try out the proposal "just a subset" because we're uneasy with full expressions. That's what v5 does. We haven't previously explored this avenue, and it deserves a try.
8. __Allow generic type arguments?__ Presumably 'yes' when naming a type since that's how expression binding already works. And presumably 'no' when naming a method-group since type arguments are used/inferred during overload resolution, and it would be confusing to also have to deal with that in nameof. [this item 8 was added after the initial v5 spec]


I should say, we're not looking for unanimous consensus -- neither amongst the language design team nor amongst the codeplex OSS community! We hear and respect that some people would like something closer to infoof, or would make different tradeoffs, or have different use-cases. On the language design team we're stewards of VB/C#: we have a responsibility to listen to and understand _every opinion_, and then use our own judgment to weigh up the tradeoffs and use-cases. I'm glad we get to do language design in the open like this. We've all been reading the comments on codeplex and elsewhere, our opinions have been swayed, we've learned about new scenarios and issues, and we'll end up with a better language design thanks to the transparency and openness. I'm actually posting these notes on codeplex as my staging ground for sharing them with the rest of the team, so the codeplex audience really does see everything "in the raw".

# C# Syntax
```
expression: ... | nameof-expression

name-of-expression:
    nameof ( expression )
```
In addition to the syntax indicated by the grammar, there are some additional syntactic constraints: (1) the argument expression can only be made up out of simple-name, member-access, base-access, or "this", and (2) cannot be simply "this" or "base" on its own. These constraints ensure that the argument looks like it has a name, and doesn't look like it will be evaluated or have side effects. I found it easier to write the constraints in prose than in the grammar.

[clarification update] Note that member-access has three forms, `E.I<A1...AK>` and `predefined-type.I<A1...AK>` and `qualified-alias-member.I`. All three forms are allowed, although the first case `E` must only be made out of allowed forms of expression.

If the argument to nameof at its top level has an unacceptable form of expression, then it gives the error "This expression does not have a name". If the argument contains an unacceptable form of expression deeper within itself, then it gives the error "This sub-expression cannot be used as an argument to nameof".

It is helpful to list some things not allowed as the nameof argument:
```
    invocation-expression        e(args)
    assignment                   x += 15
    query-expression             from y in z select y
    lambda-expression            () => e
    conditional-expression       a ? b : c
    null-coalescing-expression   a?? b
    binary-expression            ||, &&, |, ^, &, ==, !=,
                                 <, >, <=, >=, is, as, <<,
                                 >>, +, -, *, /, %
    prefix-expression            +, -, !, ~, ++, --,
                                 *, &, (T)e
    postfix-expression           ++, --
    array-creation-expression    new C[…]
    object-creation-expression   new C(…)
    delegate-creation-expression new Action(…)
    anonymous-object-creation-expression new {…}
    typeof-expression            typeof(int)
    checked-expression           checked(…)
    unchecked-expression         unchecked(…)
    default-value-expression     default(…)
    anonymous-method-expression  delegate {…}
    pointer-member-access        e->x
    sizeof-expression            sizeof(int)
    literal                      "hello", 15
    parenthesized-expression     (x)
    element-access               e[i]
    base-access-indexed          base[i]
    await-expression             await e
    nameof-expression            nameof(e)
    vb-dictionary-lookup         e!foo 
```

Note that there are some types which are not counted as expressions by the C# grammar. These are not allowed as nameof arguments (since the nameof syntax only allows expressions for its argument). There's no need to spell out that the following things are not valid expressions, since that's already said by the language syntax, but here's a selection of some of the types that are not expressions:
```
    predefined-type              int, bool, float, object,
                                 dynamic, string
    nullable-type                Customer?
    array-type                   Customer[,]
    pointer-type                 Buffer*, void* 
    qualified-alias-member       A::B
    void                         void
    unbound-type-name            Dictionary<,>
```           


# Semantics

The nameof expression is a constant. In all cases, nameof(...) is evaluated at compile-time to produce a string. Its argument is not evaluated at runtime, and is considered unreachable code (however it does not emit an "unreachable code" warning).

_Definite assignment._ The same rules of definite assignment apply to nameof arguments as they do to all other unreachable expressions.

_Name lookup_. In the following sections we will be discussing member lookup. This is discussed in $7.4 of the C# spec, and is left unspecified in VB. To understand nameof it is useful to know that the existing member lookup rules in both languages either return a single type, or a single instance/static field, or a single instance/static event, or a property-group consisting of overloaded instance/static properties of the same name (VB), or a method-group consisting of overloaded instance/static/extension methods of the same name. Or, lookup might fail either because no symbol was found or because ambiguous conflicting symbols were found that didn't fall within the above list of possibilities.

_Argument binding_. The nameof argument refers to one or more symbols as follows.

__nameof(simple-name)__, of the form I or I<A1...AK>
The normal rules of simple name lookup $7.6.2 are used but with one difference...
* The third bullet talks about member lookup of I in T with K type arguments. Its third sub-bullet says _"Otherwise, the result is the same as a member access of the form T.I or T.I<A1...AK>. In this case, it is a binding-time error for the simple-name to refer to an instance member."_ For the sake of nameof(simple-name), this case does not constitute a binding-time error.


__nameof(member-access)__, of the form E.I or E.I<A1...AK>
The normal rules of expression binding are used to evaluate "E", with _no changes_. After E has been evaluated, then E.I<A1...AK> is evaluated as per the normal rules of member access $7.6.4 but with some differences...
* The third bullet talks about member lookup of I in E. Its sub-bullets have rules for binding when I refers to static properties, fields and events. For the sake of nameof(member-access), each sub-bullet applies to instance properties, fields and events as well.
* The fourth bullet talks about member lookup of I in T. Its sub-bullets have rules for binding when I refers to instance properties, fields and events. For the sake of nameof(member-access), each sub-bullet applies to static properties, fields and events as well.

__nameof(base-access-named)__, of the form base.I or base.I<A1...AK>
This is treated as nameof(B.I) or nameof(B.I<A1...AK> where B is the base class of the class or struct in which the construct occurs.


_Result of nameof_. The result of nameof is the identifier "I" with the _standard identifier transformations_. Note that, at the top level, every possible argument of nameof has "I<A1...AK>".

[update that was added after the initial v5 spec] If "I" binds to a method-group and the argument of nameof has generic type arguments at the top level, then it produces an error "Do not use generic type arguments to specify the name of methods". Likewise for property-groups.

The standard identifier transformations in C# are detailed in $2.4.2 of the C# spec: first any leading @ is removed, then Unicode escape sequences are transformed, and then any formatting-characters are removed. This of course still happens at compile-time. In VB, any surrounding [] is removed

# Implementation
In C#, nameof is stored in a normal InvocationExpressionSyntax node with a single argument. That is because in C# 'nameof' is a contextual keyword, which will only become the "nameof" operator if it doesn't already bind to a programmatic symbol named "nameof". TO BE DECIDED: what does its "Symbol" bind to?

In VB, NameOf is a reserved keyword. It therefore has its own node:
```vb
Class NameOfExpressionSyntax : Inherits ExpressionSyntax
    Public ReadOnly Property Argument As ExpressionSyntax
End Class
```
TO BE DECIDED: Maybe VB should just be the same as C#. Or maybe C# should do the same as VB.

What is the return value from `var r = semanticModel.GetSymbolInfo(argument)`? In all cases, r.Candidates is the list of symbol. If there is only one symbol then it is in r.Symbol; otherwise r.Symbol is null and the reason is "ambiguity".

Analyzers and the IDE will just have to deal with this case.


# IDE behavior
```cs
class C {
   [3 references] static void f(int i) {...nameof(f)...}
   [3 references] void f(string s) {...nameof(this.f)...}
   [3 references] void f(object o) {...nameof(C.f)...}
}
static class E {
   [2 references] public static void f(this C c, double d) {}
}
```

__Highlight symbol from argument__: When you set your cursor on an argument to nameof, it highlights all symbols that the argument bound to. In the above examples, the simple name "nameof(f)" binds to the three members inside C. The two member access "nameof(this.f)" and "nameof(C.f)" both bind to extension members as well.

__Highlight symbol from declaration__: When you set your cursor on any declaration of f, it highlights all nameof arguments that bind to that declaration. Setting your cursor on the extension declaration will highlight only "this.f" and "C.f". Setting your cursor on any member of C will highlight both all three nameof arguments.

__Goto Definition__: When you right-click on an argument to nameof in the above code and do GoToDef, it pops up a FindAllReferences dialog to let you chose which declaration. (If the nameof argument bound to only one symbol then it would go straight to that without the FAR dialog.)

__Rename declaration__: If you do a rename-refactor on one of the declarations of f in the above code, the rename will only rename this declaration (and will not rename any of the nameof arguments); the rename dialog will show informational text warning you about this. If you do a rename-refactor on the _last remaining_ declaration of f, then the rename will also rename nameof arguments. Note that if you turn on the "Rename All Overloads" checkbox of rename-refactor, then it will end up renaming all arguments.

__Rename argument__: If you do a rename-refactor on one of the nameof arguments in the above code, the rename dialog will by default check the "Rename All Overloads" button.

__Expand-reduce__: The IDE is free to rename "nameof(p)" to "nameof(this.p)" if it needs to do so to remove ambiguity during a rename. This might make nameof now bind to more things than it used to...

__Codelens__: We've articulated the rules about what the argument of nameof binds to. The CodeLens reference counts above are a straightforward consequence of this.


## Bread and butter cases
```cs
// Validate parameters 
void f(string s) {
    if (s == null) throw new ArgumentNullException(nameof(s));
}
```

```cs
// MVC Action links
<%= Html.ActionLink("Sign up",
             @typeof(UserController),
             @nameof(UserController.SignUp))
%>
```

```cs
// INotifyPropertyChanged
int p {
    get { return this._p; }
    set { this._p = value; PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.p)); }
}
// also allowed: just nameof(p)
```

```cs
// XAML dependency property
public static DependencyProperty AgeProperty = DependencyProperty.Register(nameof(Age), typeof(int), typeof(C));
```

```cs
// Logging
void f(int i) {
    Log(nameof(f), "method entry");
}
```

```cs
// Attributes
[DebuggerDisplay("={" + nameof(getString) + "()}")]
class C {
    string getString() { ... }
}
```

# Examples

```cs
void f(int x) {
   nameof(x)
}
// result "x": Parameter (simple name lookup)
```

```cs
int x=2; nameof(x)
// result "x": Local (simple name lookup)
```

```cs
const x=2; nameof(x)
// result "x": Constant (simple name lookup)
```

```cs
class C {
   int x;
   ... nameof(x)
}
// result "x": Member (simple name lookup)
```

```cs
class C {
   void f() {}
   nameof(f)
}
// result "f": Member (simple name lookup)
```

```cs
class C {
   void f() {}
   nameof(f())
}
// result error "This expression does not have a name"
```

```cs
class C {
   void f(){}
   void f(int i){}
   nameof(f)
}
// result "f": Method-group (simple name lookup)
```

```cs
Customer c; ... nameof(c.Age)
// result "Age": Property (member access)
```

```cs
Customer c; ... nameof(c._Age)
// result error "_Age is inaccessible due to its protection level: member access
```

```cs
nameof(Tuple.Create)
// result "Create": method-group (member access)
```

```cs
nameof(System.Tuple)
// result "Tuple": Type (member access). This binds to the non-generic Tuple class; not to all of the Tuple classes.
```

```cs
nameof(System.Exception)
// result "Exception": Type (member access)
```

```cs
nameof(List<int>)
// result "List": Type (simple name lookup)
```

```cs
nameof(List<>)
// result error "type expected": Unbound types are not valid expressions
```

```cs
nameof(List<int>.Length)
// result "Length": Member (Member access)
```

```cs
nameof(default(List<int>))
// result error "This expression doesn't have a name": Not one of the allowed forms of nameof
```

```cs
nameof(default(List<int>).Length)
// result error "This expression cannot be used for nameof": default isn't one of the allowed forms
```

```cs
nameof(int)
// result error "Invalid expression term 'int'": Not an expression. Note that 'int' is a keyword, not a name.
```

```cs
nameof(System.Int32)
// result "Int32": Type (member access)
```

```cs
using foo=System.Int32;
nameof(foo) 
// result "foo": Type (simple name lookup)
```

```cs
nameof(System.Globalization)
// result "Globalization": Namespace (member access)
```

```cs
nameof(x[2])
nameof("hello")
nameof(1+2)
// error "This expression does not have a name": Not one of the allowed forms of nameof
```

```vb
NameOf(a!Foo)
' error "This expression does not have a name": VB-specific. Not one of the allowed forms of NameOf.
```

```vb
NameOf(dict("Foo"))
' error "This expression does not have a name": VB-specific. This is a default property access, which is not one of the allowed forms.
```

```vb
NameOf(dict.Item("Foo"))
' error "This expression does not have a name": VB-specific. This is an index of a property, which is not one of the allowed forms.
```

```vb
NameOf(arr(2))
' error "This expression does not have a name": VB-specific. This is an array element index, which is not one of the allowed forms.
```

```vb
Dim x = Nothing
NameOf(x.ToString(2))
' error "This expression does not have a name": VB-specific. This resolves to .ToString()(2), which is not one of the allowed forms.
```

```vb
Dim o = Nothing
NameOf(o.Equals)
' result "Equals". Method-group. Warning "Access of static member of instance; instance will not be evaluated": VB-specific. VB allows access to static members off instances, but emits a warning.
```

```cs
[Foo(nameof(C))]
class C {}
// result "C": Nameof works fine in attributes, using the normal name lookup rules.
```

```cs
[Foo(nameof(D))]
class C { class D {} }
// result "D": Members of a class are in scope for attributes on that class
```

```cs
[Foo(nameof(f))]
class C { void f() {} }
// result "f": Members of a class are in scope for attributes on that class
```

```cs
[Foo(nameof(T))]
class C<T> {}
// result error "T is not defined": A class type parameter is not in scope in an attribute on that class
```

```cs
[Foo(nameof(T))] void f<T> { }
// result error "T not defined": A method type parameter is not in scope in an attribute on that method
```

```cs
void f([Attr(nameof(x))] int x) {}
// result error "x is not defined": A parameter is not in scope in an attribute on that parameter, or any parameter in the method
```

```vb
Function f()
  nameof(f)
End Function
' result "f": VB-specific. This is resolved as an expression which binds to the implicit function return variable
```

```vb
NameOf(New)
' result error "this expression does not have a name": VB-specific. Not one of the allowed forms of nameof. Note that New is not a name; it is a keyword used for construction.
```

```vb
Class C
  Dim x As Integer
  Dim s As String = NameOf(x)
End Class
' result "x": Field (simple name lookup)
```

```cs
class C {
   int x;
   string s = nameof(x);
}
// result "x". Field (simple name lookup)
```

```cs
class C {
   static int x;
   string s = nameof(x);
}
// result "x". Field (simple name lookup)
```

```cs
class C {
   int x;
   string s = nameof(C.x);
}
// result "x". Member (member access)
```

```cs
class C {
   int x;
   string s = nameof(default(C).x);
}
// result error "This expression isn't allowed in a nameof argument" - default.
```

```cs
struct S {
   int x;
   S() {var s = nameof(x); ...}
}
// result "x": Field access (simple name lookup). Nameof argument is considered unreachable, and so this doesn't violate definite assignment.
```

```cs
int x; ... nameof(x); x=1;
// result "x": Local access (simple name lookup). Nameof argument is unreachable, and so this doesn't violate definite assignment.
```

```cs
int x; nameof(f(ref x));
// result error "this expression does not have a name".
```

```cs
var @int=5; nameof(@int)
// result "int": C#-specific. Local (simple name lookup). The leading @ is removed.
```

```cs
nameof(m\u200c\u0065)
// result "me": C#-specific. The Unicode escapes are first resolved, and the formatting character \u200c is removed.
```

```vb
Dim [Sub]=5 : NameOf([Sub])
' result "Sub": VB-specific. Local (simple name lookup). The surrounding [.] is removed.
```

```cs
class C {
  class D {}
  class D<T> {}
  nameof(C.D)
}
// result "D" and binds to the non-generic form: member access only finds the type with the matching arity.
```

```cs
class C<T> where T:Exception {
  ... nameof(C<string>)
}
// result error: the type 'string' doesn't satisfy the constraints
```



================================================
FILE: meetings/2014/README.md
================================================
# Visual Basic .NET Language Design Notes for 2014

Overview of meetings and agendas for 2014


## Feb 17, 2014

[Visul Basic .NET Design Meeting Notes for Feb 17, 2014](LDM-2014-02-17.md)

a complete roll-up of all language features that are on the table 


## Feb 10, 2014

[Visul Basic .NET Design Meeting Notes for Feb 10, 2014](LDM-2014-02-10.md)


Strict Module 


## Mar 12, 2014

[Visul Basic .NET Design Meeting Notes for Mar 12, 2014](LDM-2014-03-12.md)

ProtectedAndFriend access modifier, and faster CInt(.) 

## Apr 1, 2014

[Visul Basic .NET Design Meeting Notes for Apr 1, 2014](LDM-2014-04-01.md)

String interpolation 


## Apr 2, 2014

[Visul Basic .NET Design Meeting Notes for Apr 2, 2014](LDM-2014-04-02.md)

Null-propagating operator ?. 

## Apr 16, 2014

[Visul Basic .NET Design Meeting Notes for Apr 16, 2014](LDM-2014-04-16.md)

#Disable Warning, and ambiguity from unrelated interfaces 

## Apr 23, 2014

[Visul Basic .NET Design Meeting Notes for Apr 23, 2014](LDM-2014-04-23.md)

primary constructors, and pattern-matching. 

## Jul 1, 2014

[Visul Basic .NET Design Meeting Notes for Jul 7, 2014](LDM-2014-07-01.md)

#Disable Warning revisited 

## Oct ,1 2014

[Visul Basic .NET Design Meeting Notes for Oct 1, 2014](LDM-2014-10-01.md)

rules for assignment to readonly autoprops in constructors, and preventing outsiders from implementing your interfaces 

## Oct 8, 2014

[Visul Basic .NET Design Meeting Notes for Oct 8, 2014](LDM-2014-10-08.md)

revisit "ambiguity from unrelated interfaces" 

## Oct 15, 2014

[Visul Basic .NET Design Meeting Notes for Oct 15, 2014](LDM-2014-10-15.md)

revised nameof operator 


## Oct 23, 2014

[Visul Basic .NET Design Meeting Notes for Oct 23, 2014](LDM-2014-10-23.md)

revised nameof operator again. (Also some breaking changes for ambiguous unrelated interface members)

================================================
FILE: meetings/2015/LDM-2015-01-14-VB.md
================================================
VB Design Meeting 2015-01-14
============================

# Overload Resolution for String Interpolation

Discussion thread for these notes can be found at https://github.com/dotnet/roslyn/issues/46.

# Summary

* Exactly like C#, we will consider an interpolated string to be like a string in most cases such as overload resolution and searches for user-defined/intrinsic conversion. This implies that what the IDE intellisense shows after $"hello".| should be the same as that for regular strings.

* We wrote out some gnarly type-inference test cases for overload resolution and array literals with interpolated strings, and explained the expected output.

* We would like both C# and VB to give more actionable error messages if they end up binding to a factory Create method whose return type isn't right

* We reaffirmed intended behavior for full-width characters in interpolated strings

# Overload resolution for string interpolation

We want interpolated strings to be easily used as both String and FormattableString:
```vb
  Dim x As String = $"hello {p}"              ' works fine
  Dim x As FormattableString = $"hello {p}"   ' works fine
  Dim x = $"hello {p}"                        ' works fine, and infers x As String
```

The question is about overload resolution... Which candidate should it prefer? Or should it be an ambiguity error?
```vb
  Sub f(x As FormattableString) : End Sub
  Sub f(x As String) : End Sub

  f($"hello {p}")    ' ... which does it pick?
```

One important principle is that if there's an existing API `Sub f(x As String)` then consumers MUST be able to call it with `f($"hello {p}")`.


Another question is: if there's a language intrinsic conversion from string, does that conversion also apply to interpolated strings? e.g.
```vb
   Dim x As Char() = "hello people"  ' works fine
   Dim x As Char() = $"hello {x}"    ' should this also work?
```
And separately, if there's a user-defined intrinsic conversion from string, does that conversion also apply to interpolated strings?

(In C# the intention is that both should work. Have to verify that we've covered that in unit tests.)



## API DESIGN Proposal 1a
"Some library APIs really want consumers to use FormattableString because it is safer or faster. The API that takes string and the API that takes FormattableString actually do different things and hence shouldn't be overloaded on the same name. Library authors will want to lead people to use interpolated strings, hence it should have a shorter name."
```vb
   Sub ExecuteQueryUnsafe(s As String) ...
   Sub ExecuteQuery(s As FormattableString) ...

   Sql.ExecuteQueryUnsafe(GetRegValueEx(path))
   Sql.ExecuteQueryUnsafe("from p in people select p.Name")
   Sql.ExecuteQuery($"from p in {x} select p.Name")
```

Q. If they do different things, then wouldn't you want an ambiguity error here?


## API DESIGN Proposal 1b
"In other library APIs, strings and FormattableStrings are equally fine; overloads make sense; we should prefer string overload because it will be more efficient"
```vb
   Sub WriteLine(s As String) ...

   Console.WriteLine("hello everyone")
   Console.WriteLine($"hello {fred}")
```

Q. Isn't it an *antipattern* for an API to have both String and FormattableString if they just do the same thing?

A. Well, maybe, but it could be valid and useful to overload on both String and IFormattable. (Or an overload of both String and Object and then do a TryCast to IFormattable).


## Proposal 2
"I don't like Safe/Unsafe. How about these names? ..."
```vb
   Sub ExecuteQuery(s As String) ...
   Sub ExecuteQuery(s As FormattableString) ...

   Sql.ExecuteQuery(GetRegValueEx(path))
   Sql.ExecuteQuery("from p in people select p.Name")
   Sql.ExecuteQueryWithFormat($"from p in {x} select p.Name")
```


## API DESIGN Proposal 3
"Someone will start with ExecuteQuery, and when they change the argument to $ then they won't see or understand the differently-named method. So let's pick the FormattableString overload which is most likely to be safe."
```vb
   Sub ExecuteQuery(s As String) ...
   Sub ExecuteQuery(s As FormattableString) ...

   Sql.ExecuteQuery("from p in people select p.Name")  ' picks String overload
   Sql.ExecuteQuery(GetRegValueEx(path))  ' picks String overload
   Sql.ExecuteQuery($"from p in {x} select p.Name")  ' picks FormattableString overload
```
 
Q. What about the following consequence? Imagine an API has existed whose behavior is to format its string in a particular culture
```vb
   Sub f(x As IFormattable)
   f($"hello {p}")
```
And later on down the line someone adds a new overload that takes string
```vb
   Sub f(x As String)
```
Then the user's call will change behavior upon recompilation.


## RESOLUTION
We generally believe that libraries will mostly be written with different API names for methods which do different things. Therefore overload resolution differences between FormattableString and String don't matter, so string might as well win. Therefore we should stick with the simple principle that an interpolated string *is* a string. End of story.

Implication: in intellisense `$"hello".|` will show extension methods off String, but will *NOT* show extension methods off FormattableString.

Implication: both intrinsic and user-defined conversions that apply to string will also apply to interpolated string

Implication: overload resolution will prefer String over FormattableString candidates when given an interpolated string argument.

Implication: type inference works as follows.
```vb
Sub f(Of T)(x As T)
f($"hello {p}")
' then it picks string. (it has *contributed* string as a candidate)

Sub f(Of T)(x As T, y As T)
f($"hello {p}", CType(Nothing, FormattableString))
' Then it gets two candidates, "String" and "FormattableString"
' In most of the language (other than array literals), it checks whether
' the *type* of each argument can convert to the candidate type.
' In this case it will give an error.
```

Implication: if you have an array literal that contains an interpolated string expression
```vb
   Dim x = {$"hello", CType(Nothing, IFormattable)}
```
then this will pick "Object Assumed" in Option Strict Off, and give an error in Option Strict On. The reason is that there is no dominant type between the candidate types "String" and "IFormattable". (There's no widening/identity conversion from one to the other, and there is a narrowing conversion from each to the other).


## About the factory method that interpolation strings use

The language conversion rules bake in knowledge of `System.IFormattable` and `System.FormattableString` for their knowledge of widening conversions.

The compiler emits a call to a factory method when there is an interpolated string in source code. The factory method looks like this. There might be a whole family of overloaded Create methods.
```vb
System.Runtime.CompilerServices.FormattableStringFactory
   Function Create(...) As ...
```
The compiler separates the interpolated-string into a format string and a comma-separated list of expressions for the holes which it classifies as values before generating a call to `Create(fmtstring, expr1, expr2, ...)`. It will rely on normal VB overload resolution to pick the best Create method. This leaves the implementors of the factory free to do lots of nice optimizations.

The question is, what return type do we expect from the Create method?

Option1: We could bake in the requirement that the factory method gives back a System.FormattableString, and this type must implement System.IFormattable, and do this as a pre-filter prior to doing overload resolution of the Create() overload family.

Option2: Or we could merely invoke the method, and do a cast of the return type to IFormattable/FormattableString depends on what the user asked for. But then...
* Do we give a warning if it has the [Obsolete] attribute?
* Do we give a warning if it is narrowing?
* What if it picks a Sub() ?

Option3: Just do plain ordinary overload resolution, and if there were ANY errors or warnings, them emit them. In addition, if there were any errors (not just warnings that happened to be WarnAsError'd), then additionally report an error message at the same location "The factory is malformed". Precedent: we do this for queries. [Note: this message might appear or disappear if you change option strict on/off in your file].

Option4: As with Option3 but enforcing it to use Option Strict On for its overload resolution and its conversion to IFormattable/FormattableString.

RESOLUTION: Option3.



Q. What about delegate relaxation level of $"hello" to FormattableString/IFormattable ?
```vb
Sub f(lambda as Func(Of FormattableString))
Sub f(lambda as Func(Of String))
f(Function() $"hello")
```
RESOLUTION: From the principle above, we'd like this to pick the String overload. The way to accomplish this is to classify the lambda conversion as DelegateRelaxationLevelReturnWidening.



Q. What about full-width characters?
e.g. does $"{{" give the non-full-width string "{" even if the two source characters had different widths?
e.g. can you write $"{p}" where the open is wide and the close is normal width?
e.g. there is no escape to put a full-width {, similar to how there's no escape to put a full-width " ?

RESOLUTION: Yes that's all fine.



---

These are the workitems left to do...

C#: additionally report error message about bad factory
C#: verify (add a test case) that user-defined and intrinsic conversions on string really are used for interpolated strings.
VB: change array literal dominant type stuff
VB: all the dominant type stuff
VB: fix up delegate relaxation level to be widening (and write test for it)



================================================
FILE: meetings/2015/README.md
================================================
# Vi
Download .txt
gitextract_tsofwn20/

├── .gitattributes
├── CODE-OF-CONDUCT.md
├── Language-Version-History.md
├── README.md
├── meetings/
│   ├── 2014/
│   │   ├── LDM-2014-02-10.md
│   │   ├── LDM-2014-02-17.md
│   │   ├── LDM-2014-03-12.md
│   │   ├── LDM-2014-04-01.md
│   │   ├── LDM-2014-04-02.md
│   │   ├── LDM-2014-04-16.md
│   │   ├── LDM-2014-04-23.md
│   │   ├── LDM-2014-07-01.md
│   │   ├── LDM-2014-10-01.md
│   │   ├── LDM-2014-10-08.md
│   │   ├── LDM-2014-10-15.md
│   │   ├── LDM-2014-10-23.md
│   │   └── README.md
│   ├── 2015/
│   │   ├── LDM-2015-01-14-VB.md
│   │   └── README.md
│   ├── 2016/
│   │   ├── LDM-2016-05-06-VB.md
│   │   └── README.md
│   ├── 2017/
│   │   ├── README.md
│   │   ├── vbldm-notes-2017.04.12.md
│   │   ├── vbldm-notes-2017.05.19.md
│   │   ├── vbldm-notes-2017.08.09.md
│   │   ├── vbldm-notes-2017.08.23.md
│   │   ├── vbldm-notes-2017.08.30.md
│   │   ├── vbldm-notes-2017.10.18.md
│   │   ├── vbldm-notes-2017.11.15.md
│   │   └── vbldm-notes-2017.12.06.md
│   ├── 2018/
│   │   ├── README.md
│   │   ├── vbldm-notes-2018.02.07.md
│   │   ├── vbldm-notes-2018.02.21.md
│   │   ├── vbldm-notes-2018.02.28.md
│   │   ├── vbldm-notes-2018.03.21.md
│   │   ├── vbldm-notes-2018.05.30.md
│   │   ├── vbldm-notes-2018.06.13.md
│   │   └── vbldm-notes-2018.12.19.md
│   ├── README.md
│   └── notes-template.md
├── proposals/
│   ├── README.md
│   ├── inactive/
│   │   └── README.md
│   ├── overload-resolution-priority.md
│   ├── proposal-DerestrictedOperators.md
│   ├── proposal-Implicit-default-optional-parameters.md
│   ├── proposal-template.md
│   └── rejected/
│       └── README.md
└── spec/
    ├── README.md
    ├── attributes.md
    ├── conversions.md
    ├── documentation-comments.md
    ├── expressions.md
    ├── general-concepts.md
    ├── introduction.md
    ├── lexical-grammar.md
    ├── overload-resolution.md
    ├── preprocessing-directives.md
    ├── source-files-and-namespaces.md
    ├── statements.md
    ├── type-members.md
    └── types.md
Condensed preview — 61 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,125K chars).
[
  {
    "path": ".gitattributes",
    "chars": 12,
    "preview": "* text=auto\n"
  },
  {
    "path": "CODE-OF-CONDUCT.md",
    "chars": 259,
    "preview": "# Code of Conduct\n\nThis project has adopted the code of conduct defined by the Contributor Covenant\nto clarify expected "
  },
  {
    "path": "Language-Version-History.md",
    "chars": 1678,
    "preview": "# Features Added in VB Language Versions\n\n*NOTE:* See how to [specify the language version for your project here](https:"
  },
  {
    "path": "README.md",
    "chars": 5667,
    "preview": "# Visual Basic .NET Language Design\n\nWelcome to the official repo for Visual Basic .NET language design.\n\n* Full Languag"
  },
  {
    "path": "meetings/2014/LDM-2014-02-10.md",
    "chars": 4130,
    "preview": "VB Language Design Meeting 2014-02-10\n\n# Strict Module\n\nC# lets you have \"static class\" but VB only has \"Module\" which l"
  },
  {
    "path": "meetings/2014/LDM-2014-02-17.md",
    "chars": 60509,
    "preview": "VB Language Design Meeting 2014-02-17\n\nROLL-UP OF PROPOSED FEATURES.\n\n*Please don't reply to this post with comments on "
  },
  {
    "path": "meetings/2014/LDM-2014-03-12.md",
    "chars": 5189,
    "preview": "# ProtectedAndFriend, ProtectedOrFriend\n\n## BACKGROUND\n\nThe CLI includes two access modifiers \"FamilyAndAssembly\" (which"
  },
  {
    "path": "meetings/2014/LDM-2014-04-01.md",
    "chars": 6359,
    "preview": "# Null propagating operator ?.\n\nThe `?.` operator is the second-highest voted request on UserVoice\nhttp://visualstudio.u"
  },
  {
    "path": "meetings/2014/LDM-2014-04-02.md",
    "chars": 14938,
    "preview": "# String interpolation\nString interpolation is one of the top ten requests on uservoice - http://visualstudio.uservoice."
  },
  {
    "path": "meetings/2014/LDM-2014-04-16.md",
    "chars": 6083,
    "preview": "# #Warning Disable\n\n## REQUEST\n\nPlease add `#pragma` to VB so we can suppress warnings. This will be especially useful f"
  },
  {
    "path": "meetings/2014/LDM-2014-04-23.md",
    "chars": 9385,
    "preview": "(this discussion happened in VB language design meeting, but it strongly concerns C# also).\n\n\n# Better support for immut"
  },
  {
    "path": "meetings/2014/LDM-2014-07-01.md",
    "chars": 6084,
    "preview": "# #Warning Disable\n\n## REQUEST\n\nPlease add `#pragma` to VB so we can suppress warnings. This will be especially useful f"
  },
  {
    "path": "meetings/2014/LDM-2014-10-01.md",
    "chars": 12317,
    "preview": "There were two agenda items...\n1. Assignment to readonly autoprops in constructors (we fleshed out details)\n2. A new com"
  },
  {
    "path": "meetings/2014/LDM-2014-10-08.md",
    "chars": 11578,
    "preview": "# Back-compat break with interface implementations\n\n## High-level summary\n\n* _On the declaration side,_ C# users always "
  },
  {
    "path": "meetings/2014/LDM-2014-10-15.md",
    "chars": 18167,
    "preview": "We've been reconsidering some details about the \"nameof\" operator. This was prompted by a few questions:\n\n* _Why can't I"
  },
  {
    "path": "meetings/2014/LDM-2014-10-23.md",
    "chars": 23564,
    "preview": "# nameof operator: spec v5\nThe nameof(.) operator has the form nameof(expression). The expression must have a name, and "
  },
  {
    "path": "meetings/2014/README.md",
    "chars": 1845,
    "preview": "# Visual Basic .NET Language Design Notes for 2014\n\nOverview of meetings and agendas for 2014\n\n\n## Feb 17, 2014\n\n[Visul "
  },
  {
    "path": "meetings/2015/LDM-2015-01-14-VB.md",
    "chars": 9681,
    "preview": "VB Design Meeting 2015-01-14\n============================\n\n# Overload Resolution for String Interpolation\n\nDiscussion th"
  },
  {
    "path": "meetings/2015/README.md",
    "chars": 239,
    "preview": "# Visual Basic .NET Language Design Notes for 2015\n\nOverview of meetings and agendas for 2015\n\n\n## Jan 14, 2015\n\n[Visul "
  },
  {
    "path": "meetings/2016/LDM-2016-05-06-VB.md",
    "chars": 8294,
    "preview": "# VB Design Notes for May 6, 2016\n\n# Agenda\n- ByRef Returns\n- Tuples\n\n## ByRef Returns\n\nToday, functions and properties "
  },
  {
    "path": "meetings/2016/README.md",
    "chars": 215,
    "preview": "# Visual Basic .NET Language Design Notes for 2016\n\nOverview of meetings and agendas for 2016\n\n\n## May 5, 2016\n\n[Visul B"
  },
  {
    "path": "meetings/2017/README.md",
    "chars": 4464,
    "preview": "# Visual Basic .NET Language Design Notes for 2017\n\nOverview of meetings and agendas for 2017\n\n**April**\n* [12th](vbldm-"
  },
  {
    "path": "meetings/2017/vbldm-notes-2017.04.12.md",
    "chars": 2931,
    "preview": "Agenda\r\n======\r\n\r\n-   New conversion operator/syntax\r\n\r\n-   GitHub repo review\r\n\r\nGuest attendee: Klaus Spoonman\r\n\r\nNew "
  },
  {
    "path": "meetings/2017/vbldm-notes-2017.05.19.md",
    "chars": 3010,
    "preview": "# Visual Basic Language Design Meeting Notes - 2017.05.19\n\n## Agenda\n* Default Interface Implementations\n\n## Discussion\n"
  },
  {
    "path": "meetings/2017/vbldm-notes-2017.08.09.md",
    "chars": 1008,
    "preview": "# Visual Basic Language Design Meeting - 2017.08.09\r\n\r\n### Agenda\r\n* Await in Catch/Finally\r\n* Non-trailing named argume"
  },
  {
    "path": "meetings/2017/vbldm-notes-2017.08.23.md",
    "chars": 1467,
    "preview": "# Visual Basic Language Design Meeting\r\nAugust 23rd, 2017\r\n\r\n## Agenda\r\n* Late-binding without `Option Strict Off`\r\n    "
  },
  {
    "path": "meetings/2017/vbldm-notes-2017.08.30.md",
    "chars": 450,
    "preview": "# Visual Basic Language Design Meeting - 2017.08.30\r\n\r\n### Agenda\r\n* Nullable reference type\r\n\r\n## Nullable reference ty"
  },
  {
    "path": "meetings/2017/vbldm-notes-2017.10.18.md",
    "chars": 7627,
    "preview": "# Visual Basic Language Design Meeting\nOctober 18th, 2017\n\n### Agenda\n* Proposal [#101](https://github.com/dotnet/vblang"
  },
  {
    "path": "meetings/2017/vbldm-notes-2017.11.15.md",
    "chars": 3920,
    "preview": "# Visual Basic Language Design Meeting\nNovember 15th, 2017\n\n## Agenda\n* Proposal [#195](https://github.com/dotnet/vblang"
  },
  {
    "path": "meetings/2017/vbldm-notes-2017.12.06.md",
    "chars": 8846,
    "preview": "# Visual Basic Language Design Meeting\nDecember 6th, 2017\n\n## Agenda\n* Proposal [#25](https://github.com/dotnet/vblang/i"
  },
  {
    "path": "meetings/2018/README.md",
    "chars": 2502,
    "preview": "# Visual Basic .NET Language Design Notes for 2018\n\nOverview of meetings and agendas for 2018\n\n## February\n\n* [7th](vbld"
  },
  {
    "path": "meetings/2018/vbldm-notes-2018.02.07.md",
    "chars": 3845,
    "preview": "# Visual Basic Language Design Meeting\nFebruary 7,2018\n\n## Agenda\n* [C# Issue #1208 - C# Design Notes for nullable refer"
  },
  {
    "path": "meetings/2018/vbldm-notes-2018.02.21.md",
    "chars": 5841,
    "preview": "# Visual Basic Language Design Meeting\n\nFebruary 21,2018\n\n## Agenda\n\n* Community Update\n* Upgrade Project - Discussion\n*"
  },
  {
    "path": "meetings/2018/vbldm-notes-2018.02.28.md",
    "chars": 4989,
    "preview": "# Visual Basic Language Design Meeting\n\nFebruary 28,2018\n\n## Agenda\n\n* Implications of C# Range on Visual Basic\n* Issue "
  },
  {
    "path": "meetings/2018/vbldm-notes-2018.03.21.md",
    "chars": 3255,
    "preview": "# Visual Basic Language Design Meeting\n\nMarch 21, 2018\n\n## Agenda\n\n* MVP Summit recap\n* Issue #86 [Optimize conversions "
  },
  {
    "path": "meetings/2018/vbldm-notes-2018.05.30.md",
    "chars": 4586,
    "preview": "# Visual Basic Language Design Meeting\n\nMay 30, 2018\n\nWe have been largely on break because of travel, Build and other i"
  },
  {
    "path": "meetings/2018/vbldm-notes-2018.06.13.md",
    "chars": 2611,
    "preview": "# Visual Basic Language Design Meeting\n\nJune 13, 2018\n\nLast week's meeting subsumed with other issues.\n\n## Agenda\n\n* Rev"
  },
  {
    "path": "meetings/2018/vbldm-notes-2018.12.19.md",
    "chars": 10424,
    "preview": "# Visual Basic Language Design Meeting\n\nDecember 19, 2018\n\nLast week's meeting subsumed with other issues.\n\n## Agenda\n\n*"
  },
  {
    "path": "meetings/README.md",
    "chars": 2510,
    "preview": "# Visual Basic .NET Language Design Meetings\n\nVisual Basic .NET Language Design Meetings (LDM for short) are meetings by"
  },
  {
    "path": "meetings/notes-template.md",
    "chars": 645,
    "preview": "# Visual Basic Language Design Meeting\nMonth Day, Year\n\n## Agenda\n* [Proposal #Number - Title](#proposal-number---title)"
  },
  {
    "path": "proposals/README.md",
    "chars": 2377,
    "preview": "# VB Language Proposals\n\nLanguage proposals are living documents describing the current thinking about a give language f"
  },
  {
    "path": "proposals/inactive/README.md",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "proposals/overload-resolution-priority.md",
    "chars": 8594,
    "preview": "# Overload Resolution Priority\n\n## Summary\n[summary]: #summary\n\nWe introduced a new attribute, `System.Runtime.CompilerS"
  },
  {
    "path": "proposals/proposal-DerestrictedOperators.md",
    "chars": 4182,
    "preview": "# Derestricted Operators\n\n* [x] Proposed: [Complete](https://github.com/dotnet/vblang/issues/26)\n* [ ] Prototype: [Compl"
  },
  {
    "path": "proposals/proposal-Implicit-default-optional-parameters.md",
    "chars": 4961,
    "preview": "# Implicit Default Optional Parameters\n\n* [x] Proposed\n* [x] Prototype: [Complete](https://github.com/AdamSpeight2008/ro"
  },
  {
    "path": "proposals/proposal-template.md",
    "chars": 1282,
    "preview": "# FEATURE_NAME\n\n* [x] Proposed\n* [ ] Prototype: [Complete](https://github.com/PROTOTYPE_OWNER/roslyn/BRANCH_NAME)\n* [ ] "
  },
  {
    "path": "proposals/rejected/README.md",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spec/README.md",
    "chars": 8623,
    "preview": "Visual Basic Language Specification\n=====================================\n__Version 11__\n\n(This document is also availab"
  },
  {
    "path": "spec/attributes.md",
    "chars": 13964,
    "preview": "# Attributes in Visual Basic\n\nThe Visual Basic language enables the programmer to specify modifiers on declarations, whi"
  },
  {
    "path": "spec/conversions.md",
    "chars": 49916,
    "preview": "# Conversions in Visual Basic\n\nConversion is the process of changing a value from one type to another. For example, a va"
  },
  {
    "path": "spec/documentation-comments.md",
    "chars": 32127,
    "preview": "# Documentation Comments\n\nDocumentation comments are specially formatted comments in the source that can be analyzed to "
  },
  {
    "path": "spec/expressions.md",
    "chars": 229577,
    "preview": "# Expressions in Visual Basic\n\nAn expression is a sequence of operators and operands that specifies a computation of a v"
  },
  {
    "path": "spec/general-concepts.md",
    "chars": 79097,
    "preview": "# General Concepts\n\nThis chapter covers a number of concepts that are required to understand the semantics of the Micros"
  },
  {
    "path": "spec/introduction.md",
    "chars": 10356,
    "preview": "# Introduction to Visual Basic\n\nThe Microsoft&reg; Visual Basic&reg; programming language is a high-level programming la"
  },
  {
    "path": "spec/lexical-grammar.md",
    "chars": 22398,
    "preview": "# Lexical Grammar\n\nCompilation of a Visual Basic program first involves translating the raw stream of Unicode characters"
  },
  {
    "path": "spec/overload-resolution.md",
    "chars": 40946,
    "preview": "# Overloaded Method Resolution\n\nIn practice, the rules for determining overload resolution are intended to find the over"
  },
  {
    "path": "spec/preprocessing-directives.md",
    "chars": 9022,
    "preview": "# Preprocessing Directives\n\nOnce a file has been lexically analyzed, several kinds of source preprocessing occur. The mo"
  },
  {
    "path": "spec/source-files-and-namespaces.md",
    "chars": 23634,
    "preview": "# Source Files and Namespaces\n\nA Visual Basic program consists of one or more source files. When a program is compiled, "
  },
  {
    "path": "spec/statements.md",
    "chars": 94563,
    "preview": "# Statements - Visual Basic\n\nStatements represent executable code.\n\n```antlr\nStatement\n    : LabelDeclarationStatement\n "
  },
  {
    "path": "spec/type-members.md",
    "chars": 124065,
    "preview": "# Type Members\n\nType members define storage locations and executable code. They can be methods, constructors, events, co"
  },
  {
    "path": "spec/types.md",
    "chars": 52633,
    "preview": "# Types in Visual Basic\n\nThe two fundamental categories of types in Visual Basic are *value types* and *reference types*"
  }
]

About this extraction

This page contains the full source code of the dotnet/vblang GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 61 files (1.0 MB), approximately 254.5k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!