18 ms·
> Type annotations in Python do not actually affect any aspect of runtime and are ignored during evaluation. This is equally true in Java. Types are erased at
by joshuamorton 6y ago
> Type annotations in Python do not actually affect any aspect of runtime and are ignored during evaluation.
This is equally true in Java. Types are erased at runtime. They don't exist in the bytecode.
Just because the type checking and evaluation are done using one tool, "javac" doesn't really mean anything.
Again, what's the difference between a bash script that runs mypy prior to invoking python and a bash script that compiles and runs a java program, from the perspective of type safety, assuming you know nothing about the two programs?
There is no difference. Neither provides any more guarantees than the other. Put another way, by enforcing use of mypy prior to invocation, you convert the annotation to an ascription.
A deeper analysis would suggest that "ascriptions" are actually the things you use to disambiguate when type inference is not powerful enough (https://docs.scala-lang.org/style/types.html https://docs.scala-lang.org/style/types.html).
Scala, for example, calls its type declarations "annotations", except when they are needed to disambiguate, when they are "ascriptions". So under the scala definition, python's annotations are exactly the same as scalas as long as they are used for type checking, which, if you use mypy, they are.
- lmm 6y ago> This is equally true in Java. Types are erased at runtime. They don't exist in the bytecode. For the record this isn't true, as anyone who's seen a ClassCastException knows. A subset of type information is erased under limited circumstances, but a lot of type information is still present in the bytecode. > Just because the type checking and evaluation are done using one tool, "javac" doesn't really mean anything. What means something is that the types are part of the language specification and, even more importantly, part of the consensus of the language community. In particular, if you depend on a Java library, you can be extremely confident that the type information of that Java library is actually correct, because you can be extremely confident that the library was built in a way that involved checking the types. This is simply not the case for Python; it's very normal to build Python without running mypy. It's like arguing that C is a safe language because you can run Valgrind on your C code: yes, that external tool exists, but it's not part of the language by default, and so you can't rely on the rest of the ecosystem to have used it. > A deeper analysis would suggest that "ascriptions" are actually the things you use to disambiguate when type inference is not powerful enough (https://docs.scala-lang.org/style/types.html https://docs.scala-lang.org/style/types.html). > Scala, for example, calls its type declarations "annotations", except when they are needed to disambiguate, when they are "ascriptions". So under the scala definition, python's annotations are exactly the same as scalas as long as they are used for type checking, which, if you use mypy, they are. The distinction is a lot more general: type ascriptions change the behaviour of the code while type annotations do not. So a system that only has annotations and not ascriptions is significantly more limited than a full type system that has ascriptions as well, at least in practice - in theory we can do perfect type inference (e.g. H-M), but that ignores some edge cases that are important for real-world programming e.g. handling literals in the source code.
- joshuamorton 6y ago> part of the consensus of the language community. Indeed, so the only difference is that you trust one languages annotations more than the others. Which is what I said. > The distinction is a lot more general: type ascriptions change the behaviour of the code while type annotations do not. Well no, ascriptions don't change behavior, they remove ambiguity when systems aren't able to infer things on their own. Literals aren't the issue for H-M. They're relatively easy. H-M has trouble with inheritance and heavily polymorphic code.
- lmm 6y ago> Indeed, so the only difference is that you trust one languages annotations more than the others. Which is what I said. Eh, that's like saying there's no difference between breaking the law and not breaking the law, someone might kidnap you and lock you up either way. It's true in a sense, but it's more misleading than helpful. > Well no, ascriptions don't change behavior, they remove ambiguity when systems aren't able to infer things on their own. You're trying to gloss over everything as "removing ambiguity", but by that logic any change to a program is just "removing ambiguity". In general there are other possible ascriptions for a given term that would form valid programs, and in general those programs could have arbitrarily different behaviour from the program in question.
- joshuamorton 6y ago> You're trying to gloss over everything as "removing ambiguity", but by that logic any change to a program is just "removing ambiguity". In general there are other possible ascriptions for a given term that would form valid programs, and in general those programs could have arbitrarily different behaviour from the program in question. I'm not, for what it's worth. There are cases where you could argue that type annotations are just removing "ambiguity" (the type system is successfully inferring, you place an annotation that agrees with the inference, or a stricter annotation that still checks successfully). I can see how this is an ambiguity, but it isn't what I meant. But scala's definition of ascriptions are for places where the type system can't figure something out, and needs extra information to successfully check. More powerful type inference might address these issues (most common languages don't use H-M). Ambiguity was perhaps the wrong word to use. "aren't able to infer things on their own" is maybe the more important bit. Type ascriptions don't "change" behavior, because there wasn't valid behavior without them. The type system failed to check (but again, different inference algorithms might be able to get around this)
- half-kh-hacker 6y ago> This is equally true in Java. Types are erased at runtime. They don't exist in the bytecode. I work with bytecode on a daily basis (I develop a commercial Java obfuscator) and this is untrue. You may be thinking of generic type parameter erasure, but even then special interface methods are generated by the compiler so that no lowering to java/lang/Object happens too soon. In non-generic code, the types remain and are strongly enforced. Methods have descriptors that restrict parameters to certain types (you can get a VerifyError upon loading the class if you've generated code with a type confusion), there is a 'checkcast' instruction to ensure that a stack values is a certain type, and a ClassCastException is thrown if a cast is impossible.
- DonaldPShimoda 6y agoAlright, we've got two different discussions going on here. I'll address them separately. --- As far as "annotation" vs "ascription", you've actually just reinforced what I said. > This is equally true in Java. Types are erased at runtime. They don't exist in the bytecode. Types are erased at compile time, which means that the type-checking analysis has completed. Many compilers erase types after doing type checking to improve runtime performance. That doesn't mean the types don't do anything. They're used for guiding the type-checking by the compiler. This is in contrast to Python, which does literally nothing with the stuff you throw in the annotations. MyPy doesn't play a role in this specific aspect of the discussion because we're talking about language implementations, and in Python the type annotations are just artifacts in the code that get ignored during compilation and evaluation. This is the distinction between ascriptions and annotations, which you actually corroborated here: > Scala, for example, calls its type declarations "annotations", except when they are needed to disambiguate, when they are "ascriptions". All of the type stuff in Python is handled via annotations because the language proper does not make use of them whatsoever. They're just decoration, really. In contrast, Java uses all the types to perform type-checking, making them ascriptions. In languages with lots of type inference, like Scala, you can supply type information. Sometimes these are ascriptions (which either help the inference algorithm or are used for casting), and sometimes they are just artifacts to help the programmer (in which case they can be regarded as annotations, which I didn't address previously). But the key component in all of this is that we are only looking at the languages proper, not the suite of third-party tools available to those languages, because this is what dictates the correct terminology. In Python the language, types are just annotations which are completely ignored, and this is not the case in statically typed languages. --- Which brings us to the second point: your original argument. This thread started with somebody asking whether static typing will ever be implemented in Python proper, to which somebody said there's no reason for that when we can use MyPy and disable support for `Any` types. The response to this was that it would require all third-party libraries to be fully and correctly annotated, where you came in and claimed "that's true in any type system." The reason I disagreed with this is because in statically typed languages you're not relying on annotations for anything. Keep in mind that we've established that annotations are specifically artifacts in the code that the language itself doesn't care about, because when the language does care they are called ascriptions. Annotations are supplied by the programmer by desire, not by necessity of the language proper. You can release a fully-functioning Python library with absolutely zero type annotations, and it will run exactly the same as if you annotated everything. This is because type annotations don't do anything in Python; to gain any use from them requires using third-party tools, like MyPy. But you cannot release a Java library that doesn't have all its types specified in some manner. Because the Java language requires the types to be present, meaning they aren't annotations like they are in Python. I guess really what I'm trying to get at is that your response where you said "That's true of any type system" was completely missing the point. The point being made by the person you responded to was about how in a Python ecosystem, simply using MyPy and disabling the `Any` type requires all third-party libraries to be fully and correctly annotated — something which is not usually required in Python, so it's an extra burden on the libraries' developers. This is entirely distinct behavior from any statically typed language because in those languages, you can't just leave out the types and call it a day.