5 ms·
I agree. Prior to the introduction of types in Python, I thought I wanted it. Now I hate them. It feels like a bunch of rigmarole for no benefit. I don’t use an
by eloisius 3y ago
I agree. Prior to the introduction of types in Python, I thought I wanted it. Now I hate them. It feels like a bunch of rigmarole for no benefit. I don’t use an IDE, so code completion or whatever you get for it doesn’t apply to me. Even strongly typed languages like rust have ergonomics to help you avoid explicitly specifying types like let x = 1. You see extraneous code like x: int = 1 in Python now. Third party libs have bonkers types. This function signature is ridiculous:
sqlalchemy.orm.relationship(argument: _RelationshipArgumentType[Any] | None = None, secondary: _RelationshipSecondaryArgument | None = None, *, uselist: bool | None = None, collection_class: Type[Collection[Any]] | Callable[[], Collection[Any]] | None = None, primaryjoin: _RelationshipJoinConditionArgument | None = None, secondaryjoin: _RelationshipJoinConditionArgument | None = None, back_populates: str | None = None, order_by: _ORMOrderByArgument = False, backref: ORMBackrefArgument | None = None, overlaps: str | None = None, post_update: bool = False, cascade: str = 'save-update, merge', viewonly: bool = False, init: _NoArg | bool = _NoArg.NO_ARG, repr: _NoArg | bool = _NoArg.NO_ARG, default: _NoArg | _T = _NoArg.NO_ARG, default_factory: _NoArg | Callable[[], _T] = _NoArg.NO_ARG, compare: _NoArg | bool = _NoArg.NO_ARG, kw_only: _NoArg | bool = _NoArg.NO_ARG, lazy: _LazyLoadArgumentType = 'select', passive_deletes: Literal['all'] | bool = False, passive_updates: bool = True, active_history: bool = False, enable_typechecks: bool = True, foreign_keys: _ORMColCollectionArgument | None = None, remote_side: _ORMColCollectionArgument | None = None, join_depth: int | None = None, comparator_factory: Type[RelationshipProperty.Comparator[Any]] | None = None, single_parent: bool = False, innerjoin: bool = False, distinct_target_key: bool | None = None, load_on_pending: bool = False, query_class: Type[Query[Any]] | None = None, info: _InfoType | None = None, omit_join: Literal[None, False] = None, sync_backref: bool | None = None, **kw: Any) → Relationship[Any]
https://docs.sqlalchemy.org/en/20/orm/relationship_api.html#sqlalchemy.orm.relationship https://docs.sqlalchemy.org/en/20/orm/relationship_api.html#...
- yrro 3y agoI wouldn't mind all of that if the SQLAlchemy documentation would hide all the types until I mouse over them. Ditto for vim!
- lolinder 3y ago> It feels like a bunch of rigmarole for no benefit. I don’t use an IDE, so code completion or whatever you get for it doesn’t apply to me. Maybe try using an IDE? Without one any language's type system will feel more frustrating than it's worth, since you won't get inline error messages either. > Even strongly typed languages like rust have ergonomics to help you avoid explicitly specifying types like let x = 1. This is called type inference, and as far as I can tell this level of basic type inference is supported by the major python type checkers. If you're seeing people explicitly annotate types on local variables that's a cultural problem with people who are unaccustomed to using types. As for that function signature, it would be bonkers with or without types. The types themselves look pretty straightforward, the problem is just that they formatted it all on one line and have a ridiculous number of keyword arguments.
- eloisius 3y agoOf course I’ve used an IDE before. I still prefer Vim to an IDE. And I enjoy writing typed languages in Vim because the compiler catches mistakes. I agree part of the problem is cultural. Maybe a bunch of Python coders are eager to use types, or maybe linters are pushing them to type every last variable because that is “right.” I don’t know. I don’t hate typed languages at all. In fact I love writing Rust. Even C++ is tolerable from a type perspective. I don’t agree that _RelationshipJoinConditionArgument is a meaningful type. It feels like bolting a type system onto the language after the fact is weird and necessitates crazy types like that to make some linter happy, maybe to make VS Code users happy, at the expense of readability.
- bas 3y agoThank you, for putting many of my frustrations to words.
- robertlagrant 3y agoYou can run mypy as the Python equivalent of the typey bit of a compiler. As for SQLAlchemy, I wouldn't assume that the object model would be particularly different in any other OO language for the problem it's solving.
- mjr00 3y ago> I don’t use an IDE, so code completion or whatever you get for it doesn’t apply to me. This is a reasonable take if you're a solo developer working without an IDE. Though I suspect you'd still find a few missing None checks with type checking. If you're working on a team, though, the idea is to put type-checking into your build server, alongside your tests, linting, and whatnot. > You see extraneous code like x: int = 1 in Python now. This shouldn't be necessary in most cases; Python type checkers are fine with inferring types. > Third party libs have bonkers types. This function signature is ridiculous: It is. Part of that is that core infrastructure libraries tend to have wonky signatures just by their nature. A bigger part, though, is that a lot of APIs in popular Python libraries are poorly designed, in that they're extremely permissive (like pandas APIs allowing dataframes, ndarrays, list of dicts, and whatever else) and use kwargs inappropriately. Type declarations just bring that to the surface.
- nerdponx 3y agoEven without an IDE, I use Mypy like a test suite. It catches real bugs that would be either hard to find in testing, or intrusive and annoying to test for.
- geysersam 3y agoWhat's wrong with being extremely permissive? I'd argue that's a strength of the python ecosystem. It's true that very dense api:s are difficult to type, but I wouldn't say they're typically poorly designed because of it.
- relaxing 3y agoWhen you’ve got to pass in something that isn’t permitted and the list of things that is permitted isn’t documented you’ve got to dig 12 levels down into the library across 9 branching paths to figure out what input it actually does support.
- eternityforest 3y agoPermissive libraries violate the "one and only one obvious way" philosophy. I suspect they probably confuse AI tools more than restrictive APIs too, and give non-AI auto complete less to go on.
- yazzku 3y agoThat signature is ridiculous in any programming language. Types aren't the problem here.
- nielsbot 3y agoWas about to say the same thing... that method takes like 20 arguments. Types are the only thing making it usable.
- virtualritz 3y ago> [...] rust have ergonomics [...] For starters Rust's official linter, clippy, would also tell you that this function has too many arguments. ;) The default (max) is seven[1]. The above function has 36 named arguments ... That is a code UX wtf with or without type annotations. [1] https://rust-lang.github.io/rust-clippy/master/index.html#/too_many_arguments https://rust-lang.github.io/rust-clippy/master/index.html#/t...
- ghnws 3y agoI've literally never seen anyone put types on trivial variables like that. Maybe your team is just inexperienced with types and/or python?