dotnet / vblang

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

Ternary Select Case #342

Open ghost opened 6 years ago

ghost commented 6 years ago

I suggest this syntax for a Ternary Select Case:

Dim Result = Select Case I 
   Case 0: "Zero"
   Case 1: "One"
   Case 10: "Ten"
   Case 100: "Hundred"
   Case 1000: "Thouzand"
   Case Else: "Any Other Number"
End Select

This is a short syntax for:

Dim Result As String
Select Case I 
   Case 0
      Result = "Zero"
   Case 1
      Result = "One"
   Case 10
      Result = "Ten"
   Case 100
      Result = "Hundred"
   Case 1000
      Result = "Thouzand"
   Case Else
      Result = "Any Other Number"
End Select

It is doable today like this:

Dim timeOfWeek = (Fumction(x)
     Select Case X
          Case 0: return "Zero"
          Case 1: return "One"
          Case 10: return "Ten"
          Case 100: return "Hundred"
          Case 1000: return "Thouzand"          
          Case Else: return "Any Other Number"
     End Select
End Function) (I)

But it will be nice to simplify this syntax.. I suggest:

Dim timeOfWeek = Evaluate(x = I) As string
     Select Case X
          Case 0: return "Zero"
          Case 1: return "One"
          Case 10: return "Ten"
          Case 100: return "Hundred"
          Case 1000: return "Thouzand"          
          Case Else: return "Any Other Number"
     End Select
End Evaluate

The Evaluate block is a lamda expression with suplied values for its parameters. this aloow us to evaluate any expression not just Select case, and work on any number of variables in the expresion.

If the Evaluate end Evaluate is not accepted, it can be done by the Function end function keywords, say like this:

Dim timeOfWeek = Function(x Integer:= I) As string
     Select Case X
           Case 0: return "Zero"
          Case 1: return "One"
          Case 10: return "Ten"
          Case 100: return "Hundred"
          Case 1000: return "Thouzand"          
          Case Else: return "Any Other Number"
     End Select
End Function
Berrysoft commented 6 years ago

You can write functions like this:

Function SelectCase(Of TValue As IComparable(Of TValue), TResult)(value As TValue, ParamArray cases() As (Value As TValue, Result As TResult)) As TResult
    For Each c In cases
        If value.CompareTo(c.Value) = 0 Then
            Return c.Result
        End If
    Next
    Return Nothing
End Function
Function SelectCase(Of TValue As IComparable(Of TValue), TResult)(value As TValue, dft As TResult, ParamArray cases() As (Value As TValue, Result As TResult)) As TResult
    For Each c In cases
        If value.CompareTo(c.Value) = 0 Then
            Return c.Result
        End If
    Next
    Return dft
End Function

And call them like this:

Dim result = SelectCase(I, "Any other number", (0, "Zero"), (1, "One"), (10, "Ten"), (100, "Hundred"), (1000, "Thousand"))
ghost commented 6 years ago

@Berrysoft Nice workarround, but it is beter to have a general syntax. I suggested the same in C#, and discovered that they already exprementing with expressions like this:

var result = i switch { 
    0 => "Zero",
    1 => "One",
    10 => "Ten",
    100 => "Hundred",
    1000 => "Thouzand",
    _ => "Any Other Number"
};

so, I'd like to have this in VB.NET. I can modify my suggestion to drop the case keyword like in C#, to be:

Dim Result = Select Case I 
   0: "Zero"
   1: "One"
   10: "Ten"
   100: "Hundred"
   1000: "Thouzand"
   Else: "Any Other Number"
End Select

But the first syntax has a better readability, so it is more like VB.NET syntax.

Nukepayload2 commented 6 years ago

@Berrysoft Your workaround reminds me of Function Interaction.Switch(ParamArray ValueExpr As Object()) As Object. It will evaluate all expressions, so you may get different result if you rewrite Select Case block with Function SelectCase.

Berrysoft commented 6 years ago

@Nukepayload2 Yes, my workaround is too simple. It's like the difference between If experssion and IIf function.

AdamSpeight2008 commented 6 years ago

Kinda reminds me of #160

jrmoreno1 commented 6 years ago

Reminds me of #109

ghost commented 6 years ago

@jrmoreno1 : Yes, they almost the same, with a slightly different syntax. I don't see a reason to add {} becuase Select case is a whole block, that doesn't need additional encosure. The : I added after the case are alresy a feature ov VB to combine two lines, so this is not a difference.

jrmoreno1 commented 6 years ago

@MohammadHamdyGhanem: that proposal wasn't settled on having the {}, the issue to be determined is whether there were other instances where a block made sense, if not then no use having the brackets. There was no proposal for anything else although If/ElseIf might be useful.

ghost commented 6 years ago

@jrmoreno1 After reading the discission, I added this suggestion:: It is doable today like this:

Dim timeOfWeek = (Fumction(x)
                Select Case X
                       Case DayOfWeek.Monday To DayOfWeek.Friday
                           return "Work Week"
                       Case DayOfWeek.Saturday, DayOfWeek.Sunday
                           return "Weekend"
                 End Select 
End Function) (Date.Today.DayOfWeek)

But it will be nice to simplify this syntax.. I suggest:

Dim timeOfWeek = Evaluate(x = Date.Today.DayOfWeek) As string
                Select Case X
                       Case DayOfWeek.Monday To DayOfWeek.Friday
                           return "Work Week"
                       Case DayOfWeek.Saturday, DayOfWeek.Sunday
                           return "Weekend"
                 End Select 
End Evaluate

The Evaluate block is a lamda expression with suplied values for its parameters. this aloow us to evaluate any expression not just Select case, and work on any number of variables in the expresion.

ghost commented 6 years ago

If the Evaluate end Evaluate is not accepted, it can be done by the Function end function keywords, say like this:

Dim timeOfWeek = Function(x As DayOfWeek := Date.Today.DayOfWeek) As string
                Select Case X
                       Case DayOfWeek.Monday To DayOfWeek.Friday
                           return "Work Week"
                       Case DayOfWeek.Saturday, DayOfWeek.Sunday
                           return "Weekend"
                 End Select 
End Function
JustNrik commented 6 years ago

I like this idea :+1:

jrmoreno1 commented 5 years ago

@MohammadHamdyGhanem: using an immediately invoked function can certainly work, but that is a js idiom, not VB, and thus likely to be confusing to inexperienced devs.