dotnet / vblang

The home for design of the Visual Basic .NET programming language and runtime library.
290 stars 64 forks source link

Expression-bodied members and blocks #343

Open ghost opened 6 years ago

ghost commented 6 years ago

I think VB.NET can make use of C# => symbol to write Expression-bodied subs, functions, properties and even blocks. There should be implicit line continuation around the => symbol.

Sub Sub1() => MsgBox("Test")

Function Func1(X as integer) As Integer => 2 * X

Dim x as integer
Property Prop2() As Integer
   Get => x
   Set => x = Value/2  
End Property

' or in short:
Property Prop1( ) As Integer <=> x

Property Prop2() As Integer => 100 ' This is a read-only property

Property Prop3() As Integer <= 100 ' This is a write-only property

And in blocks:

For I = 0 To 10 => Console.WriteLine(I)

Function Test(N as Integer) =>
     For I = 0 To N => Console.WriteLine(I)
pricerc commented 6 years ago

I know this is very subjective, and I'm sure you will have people who support this idea. But I disagree.

I don't think this would improve the language, or its usefulness.

1) I think VB the language is great the way it is. Sure it is lacking access to some frameworks stuff that's already been discussed elsewhere in this forum, but it doesn't need new symbols for contracting simple constructs that are mostly supplied by code completion (snippets, Intellisense, code generators). Less does not always == more. Needing to type fewer characters is nowhere near a good reason to add a feature to the language, which is the only advantage I can see.

2) It looks like VB trying to be C#, which is kinda dumb imo. My big sister likes to make the observation: "Women who seek equality with men lack ambition". That's kind of my view of people who want VB to be more like C#: lacking vision.

3) I really don't like expression bodied stuff, since I find it makes code less easy to read, and I think it's far more important that code is easy to read than easy to write (because code gets read WAAAAY more often than it gets written). I also don't like anonymous methods/delegates for the same reason - in my view, they add 'opacity', when I prefer 'transparency'. Basically, I've had to debug so much anonymity that I now avoid it - I almost always use named methods and delegates, which are also easier to add breakpoints to.

One of the things I like about VB is that (when well written) it is understandable even by people who aren't programmers, and adding unnecessary symbology, or additional ways to do stuff we can already do, would hamper that.

And while I (kind-of) get where you're coming from, some of your examples are far from convincing. e.g. I don't think that:

For I = 0 To 10 => Console.WriteLine(I)

offers any objective advantage over:

For I = 0 To 10 : Console.WriteLine(I) : Next

And likewise, I'm struggling to think of a use-case for:

Sub Sub1() => MsgBox("Test")

since the only time I have code that looks anything like that is just prior to refactoring, usually because I've put in a placeholder method that will actually do something when I get around to coding it later, and it looks like this:

    Sub Sub1()
        ' Throw New NotImplementedException()
        MsgBox("Test")
    End Sub
ghost commented 6 years ago

@pricerc I tend to agree with most what you said. But sometimes large nunber of lines of code has a nigative effect on the readability. I want to build on this: For I = 0 To 10 : Console.WriteLine(I) : Next Can it be: For I = 0 To 10 : Console.WriteLine(I) as the single line if statment drops "End If"? I don't want to make VB.NET Like C# (I hear the opposite there :) ). I want the have the best ot the two languages. So, the =>symbol is not of any particular importance to me, and if : symbol can do the job, so be it! What about:

Sub Sub1( ) : MsgBox("Test")

Function Func1(X as integer) As Integer : 2 * X

Dim x as integer
Property Prop2() As Integer
   Get : x
   Set : x = Value/2  
End Property

And in blocks:

For I = 0 To 10 : Console.WriteLine(I)

Function Test(N as Integer) :
     For I = 0 To N : Console.WriteLine(I)

the : at the end of the line implies an implicit line continuation!

reduckted commented 6 years ago

Isn't this the same as #61?

@pricerc I know this is very subjective, and I'm sure you will have people who support this idea. But I disagree.

Same here. I'll even quote myself from my comment in https://github.com/dotnet/vblang/issues/61#issuecomment-293399015:

I find these types of expressions to be far less readable than a normal method/property. I realise that it's subjective though.

As for less typing, the IDE already does most of the work for you. You just have to type Get, press enter, and the IDE will insert the two End statements.

JustNrik commented 6 years ago

I'd like it this way:

    Private _name As String
    Public Property Name As String
        Get _name ' This would work just as Get : Return _name : End Get
        Set _name = Value ' Same as above
    End Property

    ' Also, this makes life easier for private/protected/shared/friend/etc
    ' For example
    Private _level As Integer
    Public Property Level As Integer
        Get _level
        Protected Set _level = Value
    End Property

    ' Another Example
    Private _exp As Integer
    Public ReadOnly Property Exp As Integer Protected Get _exp

    ' Now, for methods
    Public Sub Log(text As String) Console.WriteLine(text)
    Public Function IsGreaterThan(x As Integer, y As Integer) Return x > y ' Compiler may infer return type just as lambdas do
    Public Function IsLowerThan(x As Integer, y As Integer) As Boolean Return x < y' Another option.

