-
Notifications
You must be signed in to change notification settings - Fork 66
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
TypeOf x Is SomeType sounds like an exact type check #277
Comments
I think your example isn't the best for what you're asking; the runtime type of an object is never an interface. No object would ever be Could you share the scenario that where you felt |
Don't you mean
I don't follow. I am suggesting that I mean this syntax to be a drop-in replacement for |
Um, I understand what you're suggesting. I'm saying I don't understand how often the distinction between an exact match or an assignment-compatible actually matters outside of one scenario I know of (implementing If I'm reading your response right, you're not saying that you have several scenarios where the existing behavior is outright wrong and you need a more correct tool, only that it might be surprising and you'd just like a new syntax which behaves more intuitively for intuition's sake (which is a valid reason to ask, fwiw). I'm I understanding the motivation correctly? Once again though, I must remind, that if such a new syntax were created which matched your intuition, the type operand could never be any interface or abstract type. Are you ok with that? |
Yes, precisely. Although I wouldn't say behaves more intuitively; this new syntax would have the same behavior as
Why? What's the difference between
It doesn't matter to
Wouldn't |
I understand the linguistic opposition to However, I want to point out that according to OOP principles, you are supposed to necessarily not care whether you a referencing an instance of So for someone thinking in OOP, the language Nevertheless...Nevertheless, I agree that it would be more clear had they made it Another problem is that if we do pattern matching, and we allow matching with a type name (as there were plans to do), that means allowing |
Why is extracting the type of something and then checking it against a possibly compatible type (either equal, or a wider type): Dim x As Object
If TypeOf x Is IEnumerable Then ...
If TypeOf x Is String Then ... somehow more OOP style than checking whether the something is of a possibly compatible type? If x Is IEnumerable Then ...
If x Is String Then ... In either case, checking for a narrowing type is necessitated by the programmer's code logic -- if Do you mean we should never allow checking for a narrowing type?
What would be even more clear would be to focus on the VB.NET does not have a Dim n As Integer
If ValueOf n Is 5 Then ... because the extra step of extract value of n implied by such a keyword is not needed -- just compare against
No, I would not. Again, Consider the following: If x.GetType() = GetType(IEnumerable) Then ...
If x.GetType() = GetType(String) Then ... This is what If x Is IEnumerable Then ... asks whether
I think that |
@bandleader @AnthonyDGreen Do you have any further thoughts on this? |
@KlausLoeffelmann As someone who is interested in making VB.NET more accessible to entry-level users, what are your thoughts on this? |
@zspitz I'll gladly summarize my points, as from your response, I think I wasn't completely clear:
|
@bandleader Thanks for taking the time to clarify. The point of divergence is at this statement:
There is absolutely nothing wrong with The issue I am taking with A better syntax (from the perspective of this proposal) might have been 1b. we can't make a breaking change here. I don't think we can drop the 2c-d. I am proposing that 3e-f. I agree with everything you've written here. I reiterate -- I am proposing that |
what about something like If x Implements IEnumerable Then
If s Implements GetType(String) Then ? |
@pricerc
Your syntax is only appropriate to the third possibility. If the type of I don't see any reason why a new type-checking syntax shouldn't be doing exactly the same. |
@bandleader @rskar-git @AnthonyDGreen I've rewritten the initial proposal to clarify that I'm not proposing any change or limitation to type-checking behavior. |
@zspitz I know what TypeOf and GetType do, I was just proffering a possible, if not fully-thought-through alternative, which is why I opened my comment with "Something Like". Your original post referenced IEnumerable as an example a few times, so my suggestion sprang to mind as a simple alternative. I wasn't completely happy with 'Implements', but I was on site at a client, and didn't have time to think of something better, or to expand my comment. Looking through the thread again, and thinking about it a bit this time, I think the best idea is your 'IsOf' suggestion. I didn't initially like it, but 'Of' does carry pretty much the same semantics where its arguments can be an interface, abstract class or concrete class. Like others, I'm not crazy about semantic changes that might catch someone out, especially if it's subtle. I've been burned enough to know that the thing that's going to catch you out is the one you haven't thought of, so I'd be very reluctant to do anything that changes semantics. There is one possibility I can think of that might not work for your 'Is' suggestion: if you have a variable and type with the same name; e.g. (completely contrived): ' probably a really bad variable name, but hey, that's what rookies do!
dim control as object
...
if textBox1 is control then... |
I've incorporated this into my original post, and I think this is a real dealbreaker to using |
I would like to add that I have heard a number of times from various people that they avoid the If the syntax were simply odd or meaningless in English -- e.g. @KathleenDollard Could you describe the LDT's considerations in not pushing this? |
My dog Io is an instance of a dog and a dog is an animal. All of the following are equally true
I think expanding the surface area is something to do very very carefully. If there were both TypeOf Io Is Animal
Io is Animal I have no idea how I would keep straight which is which. We can't change Also, C# uses And the alignment with C# would be even more important in pattern matching, where Is will probably mean what it does today. SummarySo, personally I don't agree with the premise of the implications of Is. I think the semantics imply exactly what TypeOf..Is does. More importantly - this change would expand the surface area (adding a second way to do something) and be inconsistent with C# and probably be out of alignment with our future plans. Of course we will sometimes expand the surface area, but we're looking for big benefits there, like pattern matching. And we may do something explicitly inconsistent with C#, but it would be very high bar to respect the crossover programmer. Call to actionThat said, C# has a better introductory sentence for Everyone! This is super low hanging fruit folks...Take the C# intro sentence, morph it to your VB aesthetics as desired, and update the first sentence in We're OSS, we're a community. Someone want to grab this and find out how easy our docs are to update? |
@KathleenDollard Thanks for your quick response.
The problem is not in the implication of
This is wrong, because even though both the ESB and its address are in New York State, the statement relates to the single concrete address of the ESB, which is not equivalent to New York State. Both of the following statements are more accurate.
By analogy, either of the following would be clearer, more understandable, and thus less error-prone syntaxes for checking type-compatibility:
implying that the concrete type of an instance can match multiple types (concrete
which doesn't deal with the concrete type at all, but directly with the instance.
To be clear, I am proposing that both variants would have the same exact behavior as (I am despairing of my ability to communicate in English, considering the number of times I've had to repeat this point.)
The behavior of both syntaxes would be exactly the same as the C# |
My apologies for misreading. Thank you for clarifying.
That is now clear :) I think we could look at this again as we look at patterns. If you wold like to put a comment in the pattern matching issue to consider this, that would be fine. When we look at type check/assign this will potentially appear in new contexts, which would be a good time to add it. I removed the no-plans tag so we can look at it in that context - which will be much later this year after we land the .NET Core 3.0 work. |
I'm one of those who rarely uses TypeOf - I because I'm more likely to either a) create a generic method, b) create method overloads that accept different data types, or c) some combination of those. But I digress. Because I use TypeOf so little, I usually get it wrong when I do use it, and often end up using GetType() instead (because getting that working is faster than me finding and reading the manual entry for TypeOf). But I think I would remember So I can see the merit in |
Given the following declaration:
the following English statement would suggest an exact type check, on the concrete type of
s
:This is also what a straightforward reading of the
TypeOf
expression would suggest:However,
TypeOf
doesn't work like that (nor should it):prints
True
, becauseTypeOf x Is SomeType
is actually checking the following, in plain English:where type-compatibility in this context means equals
SomeType
, inherits fromSomeType
or implementsSomeType
.Obviously, programming languages are not natural languages, and we shouldn't expect to express the same meaning in the same way in both. However, I know that this disconnect between the syntax and what it is doing, is something that took me a while to wrap my head around, and I think we can find a more descriptive syntax for type-checking:
If s Is SomeType Then ...
-- we aren't comparing two types, but rather asking if the object supports this type; there is no implication thats
couldn't be of other types as wellIf AnyTypeOf s Is SomeType Then ...
-- expressly implying thats
can have multiple typesI prefer the first choice, because it is more directly expresses what we are asking -- if
s
is a/anSomeType
then do something. Under the hood, we are almost certainly extracting the concrete type from the object and checking its assignability with the named type (e.g.Dim t = s.GetType(): If GetType(SomeType).IsAssignableFrom(t) Then...
) but I don't see the benefit in expressing this paradigm via the wording of the code. Also, the inverse --If NoTypeOf s Is IEnumerable Then...
is rather clumsy.There is one issue with using
Is
/IsNot
on its own: sinceIs
also has meaning as reference equality check, how could the compiler differentiate between the two? I'm strongly tempted to suggest that the compiler could infer based on what is on the right-hand side of theIs
-- a typename or an identifier. However, it is possible for a name to be both an identifier and a type name in the same scope; so I think this is infeasible as it would introduce ambiguity:Therefore I would suggest one of the following dedicated type check operators:
If s IsOfType SomeType
/If s IsNotOfType SomeType
If s IsOf SomeType
/If s IsNotOf SomeType
-- this echoes generics, whereOf
is always followed by a type nameEven if this proposal is accepted, I don't think it possible to invalidate
TypeOf
. But I think the compiler/editor could rewriteTypeOf
to the final form of this proposal; there are a few places where VB.NET already does a similar rewrite.The text was updated successfully, but these errors were encountered: