8 ms·
This is already handled with dataclasses https://docs.python.org/3/library/dataclasses.html#module-dataclasses https://docs.python.org/3/library/dataclasses.ht
by tln 3y ago
This is already handled with dataclasses
https://docs.python.org/3/library/dataclasses.html#module-dataclasses https://docs.python.org/3/library/dataclasses.html#module-da...
..and the syntax is way better, handling more members, with room to document, handling methods, and not conflicting with Mojo or stdlib
- LoganDark 3y agoDoesn't support algebraic data types, though. FWIW I think this article mentioning them at all is sort of weird because the article doesn't propose them either, lmao
- tikhonj 3y agoRight, the article talks about "type Point = Point1D | Point2D | Point3D" syntax at the end... which would work just as well with dataclasses as with structs!
- masklinn 3y agoIt already does too. Just remove the `type` bit and you have an alias for a union, which has been supported since typing was added (though the `|` syntax was only added in 3.10). And AFAIK the type checkers do handle completeness on unions.
- fritzo 3y agoDo you mean Python's lack of a labeled union type?
- Spivak 3y agoPydantic does though. class A(BaseModel): status: Literal["success"] class B(BaseModel): status: Literal["error"] class C(BaseModel, ABC): __root__: Union[A, B] = Field(discriminator="status") aorb = C.parse_obj(blah…).__root__ if aorb.status == "error": # aorb will type check as B.
- b33j0r 3y agoYou are a friend and a scholar. I was looking for a solution in pydantic that is wildly relevant. Thanks, I didn’t realize that was implemented/existed. My only objection is using ABC in your MRO. Haha, just a little bit overloaded with abstract base classes and using A, B, and C. I got it eventually! Cool.
- Spivak 3y agoYa know what, on reading that that does seem confusing. My brain had long since internalized ABC as a single token I didn't even notice.
- LoganDark 3y agoI believe this is a good example of type narrowing :)
- LoganDark 3y agoYeah. Been spoiled by Rust.
- contravariant 3y agoIt doesn't seem that far off though, it does have a union type and with pattern matching you can achieve pretty much the same thing (sure you may need a few extra classes if the types aren't distinct already but that seems like a small difference). I don't know if type checkers can figure out if a pattern match statement is exhaustive yet though, that would be interesting.
- joiguru 3y agoWhich Python 3.10 and static type checkers much of the benefits of algebraic data types is already available [1]. [1]: https://stackoverflow.com/questions/16258553/how-can-i-define-algebraic-data-types-in-python https://stackoverflow.com/questions/16258553/how-can-i-defin...
- masklinn 3y agoThe typed equivalent of a sum type in python is a union (https://docs.python.org/3/library/typing.html#typing.Union https://docs.python.org/3/library/typing.html#typing.Union). Works with pretty much every type you can think of, but has the usual union limitation that you can't have two variants of the same type (e.g. int | int | float). Then again, you can just create newtype wrappers, and that's essentially the same thing as different constructors for a sum type.
- LoganDark 3y agoYou'd need to create newtype wrappers anyway in order to tell them apart, I'd assume. Otherwise it wouldn't really be an algebraic data type as much as a... union type.
- masklinn 3y agoHence “equivalent”. Of your variants all have trivial and non-overlapping payloads you can just use them as-is, or erlang-style tagged tuples, in most cases it’ll do fine.
- taeric 3y agoI was surprised at how dataclasses are not the first thing people are taught when it comes to "classes" in python. My two personal "you should probably learn how these work" things for beginners are pprint and dataclass. Goes a long long way to helping look at things.
- jasonpeacock 3y agoIt's because the traditional teaching focus is OOP and not data-driven design.
- taeric 3y agoThe part that blows my mind, on this, is that I see it in the "data science" community. An area that seems custom made for leaning on smaller or non-existent inheritance trees.
- xapata 3y agoDataclasses wind up cumbersome over time. They're nice when the defaults are what you want. After a handful of default overrides, I'd rather have not used dataclasses.
- taeric 3y agoIn the office job, I'd push on why the defaults didn't work out. In particular, I would be worried that I was specifically aiming to make future life a bit harder by not fitting with the defaults of dataclass. To that end, I'm curious what defaults you didn't use?
- olejorgenb 3y agoThis is the reasoning from the article for why its suggestion is better then dataclasses: > - Typing is optional (there are still folks who don't want to lean into that and it simply isn't always necessary) > - Class construction should be faster (which intuitively you would think shouldn't matter, but I have talked to folks where this is an actual concern, especially when startup time is critical) > - Syntax typically leads to better tooling support since there's no ambiguity > - Easier to teach than (data)classes, so can act as a stepping stone towards classes > - Better semantics than dataclasses have by default (at least in my opinion )
- IshKebab 3y ago> there are still folks who don't want to lean into that Honestly why would you cater to people who want to write worse code? Should Python have a mode with implicit type coercion too because some people can't be bothered to type `int()`? > Class construction should be faster. It's Python. You accepted your code would be extremely slow going in. Fiddling with the syntax isn't going to make it fast.
- Groxx 3y agoYeah, honestly I think if startup time is a real concern, python is simply the wrong choice. Slow startup is largely inherent in its design. Not that it's not worth spending some effort to optimize, of course. But the lower bound is quite high even if you're very careful.
- pwdisswordfishc 3y ago> - Typing is optional (there are still folks who don't want to lean into that and it simply isn't always necessary) Someone who really wants to avoid type annotations at all costs can just use ": object" everywhere
- nomel 3y agoI believe it should be ": Any".