dotnet / vblang

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

[Proposal] Lets shrink full-body properties #567

Open VBAndCs opened 4 years ago

VBAndCs commented 4 years ago

Looking at this property, which I had to write a full body just to deal with a property of some internal object in my control:

Public Property IsReadOnly As Boolean
   Get
      Return Me.TexTBox.IsReadOnly
   End Get
   Set(value As Boolean)
      Me.TexTBox.IsReadOnly = value
   End Set
End Property

I suggest to simplify it to:

Public Property IsReadOnly As Boolean
    Get Me.TexTBox.IsReadOnly
    Set Me.TexTBox.IsReadOnly = value
End Property

The Get keword have the same meaning of Return, so, when we just deal with a one line body, we can shorten it to Get [the return val] The Set [assignment statement] also makes a readable English statement, and is similar to Let statement in LinQ and old VB syntax.

Furthermore, in cases where the property is jst a wrapper of another one, I suggest a more compact form. You can choose between these:

Public Property IsReadOnly As Boolean On Me.TexTBox.IsReadOnly
Public Property IsReadOnly As Boolean Of Me.TexTBox.IsReadOnly
Public Property IsReadOnly As Boolean With Me.TexTBox.IsReadOnly
Public Property IsReadOnly As Boolean From Me.TexTBox.IsReadOnly
Public Property IsReadOnly As Boolean For Me.TexTBox.IsReadOnly

I previously suggested another compact form for multiline Readonly Properties in #403 This new suggestion offers a compact form fro single-line readonly properties too:

Public ReadOnly Property Foo As Boolean On Dictionary("Foo")
pricerc commented 4 years ago

If I was marking an exam, this code would get a fail from me.

Public Property IsReadOnly As Boolean
   Get
      Return Me.TexTBox.IsReadOnly
   End Get
   Set(value As Boolean)
      Me.TexTBox.IsReadOnly = value
   End Set
End Property

I consider exposing a property of a control like this is to be bad practice, and not something that should be encouraged.

I makes maintenance more difficult. I just had a major challenge trying to figure out how some VBA code (written years ago by someone else) worked because there was so much of that kind of thinking going on, with controls being used instead of internal flags, it made reverse engineering the logic much more complicated than it needed to be.

You also risk a threading exception if a background thread sets (or gets, for that matter) that value.

The correct code for that would be more like:

    Private _isReadOnly As Boolean
    Public Property IsReadOnly As Boolean
        Get
            Return _isReadOnly
        End Get
        Set(value As Boolean)
            _isReadOnly = value
            Me.Invoke(Sub() Me.TextBox1.ReadOnly = value)
        End Set
    End Property

