-
Notifications
You must be signed in to change notification settings - Fork 64
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
[Proposal] "In" keyword relationship operator #62
Comments
Like it! |
Much as I appreciate the thought that went into this proposal, wouldn't an extension method written for those specific cases serve the same purpose? Here is a kludge that I just spent a couple of minutes to put together: Module InExtensions
Public Function [In](Of T)(value As T, seq As IEnumerable(Of T)) As Boolean
Return seq.Contains(value) ' utilizes LINQ's extension methods
End Function
Public Function [In](Of TKey, TValue)(key As TKey,
dict As IDictionary(Of TKey, TValue)) As Boolean
Return dict.ContainsKey(key)
End Function
Public Function [In](itemName As String, directory As IO.DirectoryInfo) As Boolean
' you can choose the depth of traversal to locate an item
For Each item In directory.EnumerateFileSystemInfos("*",
IO.SearchOption.AllDirectories)
If item.Name.Equals(itemName, StringComparison.InvariantCultureIgnoreCase) Then
Return True
End If
Next
Return False
End Function
End Module With a set of extension methods like these in place, one can simply do those things you're mentioning. It also allows flexibility of implementation on the programmer's end as (s)he can choose how to go about checking the inclusion of any item within a larger set. |
@franzalex I agree but the In extensions you show would actually make more sense if they were named Contains. |
@Bill-McC You're right! I've updated the signatures of the extension methods so they really reflect the name The sample for On the following points, we seem to agree; I do not see the usefulness of the |
Hi, @franzalex , @Bill-McC On the literal meaning, the Public Structure Foo
Dim s$
Public Shared Operator Like(f As Foo, s$) As Double
Return Levenshtein.ComputeDistance(f.s, s).MatchSimilarity
End Operator
End Structure In my opinion, the Public Structure StringVector
Dim value$()
' Using the operator can returns no limited to a single boolean value
Public Shared Operator In(s$, strings As StringVector) As Boolean()
Return strings.value.Select(Function(q) InStr(s, q) > 0).ToArray
End Operator
End Structure
Dim s$
Dim V As StringVector
' The contains function interface can not satisfy the requirment for this operation:
Dim all_exists? = (s In V).All(Function(b) True = b)
' Gets all of the indices for the resources which is not exists target s
Dim not_exists_indices%() = Which.IsFalse(s In V)
' Gets all of the indices for the resources which exists target s
Dim exists_resource%() = Which(s In V) Using Extension method is also have a disadvantage:
|
@xieguigang The Like operator has special meaning within the language specifically for string pattern matching. This was from VB pre .NET. It actually when combined with LINQ provides really clear elegant solutions to some of the original examples you posted,: The thing about Like though is it really is peculiar to Strings: sure it can be overloaded, but if you go through all the .net libraries and vb samples out there from the last fifteen years how many classes/structures can you find that define their own Like operator. If anything that tells us having to have classes that implement their own In operator would be a wasteland. When LINQ was introduced, it was based heavily on extensions rather than requiring all existing types be re-written. And the worst past about having custom operators, especially if they are obscure and only in a couple of classes, is if they return different results, then the code has not become clearer, it's become one of those bits of code people have to pause on and check it's meaning: IOW, you'd have lost the clarity that was sought by introducing the operator. The only way for it to be clear is to give it fixed meaning and have it implemented similar to LINQ. But having read some of your examples, I question if it would end up doing what you want if it must be a match versus a substring match or viceversa. |
I think that having a dedicated overloadable operator is overkill. However, I like the idea of an
Then, the following will compile to the appropriate calls to
Doesn't that happen anyway when trying to write a LINQ query without the appropriate |
@zspitz because System.Linq is imported by default at the project level it's pretty hard to get into that situation. |
If |
Still can not agree with the idea of using Extension method way.
For example, if we want to determine that if each string element in s vector is in another string vector V, then by using operator Overloads, we can resulting a very simple expression: ' Using operator can returns a boolean vector at once
Dim b() = s In V
' But as the linq extension function just returns a single boolean at once,
' the expression becomes much complicated
Dim b() = s.Select(Function(t) t In V).ToArray Although the Linq extension is designed for processing the data collection in any .NET language in functional programming way, but
Another situation is that, we usually using the private field for the data storage in a user type, so that we probably have a definition like: Public Class Table
Dim innerIndex As Index(Of String)
Dim handles As Index(Of Long)
End Class Due to the reason of the external extension method can not directly access this private field. So we have to add more code to change this private field to the public access, like: ' And probably to avoid the unexpected modification from outside of this reference type property
' So I needs to clone it in each property reference call
Public ReadOnly Property NameIndex As Index(Of String)
Get
Return New Index(Of String)(innerIndex)
End Get
End Property
<Extension>
Public Function Contains(index As Table, name$) As Boolean
Return index.NameIndex(name) > -1
End Function And further more, if I want to write a extension method for another user type using handles field, and add more public access property/or function as the data source is required: Public ReadOnly Property UidIndex As Index(Of Long)
Get
Return New Index(Of Long)(handles)
End Get
End Property
<Extension>
Public Function Contains(index As Table, uid&) As Boolean
Return index.UidIndex(uid) > -1
End Function In such case, the user class type is becoming more and more heavy, and also the method is defined at external source file and required longer time to navigate to the definition and harder on using the IntelliSense. Using the operator can avoid such situation totally. |
RE: private members -- You could write a
Then, the following code:
would compile (transpile?) to calls to
without a need for any additional members on the As I said, the compiler uses the same mechanism to resolve LINQ keyword syntax to the underlying method calls. RE: I think the strongest use case for
But where the type of the result of the
I'm not sure the additional cognitive burden -- sometimes the result of
As I said above, if you have control of the class, you could write an instance method and not rely on an extension method.
I'm not sure why you think the IDE has to work harder in order to process extension methods. My guess is that all the available extension methods (marked with the Even if this is true, I don't think the additional strain being placed on the CPU or memory by the IDE is a language design consideration. If it benefits the language, and it conforms to the standards of the language, then the IDE should simply have to adapt. |
I agree that this could in the vast majority of the cases be done with an extension method (I have written just such an extension method for several projects). Where extension methods wouldn't work, a better replacement than In would be select case expressions:
Now, obviously that is a bit heavy for including in an IF/Then condition, but you could assign it to a variable before the condition. |
This is reasonable, but has some things to consider:
Because the BCL is written in C#, this issue would have to start in C#. Feel free to propose this in https://github.com/dotnet/csharplang. It's possible that this will result from work on Range. |
What do you mean when you say VB doesn't know about hashsets? Do you mean that if there was such a dedicated operator, it would have to be specially defined for the |
Generally, the word
In
make sense for these situations:So that by introduce the existed
In
keyword As a new operator, then we can makes the vb code more simple and human natural Language:And combine this new
In
keyword with the Linux bash file search API syntax in VisualBasic language:https://github.com/xieguigang/GCModeller/blob/master/src/GCModeller/CLI_tools/eggHTS/CLI/2.%20DEP.vb#L196
to makes the VB style in more Natural Language
Compared with the
List.IndexOf
,Dictionary.ContainsKey
, In keyword operator just using 2 character in our code, simple and make sense.The text was updated successfully, but these errors were encountered: