7 ms·
Working in the ML field, I can't hate Python. But the type system (pre-3.12, of course) cost me a lot of nerves. Hoping for a better post-3.12 experience once a
by davnn 1y ago
Working in the ML field, I can't hate Python. But the type system (pre-3.12, of course) cost me a lot of nerves. Hoping for a better post-3.12 experience once all libraries are usable in 3.12+. After that experience, I’ve come to truly appreciate TypeScript’s type system. Never thought I’d say that.
- hk__2 1y agoSame experience here, Python’s typing experience is awful compared to TypeScript, even post-3.12. Mypy’s type inference is so dumb you have to write arguments like `i: int = 0`; `TypedDict`s seems promisable at first and then end up as a nightmare where you have to `cast` everything. I miss TypeScript’s `unknown` as well.
- drumnerd 1y ago0 can be inferred as a float too, so doesn’t it make sense to type numbers?
- porridgeraisin 1y agoI believe mypy infers i as an integer in i = 0. I remember I had to do i = 0.0 to make it accept i += someFloat later on. Or of course i:float = 0 but I preferred the former.
- hk__2 1y agoYes, but not in arguments: def f(i=0) -> None: j = i + 1 k = 1 reveal_type(i) reveal_type(j) reveal_type(k) Output: Revealed type is "Any" Revealed type is "Any" Revealed type is "builtins.int"
- jsjohnst 1y agoBecause it shouldn’t in function arguments. The one defining the function should be responsible enough to know what input they want and actually properly type it. Assuming an int or number type here is wrong (it could be optional int for example).
- hk__2 1y agoIn TypeScript arguments with a default value "inherit" the type of that value, unless you explicitely mark it otherwise. I believe this is how Pyright works as well.
- jsjohnst 1y agoBut the type signature of: int -> int Is wrong. At minimum it’s: Optional[int] -> int Because you provided a default value so clearly it’s not required to provide an input parameter. It’s also wrong to assume `0` is an int. There’s other valid types it could be. If the default was say `42`, I’d be pushing back a little less (outside of the Optional part), but this contrived example from GP had 0, which is ambiguous on what the inferred typing must be.
- hk__2 1y agoTry: def f(i=0) -> None: reveal_type(i) The inferred type is not `float` nor `int`, but `Any`. Mypy will happily let you call `f("some string")`.
- veber-alex 1y agoThat's a mypy issue. Pyright correctly deduces the type as int. In any case it's a bad example as function signatures should always be typed.
- jsjohnst 1y agoSo you want strong typing, but then are to lazy to properly type your function definitions?
- toolslive 1y agono need to explicitly write the type if you have type inference: > # fun x -> x + 1;; > - : int -> int = <fun> >
- jsjohnst 1y ago1) the code you wrote isn’t Python. 2) inferring the type is int isn’t guaranteed to be correct in this case
- toolslive 1y agoI was merely giving an example that strong typing has nothing to do with having to write the types. (and, obviously, the inferred type (int -> int) is correct. )
- Izkata 1y agoOnly if reveal_type only accepts an int. Just because the default value of i is 0 doesn't mean anything about what could be passed in.
- davidatbu 1y agoYou really should check out pyright/pylance/basedpyright. Just an all around better type checker. Even has the "unknown" from typescript (kinda).
- quotemstr 1y agoIt still has a special case for dataclass-like things. I don't see how Python type checking (I haven't tried Red Knot) could let you do semi-magical things like Zod schema validation from TypeScript.
- davidatbu 1y ago100%. Python typing is nowhere near as powerful as TS, and the example you gave demonstrates that. I mentioned pyright because (some of) the specific concerns by OP are addressed by it.
- NeutralForest 1y agoI'm just waiting for the astral's people (uv, ruff) type checker at this point. On large projects mypy is often unreliable and slow.
- globular-toast 1y agoMypy was designed to enable gradual adoption. There is definitely Python code out there with `def f(i=0)` where `i` could be any numeric type including floats, complex, numpy etc.. This is called duck typing. It's wrong for a type checker to assume `i: int` in such a case. Pyright probably works if you use it for a new project from the start or invest a lot of time "fixing" an existing project. But it's a totally different tool and it's silly to criticise mypy without understanding its use case.
- hk__2 1y agoI’d be very happy if `def f(i=0)` would type i as a number-like, but right now it’s not typed at all: mypy "infers" its type as `Any`. I tried Pyright but as you say on an existing project you need a looot of time to "fix" it.
- drumnerd 1y agoHey kiddo… did you ever try something nastier? I’ve got something that will blow your mind and you’ll keep coming back You don’t know but you are addicted to types Come to the light - Haskell!
- hyperbrainer 1y agoWhich is despite, a decade of attempts, still missing dependent types. Time to embrace Idris. Or embrace logic + functional programming: Curry. https://curry-language.org/ https://curry-language.org/
- davnn 1y agoThat's basically where I am coming from :). I know about my addiction.
- srean 1y agoOne of the most frustrating bugs I had encountered was when I was using memory mapped CSC format sparse arrays. I needed the array indices to be int64 and specified them as such during initialization. Downstreams, however, it would look at the actual index values and dynamically cast them to int32 if it judged there would be no loss in precision. This would completely screw up the roundtrip through a module implemented in C. Being an intermittent bug it was quite a hell.
- deleted 1y ago[deleted]