Type hinting for Python
lwn.net
lwn.net
...which I prefer stylistically (decorators instead of magic monkey-patching).
...which I prefer stylistically (decorators instead of magic monkey-patching).
...which I prefer stylistically (decorators instead of magic monkey-patching).
...which I prefer stylistically (decorators instead of magic monkey-patching).
It's fast and doesn't monkey-patch things.
@ensure_annotations
def f(x: int, y: float) -> float:
return x+y
This looks great, I wish it was the standardI don't use them heavily but they are a great way to sprinkle some clarity over function signatures and APIs you care about and want to 'fortify'.
It's interesting to see the concept gaining traction in the Python and PHP communities.
Personally I am in love with the language but worried about it not gaining enough traction and ending up abandoned because of it.. that's keeping me from using it for non-trivial side-projects.
PHP is trying to provide full support for hinting (you couldn't hint a scalar type nor returns)
I can see how most languages are slowly converging.
https://www.google.com/webhp?q=bracha+optional+type#safe=off...
You are confusing parsing and reduction. In most languages - and almost certainly in Python - these are separate steps. "Parsing it wrong leads to a syntax error" is a good thing - it means you're forced to parse it right. It would be worse if there were multiple syntactically-valid interpretations (which there may well be).
So, given that `object<int>()` throws a type error in python and not a syntax error, you can't unambiguously parse that.
"So, given that `object<int>()` throws a type error in python and not a syntax error, you can't unambiguously parse that."
Apparently in Python 2, it's not even an error.
This is a well-known problem in C++; some of the parsing rules were changed in C++11: http://stackoverflow.com/questions/15785496/c-templates-angl...
If done correctly, (e. g. [] for types, () for values, and >/< for binary comparisons) this approach achieves a lot of consistency and simplicity.
If done correctly, (e. g. [] for types, () for values, and >/< for binary comparisons) this approach achieves a lot of consistency and simplicity.
If done correctly, (e. g. [] for types, () for values, and >/< for binary comparisons) this approach achieves a lot of consistency and simplicity.
def fib(n: int) -> Iterator[int]:
- Colon inside argument list
- Arrow and type
What are they used for normally?One particular point is Python subclasses: it makes a lot of sense to say that a Python subclass is a subtype of the parent class, but in reality there are no guarantees about any relationship. This means that a compiler/VM would most likely have a hard time making use of type annotations since it would have to have to support the user passing arbitrary subclasses with completely different behavior.
Or is
- MD considered an anti-pattern these days?
- This no longer 'hinting'
They're certainly a bit obscure though. Julia is the only new language that I'm aware of that prominently features multiple dispatch as a first-class language feature: http://julia.readthedocs.org/en/latest/manual/methods/
of any language, python could be a poster-child for duck typing done right.
python is also elegant and very easy to read.
this is pythonic -
def foo(a, b, c):
pass
this is ugly/trash - def foo(a, b: int, c: str) -> str:
pass
if this goes down and eventually leads to static typing i will have even less reason to consider using python 3.It looks quite simple/elegant. Plus what they're added is meant to be used by static analysis tools and IDEs, not actually for validating things at runtime.
Having these checks available for development does allow you full confidence in the type safety if the entire call stack has type annotations. If you're using some code that doesn't have these annotations, you might catch problems during development, or might not. But that's just the old familiar situation, and it allows you to iterate quickly while choosing which parts are more critical.
Note that this is analogous to the design choice made by Typescript, while the designers of Atscript chose to extend Typescript with runtime assertions as well.
x = {} # type: Dict[str, str]
I mean, it's very human-readable so it makes sense as a comment. It's optional, so not every declaration will have it. Still, something about the interpreter reading my comments is off-putting. x: dict<str, str> = {}
would be nicer, I think. x = {} # tyep: Dict[str, str]
is a recipe for spending 6 hours wondering why you've got integers in your string-only dict.(Assuming the interpreter ignores anything not matching `# type:`
Besides, how necessary is it? Presumably those constrained types can be instantiated:
x = Dict[str, str]()
The constrained type's __new__ would be annotated appropriately, and return an ordinary dict. It's a bit less "pure" in that this is no longer strictly an annotation, but I'd much prefer that bit of impurity than magic comments.Rather than the classic interface pattern, where the passed object must be a subclass of a certain type, these annotations could be used inversely to that. Something like:
duckclass foo:
def x(): pass
def y(a: int) -> str: pass
n: int
def bar(it: foo) -> boolean:
...
Where other classes don't need to explicitly inherit from foo, but rather, a checker can raise a warning where you are passing something that doesn't have an integer attribute (or getter function) called n, and the x and y functions. This allows some nice analysis, while still allowing good duck typing.There are ways to do this without special keyworks too... that was just a quick first example. (maybe something like:)
class foo:
def x(): pass
def y(a: int) -> str: pass
n: int
def bar(it: duck_as(foo)) ->str: pass
and so on.- Editors and IDEs can use them to provide better autocompletion for you. That way you can discover how to use APIs while you write code without having to look at the docs all the time.
- Static analysers can tell you when you're making trivial errors just after you type them.
- They provide a form self documentation. In practice, most medium to large Python projects already add type signature information in the form of docstrings, using thing like '@param'. This is better because it's more uniform.
This is not against duck typing, you can use Abstract Base Classes to define an interface for some behaviour and match objects that provide that behaviour even if they don't belong to any specified type hierarchy.
Finally, this is completely optional. You can keep coding without types for your small scripts or private functions, while using type information for the APIs of big libraries.
1. The default will be dynamic typing. But you can change that.
2. You can specify a specific module you release as static. This will only affect the internal parts of the module, with one exception - when you call something of that module with the wrong type, you'll get a runtime type exception, so there's no problem working with dynamic code with a fast module.
1. The default will be dynamic typing. But you can change that.
2. You can specify a specific module you release as static. This will only affect the internal parts of the module, with one exception - when you call something of that module with the wrong type, you'll get a runtime type exception, so there's no problem working with dynamic code with a fast module.
1. The default will be dynamic typing. But you can change that.
2. You can specify a specific module you release as static. This will only affect the internal parts of the module, with one exception - when you call something of that module with the wrong type, you'll get a runtime type exception, so there's no problem working with dynamic code with a fast module.
1. The default will be dynamic typing. But you can change that.
2. You can specify a specific module you release as static. This will only affect the internal parts of the module, with one exception - when you call something of that module with the wrong type, you'll get a warning "this runs XX times slower because of a wrong type, change..." , but when you run it with the right type, you'll get great speedup ?
1. The default will be dynamic typing. But you can change that.
2. You can specify a specific module you release as static. This will only affect the internal parts of the module, with one exception - when you call something of that module with the wrong type, you'll get a warning "this runs XX times slower because of a wrong type, change..." , but when you run it with the right type, you'll get great speedup ?