Some potential language ideas for future versions of VB
Mads Torgersen recently gave a talk called “The Future of C#”, where he described some potential C# ideas that are on the minds of the team at Microsoft. He showed glimpses of a delightful IDE experience that deeply understands your code and that helps with diagnostics and refactorings. On the language front, he showed no big language paradigm shifts, but instead various places where C# could remove some irksome limitations and increase productivity.
What would be the VB equivalents of what he showed?
Here are some ideas. Please note that, as with what Mads said in his talk, nothing in the list of language ideas is committed. This is all just speculation about potential ideas for some future version of VB. Some of these ideas follow in spirit (i.e. removing VB-specific irksome limitations). Others are ideas that follow in detail (i.e. speculations about the VB equivalent of C# ideas that Mads mentioned). There are many other ideas that we've considered in the past, some of which have made it into the product eventually, some of which are still under consideration even if not on this list, and some of which were rejected.
As always, the best place to tell us what features you'd like to see is through voting on UserVoice. If there are bugs you want us to fix, file them on Connect. If you want to be part of a public discussion on language design issues, you can do that anywhere - we read your comments on our blog posts, and we read your blogs and tweets (especially if you point us to them!)
Comments after implicit line-continuations
Currently you can’t write comments after an implicit line-continuation. This is a pain, especially when you want to comment individual lines in a LINQ expression or an array/object initializer. IDEA: Allow comments after implicit line-continuations.
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
Readonly autoprops
Currently when you write an auto-property, it is always ReadWrite. IDEA: (1) let you declare ReadOnly auto-properties, and the compiler will implicitly generated a ReadOnly backing field; (2) let you assign to a ReadOnly auto-property within the constructor, and the compiler will implicitly treat it as a write to the backing field.
Class Customer
ReadOnly Property Name As String
ReadOnly Property Address As String
ReadOnly Property LastModified As DateTime = DateTime .Now
Sub New (name As String , address As String )
Me .Name = name
Me .Address = address
End Sub
End Class
Multiline strings
Currently in VB, string literals can’t be split over multiple lines. IDEA: let them, as is currently the case in C# verbatim string.
Dim x = < xml ><![CDATA[ this is how
I currently write a multiline string ]]></ xml > .Value
Dim y = "this is how
I'd like to write a multiline string"
String Interpolation
Currently when you use String.Format with a lot of arguments, it’s easy to get your {0}, {1}, {2}, … mixed up. And when you build up a string using concatenation it can get hard to read. IDEA: Allow string interpolation, which is found in various other languages. The code below shows an idea for syntax - use the prefix $ in front of an interpolated string, and interpolate an expression within curly braces, and allow format specifiers. And it shows an idea for semantics - translate it into String.Format in InvariantCulture, but let the compiler optimize into String.Concat or whatever it wants if that’s faster.
Dim query = $"https://{ url }?name={ Escape(name) }&id={ Escape(id) }&o=xml"
' = String.Format("https://{0}?name={1}&id={2}&o=xml",
' url, Escape(name), Escape(id),
' CultureInfo.InvariantCulture)
Dim fn = $"{ drive }:\{ folder }\{ name }.{ ext }"
' = String.Format("{0}:\{1}\{2}.{3}",
' drive, folder, name, ext,
' CultureInfo.InvariantCulture)
Dim csv = $"Name,FractionIn,FractionOut
{ Code1.Name },{ Code1.FIn :0.00},{ Code1.FOut :0.00}"
' = String.Format("Name,FractionIn,FractionOut{0}{1},{2:0.00},{3:0.00}",
' vbCrLf, Code1.Name, Code1.FIn, Code1.FOut,
' CultureInfo.InvariantCulture)
Ease up on LINQ expression names
Currently when you write a Select clause, then under the hood VB creates an anonymous type and tries to pick names for the members. In the code below it picks the name “ToString” – but this isn’t allowed as a member name, and so it gives an error! IDEA: if “Select” is the last clause, and has only one item, then skip name-generation entirely. (Also do this if it’s followed only by Distinct / Skip / Take).
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
International date literals
Currently in VB we can only write date literals in US format. IDEA : allow them to be written in international (ISO) format as well. (Updated thanks to @rbirkby's comment that ISO requires 2-digit months and days):
Dim us_format = #2/3/2013 17:52:51#
Dim iso_format = #2013-02-03 17:52:51#
Binary Literals
Currently other languages such as F#, Java and some versions of C++ allow binary literals while VB only offers decimal, octal and hexadecimal. IDEA: allow binary literals, with the &B prefix:
Dim code = &B001010
Digit Group Separators
If you had to write out a 32-bit binary literal, it’d be easy to make mistakes. IDEA: allow a digit-group-separator. (Is underscore a better separator like in other languages? or space?)
Enum E
Car = &B 00 01
Bicycle = &B 00 10
Foot = &B 00 11
Fastest = &B 01 00
Shortest = &B 10 00
Scenic = &B 11 00
End Enum
Partial interfaces and modules
Currently in VB you can only write classes that are partial. This is sometimes a problem for people who write automatic code-generators, but is more general than just that. IDEA: allow interfaces and modules to be partial, like they already can in C#.
' a.vb
Partial Interface I
Sub WrittenByUser()
End Interface
' a.g.vb
Partial Interface I
Sub WrittenByCodeGenerator()
End Interface
Params IEnumerable
Currently if you have a ParamArray argument then it must be an array. But people typically like to write methods which take IEnumerable rather than arrays. IDEA: Allow you to declare a method with ParamArray IEnumerable(Of T).
Sub f( ParamArray x As IEnumerable ( Of String ))
' If someone invokes f("hello", "world")
' the compiler still translates the callsite into f({"hello", "world"})
TypeOf IsNot
Currently you have to write out negative TypeOf tests in a cumbersome way. IDEA: let you use TypeOf IsNot:
If Not TypeOf sender Is Button Then ... ' cumbersome
If TypeOf sender IsNot Button Then ... ' nicer!
Null-propagating operator
This is a highly-voted suggestion on UserVoice, but the comments there are decidedly mixed. IDEA: Not really sure if there are any good clean ideas here.
Dim y As Integer = x?.y?(3)?.z
' one idea: the ?. and ?() operators are like the normal . and () operators,
' but instead of throwing NullReferenceException, they just return the default
' value of the final part of the expression "z"
Dim y = If (x.y(3).z, fallback)
' another idea: re-use the existing binary If operator, but instead of throwing
' NullReferenceException along the way, it jumps straight to using the fallback.
Constructor type inference
Currently it’s a pain to have to supply generic type arguments explicitly when you construct a new object. IDEA: if you attempt to construct a new object of type “List”, say, and there is no non-generic version of List imported, and out of all constructors of all the generic versions of List that are imported there is only one where you can infer the types and it works, then pick that one.
Dim x = New List ({1, 2, 3}) ' should infer New List(Of Integer)({1,2,3})
Declaration Expressions
Currently there are several places where you declare a variable in one line only to use it in the immediate next line. IDEA: (1) Allow you to declare functions with Out parameters, and allow you to declare variables in-place when you invoke them. (2) Allow you to declare a variable “inline”
' (1) Declaration of an out-parameter function:
Function TryParse(s As String , Out x As Integer ) As Boolean
' (1) Invoking an out-parameter function, and declaring the variable inline:
If Integer .TryParse(s, Out x) Then ... ' this version infers type of x
If Integer .TryParse(s, Out x As Integer ) Then ... ' here explicitly provide type
' Both mean this: Dim x As Integer : If Integer.TryParse(s, x) Then ...
' (2) Declaring a variable inline:
If ( Dim x = GetValue()) > 15 Then Console .WriteLine(x)
' Means this: Dim x = GetValue() : If x > 15 Then ...
Expression-bodied functions
This was one of Mads’ ideas in C#, to allow you to write particularly terse functions and getter-only properties. It’s not clear what would be the VB equivalent syntax for such a feature, or even whether VB would benefit from such terseness.
public override int GetHashCode() => X.GetHashCode() % Y.GetHashCode();
public double Dist => Math .Sqrt(X * X + Y * Y);
Primary constructors
This was one of Mads’ ideas in C#, to allow you to write constructors more easily whose parameters can be used in field/property initializers. It’s not clear what would be the VB equivalent for such a feature, because VB is case insensitive, so this example would be impossible.
class Point ( int x, int y)
{
public double X { get ; } = x;
public double Y { get ; } = y;
public double Z { get ; } = Math .Sqrt(X * X + Y * Y);
}