Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] AnyOf Operator #75

Closed
AdamSpeight2008 opened this issue May 17, 2017 · 8 comments
Closed

[WIP] AnyOf Operator #75

AdamSpeight2008 opened this issue May 17, 2017 · 8 comments
Labels

Comments

@AdamSpeight2008
Copy link
Contributor

AdamSpeight2008 commented May 17, 2017

AnyOf Operator

This is a generalisation of Proposal #23 to allow other usage cases.

The AnyOf operator as two modes of usage, as a :=

  • Binary Operator left AnyOf right
  • Unary Prefix Operator AnyOf right

Binary Operator

This is provides the equivalent of an = against a single instance and collection of instance, of some type.

Example Usage
Consider the following code., where we are checking the part.Kind is one of a set of values.
Exisiting

previousWasClass = ( part.Kind = SymbolDisplayPartKind.ClassName )     OrElse
                   ( part.Kind = SymbolDisplayPartKind.InterfaceName ) OrElse
                   ( part.Kind = SymbolDisplayPartKind.StructName )

What if we express that in a more operator like form.
Proposed

previousWasClass = part.Kind AnyOf {SymbolDisplayPartKind.ClassName,
                                    SymbolDisplayPartKind.InterfaceName,
                                    SymbolDisplay}

The code produced by both are functionally equivalent


Today this functionality (not syntax) via extension method

<Extension()>
Function AnyOf( p As SymbolDisplayPartKind, paramarray these() as SymbolDisplayPartKind) As Boolean
  For i = 0 To these.length - 1
    If p = these(i) Then Return True
  Next
End Function

Unary Operator

The primary usage target of this prefix is in TypeOf obj Is ... expressions.
Existing

(TypeOf obj Is T0) OrElse (TypeOf obj Is T1) OrElse (TypeOf obj Is T2) ...
(TypeOf obj IsNot T0) AndAlso (TypeOf obj IsNot T1) AndAlso (TypeOf obj IsNot T2) ...

Proposed

 TypeOf obj Is AnyOf { T0, T1, T2 ... }
 TypeOf obj IsNot AnyOf { T0, T1, T2 ... }

Implementation

The compiler treats them as syntactic sugar for the exist code. Just that we let the compiler build the underlying expression itself. It then could choose to implement the expression using the operators = and <> or if the object is IComparable/IComparable(Of T) via o.ComparedTo( x ) = 0 or EqualTo( ).

@Echo-8-ERA
Copy link

Isn't your binary operator basically the IN operator from SQL? obj In collection is more intuitive than obj AnyOf collection while reusing an existing keyword.
Your unary operator could also reuse the In keyword and from what I can tell, keeps the spirit of your proposal intact.

@AdamSpeight2008
Copy link
Contributor Author

@Echo-8-ERA It is just like the In operator from SQL.

@zspitz
Copy link

zspitz commented May 25, 2017

@AdamSpeight2008

I think the usage your AnyOf operator is unclear, in that there are multiple possibilities for what goes on the right side -- the right hand side can be an array of values, or a curly-brace-wrapped set of type names (which is definitely not an array).


This could be resolved by leaving AnyOf exclusively for type-checking, and reusing the In keyword for the value-comparison usage, like @Echo-8-ERA suggests:

If part.Kind In {SymbolDisplayPartKind.ClassName,
                                    SymbolDisplayPartKind.InterfaceName,
                                    SymbolDisplay} Then
End If

and extended to any IEnumerable(Of T):

Dim i=5
Dim range = Enumerable.Range(1,5)
If i In range Then
End If

See my comment here.

@AdamSpeight2008
Copy link
Contributor Author

Using .Range(1,5) then .Contains(..) over a contiguous set of values, seems to (me) inefficient
When it could be simpler to express as a Bounds of Limits. eg 1 <= x <= 5

@zspitz
Copy link

zspitz commented May 26, 2017

@AdamSpeight2008 Of course, but the idea is that the pattern can be extended very simply:

Dim i=5
Dim squares = Enumerable.Range(1,5).Select(Function(x) x*x)
If i in squares Then
End If

@AdamSpeight2008
Copy link
Contributor Author

@zspitz I was thinking of an type the did represent Bounds / Limits. It could implement IEnumerable so it as access to the LINQ to Objects extension methods.

@ghost
Copy link

ghost commented Nov 30, 2017

@AdamSpeight2008

TypeOf obj Is AnyOf { T0, T1, T2 ... }
TypeOf obj IsNot AnyOf { T0, T1, T2 ... }

This is already possible:

{T0.GetType, T1.GetType, T2.Gettype, ...}.contains(obj.GetType)
Not {T0.GetType, T1.GetType, T2.Gettype, ...}.contains(obj.GetType)

Same for:

previousWasClass = ( part.Kind = SymbolDisplayPartKind.ClassName ) OrElse
( part.Kind = SymbolDisplayPartKind.InterfaceName ) OrElse
( part.Kind = SymbolDisplayPartKind.StructName )

{SymbolDisplayPartKind.ClassName, 
 SymbolDisplayPartKind.InterfaceName, 
 SymbolDisplayPartKind.StructName}.contains(part.Kind)

@zspitz
Copy link

zspitz commented Nov 30, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants