dotnet / vblang

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

[Proposal] Allow using New in Function declaration #580

Open VBAndCs opened 4 years ago

VBAndCs commented 4 years ago

Suppose we have this function:

    Function Foo() As List(Of Integer)
        Foo = New List(Of Integer)
        Foo.Add(1)
        Foo.Add(2)
    End Function

I suggest to allow use New in the declaration (as in properties), like this:

    Function Foo() As New List(Of Integer)
        Foo.Add(1)
        Foo.Add(2)
    End Function
Echo-8-ERA commented 4 years ago

Auto properties allow it so they can have similar syntax to field declarations. The same cannot be said for methods.

pricerc commented 4 years ago

Actually.

Personally, I no longer return values from functions this way - I always use a "Return" statement.

BUT this is legal syntax in VB:

Function Foo() As Integer
    Foo = 1
    Foo = Foo * 10
    Foo = Foo + 3
End Function

So, I think I could buy into this proposal. I don't think it's inconsistent with the language, and it would not be a breaking change.

I don't see a problem with an explicit instantiation of the result for a reference-type function in this way.

Also, this might encourage developers with the concept that a method should "do one thing, and do it well".

VBAndCs commented 4 years ago

Personally, I no longer return values from functions this way

Me too, but in case of returning a list, it seems a better choice. But I wouldn't use the function name in the right-hand side, as only () can make it a recursive expression.

pricerc commented 4 years ago

But I wouldn't use the function name in the right-hand side, as only () can make it a recursive expression.

I don't think that's a necessary limitation.

This completely contrived example doesn't do anything useful, except to show how it could be on both sides, abusing recursion to produce a list of tuples (example written using LINQPad):

Sub Main
    Foo(0).Dump()
End Sub

Shared foos As Integer = 0

Function Foo(depth As Integer) As List(Of (Integer, Integer))
    Foo = New List(Of (Integer, Integer))
    For f As Integer = 1 To 5
        foos += 1
        Foo.Add((depth, foos))
    Next

    If depth < 5 Then
        Foo.AddRange(Foo(depth + 1))
    End If
End Function

Could this be abused? Absolutely. But recursion has always been an excellent target for abuse; that's no reason to not allow it.

But if you needed a Foo that was a bit more complex, then this could be useful. Maybe some kind of fractal calculation for building a tree for use in a modeling program.

pricerc commented 4 years ago

I suppose, technically, my example didn't have the result on the right hand side anywhere, but I do have it being used as a parameter, which is nearly the same thing.

gilfusion commented 4 years ago

I wonder if this could somehow play into writing single-line factory methods?

Function CreateFoo(value As Integer) As New Foo(value) : End Function

It's a far cry from C#'s =>, but it's something.

VBAndCs commented 4 years ago

Recently, I am dealing with an interesting language named Ring. Blocks in this langue can be identified just by their header line, so, it is optional to add a closing token to the block (the keyword end), or to enclose the body with {} like C-family languages (as Ring is written by C++, but belongs to dynamic languages). Look at this image:

Ring

So, why just VB allow one line methods, to optionally drop the End Sub, End Function, End Get, "End Set", and "End Property" (if the driped out the Get/End Get decoration from read only properties?` This could be be a smart compromise between Ring multi-line methods and C# bodied methods.

Function Foo1( )
     Return Something

Function Foo2( ) :  Return Something