GithubHelp home page GithubHelp logo

vblang's Introduction

Visual Basic .NET Language Design

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

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, 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.

If you want to suggest a feature, discuss current design notes or proposals, etc., please open a new issue, 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.

  2. Ideas that the LDT feel could potentially make it into the language should be turned into proposals, based on this template, 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. 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 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. The bar for implementation quality can be found here.

  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). Rejected proposals are archived under the rejected folder.

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 folder, organized in folders by year. The lifetime of a design meeting note is described in 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. 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.

vblang's People

Contributors

333fred avatar adamspeight2008 avatar alexbuckgit avatar anthonydgreen avatar cupuyc avatar cyrusnajmabadi avatar gafter avatar gewarren avatar jcouv avatar kathleendollard avatar mairaw avatar nschonni avatar reduckted avatar rolfbjarne avatar scottdorman avatar sharwell avatar terrajobst avatar v-thpra avatar youssef1313 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vblang's Issues

[Proposal] GUID Literal

(Ported from Roslyn Repo)

When guid are used their value tends not to change, throughout it's usage.

If we make it a compile-time constant,

  • It can be used in attributes.
  • Removes the runtime parse of the GUID string.
  • Compile-Time verification of the formatting.
  • If the GUID is a well known one, we could offer suggestions / completion like intellisense.

Guid.Parse currently supports 5 different formats.

Specifier Description Format
N 32 digits 00000000000000000000000000000000
D 32 digits seperated by hypens 00000000-0000-0000-0000-0000000000000
B 32 digits seperated by hypens, enclosed in braces {00000000-0000-0000-0000-0000000000000}
P 32 digits seperated by hypens, enclosed in parentheses (00000000-0000-0000-0000-0000000000000)
X Four hexadecimal values enclosed in braces, where the fourth value is a subset of eight hexadecimal values that is also enclosed in braces {0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}

These format should also be supported by any GUID literal.


Proposed Literal Syntax (VB)

We could extend VB's date time literal syntax #2016/06/01# to cover GUIDs.

Dim guid0 As Guid = #00000000000000000000000000000000# ' Specifier N
Dim guid1 As Guid = #00000000-0000-0000-0000-0000000000000# ' Specifier D
Dim guid2 As Guid = #{00000000-0000-0000-0000-0000000000000}# ' Specifier B
Dim guid3 As Guid = #(00000000-0000-0000-0000-0000000000000)# ' Specified P
Dim guid4 As Guid = #{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}#

In an Attribute