In my experience (and I've just been writing an app that does that kind of thing), it may start out as only one control that needs setting 'readonly', but then you need to add another control, and your 'one line' property has to be expanded again anyway.

VBAndCs commented 4 years ago

I don't know do you mean. This is a simple user controls with a combo box and add button, and I just want to expose some properties to control the inner comboBox. This is a WPF app and I figured out that I can modify the cod to be: Public Property IsReadOnly As Boolean On Me.cmboBox.IsReadOnly Of cource I use the shrinked syntax only here but there I am using the full chatty one! Any way, I see no harm in my code, so no need to complicate things without a real need. Thanks.

franzalex commented 4 years ago

If I was marking an exam, this code would get a fail from me.

@pricerc

I think you didn't get the suggestion made and instead dwelled on the propriety of the code sample given.

The suggestion is to simplify property getters and setters such that instead of writing something like this:

Dim _someValue As SomeType

Public Property SomeValue As SomeType
    Get
        Return _someValue
    End Get
    Set (value As SomeType)
        _someValue = value
    End Set
End Property

You rather write this:

Dim _someValue As SomeType

Public Property SomeValue As SomeType
    Get Return _someValue
    Set _someValue = value
End Property

This is however different from auto-implemented properties in that it allows binding a property to any member (or a property of that member).

VBAndCs commented 4 years ago

No need for return:

Dim _someValue As SomeType

Public Property SomeValue As SomeType
    Get _someValue
    Set _someValue = value
End Property
VBAndCs commented 4 years ago

And in ultra compact form (as there is no operations on the body:

Dim _someValue As SomeType

Public Property SomeValue As SomeType On _someValue
JustNrik commented 4 years ago

And in ultra compact form (as there is no operations on the body:

Dim _someValue As SomeType

Public Property SomeValue As SomeType On _someValue

Auto properties already exist in VB and they already expose the backing field with an underscore.

VBAndCs commented 4 years ago

@JustNrik This is why I gave a use case, where we need to expand the property to control the back field. Auto properties are not always an available solution.

gilfusion commented 4 years ago

The case where a property just wraps around a field or other property but not the one an auto property gives... seems so rare that it's not worth wasting special syntax on. Either go for the auto property or the regular manual one.

Now, single-line Get and Set I understand and fully support. The fact that there's nothing between single-line auto properties and 8-lines-minimum full properties is quite frustrating, especially when the logic in the properties is short and simple.

One case I have hit before is the casting property case:

Public Property Value As Double

Public Property StringValue As String
    Get
        Return CStr(Me.Value)
    End Get
    Set
        Me.Value = Val(Me.Value)
    End Set
End Property

Of course another common case is computed properties, where a one-liner in C# is still five lines of code in VB.

public bool IsValid => data != null;

vs

Public ReadOnly Property IsValid As Boolean
    Get
        Return data IsNot Nothing
    End Get
End Property

Even shortening those down like this would be a partial win.

Public Property StringValue As String
    Get CStr(Me.Value)
    Set Me.Value = Val(Me.Value)
End Property

Public ReadOnly Property IsValid As Boolean
    Get data IsNot Nothing
End Property

(Now, is this more readable? That's subjective, and while I think it is, that might not be true for everyone.)

VBAndCs commented 4 years ago

seems so rare that it's not worth wasting special syntax on

I disagree. I face this a lot, and I fall in an error due to differences between C# and VB, since I tend to write: Public ReadOnly Property Foo = MySource Thinking it is like the C#'s: Public Foo => MySource to find out that the VB syntax reads the value of MySource once and stuck with it. This will differ is we can use: Public ReadOnly Property Foo On MySource and in readonly properties, I suggest to allow expressions not just vars: Public ReadOnly Property Foo On MySource + 1 Or maybe: Public ReadOnly Property Foo : Get MySource + 1

I like this even more than:

Public ReadOnly Property Foo 
   Get MySource + 1`
End Property

In fact, I'd like to generalize the one line If Then rule to be used on all blocks, to have compact one statement blocks, such as: For I = 0 to 5 : Console.WriteLine(I) Without the need of Next

For some reasons: 1- We are in a surviving war against C#. Developers tend to compare the two syntaxes and prefer the more compact one. We prefer VB readability and will not give it up, but if there is any chance to combine readability and compaction, so we must go for it. 2- Compact syntax is a must for nowadays huge apps, to save not only the coding time, but also to make it easier for new team members to read the code and maintain it.

  1. VB is a LANGUAGE, and should be eloquent. Every time I code in VB or C#, I face many situations where I need to write more lines to do simple things, so, I can't express my thoughts directly, and loose time to reshape my ideas and use workaround to get what I want. Over years, VB and C# became a workaround-based languages, and the teams always busy to do important things, so, why give us a better way to do thing we can do by ugly workarounds? It is a luxury they can't afford! So, the languages becomes harder for beginners, breaks the new developers expectations, and the code becomes unnecessarily longer and less readable.

So, I think VB.NET must make use of this mandatory break, to get a fresh design that solve every minor issue and have every syntactic sugar we desire, to come out in a new fashion as the simplest and most powerful smart language ever. Note that I am not concentrating on just basic syntax. I started a different approach a year ago by looking at XML literal as a powerful forgotten tool of VB, and Used it to create a Razor engine (named Vazor), and suggested to extend this to make VB a generic script host language by allowing to embed scripts in interpolated strings with the support for already existing VS editors for many scripts such as JS, TS .. Etc. The idea is VS has lots of tools, but they belong to different teams, and every team don't want to do any thing more! This ends up having the same thing done more than once by different teams, but you can't make use of any when you need them! As and example, I was trying to add Blazor support for VB.NET, and needed to use the DOM in my project. Theere are two DOMs in VS: one is a COM library, and the other belongs to TS. I failed to find any easy way to convert the source of any to VB or C#, and it wat too huge for me to do it manually. I figured out that I dive into TS source to modify its code generators to generate the C# code, which will need a life time! The easiest and simplest way if to use the Ts Dom as a dll in C#, which turned out to be impossible, as CLR doesn't know any thing about TS! So, there is no code translator, no CLR compatibility, and no way for Dot net to converse with TS, although they belong to the same company, and used in the same IDE! This is the kind of wasting resources that eventually lead to kill VB! Also, there was a promising path, when Anthony D. Green picked up the XML literal potential, and used it to embed Xaml of WPF and Xamarin and razor syntax as in my Vazor, beside translating VB to JS (via expressions tress) to work in browsers. There are wonderful prototypes for all that in his VB fork. This could make VB.NET the most powerful langue in VS, but every thing collapsed suddenly and VB declared frozen! So, in short: 1- We need to razor the VB syntax. 2- We need to energize the XML literals to make VB work everywhere with the most resilient and powerful dynamic script generator ever. I have a working project (Vazor) that make VB create ASP.NET Core apps, and Anthony has amazing proto types for WPF, Xamarin and VB on client side, which I hope he finish.

  1. We need to make the general form of script embedding, so VB can host other languages scripts, not just HTML-Like taged scripts that uses XML literals. These three points, can take VB.NET where no language went before!
pricerc commented 4 years ago

@pricerc

I think you didn't get the suggestion made and instead dwelled on the propriety of the code sample given.

Not at all.

I think I have been reading Mr @VBAndCs suggestions for long enough that I usually understand them quite well! We've have a few 'enthusiastic' discussions, and long may they continue.

This proposal is basically about a VB version of C#'s expression-bodied properties. I have some sympathy with that.

However, his example was (in my opinion, and it's only an opinion) a poor one, because it uses a control on a form to hold a value that belongs to the form, and in the 20-odd years that I've been coding in VB, that's always been a bad idea.

In other words, he is proposing a syntax to help with a problem that wouldn't be helped by his example (IMO).

For a proposal to have credibility with a language designer, it needs to 1) clearly articulate a problem, then 2) clearly articulate a proposed solution, and then 3) clearly articulate how the change will improve the language. I think that as provided, this proposal fails on all three counts.

pricerc commented 4 years ago

I face this a lot, and I fall in an error due to differences between C# and VB

You are not alone. But I think this is a bad reason to make changes to VB.

Especially if the existing VB logic could be considered "Better".

1- We are in a surviving war against C#.

Not that I agree with this statement, but even if it is true, then the more VB changes to be more like C#, the more VB loses the war: the fewer differences there are between the languages, the fewer are the reasons to choose VB over C#.

2- Compact syntax ... easier for new team members to read the code and maintain it.

For me, these are usually mutually exclusive.

pricerc commented 4 years ago

Also, how is this different from #61 ?