' This will basically work as
    Public Sub Log(text As String)
        Console.WriteLine(text)
    End Sub

    ' Another possible syntax
    Public Sub Log(text As String)(Console.WriteLine(text))
    Public Function IsGreaterThan(x As Integer, y As Integer)(x > y)
    ' Other options for Functions
    Public Function IsLowerThan(x As Integer, y As Integer)(As Boolean)(x > y)
    ' -- Or --
    Public Function IsLowerThan(x As Integer, y As Integer)(Boolean)(x > y)
    ' -- Or --
    Public Function IsLowerThan(x As Integer, y As Integer)(x > y)(As Boolean)
    ' -- Or --
    Public Function IsLowerThan(x As Integer, y As Integer)(x > y)(Boolean)
    ' -- Or -- -- Personally, this is the one I most like --
    Public Function(Of Boolean) IsLowerThan(x As Integer, y As Integer)(x > y)
    ' -- Or --
    Public Function IsLowerThan(x As Integer, y As Integer)(Of Boolean)(x > y)
hartmair commented 6 years ago

What about almost already existing lambda syntax in order to keep the VB.NET language consistent?

Public Function Foo(x as Integer, y as Integer) x > y
ghost commented 6 years ago

@JustNrik @hartmair Nice. I like what your syntax. But add bloks like loops: For I = 0 to 4: Console.WriteLine(I)

@AdamSpeight2008 @AnthonyDGreen

JustNrik commented 6 years ago

I can't really figure out a good syntax for it, not saying yours is bad but idk

For x = 0 To 4 Do Console.WriteLine(x)

Or yours maybe

ghost commented 6 years ago

@JustNrik Mine doesn't add new syntax to VB. the : symbol is already a part of the language. All I want is to erase the next keyword if the for loop has only one statement written in the same line. This is similar to If cond then DoSomthing. Same with other loops and blocks: While Not Stop : Stop = ReadData(Buffer)

JustNrik commented 6 years ago

@JustNrik Mine doesn't add new syntax to VB. the : symbol is already a part of the language. All I want is to erase the next keyword if the for loop has only one statement written in the same line. This is similar to If cond then DoSomthing. Same with other loops and blocks: While Not Stop : Stop = ReadData(Buffer)

The small issue about it is that : already has an use, so I think the compiler will confuse it

Atm you can do this:

For x = 0 To 4 : Console.WriteLine(x) : Next

How the compiler will know if he should wait for that : Next or just put it implicitly?

For x = 0 To 4 : Console.WriteLine(x)
Dim y = x + 1

In this case, will the compiler know the end of for-loop scope or take in count the variable declaration?

Implementing this feature without a keyword will be kinda hard, specially if you pretend to use : which is used for line continuation

What about almost already existing lambda syntax in order to keep the VB.NET language consistent?

Public Function Foo(x as Integer, y as Integer) x > y

Personally, it will look weird.

Public Function Sum(x As Integer, y As Integer) x + y

I'd prefer

Public Function Sum(x As Integer, y As Integer)(x + y)

or

Public Function Sum(x As Integer, y As Integer) Return x + y

or

Public Function(Of Integer) Sum(x As Integer, y As Integer)(x + y)
ghost commented 6 years ago

@JustNrik You are right. This brings back the need for the => symbol. it is a very well self explaning famous symbol, so I do not waorry about VB code readability. For x = 0 To 4 => Console.WriteLine(x)

pricerc commented 6 years ago

it is a very well self explaning famous symbol

possibly, depending on your background, but for me: not really, I've never fully understood it. It looks like an assignment symbol.

But then I've only been coding for 33 years. (I started with (Turbo) Pascal, Assembler and COBOL before C, then C++, and later VB6/VBA).

so I do not waorry about VB code readability

Really? For anyone I know who has worked with code that is more than about six weeks old, code readability is THE. MOST.IMPORTANT thing, if not THE.ONLY.THING. And probably the best thing VB has over C/C++/C# is code readability.

The only objective advantage I can see with your suggestion is less typing. But as well stated by @reduckted in #61:

As for less typing, the IDE already does most of the work for you

So aside from less typing, what is the practical enhancement that this suggestion makes to the language?

Berrysoft commented 6 years ago

How about

For x = 0 To 4 Do Console.WriteLine(x)
hartmair commented 6 years ago

@JustNrik Just my two cents to your suggestions:

Public Function Sum(x As Integer, y As Integer) x + y

Although I suggested it yesterday, I agree: I dislike it visually

Public Function Sum(x As Integer, y As Integer)(x + y)

I dislike the parentheses. Too many parentheses quickly become confusing

Public Function Sum(x As Integer, y As Integer) Return x + y

I have nothing to complain about this syntax 👍 👍 👍

Public Function(Of Integer) Sum(x As Integer, y As Integer)(x + y)

Please, don't change the order of declaration like in C# where result comes first

ghost commented 6 years ago

@hartmair I like your syntax too: Public Function Sum(x As Integer, y As Integer) Return x + y

ghost commented 6 years ago

@pricerc

So aside from less typing, what is the practical enhancement that this suggestion makes to the language?

In fact my main focus is on for loops and similar blocks. making these blocks shorter when they contain only one statement will make lambda expression containing them more readable. Besides, I have a different opinion about readability. Code doesn't exist only in VS.NET. We read also in books, websites like this and in slides. Why do wast paper, ink and scrolling time (in pdfs, slides and websites) just to write/read unuseful ending statements? Verbose VB.NET code became one disadvantage that drive new programmers away to C#. I am a fan of VB semi-English syntax, and I prefer it over C-languages syntax, and feel sorry that MS pushes VB.NET back behind C# and even F#. But this doesn't mean VB shouldn't make use of good features in other languages. Good Readability doesn't mean writing more than enough! Verbose readability is inefficient readability.