Imports System
Imports System.Runtime.InteropServices


 <GuidAttribute(#9ED54F84-A89D-4fcd-A854-44251E925F09#)> _
 Public Class SampleClass
     ' Insert class members here.
 End Class

[Proposal,Test] Simple Object Model to help with Unit Tests.

Unit Test Object Model

The ultimate aim of the this model is to remove all of the helper test methods that take XElement or String as type of the Source parameter. With just one or two that take a TestCompilation or TestSource (Alternate Name)

This should make them a little easier to write and potentially quicker to execute.

Existing

        <Fact>
        <WorkItem(111538, "https://devdiv.visualstudio.com/defaultcollection/DevDiv/_workitems?_a=edit&id=111538")>
        <WorkItem(658398, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems?_a=edit&id=658398")>
        Public Sub Test_UnaryOperatorsInvalid()
            'Added for Code Coverage 
            Dim compilationDef =
<compilation name="CConst.vb">
    <file name="a.vb">
Imports System
Imports Microsoft.VisualBasic

#If -"1"c Then
#End If

#If +"1" Then
#End If

#If +" "c Then
#End If

#If +"test"$ Then
#End If

#If Not " "c Then
#End If

#If NOT "test"$ Then
#End If

#If - Then
#End If

#If + Then
#End If

#If NOT Then
#End If

Module Module1
    Sub main()
    End Sub
End Module

</file>
</compilation>

            Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime(compilationDef)
            compilation.AssertTheseDiagnostics(
<expected>
BC30487: Operator '-' is not defined for type 'Char'.
#If -"1"c Then
~~~~~~~~~~~~~~
BC30487: Operator '+' is not defined for type 'String'.
#If +"1" Then
~~~~~~~~~~~~~
BC30487: Operator '+' is not defined for type 'Char'.
#If +" "c Then
~~~~~~~~~~~~~~
BC30037: Character is not valid.
#If +"test"$ Then
           ~
BC30205: End of statement expected.
#If +"test"$ Then
           ~
BC30487: Operator 'Not' is not defined for type 'Char'.
#If Not " "c Then
~~~~~~~~~~~~~~~~~
BC30037: Character is not valid.
#If NOT "test"$ Then
              ~
BC30205: End of statement expected.
#If NOT "test"$ Then
              ~
BC31427: Syntax error in conditional compilation expression.
#If - Then
      ~~~~
BC31427: Syntax error in conditional compilation expression.
#If + Then
      ~~~~
BC31427: Syntax error in conditional compilation expression.
#If NOT Then
        ~~~~
</expected>)
        End Sub

Using Object Model

        <Fact>
        <WorkItem(111538, "https://devdiv.visualstudio.com/defaultcollection/DevDiv/_workitems?_a=edit&id=111538")>
        <WorkItem(658398, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems?_a=edit&id=658398")>
        Public Sub Test_UnaryOperatorsInvalid()
            'Added for Code Coverage 
        Dim code = TestCompilation.CreateNew(Name:="CConst.vb").
                    WithFile(Name:="a.vb", Source:= _
"
Imports System
Imports Microsoft.VisualBasic

#If -""1""c Then
#End If

#If +""1"" Then
#End If

#If +"" ""c Then
#End If

#If +""test""$ Then
#End If

#If Not "" ""c Then
#End If

#If NOT ""test""$ Then
#End If

#If - Then
#End If

#If + Then
#End If

#If NOT Then
#End If

Module Module1
    Sub main()
    End Sub
End Module

").WithExpectation("BC30487: Operator '-' is not defined for type 'Char'.", Highlight("#If -""1""c Then", 0, 14)).
   WithExpectation("BC30487: Operator '+' is not defined for type 'String'.", Highlight("#If +""1"" Then", 4, 13)).
   WithExpectation("BC30487: Operator '+' is not defined for type 'Char'.", Highlight("#If +"" ""c Then", 4, 14)).
   WithExpectation("BC30037: Character is not valid.", Highlight("#If +""test""$ Then", 11, 1)).
   WithExpectation("BC30205: End of statement expected.", Highlight("#If +""test""$ Then", 11, 1)).
   WithExpectation("BC30487: Operator 'Not' is not defined for type 'Char'.", Highlight("#If Not "" ""c Then", 0, 17)).
   WithExpectation("BC30037: Character is not valid.", Highlight("#If NOT ""test""$ Then", 14, 1)).
   WithExpectation("BC30205: End of statement expected", Highlight("#If NOT ""test""$ Then", 14, 1)).
   WithExpectation("BC31427: Syntax error in conditional compilation expression.", Highlight("#If - Then", 6, 4)).
   WithExpectation("BC31427: Syntax error in conditional compilation expression.", Highlight("#If + Then", 6, 4)).
   WithExpectation("BC31427: Syntax error in conditional compilation expression.", Highlight("#If NOT Then", 8, 4))

        code.CompileAndVerifyExpectations(with:= _Compiler)

        End Sub

The Object Model

Public Class TestCompilation

    Public Class File
        Public ReadOnly Property Name As String
        Public ReadOnly Property Source As String
        Private Sub New(Optional Name As String = Nothing, Optional Source As String = Nothing )
            Me.Name= Name
            Me.Source= Source
        End Sub

        Public Shared Function CreateNew(Optional Name As String = Nothing, Optional Source As String = Nothing ) As TestCompilation.File
           Return New TestCompilation.File(Name,Source)
        End Function
    End Class

    Public Class Expected
        Public Class Highlighted
            Public ReadOnly Property Source As String
            Public ReadOnly Property Index As Integer
            Public ReadOnly Property Count As Integer

            Private Sub New(Source As String,Index As Integer, Count As Integer)
                Me.Source = Source
                Me.Index= Index
                Me.Count = Count
            End Sub
           Public Shared Function CreateNew(Source As String,Index As Integer, Count As Integer) As Highlighted
                Return New Highlighted(Source, Index, Count)
            End Function
        End Class

        Public ReadOnly Property Source As String
        Public ReadOnly Property Highlight As Highlighted

        Private Sub New(Source As String,Optional Highlight As Highlighted = Nothing)
            Me.Source = Source
            Me.Highlight = Highlight
        End Sub
        Public Shared Function CreateNew(Source As String,Optional Highlight As Highlighted = Nothing) As TestCompilation.Expected
            Return New TestCompilation.Expected(Source, Highlight)
        End Function

    End Class

    Public ReadOnly Property Name As String
    Public ReadOnly Property Files As List(Of TestCompilation.File)
    Public ReadOnly Property Expectations As List(Of TestCompilation.Expected)

    Private Sub New(Optional Name As String = Nothing)
        Me.Name = Name
    End Sub

    Public Function WithFile(File As TestCompilation.File) As TestCompilation
        If File Is Nothing Then Throw New ArgumentNullException(NameOf(File))
        If Me.Files Is Nothing Then _Files = New List(Of File)
        Me.Files.Add(File)
        Return me
    End Function
    Public Function WithFile(Optional Name As String = Nothing, Optional Source As String = Nothing ) As TestCompilation
        Return WithFile(File.CreateNew(Name, Source))
    End Function

    Public Function WithExpectation(Expected As TestCompilation.Expected) As TestCompilation
        If Expected Is Nothing Then Throw New ArgumentNullException(NameOf(Expected))
        If Me.Expectations Is Nothing Then _Expectations = New List(Of Expected)
        Me.Expectations.Add(Expected)
        Return me
    End Function

    Public Function WithExpectation(Source As String,Optional Highlight As TestCompilation.Expected.Highlighted = Nothing) As TestCompilation
        Return WithExpectation(Expected.CreateNew(Source, Highlight))
    End Function

    Public Shared Function Highlight(Source As String,Index As Integer, Count As Integer) As TestCompilation.Expected.Highlighted
        Return TestCompilation.Expected.Highlighted.CreateNew(Source,Index,Count)
    End Function

    Public Shared Function CreateNew(Optional Name As String = Nothing) As TestCompilation
        Return New TestCompilation(Name)
    End Function

End Class

Proposal: Improving async support for better cooperation between sync and async functions

Async support is great feature, but there is well known problem with mixing sync and async functions. Handling async procedures form sync procedures is very unpleasant and dangerous (deadlocks), while switching most sync code to async variant is equally problematic and non-practical. To enable better cooperation between sync and async procedures, there is need to create universal functions, that can be used with sync and async calls.

Dim data() As Byte
Public Function ReadFromDisk () As Boolean
    data = Await GetFile() ' GetFile return Taks(Of Byte())
    Return True
End Function

Because this function use await, then is implemented similar to current async functions: creates internal task with state machine, (IAsyncStateMachine). Additionally, such function is aware of external service. If such service exist, then function register their internal task to that service and return nothing. If service do not exist, then executes internal task synchronously to the end, and return result from finished task.

With updated model, service is set for calls with Await keyword, but only for these functions, that can register their internal task. After acquiring task from called universal function, global service is removed. This is alternative way to get task from called function, to current approach where task is grabbed via direct return.

Global service is stack-based, where every thread have separated stack.

Examples how this function and caller work.

Call from synchronous function:

Public Function LoadData () As Boolean
    ReadFromDisk()
    Return True
End Function

LoadData is synchronous, so service is not set, and ReadFromDisk execute their task internally and return result to the caller.

Call from universal function in synchronous way. LoadData is called from other synchronous function:

Public Function LoadData () As Boolean
    Await ReadFromDisk()
    Return True
End Function

Inside this function, Await sets global service. Called function (ReadFromDisk) detect this service, and register internal task to that service. After registering, called function returns Nothing. With acquired task function (LoadData) do not return their own task to the synchronous caller, but wait when acquired task is completed, then executes their own continuation (return True).

If this function (LoadData) is called from async caller, then register their own task to global service, register itself to grabbed task (really awaiter) and return Nothing..

Call from async function:

Public Async Function LoadData() As Task(Of Boolean)
    Await ReadFromDisk()
    Return True
End Function

As above this function grab task from called function via global service, but register itself to awaiter, and return their own task - all just like current behaviour for async functions (except estabilishing service to acuire task)

For cross assembly compatibility, universal function can be marked with attribute (like SyncUniversalAttribute), so compilter will known if called function from library, will register internal task to service or not.

VB can't split long lines at .

In the following code I want to split long lines at "." like I can in c#. If I split the lines the same way they are split in C# I get Error BC30157 Leading '.' or '!' can only appear inside a 'With' statement.

    Private Shared Iterator Function GenerateNewScript(ifBlock As MultiLineIfBlockSyntax) As IEnumerable(Of SyntaxNode)
        Dim ifStatement As IfStatementSyntax = GenerateInvertedIfStatement(ifBlock.IfStatement)
        Yield SyntaxFactory.MultiLineIfBlock(ifStatement).WithStatements(GenerateNewTrueStatement(ifBlock.ElseBlock.Statements)).WithLeadingTrivia(ifBlock.GetLeadingTrivia()).WithTrailingTrivia(ifBlock.GetTrailingTrivia()).WithAdditionalAnnotations(Formatter.Annotation)

        For Each stmt As StatementSyntax In ifBlock.Statements
            Yield stmt.WithAdditionalAnnotations(Formatter.Annotation)
        Next
    End Function

Desired code formatted like in C# below.

        static IEnumerable<SyntaxNode> GenerateNewScript(MultiLineIfBlockSyntax ifBlock)
        {
            var ifStatement = GenerateInvertedIfStatement(ifBlock.IfStatement);
            yield return SyntaxFactory.MultiLineIfBlock(ifStatement)
                .WithStatements(GenerateNewTrueStatement(ifBlock.ElseBlock.Statements))
                .WithLeadingTrivia(ifBlock.GetLeadingTrivia())
                .WithTrailingTrivia(ifBlock.GetTrailingTrivia())
                .WithAdditionalAnnotations(Formatter.Annotation);

            foreach (var stmt in ifBlock.Statements)
            {
                yield return stmt.WithAdditionalAnnotations(Formatter.Annotation);
            }
        }

[Proposal] Concurrent Block

(Ported from Roslyn Repo)

Concurrent Block

I'm thinking this along the lines of abstracting away the underlying machinery, so that the programmer can express that this section can be run concurrently. This proposal is for introduction of a new block construct in the C# and VB language, which permits code with the block to be run concurrently.

  T0 a;
  T1 b;

  concurrent
  {
    a = await PartA();
    b = await PartB();
  }
  Dim a As T0
  Dim b As T1

  concurrent
    a = await PartA()
    b = await PartB()
  end concurrent

There will be some form of flow analysis to check the "lines" can be run concurrently. eg there have no interdependencies with each other. The result will be the same as if it was run consecutively.

Join Patterns
Express the join pattern.

winner = concurrent { a , b } when any;
results = concurrent { a , b } when all;

target
Have the ability to specify where the concurrent code should be executed, eg GPUCPU.

winner = concurrent gpu { a , b } when any;
results = concurrent gpu { a , b } when all;

The ConcurrentBlock is a indicating a pattern. How that pattern is implemented is handled by another component, let's call it a PatternMaker. The PatternMaker takes the code in the block translates it into form that can be processed by the Concurrency Target, which is similar to how async blocks work.

concurrent Task {} /* Transforms uses Task (possible Default) */
concurrent Thread {} /*  Transform uses Threads */
concurrent Process { } /* Transform uses Processes */
concurrent Fibres {} /* Transform uses Fibres */
concurrent GPU { } /* Transform use GPU concurrency */

[Proposal] De-Restricted Operators.

(Ported from Roslyn repo)

VB Proposal: De-Restricted Operators.

Proposal to remove the restriction on some operators to be defined in compliment pairs.
Link To Proposal

Example

Public Shared Operator <( x As Foo, y As Foo ) As Boolean
End Operator
'' The compliment operator =>( x As Foo, y As Foo ) As Boolean not defined.

Addition
I think that the unary complement operators IsTrue and IsFalse should remain as is.

[Proposal] optional parameter implicit type conversion

2017-02-22 3
2017-02-22 2

Due to the reason of the optional parameter its value required of the primitive type constant value, so that there is no way for using non-primitive value as the optional parameter its default value. So that this example code will throw the compiler error:

Sub Plot(Optional padding As Padding = New Padding(100, 100, 100, 100))
...
End Sub

But if assuming that we have define the CType implicit conversion for our non-primitive type creates from a primitive type value, then is there any possible to apply this implicit conversion on the optional parameter?

2017-02-22 5

For example, we have creates a CType implicit conversion for type Padding convert from String type, so that we can using a constant string value padding: 100px 100px 100px 100px; as its optional parameter default value:

Sub Plot(Optional padding As Padding = "padding: 100px 100px 100px 100px;")
...
End Sub

Due to the reason of the optional parameter padding its default value is a string and this string value is also constant, so that this will not violate the rule of the optional parameter should be constant. and this default value can be stored in the compiled assembly as meta data as other optional parameter does.

2017-02-22

This new feature will makes the VisualBasic coding more convenient when the function have a lot of the optional parameter.

[Proposal] Grouped Const.

(Ported from Roslyn Repo)

Grouped Const

In the big open-source projects (I've seen) using C# or VB.net, tend to contain a lot of constants.
Eg Roslyn Project System

        Public Const Undefined As UInt32 = 0
        Public Const DATAID_SQM_ACTIVATEDOCWINDOW As UInt32 = 1    ' (Stream) 
        Public Const DATAID_SQM_UICONTEXTCHANGED As UInt32 = 2    ' (Stream) 
        Public Const DATAID_SQM_PERFMEMORY As UInt32 = 3
        Public Const DATAID_SQM_STARTUPOS As UInt32 = 4
        Public Const DATAID_SQM_STARTUPOSVERSION As UInt32 = 5
        Public Const DATAID_SQM_STARTUPOSBUILD As UInt32 = 6
        Public Const DATAID_SQM_STARTUPOSSERVICEPACK As UInt32 = 7
        Public Const DATAID_SQM_STARTUPAPPID As UInt32 = 8
        Public Const DATAID_SQM_STARTUPAPPBUILDTYPE As UInt32 = 9
        Public Const DATAID_SQM_STARTUPAPPVERSION As UInt32 = 10

I think it would help if there was an alternative syntax for writing them. In c# and VB.net we have a nice syntax for writing Enums values. Why not have a similar syntax for constants.

Proposed Syntaxes

VB.net

Public Const UInt32
  Undefined                       =  0,
  DATAID_SQM_ACTIVATEDOCWINDOW    =  1, ' (Stream) 
  DATAID_SQM_UICONTEXTCHANGED     =  2, ' (Stream) 
  DATAID_SQM_PERFMEMORY           =  3,
  DATAID_SQM_STARTUPOS            =  4,
  DATAID_SQM_STARTUPOSVERSION     =  5,
  DATAID_SQM_STARTUPOSBUILD       =  6,
  DATAID_SQM_STARTUPOSSERVICEPACK =  7,
  DATAID_SQM_STARTUPAPPID         =  8,
  DATAID_SQM_STARTUPAPPBUILDTYPE  =  9,
  DATAID_SQM_STARTUPAPPVERSION    = 10
End Const

The compiler would consider this to be equivalently to as if it was the first.

C#

public const uint32
{
  Undefined                       =  0,
  DATAID_SQM_ACTIVATEDOCWINDOW    =  1, // (Stream) 
  DATAID_SQM_UICONTEXTCHANGED     =  2, // (Stream) 
  DATAID_SQM_PERFMEMORY           =  3,
  DATAID_SQM_STARTUPOS            =  4,
  DATAID_SQM_STARTUPOSVERSION     =  5,
  DATAID_SQM_STARTUPOSBUILD       =  6,
  DATAID_SQM_STARTUPOSSERVICEPACK =  7,
  DATAID_SQM_STARTUPAPPID         =  8,
  DATAID_SQM_STARTUPAPPBUILDTYPE  =  9,
  DATAID_SQM_STARTUPAPPVERSION    = 10

}

Caveats

  • All of the constants defined within a grouped const have the same type
    • In this example UInt32
  • All of the constants defined within a grouped const have the same visibility.
    • In this example: Public
  • You can not change the type / visibility of an entry within a grouped const
    • eg Private DATAID_SQM_STARTUPOSSERVICEPACK = 7, error

Range `1 To 10 Step 2` expressions

(Ported from Roslyn repo)

Range Query Syntax

Dim odd = From x In 1 To 100 Step 2
Dim HundredToZero = From x In 100 To 0 Step -2

Updated (04 Dec 2017)
The range expression will produce a range object, that has the capability of being enumerated.

Dim r As Range(of Byte, Sbyte) = Byte.MaxValue To Byte.MInValue Step -1

Compatibility rules of types, will be the same as those used for addition and subtract.
This to allow simple unsigned type to be used with signed types.
We may want a code advisory, that can detect possible failures at compile-time. Eg unsigned beyond the limits of signed.

The range used will be (inclusive, inclusive), so that expressing the full range of values is permitted eg.

Dim byteValues = From Byte.MinValue To Byte.MaxValue ' 256 values (not 255)` 

Production of the values from the enumerator isnot allowed to overflow / underflow, regardless of any options eg Option Checked Off This is to allow an alternative form of For Loop

For Each value In Byte.MaxValue To Byte.MinValue Step -1
 '...
Next

New Feature, VisualBasic With Keyword Syntax for property mapping

Hi, currently, if we want to get or set property value to another object, 7 lines of code must be used,

Current:

Dim _value As <Value>

Public Property Value As String
Get
    Return _value.Label
End Get
Set
    _value.Label = value
End Set

This is not so convenient and not a brief code, and I think this situation can be simplify with the VisualBasic With keyword

Dim _value As <Value>

' maps both get and set
Public Property Value As String With _value.Label
' maps readonly
Public ReadOnly Property Value2 As String With _value.Label
' maps writeonly
Public WriteOnly Property Value3 As String With _value.Label

Or with two lines of code syntax

Dim _value As <Value>

' maps both get and set
Public Property Value As String 
    With _value.Label

' maps readonly
Public ReadOnly Property Value2 As String 
    With _value.Label

' maps writeonly
Public WriteOnly Property Value3 As String 
    With _value.Label

Which it means the Value property its value was mapped to the property of another object _value.Label, this will makes the code more beautiful and briefly.

Tags For Repo

Thoughts on some potential tags to use in this repo. External user may prefix the Issue / PR with the tag as they not have the facility to tag.

Tag Color Meaning
[External] From a non-affiliated contributor. eg Non-Mircosoft. Note the contributor may not have all of the skills and knowledge of affiliates / core developers. (So be nice and understanding.) .
[Internal] From an affiliated contributor. eg. Mircosoft \ Xamerin
[Idea] White Just a quick though on a potential proposal not fully thought out yet.
[Proposal] White Language Feature Proposal
[Proposal - Prototyped] Blue Proposal has "working" prototype in a branch. Doesn't have to be stable, just give an implementation to get the initial sense of the using feature within the language.
[Proposal - LDM Review] Yellow Being reviewed by LDM
[Proposal - LDM Feedback] Yellow Feedback from the LDM review
[Proposal - Accepted] Green Proposal was Accepted by the LDM
[Proposal - Declined] Red Proposal was Declinec by the LDM with rationale.
[Proposal - Withdrawn] Red Contributor has withdrawn the proposal
[Proposal - Up for Grabs ] An accepted proposal pending a developer to implement feature. Used in association with tag [Up for Grabs] so an interested party could develop.
[Feature] A proposal that has been accepted be the LDM
[Feature - In Development] Feature is in development into the official language.
[Feature - Completed] Feature has been developed.
[Feature - Pending] Feature is pending review / sign off
[Feature - Preview] Silver Feature is now in an official preview version (eg CTP) of the language
[Feature - Released] Gold Feature is now in an official release version of the language. If an external contributor does manage to achieve this, (I think) we as a community should acknowledge them with something special.

[Proposal] Extend Escaped Identifiers to Access External Case-Sensitive Objects

From time-to-time, it happens that the developers of some library of interest decides to use essentially the same name for a string, a property, an enum etc., that are made distinct by letter casing. This of course make life on the VB side quite difficult.

I propose extending the escaped identifier (an identifier delimited by square brackets) to aid in resolving case-sensitive identifiers.

For example:

    [@myProperty]
    [@MyProperty]
    [@X]
    [@x]

I'm thinking maybe an at-sign prefix can indicate this new mode (since that's how C# does its escaped identifiers). I'm OK if we cannot use this to define things in VB this way - i.e. not allowed to define classes or members with case-sensitive names within VB. Mostly it's about having the ability to fully utilize someone else's (perhaps C# based) code that uses casing as a pattern.

[Idea] .Me to reference subject of With block

I find VB With blocks to be extremely useful. The idea here is to enhance the With block to be able to reference the subject of the block itself, not just a member of the subject.

For instance:

With New Grover
   .Subparticle = Quark
   .Limeade = "Quip"
   NowDoSomething(.Me)
End With

This saves having to declare a variable as Grover and then using that variable. I don't want to declare a variable if I don't have to for something so short-lived.

If an object has a Me property (which I would think unlikely) it could be escaped as with other keywords (e.g., x.[Me]).

Proposal: Try ... Else Try

    Public Function GRTZ(Obj As Object) As Boolean
        Try
            Return CType(Obj, Integer) > 0
        Else Try
            Return CType(Obj, Box).Width > 0
        Catch ex() As Exception
            Return False
        End Try
    End Function

Proposal: Allow ByRef overloading in VB

Overloading between in parameters and out or ref parameters is supported in C#.
But in VB, if you want to call one of an overload method which differ only by ByVal and ByRef, the compiler will report error BC31429 .
This feature was used in some C# class libraries such as CocosSharp, made them incompatible with VB.

C# signature:

public void TestA(int param);
public void TestA(ref int param);
public void TestB(int param);
public void TestB(out int param);
public void TestC(int param);

C# call:

int i = 0;
TestA(i);
TestA(ref i);
TestB(i);
TestB(out i);
TestC(i);

Suggested new VB syntax to distinguish between ByVal and ByRef:

Dim i = 0
TestA(i)              ' TestA(i);
TestA(ByRef i)        ' TestA(ref i);
TestB(i)              ' TestB(i);
TestB(ByRef i)        ' TestB(out i);
TestC(i)              ' TestC(i);

[Proposal] TypeOf over multiple types.

(Ported from Roslyn Repo)

TypeOf ... IsNot ..

If TypeOf obj IsNot TypeA AndAlso
   TypeOf obj IsNot TypeB Then
If TypeOf obj IsNot {TypeA, TypeB} Then

TypeOf ... Is ...

If TypeOf obj Is TypeA OrElse
   TypeOf obj Is TypeB Then
If TypeOf obj Is {TypeA, TypeB} Then

Grammar

TypeOf_Obj	 ::= "TypeOf" ws+ identifier
TypeOf_IsExpr    ::= TypeOf_Obj ws+ "Is" ws+ MatchAgaist
TypeOf_IsNotExpr ::= TypeOf_Obj ws+ "IsNot" ws+ MatchAgainst
MatchAgainst	 ::= Single | MultipleTypes 
SingleType       ::= typeIdentifier
MultipleTypes    ::= '{' typeIdentifier (ws* ',' ws* typeIdentifier)+ ws* '}'

Ruled out TypeOf obj Is ( Type0, Type1. Type2 ) as that conflicts with tuple literal syntax.

[Proposal] Case ... When ... Clauses

(Ported from Roslyn Repo)

Is VB going to support patterns?
What about guard clauses? eg Case ... .... When boolEpxr
What about type matching and value manifesting? eg TypeIs String As str
How will tuple clause be handled?

Select Case obj
  Case TypeIs String As str When str IsNot Nothing
    ' do stuff
  Case ( TypeIs Boolean As valid, TypeIs Int32 As i32 ) When ( valid AndAlso ( i32 > 0 ) )
   ' manifesting into Tuple(Of Boolean, Int32 ), which has named elements ( valid:= , i32:= ) 
End Select

Proposal: Chainable (postfix) casting

Currently explicit casting can be made in prefix style:

CType (obj, SomeType)

which is uncomfortable in many situations:

CType(coll.First(Function (x) x.ID > 0), SomeType)
CType(CType(obj, SomeType).member, SomeOtherType)

This may be improved by adding virtual method, similar to ToString, but that exist only in language:

obj.ToType(SomeType)
coll.First(Function (x) x.ID > 0).ToType(SomeType)
obj.ToType(SomeType).member.ToType(SomeOtherType)

Such function may be currently created as extension method:

<Extension()>
Public Function ToType(Of T1)(ByRef Src As Object) As T1
    Return Src
End Function

but do not work for input casted to Object

Dim o As Object = ""
o.ToType(Of String).Length ' runtime error

and typing (Of ) with each call is redundant.

Proposal: Assign value to variable before definition

Sub XX ()
    x = 1
    ... ' newly typed code using x here    
    Dim x = 0
    ... ' previously typed code using x here
End Sub

Why not ?

I want to avoid moving definitions to the top, if I need to write code after variable was defined, but new code must be placed before this already typed.

[Proposal] Option Unchecked On | Off

Under "Advanced Compiler Options..." there is "Remove integer overflow checks". That's a cool feature to have, but it's an all-or-nothing proposition.

Could we have a new Option:

Option Unchecked On

The "Remove integer overflow checks" setting could be the default. This new option would only affect the *.vb file it's in. This would make having modulus binary arithmetic operations available when needed, and regular overflow checks also available within the same project.

Proposals from roslyn repo

Here are my most relevant proposals, that - imo - should be implemented
Placed by order of significance

https://github.com/dotnet/roslyn/issues/14014 : makes function suitable for both sync and async models
https://github.com/dotnet/roslyn/issues/14338 : filling async gaps, still missing in latest VS RC
dotnet/roslyn#13847 : streamlined asynchronously waiting for events
dotnet/roslyn#13364 : better grouping conditional operations
https://github.com/dotnet/roslyn/issues/14274 : simpler casting
dotnet/roslyn#14395 : tuples suitable for databinding via reflection

[Proposal] NameOf(Me)

Ported from Roslyn Repo

NameOf(Me) should evaluate to the Class / Structure / Module name, it is used in.

Module Exts
  Public Function Foo() As Object
    Debug.WriteLine(NameOf(Me)) ' output "Exs"
 End Function
End Module

Advantage
Doesn't require reflection.
Doesn't require repetition of the TypeName

Should VB latebinder understand tuple conversions?

The following will fail at run time, because latebinder does not know how to do tuple conversions

Imports System
Module C
    Sub Main()
        Dim i as (object, object) = (1, (2,3))
        Dim o as object = i
        Dim x as (integer, (integer, integer)) = ctype(o, (integer, (integer, integer)))
        System.Console.WriteLine(x.ToString())
    End Sub
End Module

Proposal: Using $ operator for shortening VisualBasic anonymous type declaration code

Hi,

Current usage of $ operator

String interpolation

$ operator can using for provides the string.format function, like:

Dim user$
Dim project$
Dim issue%
Dim url$ = $"https://github.com/{user$}/{project$}/issues/{issue%}"

Extends the $ operator

And I think this $ is also can be using for shortening anonymous type declaring:

Dim url$

With ${ 
  .key = user$, .time = Now, .percent% = 52%
}   
    Call url.POST($)   

    Return $.GetJson
End With

' another $ anonymous type example
With getURL()
    Call $.POST(${ .key = user$, .time = Now, .percent% = 52%})
End With

This anonymous type declare and usage was combine with the anonymous variable syntax in VisualBasic

[Proposal] Improvements on the VisualBasic anonymous variable more elegant #16096

[Proposal] Single line comments with Collection intialisers.

Whilst changing to some roslyn code to use collection initialisation. I came across this issue.

        Shared Sub New()
            Dim operators As New Dictionary(Of String, OperatorInfo)(IdentifierComparison.Comparer) From
            {
                {WellKnownMemberNames.OnesComplementOperatorName, New OperatorInfo(UnaryOperatorKind.Not)},
                {WellKnownMemberNames.TrueOperatorName, New OperatorInfo(UnaryOperatorKind.IsTrue)},
                {WellKnownMemberNames.FalseOperatorName, New OperatorInfo(UnaryOperatorKind.IsFalse)},
                {WellKnownMemberNames.UnaryPlusOperatorName, New OperatorInfo(UnaryOperatorKind.Plus)},
                {WellKnownMemberNames.AdditionOperatorName, New OperatorInfo(BinaryOperatorKind.Add)},
                {WellKnownMemberNames.UnaryNegationOperatorName, New OperatorInfo(UnaryOperatorKind.Minus)},
                {WellKnownMemberNames.SubtractionOperatorName, New OperatorInfo(BinaryOperatorKind.Subtract)},
                {WellKnownMemberNames.MultiplyOperatorName, New OperatorInfo(BinaryOperatorKind.Multiply)},
                {WellKnownMemberNames.DivisionOperatorName, New OperatorInfo(BinaryOperatorKind.Divide)},
                {WellKnownMemberNames.IntegerDivisionOperatorName, New OperatorInfo(BinaryOperatorKind.IntegerDivide)},
                {WellKnownMemberNames.ModulusOperatorName, New OperatorInfo(BinaryOperatorKind.Modulo)},
                {WellKnownMemberNames.ExponentOperatorName, New OperatorInfo(BinaryOperatorKind.Power)},
                {WellKnownMemberNames.EqualityOperatorName, New OperatorInfo(BinaryOperatorKind.Equals)},
                {WellKnownMemberNames.InequalityOperatorName, New OperatorInfo(BinaryOperatorKind.NotEquals)},
                {WellKnownMemberNames.LessThanOperatorName, New OperatorInfo(BinaryOperatorKind.LessThan)},
                {WellKnownMemberNames.GreaterThanOperatorName, New OperatorInfo(BinaryOperatorKind.GreaterThan)},
                {WellKnownMemberNames.LessThanOrEqualOperatorName, New OperatorInfo(BinaryOperatorKind.LessThanOrEqual)},
                {WellKnownMemberNames.GreaterThanOrEqualOperatorName, New OperatorInfo(BinaryOperatorKind.GreaterThanOrEqual)},
                {WellKnownMemberNames.LikeOperatorName, New OperatorInfo(BinaryOperatorKind.Like)},
                {WellKnownMemberNames.ConcatenateOperatorName, New OperatorInfo(BinaryOperatorKind.Concatenate)},
                {WellKnownMemberNames.BitwiseAndOperatorName, New OperatorInfo(BinaryOperatorKind.And)},
                {WellKnownMemberNames.BitwiseOrOperatorName, New OperatorInfo(BinaryOperatorKind.Or)},
                {WellKnownMemberNames.ExclusiveOrOperatorName, New OperatorInfo(BinaryOperatorKind.Xor)},
                {WellKnownMemberNames.LeftShiftOperatorName, New OperatorInfo(BinaryOperatorKind.LeftShift)},
                {WellKnownMemberNames.RightShiftOperatorName, New OperatorInfo(BinaryOperatorKind.RightShift)},
                {WellKnownMemberNames.ImplicitConversionName, New OperatorInfo(UnaryOperatorKind.Implicit)},
                {WellKnownMemberNames.ExplicitConversionName, New OperatorInfo(UnaryOperatorKind.Explicit)},
 ' These cannot be declared in source, but can be imported.
                {WellKnownMemberNames.LogicalNotOperatorName, New OperatorInfo(UnaryOperatorKind.Not)},
                {WellKnownMemberNames.LogicalAndOperatorName, New OperatorInfo(BinaryOperatorKind.And)},
                {WellKnownMemberNames.LogicalOrOperatorName, New OperatorInfo(BinaryOperatorKind.Or)},
                {WellKnownMemberNames.UnsignedLeftShiftOperatorName, New OperatorInfo(BinaryOperatorKind.LeftShift)},
                {WellKnownMemberNames.UnsignedRightShiftOperatorName, New OperatorInfo(BinaryOperatorKind.RightShift)}
            }

            s_operatorNames = operators
        End Sub

Anything in the collection iniitialiser after the comment is an error.

I think we should allow single line comments with collection initialisers.

Spec "tuples"

Please add specification text for the "tuples" feature.

Propose change to permited repo code style.

We should less strict on the code style used with the repo.

  • allow single line If Statements with in Pull Requests.
    *Especially on guard statements at the beginning of methods. As it reduces the code noise before getting to the core code section of the method.
        ''' <summary>
        ''' Checks if <paramref name="symbol"/> is accessible from within the assembly <paramref name="within"/>', but outside any 
        ''' type. Protected members are deemed inaccessible.
        ''' </summary>
        ''' <param name="symbol">The symbol to check accessibility.</param>
        ''' <param name="within">The assembly to check accessibility within.</param>
        ''' <returns>True if symbol is accessible. False otherwise.</returns>
        Public Shared Function IsSymbolAccessible(symbol As Symbol, within As AssemblySymbol) As Boolean
            If symbol Is Nothing Then Throw New ArgumentNullException(NameOf(symbol))
            If within Is Nothing Then Throw New ArgumentNullException(NameOf(within))

            Return AccessCheck.IsSymbolAccessible(symbol, within, useSiteDiagnostics:=Nothing)
        End Function

[Proposal] Allow Single Line Comments in more places.

This proposal unifies proposals #14 #21 in to more generalized proposal.
There are currently places where would like to have a single line comment, but not permitted.

Within Object Initializer Lists and Collection Initializers
eg

Dim XmlAppConfigReader As New XmlTextReader(Reader) With {
            ' Required by Fxcop rule CA3054 - DoNotAllowDTDXmlTextReader
                .DtdProcessing = DtdProcessing.Prohibit,
                .WhitespaceHandling = WhitespaceHandling.All
            }

and

        Shared Sub New()
            Dim operators As New Dictionary(Of String, OperatorInfo)(IdentifierComparison.Comparer) From
            {
                {WellKnownMemberNames.OnesComplementOperatorName, New OperatorInfo(UnaryOperatorKind.Not)},
                {WellKnownMemberNames.TrueOperatorName, New OperatorInfo(UnaryOperatorKind.IsTrue)},
                {WellKnownMemberNames.FalseOperatorName, New OperatorInfo(UnaryOperatorKind.IsFalse)},
                {WellKnownMemberNames.UnaryPlusOperatorName, New OperatorInfo(UnaryOperatorKind.Plus)},
                {WellKnownMemberNames.AdditionOperatorName, New OperatorInfo(BinaryOperatorKind.Add)},
                {WellKnownMemberNames.UnaryNegationOperatorName, New OperatorInfo(UnaryOperatorKind.Minus)},
                {WellKnownMemberNames.SubtractionOperatorName, New OperatorInfo(BinaryOperatorKind.Subtract)},
                {WellKnownMemberNames.MultiplyOperatorName, New OperatorInfo(BinaryOperatorKind.Multiply)},
                {WellKnownMemberNames.DivisionOperatorName, New OperatorInfo(BinaryOperatorKind.Divide)},
                {WellKnownMemberNames.IntegerDivisionOperatorName, New OperatorInfo(BinaryOperatorKind.IntegerDivide)},
                {WellKnownMemberNames.ModulusOperatorName, New OperatorInfo(BinaryOperatorKind.Modulo)},
                {WellKnownMemberNames.ExponentOperatorName, New OperatorInfo(BinaryOperatorKind.Power)},
                {WellKnownMemberNames.EqualityOperatorName, New OperatorInfo(BinaryOperatorKind.Equals)},
                {WellKnownMemberNames.InequalityOperatorName, New OperatorInfo(BinaryOperatorKind.NotEquals)},
                {WellKnownMemberNames.LessThanOperatorName, New OperatorInfo(BinaryOperatorKind.LessThan)},
                {WellKnownMemberNames.GreaterThanOperatorName, New OperatorInfo(BinaryOperatorKind.GreaterThan)},
                {WellKnownMemberNames.LessThanOrEqualOperatorName, New OperatorInfo(BinaryOperatorKind.LessThanOrEqual)},
                {WellKnownMemberNames.GreaterThanOrEqualOperatorName, New OperatorInfo(BinaryOperatorKind.GreaterThanOrEqual)},
                {WellKnownMemberNames.LikeOperatorName, New OperatorInfo(BinaryOperatorKind.Like)},
                {WellKnownMemberNames.ConcatenateOperatorName, New OperatorInfo(BinaryOperatorKind.Concatenate)},
                {WellKnownMemberNames.BitwiseAndOperatorName, New OperatorInfo(BinaryOperatorKind.And)},
                {WellKnownMemberNames.BitwiseOrOperatorName, New OperatorInfo(BinaryOperatorKind.Or)},
                {WellKnownMemberNames.ExclusiveOrOperatorName, New OperatorInfo(BinaryOperatorKind.Xor)},
                {WellKnownMemberNames.LeftShiftOperatorName, New OperatorInfo(BinaryOperatorKind.LeftShift)},
                {WellKnownMemberNames.RightShiftOperatorName, New OperatorInfo(BinaryOperatorKind.RightShift)},
                {WellKnownMemberNames.ImplicitConversionName, New OperatorInfo(UnaryOperatorKind.Implicit)},
                {WellKnownMemberNames.ExplicitConversionName, New OperatorInfo(UnaryOperatorKind.Explicit)},
 ' These cannot be declared in source, but can be imported.
                {WellKnownMemberNames.LogicalNotOperatorName, New OperatorInfo(UnaryOperatorKind.Not)},
                {WellKnownMemberNames.LogicalAndOperatorName, New OperatorInfo(BinaryOperatorKind.And)},
                {WellKnownMemberNames.LogicalOrOperatorName, New OperatorInfo(BinaryOperatorKind.Or)},
                {WellKnownMemberNames.UnsignedLeftShiftOperatorName, New OperatorInfo(BinaryOperatorKind.LeftShift)},
                {WellKnownMemberNames.UnsignedRightShiftOperatorName, New OperatorInfo(BinaryOperatorKind.RightShift)}
            }

            s_operatorNames = operators
        End Sub

LINQ Queries

 dim q = From x In xs
              ' Filter Odd
              Where (x Mod 2) = 1

[Proposal] Implicit Default Optional Parameter

(Ported from Roslyn Repo)

The grammar definition for an Optional Parameter is something similar to this.

OptionalParameter ::= "Optional" ParameterName Typing? DefaultToValue?
           Typing ::= "As" TypeIdentifier
   DefaultToValue ::= "=" ( "Nothing" | ConstantValue )

Examples

Foo( Optional arg0 ) ' --> Foo( Optional arg0 As Object = Nothing )
Foo( Optional arg1 As String ) ' --> Foo( Optional arg1 As String = Nothing )
Foo( Optional arg2 As String = Nothing ) ' --> Foo( Optional arg2 As String = Nothing )
Foo( Optional arg3 = "" ) ' --> Foo( Optional arg3 As String = "" )
Foo( Optional arg4 As Integer ) ' --> Foo( Optional arg4 As Integer = Nothing )
Foo( Optional arg5 As Integer = 0 ) ' --> Foo( Optional arg5 As Integer = 0 )
Foo( Optional arg6 As Integer = 1 ) ' --> Foo( Optional arg6 As Integer = 1 )
Foo( Optional arg7 = 7 ) ' --> Foo( Optional arg7 As Integer = 7 )

It will simplify the common cases of optional parameter.

Link to Proposal #13

NameOf does not return the canonical name of the parameter

Version Used:
Microsoft Visual Studio Enterprise 2015
Version 14.0.25123.00 Update 2
Microsoft .NET Framework
Version 4.6.01590

Installed Version: Enterprise

Visual Basic 2015 00322-90150-04967-AA372
Microsoft Visual Basic 2015

Steps to Reproduce:

  1. Turn off pretty listing (Tools->Options->Text Editor->Basic->Advanced->Editor Help->Pretty listing

  2. run code below
    Module Module1

    Sub Main()
    Dim VARiable As Integer
    Console.WriteLine(NameOf(VARIABLE))
    End Sub

Expected Behavior:
Output VARiable
Actual Behavior:
Outputs VARIABLE

[Proposal] Single Line comments in Object Initializers

(Ported from Roslyn Repo)

Currently the following comment isn't valid.

Dim XmlAppConfigReader As New XmlTextReader(Reader) With {
            ' Required by Fxcop rule CA3054 - DoNotAllowDTDXmlTextReader
                .DtdProcessing = DtdProcessing.Prohibit,
                .WhitespaceHandling = WhitespaceHandling.All
            }

I propose that we change the compiler to allow it.
So would have to implement a work around for #15525

Looking at the VB.net specification.

ObjectCreationExpression
    : 'New' NonArrayTypeName ( OpenParenthesis ArgumentList? CloseParenthesis )?
      ObjectCreationExpressionInitializer?
    ;

ObjectCreationExpressionInitializer
    : ObjectMemberInitializer
    | ObjectCollectionInitializer
    ;

ObjectMemberInitializer
    : 'With' OpenCurlyBrace FieldInitializerList CloseCurlyBrace
    ;

FieldInitializerList
    : FieldInitializer ( Comma FieldInitializer )*
    ;

FieldInitializer
    : 'Key'? ('.' IdentifierOrKeyword Equals )? Expression
    ;

ObjectCollectionInitializer
    : 'From' CollectionInitializer
    ;

CollectionInitializer
    : OpenCurlyBrace CollectionElementList? CloseCurlyBrace
    ;

CollectionElementList
    : CollectionElement ( Comma CollectionElement )*
    ;

CollectionElement
    : Expression
    | CollectionInitializer
    ;

By modifying FieldInitializer to

FieldInitializer
    : 'Key'? ('.' IdentifierOrKeyword Equals )? Expression
    | Comment
    ;
Comment
    : CommentMarker Character*
    ;

CommentMarker
    : SingleQuoteCharacter
    | 'REM'
    ;

SingleQuoteCharacter
    : '\''
    | '<Unicode 0x2018>'
    | '<Unicode 0x2019>'
    ;

we should enable single line comments.

Updated version of the Language Spec

The latest version of VB.net available is VB14 (VB15 in preview) the most current version of the Language Specification is VB11. That 3 or 4 versions behind. We should really have at least the most recently released version ie VB14.

[Proposal] "If Call" syntax sugar

Hi,

Assuming that we have a single method call in a single If test block, and then If..Then will be used:

Dim test As Boolean

' If test Then Call method()
' Or
If test Then
    Call method()
End If

Dim i%

If i = 10 Then
    Call method()
End If

Dim test2 = Function(str$) As Boolean
                ' blabla
            End Function

If test2(str:="blabla") Then
    Call method()
End If

' If want call multiple lines sub program
If Not test2(str:="blabla") Then
    Call Sub()
             ' blabla
         End Sub
End If

And I think this situation can be simplify by using a If Call syntax sugar

Dim test As Boolean

Call test ? method()

Dim i%

Call (i = 10) ? method()

Dim test2 = Function(str$) As Boolean
                ' blabla
            End Function

Call test2(str:="blablabla") ? method()

' If want call multiple lines sub program
Call (Not test2(str:="blabla")) ? Sub()
                                      ' balbala
                                  End Sub

[Proposal] Dim ByRef to allow references to Structure's

In VB today, there are two ways to make a reference to a Structure (value type):

1. via ByRef parameter of Function or Sub

2. as the objectExpression of a With statement

Signficant performance benefits are possible as demonstrated by the With statement (see "Avoiding Requalification" at https://msdn.microsoft.com/en-us/library/aa289513(v=vs.71).aspx). Of course today one could use Class instead of Structure, or perhaps an Interface trick, and get some performance benefit those ways, but really that's of no use if the Structure in question is somebody else's (outside of one's control).

My suggestion is to extend the Dim statement:

Dim ByRef myRef = objectExpression

This would be only as an automatic variable in a Sub or Function, never as a Field in a Class or Module. The semantics would seem the same as a ByRef parameter to a Sub/Function. Behind the scenes, it would work about the same as a With ... End With, except that what is the objectExpression of the With now has an indentifier (e.g. "myRef"), and the End With is implied by the scope and lifetime of that identifier. During its lifetime, it can only reference its original objectExpression. I'm thinking that this Dim ByRef idea can be real handy when dealing with arrays of Structure.

Hence something like this:

    For i As Integer = 0 to n - 1
        Dim ByRef item_i = A(i)
        item_i.member1 = expression
        item_i.member2 = expression
    Next

Would amount to the same as:

    For i As Integer = 0 to n - 1
        With A(i)
            .member1 = expression
            .member2 = expression
        End With
    Next

But here's the so what - what if one is working with two or more sets of Structure types? With statement is limited - only one Structure at a time! Nested With's are of no help. Dim ByRef would allow for things such as this:

    For i As Integer = 0 to n - 1
        Dim ByRef item_A = A(i)
        Dim ByRef item_B = B(i + 1)
        With item_A
            .member1 = item_B.member1
            .member2 = item_B.member2
        End With
    Next

VB spec corrections in definition of identifier

The VB spec says

2.2 Identifiers
An identifier is a name. Visual Basic identifiers conform to the Unicode Standard Annex 15 with one exception: identifiers may begin with an underscore (connector) character. If an identifier begins with an underscore, it must contain at least one other valid identifier character to disambiguate it from a line continuation.

However, that is the wrong Annex. That should be Unicode Standard Annex #31.

See

http://unicode.org/reports/tr15/
http://unicode.org/reports/tr31/

We should probably also clarify that “underscore” refers only to Unicode U+005F ‘LOW LINE’ and not other connector characters. It used to be called ‘SPACING UNDERSCORE’ but Unicode changed its name some time ago.

[Proposal] Do ... End Do

A popular trick is:

If True Then
    Dim myAutoVar1
    Dim myAutoVar2
    ' etc.
    ' ...
    ' All done, end lifetime of myAutoVar*
End If

This is nice for keeping the number of temporary variables under control, and letting pithy names get reused nicely. The above works, but looks goofy. I'm proposing:

Do
    Dim myAutoVar1
    Dim myAutoVar2
    ' etc.
    ' ...
    ' All done, end lifetime of myAutoVar*
End Do

The End Do would work about the same as Loop Until True. Indeed the added benefit is that Exit Do and Continue Do can still be legitimate, so that one could exit the block early (a plus over the If True trick).

Champion "Await in Catch and Finally"

VB doesn't allow this today and C# does. Seems like it could be a pain if APIs require this pattern a lot.

There are special design considerations required for VB as in VB it is permitted to Goto from the Catch block back into the Try block. This would complicate the state machine rewrite a bit:

dim retryCount = 0
try
retry:
catch ex as Exception When retryCount < 3
retryCount += 1
goto retry
end try

Language Specification Archive

Should we put the different version of the language specification into?

  • Own Branch
  • Own Subdirectory under spec?
    So that when a new language version is officially released it has be archived, thus supporting reviewing bugs / issues from a specific version.

[Proposal] Improvements on the VisualBasic anonymous variable more elegant

Hi,

Currently the VisualBasic With anonymous variable syntax can save our coding time, but we just can not get the value of the anonymous variable, so I think we can using $ to reference the anonymous variable and get its value:

Sub Main()
    Dim array%() = {1, 2, 3, 5}

    For i% = 0 To array.Length - 1
        With array(i)
            Call Console.WriteLine(.ToString)
            Call Console.WriteLine($)
        End With
    Next

    With PopulateData()
        Call Console.WriteLine(.ToString)
        Call Console.WriteLine($)
    End With
End Sub

Public Function PopulateData() As Integer
    Return 1
End Function

If this new feature was implented, then we can using this With anonymous variable syntax in a more elegant way:

Sub Main()
    Dim array%() = {1, 2, 3, 5}

    For i% = 0 To array.Length - 1
        With array(i)

            ' using anonymous variable that we can know that 
            ' this code block is focus on implement the function 1
            Call Console.WriteLine(.ToString)
            Call Console.WriteLine($)
        
            ' This $ reference to the anonymous variable of   With array(i)
            With PopulateData($)  

                ' using anonymous variable that we can know that 
                ' this code block is focus on implement the function 2
                Call Console.WriteLine(.ToString)
                ' This $ reference to the anonymous variable of  With PopulateData($)
                Call Console.WriteLine($) 
            End With

            ' This $ reference to the anonymous variable of   With array(i)
            Call Console.WriteLine($ + 100)
        End With
    Next
End Sub

Public Function PopulateData(x%) As Integer
    Return x% + 98%
End Function

[Proposal] Extension method parameter modifer. eg Me

'Me' Parameter Specifier for VB

Proposal
Allow the usage of 'Me' on the first parameter of a method, to indicate an extension method.

  • Definition
    Same semantic usage rules as the attribute <System.RunTime.CompilerServices.Extension()>
    Must be on first parameter, and only first parameter.
  • Parser Support Personal PR
  • Semantics / Binder Support
  • Synthesis of the method attribute <System.RunTime.CompilerServices.Extension()>
  • Unit Tests
  • Error Messages (needs reworking)

Example

Public Module Exts
  Public Function IsEven(Me Value As Integer) As Boolean
    Return Value Mod 2 = 0
  End Function

  Public Function IsOdd(Me Value As Integer) As Boolean
    Return Value Mod 2 = 1
  End Function

End Module

will be functionally equivalent to have then <System.RunTime.CompilerServices.Extension()> attribute on the method.

Public Module Exts
  <System.RunTime.CompilerServices.Extension()>
  Public Function IsEven(Value As Integer) As Boolean
    Return Value Mod 2 = 0
  End Function

  <System.RunTime.CompilerServices.Extension()>
  Public Function IsOdd(Value As Integer) As Boolean
    Return Value Mod 2 = 1
  End Function

End Module
Public Module Exts
  <System.Runtime.CompilerServices,Extension>
  Public Function IsOdd( value As Int32 ) As Boolean
    Return ( value Mod 2 ) = 1
  End Function
End Module

Proposal: Removing limitations of Tuples, by adding reference tuples and generating custom tuple types

Reference tuple types
I have been using tuples with Preview 5, and lack of reference types is particularly striking. With ValueTuple as structure, I can't use tuples for mutable lists or dictionaries.

Dim l = new List(Of (X As Integer, Y As Integer)
l.Add((1,1))
l(0).X = 2 ' compiler error, member of structure can't be modified

Replacing whole tuple

l(0) = (2, l(0).Y)

is very unpractical, and nobody will update lists that way, especially with higher number of tuple's members.

For now I have solved this problem by creating my own library with tuples identical to those in your library posted on nuget, except that ValueTuple types are classes instead of structures. After referencing this library to the app, tuples in lists can be mutable.

I suggest to add another set of tuple types to the library that you created and posted on nuget. New tuple types will be classes with another name (for example ReferenceTuple). To specify that reference tuples must be used, there must be added entry in AssemblyInfo,

<Assembly: TupleReferenceTypes(True)>

(BTW:
If external library with tuples is not referenced by app, then compiler error says that 'ValueTuple must be defined or imported'. How to define these ValueTuple in my app code, if I do not want to use external library ? Docs do not state how to do it.
)

Custom generated types for tuples.
Tuples using ValueTuple are not suitable for reflection scenarios (databinding, serialization and others), because these scenarios require original names of members. These limitations can be removed, when tuples will be handled by compiler generated custom types, instead of ValueTuple types.

Custom types for tuples are enhancement, not replacement, so user may decide which model is used across assembly / app, by adding entry to AssemblyInfo

<Assembly: TupleCustomTypes(True)>

There is need that names of compiler generated types must be deterministic, because serialization requires that behaviour to operate correctly. For example for tuple:

Dim t = (A:=0, B:=(C:="abc", D:=0))

name may be like VT_A_INT_B_TUPLE2_C_STRING_D_INT (prefix VT_ means value type, while RT_ means reference type, if TupleReferenceTypes(True) is specified for app/library). Such name is too long, so may be hashed to shorter variant, and final name for custom type is Tuple_7654567. Such generated names are bit cryptic, but they are only used to carry data, and with widespread use of type inference, this won't be problematic.

These custom types must be unique across assemblies,and this may be achieved in some special way. Custom types won't be included into app/library, but into external assembly with fixed name (for example TupleCustomTypes.dll). This external assembly will be automatically created and updated by compiler. App/library will get only metadata which describe custom types that are used internally, and these types will be referenced from external assembly (TupleCustomTypes.dll). When some library with metadata will be referenced by project, then compiler will read these metadata, and update external assembly (TupleCustomTypes.dll). For backward compatibility with previous compilers, external assembly must be shipped with library. There also may be created external tool, that generate single external assembly, from multiple libraries with metadata.

These two enhancements, will make tuples really shining and universally accessible for much many scenarios, than currently.

Proposal: Add Exit If to VB

Will be useful for quick exit and enable to avoid 'iffize' inactive code

First case:

...
If x = 0 Then
Dim y  = 0
...
If y > 1 Then Exit If 
...
End If

Here Exit If exits from outer If

Second case:

...
If x = 0 Then
...
Exit If
...
...
End If

Seems like unnecessary, but this is useful when we want to temporarily avoid some code (potentially problematic) from execution

Current alternative is

...
If x = 0 Then
...
If False Then
  ...
  ...
End If
End If

which require more work and attention

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.