Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

That’s the point though:

Duck typing and heterogeneous dictionaries are (and have been) standard Python.

Adding a type system which doesn’t respect duck typing by trying to access the member even when the types don’t match or which can’t express standard idioms used in Python seems a poor architectural choice.

It’s not saying that Python’s type system is “too much discipline”, but rather that the type system doesn’t encode typical Pythonisms.



Python typing supports duck typing: https://peps.python.org/pep-0544/

and heterogeneously typed ducts: https://peps.python.org/pep-0589/


I read 0544 and the proposal for protocols fails to support the main benefit of duck typing, as it requires the substituted-for class to be defined as a protocol.

Traditionally, duck typing is used to inject types into a library that isn’t expecting extension at that particular point — eg, substituting a test class for a real class in a data object that normally wouldn’t be a protocol.

I’m not seeing how that PEP addresses that use case.

- - - -

Similarly, the heading on the dictionary says “for a fixed set of keys” — but what if I want a dynamic heterodox dict? Eg, unpacking JSON.

You just end up shoving “any” all over the place. At which point, are the types helping?

Though, protocols do help the dict case for typing:

dict : Hashable -> Any


Can you re-read please?

https://peps.python.org/pep-0544/#:~:text=Structural%20subty....

> substituted-for class to be defined as a protocol.

... which is false

> Similarly, the heading on the dictionary says “for a fixed set of keys” — but what if I want a dynamic heterodox dict? Eg, unpacking JSON.

You can quite obviously decode to recursive types (e.g. using pydantic), not sure what the problem is.


Your link appears not to work (for me) — can you cite what you believe I have incorrect?

This section seems to agree with me, where it explains why normal classes can’t be subclassed to protocols:

> Now, C is a subtype of Proto, and Proto is a subtype of Base. But C cannot be a subtype of Base (since the latter is not a protocol). This situation would be really weird. In addition, there is an ambiguity about whether attributes of Base should become protocol members of Proto.

https://peps.python.org/pep-0544/#protocols-subclassing-norm...

- - - -

I’m not sure why you think it’s “obvious” that you can use a third party library to solve the problem — or why that addresses my complaint that the built-in type system doesn’t work for that.

If anything, the existence of a third party library hints the standard library doesn’t cover the use case.


And you can make it work at runtime too! So as long as you have the right methods and attrs isinstance on your duck-typed object will return true!


No offense, but have you actually given it a shot? Duck typing is supported and you can get virtually all use cases of heterogenous dictionaries by using union types and duck typing. The article even touches on this.

edit: To be more precise: The article specifically mentions that accessing invalid members give you a type error, but posits that people will probably not bother and just use 'any' instead. How is that not saying 'too much discipline'?


Yep — I use mixed annotations on my Python code because as the person I’m responding to pointed out, they catch many small type errors. Dataclasses have been awesome.

I’m also generally pro-types, but I think it’s worth having a discussion about this type system in the context of Pythonisms.

- - - - -

If you’re using “any” for most of your types, then it’s not providing value — an untyped statement implicitly has the type “any”.

There’s a reason I brought up the JSON example: loading and manipulating JSON of varying structure is something I do a lot at work.


Sure, but the idea behind gradual typing is that 'Any' should only be temporary. IMO if you're serious about it, stable code should at least pass strict type checking, if not completely forbid even explicit Any.

>There’s a reason I brought up the JSON example: loading and manipulating JSON of varying structure is something I do a lot at work.

Do you have a specific example that you find troublesome? For JSON with a fixed, regular structure (i.e. no subtyping) something like Pydantic works well, otherwise using unions + protocols with custom validation code has covered even my most esoteric use cases so far.

If we're talking about unstable JSON, a recursive union type works well enough in my experience, though defining that type gets a bit ugly if your type checker doesn't directly support recursive types.


Your suggestion to “use a recursive union type” and that being “ugly … if your type checker doesn’t … support recursive types” being required to support varying JSON is my point:

Python types don’t support a common Pythonism used frequently in my work.

In fact, you admit that even fixed JSON can be difficult without a 3rd party library.

You’re lecturing me like I don’t understand types without realizing that you repeated my point about a gap in the current type system.


I think I might not have been clear: this is not a limitation of the type system, but of a specific type checker (mypy), that will hopefully be fixed soon. Both Pyright and Pyre support recursive type aliases right now. Open one of their playgrounds and you'll see that the following, intuitive definition

  JSON = Union[
      None,
      bool, 
      int,
      float,
      str,
      List['JSON'],
      Dict[str, 'JSON'],
  ]
works without issue.

>In fact, you admit that even fixed JSON can be difficult without a 3rd party library.

Sure, but that's just because the standard library (for now?) doesn't offer deserialization with runtime validation. Java doesn't have that either, if you want to parse JSON you'll have to either roll your own or rely on a third party library.

Don't get me wrong, the situation isn't perfect, but especially if you use the 'right' tooling, you can in my experience already get a perfectly serviceable experience, which to me is indicative that the type system itself is fine and pythonic, it's just the tooling that is lagging a bit behind at the moment.


> this is not a limitation of the type system, but of a specific type checker (mypy), that will hopefully be fixed soon

> Sure, but that's just because the standard library (for now?) doesn't offer deserialization with runtime validation.

> it's just the tooling that is lagging a bit behind at the moment

So… the standard library has exactly the problem I articulated, and you’re violently agreeing while speaking down to me.

I think that reflects poorly on you.


Your initial statement was that the type system was a poor architectural choice because it doesn't support standard python idioms. To the best of my ability I've tried to communicate that there's an important difference between the type system and the standard library, that one can make it work and that the situation is not worse than most other typed languages.

If you think that's violently agreeing and talking down to you, then there must be some communication barrier that I don't know how to overcome.


> JSON = Union[....]

This does not define the type of a valid json object. (fe None is not a valid json object, neither is '')


A decade or so ago JSON was changed so that JSON text doesn't have to be an object, it can also be a value. 'null' (or say, '5') is therefore legal JSON.





Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: