| Profil de JustinVarious Technical TopicsPhotosBlog | Aide |
|
|
21 mai VB and Language ChoiceA recent Coding Horror post got me thinking again about C# vs. Visual Basic. As you know, I myself think that VB is probably the best general purpose managed language available right now, so I thought I'd add my $.02 to the discussion. VB vs. C# is like Coke vs. PepsiI don't think this analogy holds up, because it doesn't take into account the complexities of the situation. I believe that there are real substantive differences that make VB a better tool for writing programs than C#. While it's true that tools like CodeRush and Resharper can greatly improve the C# experience, they still fall short of what's theoretically possible from a VB-based toolset, because, no matter what you do to C# (or Java or any other C-style language) you will always be missing the three key features that make VB better. Namely the Readable Keywords, Line-Orientation, and Case-Insensitivity I detailed in a previous post. I'm not claiming VB/Visual Studio is better in every way than Eclipse/Java, IntelliJ/Java, Resharper+VS2005/C#, etc. I'm just saying that if all these tools were refined to their highest potential, I would like VB best because it has a better foundation. VB is currently missing some major features such as the ability to automatically handle Imports, that make it difficult to compare it favorably to these other tools. Case Insensitivity is Right and Case Sensitivity is WrongI hope that most VB users would agree that it's not the Case Insensitivity of VB that we actually like. In fact, at the language level I believe it's a mistake for VB to be Case Insensitive. What people really like about VB is that most of the time it's not the author's responsibility to worry about case. The feature that we really like is that the IDE will fix the case to match the declaration or keyword. I think a better way to implement this feature would be to require Case Hyper-Sensitivity at the language level which would disallow multiple symbols in scope that differ only by case. No competent VB programmer would ever want something like "sySTeM.cONsolE.WRitELINE(foo)" to compile. We just think it's ridiculous that C# and Java IDE editors make us constantly contort our hands with two-key combinations. This only slows down our typing, causes hand cramps, and makes us 2% (est.) less happy. For those of you who've grown accustomed to Resharper, IntelliJ or Eclipse, this is exactly equivalent to many of the features you would miss if switching to Notepad/Java. In fact, my first impression using IntelliJ was that somebody copied 20% of the good features from VB, and then thought of a bunch of new must-have features that I didn't even consider. The problem is that none of the IDE vendors are really doing a good job of incorporating the best features of their competition. What would be ideal is a JetBrains/VB based on Mono, or better yet a completely new language that takes the important ideas of VB while stripping away the too-long keywords, and other features that I dislike in VB. (Overall I like the readable keywords in VB, but some are just too much. ) Strongly TypedThe Ruby and Python movements have convinced many people that they really want a loosely typed language. Of course, one of the great things about VB is that you can choose within a given file whether you want strong or loose typing, but I'm not convinced that most people even truly want loose typing in most cases. What people really seem to like is not having to waste time keying in all the type information. They like the flexibility that the tool can just figure it out. You can get most of this benefit without having to give up the performance and other benefits of a strongly typed language. Upcoming versions of C# and VB will have a feature called Type Inference, wherein the language will simply figure out the type from the context in which it is used. For instance, in C# 3.0 I can write "var x = foo.ToString();" and C# will infer that the type of x is String. One thing that I don't like about the new VB/C# type-inference feature is that it seems to be implemented at the language level. Language vs. IDEI believe that the single most important key to the future of programming is the realization that Programming Languages as classically defined are an idea whose time has passed. Tools like VB, IntelliJ, and Eclipse have blurred the line between IDE and language, but the real key is realizing that the language side of the line is no longer needed at all. In fact, it's a huge detriment. This is the primary reason why I can't really get excited about any new language such as Ruby. I see these all as vestiges of a legacy mode of thinking. Multi-LanguageOne of the benefits of .NET was supposed to be that you could use any language that you like. However, as Jeff has noticed this dream has not been realized. The problem is that we're not really free to choose any language we like, because the fact is that most code is going to have to be maintained and written by multiple people each with different preferences. Jeff's experience is that most people have settled on C# as the de-facto .NET standard language despite the superiority of VB. Over time he seems to have been worn down by the C#-zealots, and their fanatical devotion to a language attuned to those with masochistic tendencies, but I have to believe that he still realizes deep-down that he knows a better way. The fundamental problem with a multi-language platform like .NET is that what we really want is the ability to maintain the same code in multiple languages. If I write a class in VB, then someone else needs to be able to maintain that class in C#, Python, or Ruby without having to translate the language. The key is that the code itself can't know what language it's written in, and that can only happen when we get rid of this silly old-fashioned notion of parsing languages written as text files. 18 janvier Things I Would Change in VB
VB is a great language, but I still think it has room for improvement. For example, there are far too many keywords, some of the keywords are confusing, and some keywords have too many overloaded meanings. There are also problems with the IDE that should be addressed. More than any other language, VB has always been about a partnership with the IDE, and this functionality is crucial for its ease of use and power. Language ChangesDeclare instead of Dim for variable declarationThe use of the keyword ‘Dim’ for variable declaration is an historical artifact of Basic. A more descriptive name would be ‘Declare’ which is already a VB keyword, but used for a feature of dubious value. Here are some examples, of what I would prefer, and I'll continue to do so in subsequent examples: Declare x,y,z As Integer Declare names(1 to 10) As String Declare teams() As String = GetTeams() Too many uses of parenthesesI personally find it confusing that parentheses are used for expression grouping, array declarations, indexing, and function calling. I think it would be more readable if we used brackets for indexing and arrays. Declare names[10] As String names[0] = “Justin” names[(x + (y \ 2))] = “Michel” Console.WriteLine(“Name = “ & GetNamePrefix() & names[2]) GetType, TypeOfIt doesn’t seem like we should need both of these keywords. One option would be to use TypeOf (T) for retreiving the type of a class. I think this is more consistent with VB’s readable syntax. Even better would be to support accessing a Shared GetType method or read-only Type property on any type, which would eliminate the need for a keyword in this use case completely. Best might be to allow the type name itself to be used. Declare t As Type = FileStream.GetType() —or— Declare t As Type = TypeOf(FileStream) —or— Declare t As Type = FileStream.Type —or— Declare t As Type = FileStream Is, IsA, and TypeOfThe current keyword "Is" should be used to compare for identity only. If used with two reference types then it returns true if both refer to the same exact object. If used with value types then it returns true if both have the same value. Basically, I’m suggesting elimination of “If TypeOf X Is Y Then” as a special case, although if we retain TypeOf as outlined above, then “If TypeOf(X) Is Y Then” and “If TypeOf(X) = Y Then” are both legal and equivalent. A new keyword IsA should be introduced to allow easy comparison of types. A IsA B should return true if A is the same type as B, A derives from B, or if B is an interface implemented by A. Declare A, B As Foo A IsA Foo ' returns true Foo IsA A ' won’t compile, because left hand side is a type. A IsA B ' won’t compile, because B is an object. A IsA B.GetType() ' returns true It’s also confusing that Is must be used in a Select expression. It seems like the extra keyword should be unnecessary. Select age Case 5 To 10, 12 To 15 Case < 5, 13, 16, > 80 ' No need for “Case Is < 5, 13, 16, Is > 80” Case Default End Select Too many conversion keywordsI think all of CBool, CByte, CChar, CDate, CDbl, etc. can be eliminated by replacing them with a single Convert function. It would behave exactly the same as the current keywords. Declare d As Double = 3.14 Declare x As Integer = Convert(d, Integer) -- but also allowing -- Declare x As Integer = Convert(d) My proposed syntax is a little more verbose, but eliminates 15 keywords, some of which can be hard to remember. It also supports implicit detection of the desired type if possible, as in the example above where it can see that the target of the Convert is an Integer, and saves you the trouble of explicitly stating that. I would also allow a third parameter to Convert for specifying the type converted from. This can be useful when the source type is not always obvious, and when you want a warning when source type is refactored. Declare x As UInt32 = Convert(GetAge(), From := UInt64) This takes advantage of current named argument syntax to allow both implicit detection of the To type and explicit specification of the From type. If the GetAge function is someday updated to return a Int64, then the code would no longer compile, preventing a possible bug when dealing with negative values. DirectCast too verboseThis keyword is unnecessarilly verbose. Fortunately there is already an intuitive and logical replacement already in the language. Declare x As Object = GetFoo() Declare y As Foo y = x As Foo The As keyword is already used to declare the type of an object, and the above syntax should be obvious in meaning. As with DirectCast, if x is not a Foo, then an exception would be thrown. It would also be nice to allow this syntax to be used when it’s known that the source and destination types differ. In this case, “As” would be equivalent to Convert. Declare d As Double = 3.14 Declare x As Integer = d As Integer Eliminate TryCastThe use of TryCast doesn’t really add any value. Instead of: Declare x As Foo = TryCast(y, Foo) If x Is Nothing Then x.Blah() End If you could just use: If y IsA Foo Then Declare x As Foo = y As Foo x.Blah() End If The compiler should be able to figure out how to make the latter syntax just as efficient as the former. No need for CTypeThere should be no need for this keyword, which is kind of a hybrid between casting and conversion. This should be replaced by either As or Convert. The use of CType for defining conversion operators on a class would use the keyword Convert instead. Nothing vs. NullThe VB concept of Nothing is almost always referred to as Null in other languages, and even within much of the VB community (Probably because of SQL). Having a separate term for such a common concept is just confusing for users old and new. Declare x As Foo = Null Assert(x IsNot Null) Assert(x = Null) No need for AddressOf keywordNowhere else in VB is the notion of pointer or address exposed, and it’s likely that AddressOf doesn’t really return an address anyway. We could just use the Function or Sub keyword in place of AddressOf. From the examples in AddressOf documentation: AddHandler Button1.Click, Sub Button1_Click Declare t As New Thread(Sub CountSheep) Add the ability to Define aliasesThe C++ typedef keyword is often useful for writing maintainable code, and sometimes C++ references are handy in situations other than parameter passing. I propose that a new Define keyword could provide this functionality for VB in an intuitive way. It can allow you to enhance readability. For example, by defining a new IntList type we save typing and enhance readability whereever List(Of Int) is used. This becomes more valuable with more complex generic types. Define IntList As List(Of Integer) Declare v As IntList It can also be useful for changing a type without having to update all the code, or to allow conditional compilation to use different types. #If SafetyEnabled Then Define MyInt As SafeInteger #Else Define MyInt As Integer #End If Define is already partially available with Imports. I would remove the ability for Imports to define new aliases and use the Define syntax instead. Imports Con = System.Console
becomes Define Con As System.Console This keyword could also be useful for defining aliases for other things besides Types. Sub Foo Declare aReallyReallyLongName As SomeType = GetSomeType() Define s As aReallyReallyLongName s.SomeMethod() Define sm As s.SomeReallyLongMethodName s.sm() End Sub More flexible ImportsI’d like to Import a symbol within small scope. I see no reason why this couldn’t be allowed anywhere instead of only at the top of a file. Sub Log() Imports System.Console Write(a) Write(b) WriteLine(c) End Sub No need for Delegate keywordWe should just be able to define a delegate type like any other. Define Sub OnClick(ByVal e As EventArgs) AddHandler Button1.Click, Sub OnClick Public Event As OnClick Remove Alias, Ansi, Auto, Declare, Lib, and UnicodeThese keywords for declaring access to external functions make it marginally easier to access external Win32 routines, but cause unnecessary clutter in the language, making it that much harder to understand. They are also unnecessary, because it’s not much harder to just use the DllImport attribute. Consider removing keywords for basic typesThe CLR already defines nice unambigous names for all the basic types such as Byte, Integer, Short, Long, etc. It might be better just to use those, and eliminate the unnecessary keywords from VB. Most of the VB keywords are the same as the names defined in System anyway, so this wouldn’t be that onerous. The proposed Define feature could even provide easy compatibility for old code. No need for the Call keywordIn VB you can call a subroutine by saying “Call Foo”, but you can also get exactly the same behavior by saying “Foo()”. I don’t see any benefit to the former syntax, and it adds yet another unnecessary keyword to the language. Select instead of “Select Case”There’s no need to support an optional Case keyword in the first line of a Select statement. We should just standardize on the following syntax, and eliminate a little more clutter from the language. Select age ' vs. Select Case age Case 0 To 20 Foo1() Case 21 Foo2() Case 25, > 30 Foo3() Case Else Foo4() End Select LiteralsThere are currently some basic types that have no syntax for literal declaration such as Byte. There are also some type such as Char where the literal syntax is unintuitive. A better character literal might use the back-tick (e.g. `c`). Eliminate the colonOne of the strengths of VB is its readable line-oriented syntax. The colon operator allows you to subvert this. Eliminating this would help keep VB code readable to all VB programmers. The other use for the colon is to declare labels for GoTo statements, but I’m also proposing elimination of GoTo for VB. Eliminate the underscoreSimilarly the underscore is a crutch that should not be needed. Code should either rely on wrapping in the IDE, or introduction of temporary variables to make code more readable. However, to make this work, we need to eliminate some of the most egregious causes of lengthy lines. The UsesAttribute keyword fixes one such area, new syntax for Implementing interfaces fixes another, and the proposed Define keyword another. Bring Back the underscoreInstead of using the underscore for line continuation, I would use it to disambiguate VB keywords that match symbols. Currently the [] brackets are used for this purpose, but I think those work better for array access as stated previously, and prepending an underscore seems a more intuitive solution. Hopefully the elimination of many keywords will make the need for disambiguation much less prevalent. Remove the \ symbolAlthough integer division is probably fairly frequently used, I find the inclusion of two separate division symbols confusing. Integer / Integer, should leave the arguments as integers, while Int / Float and Float / Div Int should convert the result to a floating point type. Anything else can be handled by explicit conversions and/or separate math library functions. It would also be helpful if the IDE would colorize integer types differently than floating point. Eliminate If … Then … Else … StatementsOne of the primary values of VB is its line-oriented nature. I was completely unaware that the current VB allows If Then Else on a single line without an End If. This should not be allowed, as it subverts the nature of VB, by allowing a tiny syntactic convenience with far greater potential for misuse than valid use cases. For example, this currently compiles, and I don’t think it should. If x > 0 Then Return “>” Else Return “<=” Introduce a short-circuiting ternary expressionOne of the problems with the C ternary expression is that the default case is separated from the context by the boolean expression. For example, if I want to Trim() only a non-null string in C#: String trimmed = s != null ? s.Trim() : “”;
Notice how the code we really want to write “String trimmed = s.Trim();” is very different from the code we have to write to handle the null. I think VB has the opportunity to make this common expression more readable by reordering the “arguments” to allow: String trimmed = s.Trim() ? s != null : “”; Or in VB: Declare trimmed As String = s.Trim() IIf s IsNot Nothing Else “”; Other examples: If a = (b IIf b < 5 Else 5) Then If a = (b IIf b IsNot Nothing Else GetDefault()) Then Foo(a, (x IIf a > 0 Else GetDefault()), z) y = 10 IIf x Is Nothing Else x.Foo() Introduce UsesAttributeInstead of overloading the < and > operators for applying attributes, I propose we add a new keyword to make this feel more natural in VB, and to eliminate one of the major needs for the underscore line continuation character. Sub Foo(ByVal s As String, ByVal n As Int32) UsesAttribute Conditional(“A”) UsesAttribute WebMethod ' Body of subroutine End Sub Class SomeService Inherits Foo Implements Bar UsesAttribute WebService(Namespace:=”blah”) Sub New() End Sub Sub Calculate UsesAttribute WebMethod End Sub End Class Unweildy Interface-based polymorphismA strength of VB is its readable English keywords, but in practice this can sometimes get out of hand. Public Interface Shape Function CalculateArea(ByVal X As Double, ByVal Y As Double) As Double End Interface Public Class RightTriangleClass Implements Shape Function CalculateArea(ByVal X As Double, _ ByVal Y As Double) As Double Implements Shape.CalculateArea Return 0.5 * (X * Y) End Function End Class In general, any time the underscore has to be introduced to allow a logical line to continue on the next physical line, we see an area for improvement. The following would be a much nicer syntax for the above, with the option of reverting to the really verbose syntax only when there’s a conflict, or when you want to change the name of the interface. Public Class RightTriangleClass2 Implements Shape2 Function Implements CalculateArea(ByVal X As Double, ByVal Y As Double) As Double Return 0.5 * (X * Y) End Function End Class EraseThere’s no need for this keyword, as you can get the same effect by assigning Null. The Erase statement supports a variable number of arguments, but the limited utility of this is not worth the introduction of a keyword. Instead, if this functionality is important, then it would be more useful to allow ParamArray to use ByRef making it easy to implement Erase as a user function, as well as other possibly useful functions. ReDim and PreserveThis functionality seems easy enough to reproduce with a few small functions, possibly added to the Array class. On, Error, ResumeThese keywords are no longer necessary in a modern VB. We now have exception handling, and these just clutter the language in the name of reverse compatibility. No public fields in Class typesBy eliminating the capability to create Public members of a class type, we can use the following syntax to declare simple properties. Class Foo Public ReadOnly name As String Public age As Int32 End Class More complex properties could revert to the older syntax using Property. Public fields would still be allowed in value types. No more Set or Get“Set” is just too valuable to waste on a keyword. I’d rather have a System.Collections.Generic.Set for holding sets of objects. When declaring properties we can just take advantage of the fact that the mutator is always a Sub, while the accessor is always a Function. Then we no longer need the two keywords. Private myName As String Public Property Name As String Sub (ByVal s As String) myName = s End Sub Function Return myName End Function End Property Goodbye GotoLet’s be the first language to discard goto. CS programs usually go to great lengths to teach students that goto is almost always the wrong solution. The variety of languages available on the .NET platform means that some languages like VB and C# can eliminate goto, while others (C++?) could keep it. Generic RAII scopeThe Using statement is one useful way to ensure that object are disposed correctly, but sometimes it can be cumbersome, and can lead to unnecessarilly deep nesting. It would be useful to introduce Scoped variables to handle this more cleanly in some cases. Sub Test If blah Then Scoped x, y, z As Connection ' x, y, aand z are disposed here End If If blahblah Then Scoped lock1 As Mutex = … Scoped lock2 As Mutex = … … ' lock2, lock3, … are released End If End Sub Eliminate SyncLockMore general Scoped and Using keywords can replace the need for this. Modules, Namespace, and Shared Class membersI find it a little confusing that all these exist. Maybe this could be simplified by allowing global functions in a Namespace as an alternative to Modules, or eliminating the Namespace keyword entirely and using the Module keyword for this concept. No NextIt would make VB easier to understand and more consistent if “Loop” were used to end For Loops. This is consistent with the other loop variants, and makes it clearer what’s happenning. Eliminate While LoopsDo While … Loop should be sufficient without the need for While…End While. This doesn’t actually save keywords, but simplifies the language by eliminating an unnecessary and more verbose syntax for while loops. The IDE could allow leaving off the Do keyword, and filling it in automatically. Simplify Continue and ExitContinue is followed by Do, While, or For to indicate which type of loop to continue. This added flexibility is unnecessary, and Continue should just jump to the top of the current loop. For I = 1 to 10 Do While blah … If x Then Continue End If Loop Loop The above, would simply restart the Do While loop when x is True. If you really need to restart at the beginning of the For loop then the code can be refactored into multiple methods or some other approach. Similarly, only “Exit Loop” should be supported in the future. Exiting a sub, function, or property is accomplished with “Return”, and exiting a Select is unnecessary. ElseIf is inconsistent"For Each" and "End If" use two separate words, so Else If should also. Declare x As ObjectIt would be nice if the “As Object” part of the expression were optional even when Option Strict and Option Explicit are enabled. The default value for any type would be Object. So I would advocate: Declare x More flexible OptionsAs fancy new features such as Lambda Expressions and Closures are added to the language, we may want more flexible control over the options. For example, we may want to turn Strict and Explicit off for Lambdas, while leaving them on for everything else. We might also want finer control of the scope for these options, perhaps turning off Option Strict within the scope of a single Function. Rather than have keywords for these two statements, just introduce new VB attributes. StrictMethods(on|off) – controls whether late binding is allowed StrictConversions(on|off) – controls whether Int64 auto-converts to Int32 ExplicitLambdas(on|off) – controls whether lambda expressions require types etc. Consider eliminating or extending WithBy allowing an empty with statement we can introduce an artificial scope, which can sometimes be useful to avoid having too many variables in scope. Usually it’s better to split such a method into separate subroutines, but this can sometimes make an algorithm harder to understand. With Declare x As Integer … End With ' x is not in scope It would also be useful to assign an alias for the With object. Sub Foo() With f = GetEmployee.Name.FirstName f.blah() Log(f) End With End Sub However, this is not so necessary with the proposed Define keyword: Sub Foo() Define f As GetEmployee.Name.FirstName f.blah() Log(f) End Sub RaiseEvent unnecessaryThis keyword is similar to Call, and is also unnecesary, when the obvious syntax of calling the event as a function would be more intuitive. Event LogonCompleted(ByVal UserName As String) Sub Logon LogonCompleted(“Justin”) End Sub AddHandler, RemoveHandlerUsing language keywords for these is confusing. The C# syntax might be fine, or VB could automatically allow any Event/Delegate to have implicit Add/RemoveHandler methods. Note that += should NOT be used, because we’re appending to the list of handlers, therefore &= concatentation is more appropriate. Public Event LogonCompleted(ByVal UserName As String) Sub OnLogon(ByVal x As String) End Sub Sub New LogonCompleted &= Sub OnLogon LogonCompleted.AddHandler(Sub OnLogon) End Sub No more REM, and add comment blocksThere’s no point in having two mechanism for line comments, although it might be useful to introduce a multiline comment. ‘’’ Anything between here and here is a comment ‘’’ No more implicit return variable for functionsHaving two ways to return a value from a function just adds complexity to the language with very little benefit. At best it saves a line of code or two to declare the return value and return it, but often modern programs don’t (and shouldn’t) declare a single return value anyway. Rename ShadowsThe description for this feature, provides the answer for what the keyword should be. “Specifies that a declared programming element redeclares and hides an identically named element, or set of overloaded elements, in a base class.” By renaming the keyword to Hides, it becomes more accessible to a new or infrequent VB programmer. Hides should also be useable to explicitly state desired behavior. Sub Foo Declare I As Integer If blah Then Hides I As String End If End Sub No End or StopThe Stop keyword should be removed from the language. There’s no need for this to be a language-specific feature, as it’s easy enough to use the portable System.Diagnostics.Debugger.Break() method. The End keyword (that halts the process) should also be removed for similar reasons. Normally, you would either let an uncaught exception percolate up and kill the process, or you could call Process.Kill() possibly followed by Process.WaitForExit(). Allow automatic assignment of Arrays to variablesPython has some useful syntax for working with Tuples. VB could add some of the same convenient syntax for working with arrays. Allow automatically assigning array values to variables. The a,b, and c variables would be filled with the first three values from the array. Function Foo() As String() … End Function Declare a, b, c As Integer = Foo() Also, allow more flexibility for array initializers. Declare x, y, z As Integer = 1, 2, 3 Add SlicesPython has the useful ability to access a subset of any List, String, or Tuple. VB could support similar syntax without complicating the language much. Declare s As String = “Hello World” s[0] equals ‘H’ s[0 To 2] equals “H s[-1] equals ‘d’ s[-4 To -2] equals “orl” etc. Remove MidBy allowing slices to be assigned, you make a more flexible Mid that is also more intuitive to read. Eliminate need for GetCharA single element slice should automatically return a Char instead of a one element string. The new `a` character literal should be equivalent to “a”[0]. No need for { } array initializersVB should be able to figure this out without the braces, and should be able to parentheses to make the association explicit where it would be ambiguous. Declare x, y, z As Integer = 1, 2, 3 Declare x[] As Integer = 1, 2, 3 Declare x[][] As Integer = (1, 2, 3), (1, 2, 3) Declare x[2, 2] As Integer = (1, 2, 3), (1, 2, 3) Sub Foo(ByVal a() As Int32, ByVal b As Integer) End Sub Foo((1, 2, 3), 4) Array Bounds vs Last index confusionI still find the syntax choice for array declarations confusing, and it doesn’t help much that the To keyword is supported. (Unless the IDE were to add it automatically.) Declare x(5) As Integer should create a 5 element array with a lower bound of zero. This use of the To keyword should be removed again, because allowing flexible lower bounds just makes arrays more confusing to work with. For those who want or need explicit lower bounds, a generic BoundedArray class could be provided. Automatic ToString when using concatenationOne of the benefits of having separate unambiguous concatenation operator ‘&’ in VB, is that it can automatically convert its arguments to strings. Declare I As Integer Declare f As New Foo f & I & “blah” I & f & “blah” This is currently possible only by explicitly implementing the concatentation operator for Foo, but it requires providing an implementation for every possible valuetype, or inefficiently overriding for just Object, forcing boxing. This could be partially helped by allowing generic operator overloading, but that would still be far too tedious for the common case. It might even be desirable to remove operator overloading for the ‘&’ operator, and instead forcing that to always represent string concatenation and be handled automatically. Separate operator for assignment and equalityOne of the keys to VB’s ease of use is that it doesn’t allow assignment statements to return a value. Unlike other languages, you can’t do: Declare a, b, c As Integer a = b = c = 5 One result is that VB can always tell from the context whether ‘=’ is meant as an assignment or a comparison. This is actually a valuable feature, because it saves typing and prevents a common error from other languages. What I propose is that we use the := operator that is already used for named arguments as the only allowed assignment operator, and have the IDE automatically change ‘=’ into ‘:=’ as it’s parsed in the same way that it automatically changes “Endif” into “End If” and other similar transformations. One benefit is that we get immediate visual feedback that VB understood what we meant when it makes the transformation. For Loop should iterate only over the specified rangeThe following expression currently increments M, then checks to see if it’s less than 5. For M = 0 To 5 This is confusing given the VB syntax, because the syntax seems to imply that “M” will only take on the values 0, 1, 2, 3, 4 and 5, but it will actually be 6 after the loop. Besides being confusing, it can easily lead to infinite loops if the incremented variable overflows. If overflow checking is enabled, then instead of an infinite loop, you get an exception. Either is unwarranted. Eliminate MyClassI find this keyword hard to remember, and I’d just like to be able to use the name of my class to be explicit when necessary. Class Foo Protected Overridable Sub Bar() ... End Sub Public Sub CallMyBar() Foo.Bar() ' calls our own Bar Bar() ' calls the bar of our most derived class End Sub End Class Allow alternate spellings for Overridable, NotOverridableIt would be consistent with the English language to also allow Overrideable and NotOverrideable as synonyms. Eliminate Type CharactersOld style code that used type characters should no longer be supported. Function StrFunc(ByVal x&, ByVal y$, ByVal z#) They also shouldn’t be allowed for literals. Literal DateTime values should still be supported however, because they’re useful, and easier to read than alternatives. Declare d As DateTime = #11/11/1970 13:32# Literal Values for every typetmp = 42 ' Int32 tmp = 42UI ' Unsigned Int32 tmp = 42L ' Int64 tmp = 42UL ' Unsigned Int64 tmp = 42S ' Int16 tmp = 42US ' Unsigned Int16 tmp = 42B ' Byte tmp = 42SB ' Signed Byte tmp = 42.5F ' Float32 tmp = 42.5 ' Float64 Currently, only L, UL, and UI are supported Eliminate Assembly, Option Compare, Binary, and Text KeywordsWe shouldn’t have to use language keywords (even unreserved ones) to change these behaviors. The IDE or command line tools should be able to handle it when necessary, or UsesAttribute. Option Compare may be completely unnecessary, as String already provides explicit control. Add missing Volatile keywordThis should have the same meaning as other languages. GoSub, Let, and WendThese have been deprecated long enough and can all be eliminated if making the kind of sweeping changes I’m advocating. Bring Back VariantOption Strict is currently used for many related features, such as implicit type conversions and duck typing. However, it might be even better to reintroduce the Variant keyword to allow duck typing for individual identifiers. This would work even with Option Strict enabled. No VB-specific extension libraries by defaultI’d like to be able to write portable code that doesn’t rely on VB-specific libraries. I don’t care about access to legacy APIs that are currently in the Microsoft.VisualBasic namespace. Any features, such as the Convert function that are needed should be available without having to pull in other baggage as well. Lambda ExpressionsThis feature is partially planned for the next release, but I’m afraid it’s going to allow code that is too cryptic and terse for Basic. The proposed syntax is: inc = Function(y) y + 1
Which creates an anonymous single-parameter function that returns its parameter incremented by 1. This really doesn’t feel like VB, as a) It’s not line-oriented, and b) it implicitly returns y+1. Even though it would prevent some common lambda use-cases, I’d prefer VB to only allow lambda expressions as variable initialization, and requiring multiple lines. inc = Function(y) Return y + 1 End Function This is only a fairly minor extension to existing Function and Sub usages. The above would only be allowed with Option Strict and Explicit disabled. Otherwise you’d get the usual: Dim inc As Function(ByVal y As Integer) As Integer Return y + 1 End Function Must Intrinsic Functions Be Keywords?Several VB features involve mapping syntax that looks like a function call to CLR features. For example, Convert(x) becomes an appropriate ILAsm conversion function for the target assignment. If none of these had to be reserved as keywords, then it would simplify the language quite a bit. Assuming all the intrinsic function are in a suitable namespace, the usual namespace disimbiguation rules would apply. If these keywords can become intrinsic functions in a namespace, then more useful variations could be added such as explicit SafeConvert and UnsafeConvert functions that map to the various ILAsm type conversion features. Support Unmanaged CodeI’d like to be able to use VB syntax to write lower level code. Instead of dropping in to C++, I’d like to forgo garbage collection, and other fancy features to write small efficient code without giving up the readability of VB. A separate smaller set of System namespace libraries could be provided to give me everything I need to write device drivers, protocol stacks, and programs that need absolutely minimal footprint. SummaryIn summary the above proposals would eliminate 88 of the roughly 200 existing keywords while only adding 12 new ones. It would also eliminate some overloaded uses of current keywords, and introduce several powerful new features from other languages. The cost of all this is reducted compatibility with existing programs, eliminating the ability to simply compile. If this isn’t desirable, then a new Basic-style languages could be introduced. I believe the advantages of a much simpler yet more powerful language are worth it for writing new programs, and possibly even porting existing ones. Although the language would retain approximately 120 keywords after these changes, the remaining ones seemed to make for more readable code than alternatives from other languages. Many of the remaining words can only be used as part of compound word key words, as with “Each” which can only be used in a “For Each” statement. New Keywords (13)[], Declare, Null, IsA, Hides, Scoped, Volatile, ''', UsesAttribute, Define, ‘_’, Overrideable, NotOverrideable Removed Keywords (86){}, CBool, CChar, CDec, CDbl, CInt, CLng, CObj, CSByte, CShort, CSng, CStr, CUInt, CULng, CUShort, CDate, CType, DirectCast, AddHandler, RemoveHandler, AddressOf, Alias, Declare, Ansi, Unicode, Lib, Dim, Object, Byte, Char, String, Integer, Short, Double, Single, Long, UInteger, ULong, UShort, SByte, Decimal, Date, Call, Declare, Delegate, Erase, ReDim, Preserve, Error, Resume, GetType, GoTo, Let, GoSub, Wend, Namespace (Or Module), Next, Nothing, Option, Explicit, Strict, Compare, Text, Binary, On, Off, RaiseEvent, REM, Shadows, Stop, SyncLock, TryCast, TypeOf, Assembly, IsTrue, IsFalse, Mid, ':', '_', ‘%’, ‘@’, ‘!’, ‘$’, Set, Get IDE FeaturesAnother problem with the current VB is some very annoying or broken IDE functionality. Case Fixing BrokenVB is supposed to update the case of symbols to match their declaration, but this is currently broken in several instances. For example, when I type “imports system.data\n” at the top of the file, it should automatically change it to “Imports System.Data\n”. A concerted effort should be made to fix this in the various places where it doesn’t currently work, and additionally a simple Ctrl-K, Ctrl-D should fix up the whole document. Indentation is brokenIf you type “if blah then\n” then VB will automatically indent to the proper position on the next line. However, if you move the cursor to a different line, and then go back, it will no longer be at the correct position. This wouldn’t be too bad if the Tab key would take you to the correct position, but it does not. Improve syntax recognitionThe VB IDE used to be better about recognizing syntax as I type. For example, if I were to type “for<space>each<space>” on a line, then the IDE would capitalize “For” as soon as I hit the first <space> key. Currently, the IDE only colorizes “for” which tells me that it does recognize the keyword, but it doesn’t fix capitalization until the whole line is entered. I do think that most syntax errors shouldn’t be highlighted and indentation shouldn’t be changed until the line is finished, but case-fixing, coloring, and other formatting changes should happen as soon as possible. This used to be one of the best things about working with VB. Tab key shouldn’t indentIt should be possible to redefine the tab key to always indent the current line to the correct position, and NEVER to actually insert indentation. Basically it should be have the same as Emacs Tab, but without having to choose Emacs emulation. Allow assigning macros to tabIn previous versions of VisualStudio I was easily able to implement my own EmacsTab using a macro, and I was able to bind this to the tab key. This will require cleaning up the Code Snippets feature to not be hard-coded to use the Tab key for moving between editable fields. Macros Too DifficultA macro should be able to programmatically duplicate anything I can do using the keyboard. I've tried repeatedly to write a macro that would duplicate the functionality of the Emacs tab key, but I haven't been able to get what I want. This macro took me only a few minutes to figure out with Visual C++ 6. In general the macro API is just too difficult-to-use for the amount of time have to devote to customization. Maybe a simplified facade should be provided. More AssistanceVB should be more helpful by more often allowing me not to type long keywords such as NotInheritable. For example, it could let me type the shorter text “not”, and then automatically expand it to the real keyword based on the current context. In general the VB parser should provide more context-sensitive assistance as I type code. It should always provide immediate but non intrusive feedback that it understands what I’m typing. Non-Intrusive LayoutOften when I’m editing code, the current VB will immediately make layout changes as I type. This can make it very confusing in practice, because the indentation could “jump around” causing me to lose track of what I was doing. In general this is an example of VB taking the viewpoint of the parser rather than providing the illusion that it’s reading my mind. If I want to surround some code with “If … Then … End If”, then it only upsets me when VB immediately matches my newly inserted If with a previously existing End If, and indents my code accordingly. It’s only a slight distraction that some previous If now has a squiggly red underline indicating that it no longer has a matching End If. The solution is to ensure that VB doesn’t “jump to conclusions” on incomplete information. If a block of code contains syntax errors, then it should not be formatted, and it probably shouldn’t even be shown as a syntax error until I do something (Ctrl-S, Ctrl-K D, etc.) to indicate that I think the code is now correct. Perhaps VB could use a squiggly beige underline to tell me that it knows the code is not yet correct, but is currently waiting to see what I’ll type next. CustomizableI’d like some more advanced control over how the code is formatted. In addition to indentation stlye and coloring that are currently available, I’d like control over how keywords are capitalized, the ability to disallow language features, and other controls. No More CompilingWhen working with Eclipse/Java there is no concept of Compiling per se. Instead, the syntax is highlighted as you type, and certain actions like saving files or running the program will cause the compilation to happen in the background. This seems very much in the spirit of VB, and seems almost there already. MultiFile AssembliesIt would make unit testing much better if VB allowed you to easily create unit tests in the same assembly as the tested code, but in a separate project. This allows me to expose testing interfaces as Friends. The current workaround is to just include the tests in the same project as the tested code. Intellisense shows invalid valuesOften, after typing “xyx<dot><ctrl-space>” I’ll be given a dropdown list of irrelevant information. If VB doesn’t know the actual members of the xyz object then it shouldn’t provide a list at all. Automatic ImportsOne extremely nice feature of Eclipse/Java is that it can automatically figure out the imports. If I type in “Dim sw As StringWriter<ctrl-space>” then VB should prompt me with a list of namespaces that have StringWriter types. If there is only one possible choice then it should not even prompt. Additionally it should insert the necessay Imports statement at the top of the file. A corresponding feature from Eclipse/Java is the Ctrl-Shift-O keystroke which optimizes Imports. This automatically removes Imports that are no longer needed, and attempts to add any that are necessary. VB would require a new syntax for only importing selected types from a namespace. Code SnippetsSeveral things about this feature really annoy me. Foremost is that the replacment fields stay active till the file is closed. Maybe it wouldn’t bother me as much if it was formatted differently, such as a solid underline that only highlighted when the field was the active one. The ugly green color is enough to prevent me from using this feature. The workaround I’ve decided on is to make the background color white. This makes the code snippet fields invisible unless the cursor is inside the field. Still, I’d like to be able to hit Enter (or maybe Ctrl-Enter) and have the fields finalized as if I’d closed and reopened the file. Eliminate MyI’ve never liked the My feature very much. It seems like it could be replaced with the ability to assign duplicate Imports aliases. This would also allow me to pick a different name than “My”, and better control exactly what is included. For example, I might do the following: Imports Foo As System.Text.RegularExpressions Imports Foo As Microsoft.VisualBasic.Devices Imports Foo As Microsoft.VisualBasic.FileIO This would combine all the listed namespaces into a single Foo namespace. Any ambiguities would have to be resolved explicitly as usual. It would also work with classes, allowing Shared methods to be called directly as usual. SummaryEven though the list of things I would change about VB seems longer than my previous post about the things I like about VB, that shouldn’t give you the impression that I dislike the language. On the contrary I think it’s the best choice available on the .NET platform for most problems. C++/CLI provides more control, and the unique ability to comingle unmanaged and managed code. C# is similar to Java, more portable (Mono Linux), and has a few features that haven’t yet made it into VB. (yield, anonymous methods, unchecked, etc.) However, VB is the easiest to read and type, has the best editor, and is generally easier to work with for many problems. 17 janvier Why VB is Best
As I said in my previous post, I believe that Visual Basic is the best language for many types of applications. It provides all the power of C# and Java, but has arguably better tools and syntax. For now, I’ll concentrate on the positive, but in a later post I’ll discuss what I feel are VB’s shortcomings, and my suggestions for addressing them. For me, the most valuable VB language features are its Readable English Keywords, Line-Orientation, and Case-Insensitivity. The ability to quickly create GUI applications using drag-and-drop may have been the original selling point, but to me what makes VB great is the language. It’s currently my preferred tool for working on personal projects. Readable English KeywordsFor the most part, VB is a very easy language to read, and the keywords chosen come closer to conveying the correct meaning than with other languages. Many languages have a long list of special symbols that the user is required to memorize before the language is readable. Often the same symbol will mean completely different things depending on the context. While VB has the commonly used Math symbols, and even a separate concatenation symbol, overall its philosophy is to favor the use of keywords to help the user to understand the code. (As you’ll see later, I even think some of the current symbols should be removed.) The best VB keywords are those that help the reader to understand what’s going on without having to be fluent in VB or any other OO language. This helps beginners to learn the concepts, and also helps experienced programmers write more maintainable code. ExamplesInherits, NotInheritable, MustInheritThe VB syntax for object derivation is very clear and explicit as long as you’re familiar with the concept of inheritance in object oriented languages. Class Foo Inherits Bar End Class Furthermore the NotInheritable keyword is clearly related, and has the obvious meaning. NotInheritable Class Bar End Class This would cause the Foo class above to have a compilation error. The MustInherit keyword is also clearly related to the other two. MustInherit Class Bar End Class Even someone new to the language should be able to guess that this prevents the Bar class from being instantiated on its own. If you contrast the above with the corresponding concepts in Java (extends, final, and abstract) and C# (‘:’, sealed, abstract), it should be clear that the VB keywords are superior. Although Extends, NotExtendable, and MustExtend would work almost as well, the term “inheritance” for the whole concept is usually used even in Java circles. Overrides, Overridable, MustOverride, NotOverridableSimilarly, the concept of “virtual” is overused in computer science, and therefore a poor choice for describing class methods that can be overridden in derived classes. The VB keywords have a more obvious meaning, and may even make OO polymorphism easier to grasp for beginners. The equivalent Java ( [virtual], virtual, abstract, and final), and C# (overrides, virtual, abstract, and sealed) are not as clear and don’t work as well together. Shared, StaticVB uses the keyword Shared for methods and fields that apply at the class level. The C#, Java, C++ keyword static seems a little less clear to me, and gets muddled up with the separate concept for local data within a function that lives past the lifetime of the function. All four languages use static to describe this concept. Class Foo Public Shared Function CreateFoo() As Foo End Function Private Sub Bar Static called As Integer = 0 called += 1 End Sub End Class And, Or, NotUsing these simple keywords instead of the common &&, !, and || is more approachable and actually easier to type, because the latter require shift-key combinations. The C-style symbols are also fairly arbitrary and make C-style languages just a little harder to learn and use. ByRef, ByValLike C#, these do require you to understand the concepts of passing by value versus passing by reference, but I find the VB keyword a little clearer. Allowing the programmer to be explicit about ByVal also enhances readability, because I no longer have to remember which is the default. (It’s ByVal.) Do, While, Until, LoopI find the VB loop syntax to be flexible enough for any purpose, and much more intuitive than Java, C#, or C++. All the following are allowed. Do Until x Loop Do While x Loop Do Loop Until x Do Loop While x You can also Continue or Exit a loop explicitly. For, Each, InI think the VB iteration syntax is nearly perfect. For Each x In y is not so different from C#: foreach (x in iterable) but the required parentheses seem to break up the statement in a weird place. Java is worse, because it uses an arbitrary ‘:’ symbol that you have to train yourself to read as “in”. for (x : iterable)
For, To, StepThe counted loop is also fairly simple, and I think much easier to read than C#, Java, C++ equivalents. For c = 0 To 9 For n = 1 To 20 Step 2 as compared to : for (c = 0; c < 10; ++c) for (n = 1; n <= 20; n += 2) SummaryThe above is certainly not an exhaustive list of the well-named features in VB, and I certainly don’t imply that all VB keywords have good names. (Later, I’ll explore in more detail just which keywords I think should be renamed, and I even advocate removing almost 90 keywords.) However, overall I find most of the VB keywords to be more intuitive than alternative languages, especially for those who don’t have preconceived notions of what a concept should be named. (e.g. virtual) This makes the language more approachable for beginners, but also easier for experienced programmers. Line OrientedAnother major feature of VB is its preference for having one statement per line. This is a common practice by many programmers in Java, C#, and C++ as well, but VB has features to encourage the practice. No Semi-colon necessaryIn C-based languages you are required to put a semi-colon at the end of each statement, and an end-of-line has no special meaning. This allows a single statement to span multiple lines, and multiple statements to reside on a single line. I find that both of these practices tend to make code difficult to read. Tools such as Eclipse/Java have built-in code formatters to ensure that each statement resides on a single line, and to ensure that statements that span multiple lines have a consistent format. In VB, the default is for each statement to be terminated at the end of the line unless an underscore ‘_’ is placed after the statement, allowing a single statement to span multiple lines. VB also allows a colon ‘:’ between statements to force multiple statements on one line. As you’ll see later, I’d actually like these exceptions removed to force the programmer to find a more readable line-oriented style. Assignment Side EffectsIn VB, assignment is a statement, not an expression, and has no return value. In C++ terms, the VB assignment operator is written like this: void operator=(T lhs, T rhs); If I have an example, java program like this: if (x == 1000) {
x = y = z = 0;
}
Then in VB, I must write it as: If x = 1000 Then x = 0 y = 0 z = 0 End If Alternatively, I could use the colon: If x = 1000 Then x = 0: y = 0: z = 0 End If One other side-effect is that VB is able to disambiguate assignment from equality checking. The common problem of typing “if (x = y)” instead of “if (x == y)” in C-based languages is eliminated, because “If x = y Then” always refers to equality checking and “x = y” always refers to assignment. (Later, I discuss why I think VB should automatically display a different operator for assignment.) Syntax ValidationWhen you press the Enter key, VB knows that the statement is likely complete, and usually does syntax validation as well as possible automatic syntax cleanup. For example, if you type the first line of a multi-line expression such as “If x Then”, VB will automatically insert a closing “End If”, and put the insertion point at the correct spot, formatting your code as necessary. In practice this makes it feel as if VB is really aware of what the programmer is trying to do, and the IDE is an active partner in code construction. Other tools have some of these features, but I’ve never seen another tool be as unintrusive and natural about it as VB, although with VB.NET some things aren’t quite as smooth as in the past, which I’ll discuss later. Case InsensitiveIt’s pretty well known that VB is a case-insensitive language, but some may not realize just how much of a benefit this is to the programmer. Faster TypingDespite its propensity for fairly verbose keywords, I’ve always found that actually typing in vb programs is often faster than with other languages. This is partly because you rarely need to use two-key combinations. The IDE will automatically capitalize symbols to match the declaration. My educated guess is that VB will be 10-20% faster to type than an equivalent language like C# or Java. The key is to allow the IDE to share the load, and when switching to VB from another language I usually need some time to train myself not to capitalize symbols, add unnecessary parentheses, and to use caps-lock effectively. Here’s an example. Type in: mustinherit class Foo<Enter>public mustoverride function Count as integer<Enter><Delete Line><End><Enter>class Bar<Enter>inherits foo<Enter><Down><Down>return 0<Down> And what you will see is: MustInherit Class Foo Public MustOverride Function Count() As Integer End Class Class Bar Inherits Foo Public Overrides Function Count() As Integer Return 0 End Function End Class Only 3 two-key combinations are required for the above in VB. (The initial declarations of Foo, Count, and Bar.) For comparison, the same code requires at least 16 two-key combinations in C#. Furthermore, the VB code doesn’t require cleanup for formatting and indentation, making it even faster to write equivalent code. Better NamingBy disallowing multiple symbols with names differing only by case, VB forces you to pick less ambiguous names. This leads to better readability than common code in other languages. For example, I’ve often seen code like the following: Foo foo = new Foo(); If you read this aloud then both “foo” symbols sound exactly alike (which is the definition of less-readable). To make the best use of VB, you should also pick a naming convention that works well. For example, by always prepending or appending an underscore to private fields, you are increasing the number of two-key combinations required. A better convention is to prepend “my” or "m" to private fields, and to use camel-case for all other names. OtherConcatenation OperatorUsing the same operator for addition and concatenation leads to less readable code. By having a separate concatenation operator, the following code can compile. Dim s As String = 123 & "456" Note: If the + operator were used instead, then this would be a compile error. Optional Duck TypingVB supports optional relaxing of type rules. When “Option Strict Off” is specified for a file, then you no longer have to explicitly specify the type when declaring variables. VB will also automatically convert types. For example: Console.WriteLine(123 + “456”) will print “579”, not “123456”. VB will also allow access to any public member of a type as long as it can be found at runtime. This is what’s known in Python as “Duck Typing”, because "If it walks like a duck and quacks like a duck, it must be a duck". VB is the only language I know which allows selectively enabling this feature. Optional Explicit DeclarationCompletely separate from the question of type safety is whether to require variable declarations. Even when duck typing is desired, often it’s nice to still enforce variable declaration. This can eliminate some common typos, but can be selectively disabled just as with type safety. Declarative EventsVB supports the same events and delegates as C#, but also provides the ability to specify event handlers in the signature of a method. Class Foo WithEvents myCon As Bar.Connection Sub OnConnected() Handles myCon.ConnectedEvent End Sub End Class In this example, the OnConnected method is automatically “wired-up” to the myCon Connection object. This can often be more readable than the alternatives. Reference ParametersOccasionally it’s useful to be able to pass arguments by reference. This is supported by most (all?) .NET languages. Sub ChangeTwoInts(ByRef n As Int32, ByRef m As Int32) n += 1 m += 2 End Sub Named ParametersVB allows specifying explicit names for parameters. One place this can be useful is when calling a function that take a boolean. Public Sub DoSomething(ByVal isFinished As Boolean) End Sub b.DoSomething(isFinished:=True) This makes the code much more readable, and eliminates the need for a comment or temporary variable to clarify the code. Optional ParametersVB also allows optional parameters, although using this feature for public methods is discouraged because doing so makes the code non-portable. For example, C# doesn’t support code with optional parameters. Still, optional parameters can eliminate code duplication that would be required with method overloading, and shouldn’t be avoided for internal functionality or when portability isn’t important. Parameter ArraysVB supports creating methods that take 0 or more optional arguments of a single type. For example: Public Sub Foo(ByVal ParamArray args() As String) This function accepts Foo(), Foo(“a”), Foo(“a”, “b”), etc. Powerful SelectThe VB Select statement is similar to the switch statement provided in C-like languages, except that it’s more flexible. Here are examples that use the advanced VB features. Select Case age Case 0, 5, 10 Console.WriteLine("0,5,10") Case Is > 50 Console.WriteLine(">50") Case Is < 10 Console.WriteLine("<10") Case 16 To 19, Is > 30 Console.WriteLine("16-19 or > 30") Case Else Console.WriteLine("else") End Select Dim name As String = "Justin" Select Case name Case "Abe" To "Barney" Console.WriteLine("a-b") Case "Boris" To "Kevin" Console.WriteLine("b-k") Case "Kevin" To "Vincent" Console.WriteLine("k-v") Case Else Console.WriteLine("else") End Select Full Featured Exception CatchingThe .NET framework supports an optional filter for catch statements. VB exposes this functionality allowing you to only catch exceptions when some criteria is met. For example: Try ' do something Catch ex As Exception When LoggingIsEnabled Log(ex) End Try RefactoringVB has some basic Refactoring support built in, and a license for Refactor! which provides even more. I’m generally not a big fan of refactoring tools, but the VB stuff is pretty intuitive and unintrusive. The important ability to rename things is what I use most. Powerful ImportsVB can use the Import statement for more than just namespaces. For example, if I include “Imports System.Console” at the top of a file, then I can call “WriteLine()” directly without having to specify the Console class. SummaryDespite the length of the above list, I’m sure I’ve forgotten some features, but maybe it will entice you to download the free Express version and try it yourself. Overall I think that VB is the best language for most programming, and it should get even better in the future. The next version will likely introduce Type Inference, Lambda Expressions, Closures, LINQ, and other enhancements. In my next post I’ll discuss a large list of new features and changes that I personally would like to see in a future version of VB. 16 janvier Visual BasicI’ve been wanting to write some posts about Visual Basic for a long time. It’s one of the reasons I finally started blogging. While I haven’t been able to use VB for much beyond personal projects for the last 8 years, I had used it pretty extensively in the past. More recently, I’ve been using VB.NET for various personal projects, and I thought I’d share some of my thoughts and experiences. It seems that VB has always been misunderstood. Versions <= 6 have an undeserved reputation as a “toy” language, and this has carried over to some extent for VB.NET, even though it’s now almost identical to Java or C#. I feel VB was also misunderstood as a tool only suitable for database front-end applications. I actually never felt it was a very good tool for writing these types of programs. MS Access (which I suppose can be considered a VB dialect) was a far better choice, because of its improved support for bound controls and built-in reporting tools. For years VB was the most logical choice for many types of applications, but my problem was that it wasn’t terribly suitable for the kinds of programming that I prefer. With the advent of VB for .NET, I think VB may actually be the best choice for writing many applications that have been traditionally developed in C++. The Java community has proved that it’s at least possible to write Databases, Compilers, Development Tools, and other systems programs using a similar platform, and from a purely technical perspective, I think Visual Basic is a better choice than C# or Java for many of these kinds of applications. In coming posts, I’ll detail my reasons for believing so as well as a pretty exhaustive list of what I think could/should be done to make VB even better in the future. In my next post, I’ll discuss what I think are the best features of VB. 12 décembre Lambda Expressions In Visual BasicPaul Vick had a post last week, where he solicited feedback on syntax for this feature that will likely be included in a future version of Visual Basic. http://www.panopticoncentral.net/archive/2006/12/08/18587.aspx#FeedBack I originally posted my opinion in a comment on his blog, but it apparently didn't make it past the censors. He proposed 3 possible syntax variations, but I'm not found of any of them. My proposal is a fourth style, and I think it has a lot of merit. What's a Lambda Expression?This is probably better explained elsewhere, but basically it as an anonymous function. For example, given the following code, ... Class Test Private myNames As List(Of Name) ... Public Sub PrintLegalNames() For Each n As Name In myNames Console.WriteLine(n.ToString()) Next End Sub End Class we could replace the explicit loop using List.ForEach. Public Sub PrintLegalNames() myNames.ForEach(AddressOf WriteName) End Sub However, for this to work, we have to provide a suitable WriteName function. Public Sub WriteName(ByVal n As Name) Console.WriteLine(n.ToString()) End Sub My proposal is to support the following syntax. Public Sub PrintLegalNames() myNames.ForEach(Console.WriteLine(ByVal(0).ToString())) End Sub The lambda expression is just a normal expression that uses parameters and return statements inline. Here are some more examples that show multiple parameters, functions, and ByRef parameters compared to roughly equivalent code. Dim ary(0 to 9) As Integer Array.Find(ary, Return ByVal(0) = 2) Function Find2(ByVal x As Integer) As Boolean Return x = 2 End Function Array.Find(ary, AddressOf Find2) Array.ForEach(ary, ByRef(0) += 1) Sub AddOne(ByRef x As Integer) x += 1 End Sub Array.ForEach(ary, AddressOf AddOne) Array.Sort(ary, ByVal(1) >= ByVal(0)) Function Less(ByVal lhs As Integer, ByVal rhs As Integer) As Boolean Return lhs < rhs End Function Array.Sort(ary, AddressOf Less) What about closures?It wasn't mentioned in Pauls post, but I think closures are also a necessary feature so that the following code will work. Sub SendPartyInvitation(ByVal state As State) ... Dim legal As Integer = state.LegalDrinkingAge Dim names As List(Of Name) = CreateList() ... tmp = List.FindAll(names, Return ByVal(0).Age >= legal) ... End Sub The key feature, is that the "legal" local variable is available for use within the lambda expression, which would not be the case if each expression where simply an anonymous function. |
|
|