Live data from Hacker News

Are you expected to run five Python type-checkers now?

pyrefly.org

141–150 of 220 posts

Re: Are you expected to run five Python type-checkers now?

#141

> "In Python, any method __eq__ is expected to return bool, and if it doesn't, then we need to explicitly tell type-checkers to ignore the type error. This function in Polars can also return different types depending on the inputs, thus requiring overloads." Why would you ever want a == b to not return a bool?? EDIT: Yes, I understand that you can do element-wise equality checks on numpy arrays now

There are examples like ORM query builders (something like `User.id == user_id` should not return a boolean, but rather some inspectable query part), multi-value comparisons (e.g. numpy arrays and views which could also be used as masks for indexing) In general, when you get your hands on operator overloading you get a bunch of various quirky applications for each. Some dunder methods have strict runtime-level rules…

That's one of the things I truly didn't get from my (very limited) experience with SQLAlchemy. Why not just have a method like orm.eq(User.id, user_id)? Much more readable.

Re: Are you expected to run five Python type-checkers now?

#142

> "In Python, any method __eq__ is expected to return bool, and if it doesn't, then we need to explicitly tell type-checkers to ignore the type error. This function in Polars can also return different types depending on the inputs, thus requiring overloads." Why would you ever want a == b to not return a bool?? EDIT: Yes, I understand that you can do element-wise equality checks on numpy arrays now

Elementwise equality! Given two dataframe columns or ndarrays, users often expect `==` to give out a column or ndarrays of bools (like `+`, ` `, `*, `&`, and just about every other binary operator).

What I love about operator overloading is that now you can't use operators without looking at their definition, in which case.. you could have done numpy.equals(a, b) anyway.

Does a == b true, if all elements are the same? Does it return an array of booleans? It's anyone's guess!

Re: Are you expected to run five Python type-checkers now?

#143

Earlier quoted context omitted.

Lack of typing is my biggest problem with Python, Ruby, and ES6 Javascript; I have to write everything twice, once to do the stuff I want, and once to double check that it's actually doing stuff, because a single typo blow the program up despite it parsing fine. Python typing is easy to dip in and out of. It handles None nicely; not as nicely as a true Optional, but enough for daily driving. The annotations are reada…

I believe you are right to point out how you feel about some of these features of a particular language, and to let that guide your decision in how and whether you use them. It does not, however, say anything about the actual productivity gain or loss of using types in a language like Python which does not require them — that should be the ultimate objective measure of whether they make sense or not. With most langua…

What I like about Python types is that they accommodate both styles of programming. I happen to be completely sold on at least some baseline level of type safety (I don't need my type system to be a complete modeling toolkit for everything in my problem domain, just enough for basic sanity), but if you're an old-school Python type, you and I can work on the same codebase without types ruining your life.

Re: Are you expected to run five Python type-checkers now?

#144

Earlier quoted context omitted.

Static type checking catches a whole class of programming errors for free. Writing tests costs tokens or human time, so you end up needing more code (and probably more CPU time) to achieve the same level of error-checking in a dynamic language.

Very simplistic look, IMO. I'll add another one mostly as a counterpoint (not that I believe it is strictly true, but largely yes!). Python is a lot more expressive than other languages and has a very terse syntax, and thus requires LLM to output much fewer tokens to achieve the same job compared to other languages. Adding a few more tests to ensure data conformity on top of what you have to do anyway with a statical…

Does it have a terse syntax? I main F#, and when I have to work with Python I generally find myself complaining about how verbose it is. (Needing intermediate variables for what should have been a pipeline, the ceremony around parallelism, having to store constructor parameters as object fields, etc.)

Re: Are you expected to run five Python type-checkers now?

#146

Dynamically typed languages are going to decline with the rise of AI coding. Statically typed languages provide the determinism necessary to efficiently anchor probabalistic coding agents. You can throw as much type checking at dynamic languages after the fact, but youre just going to burn energy (and tokens) doing what another language gets 'for free'.

Python is dynamically, strongly typed. It cares a lot about the types of its objects, you can't just mix and match at will. Perhaps you meant statically typed?

Oops thank you, I did mean static. I should know better as I am a cpp fan. Updated.

Re: Are you expected to run five Python type-checkers now?

#147
post #23
post #15

If you are going to be super-strict with type-checking, wouldn’t it be best to switch to a statically typed language and get the performance gains as well?

Hallelujah, that's always been my position. To the static typing folks: leave my dynamically typed languages alone and go coding with something that really suit your needs. If the answer is that Python, Ruby, JS, whatever are really much more pleasant to code with, my reply is that they are so precisely because we don't have to type type definitions. Tradeoffs.

My engineers write better code when we enforce types.

It's easier to do this then retrain everyone on Go and rewrite all our code.

New stuff is often in Go now, but prototyping quickly in Python and then enforcing types when we have to get it ready for production has been working decently

Re: Are you expected to run five Python type-checkers now?

#148
post #23
post #15

If you are going to be super-strict with type-checking, wouldn’t it be best to switch to a statically typed language and get the performance gains as well?

Hallelujah, that's always been my position. To the static typing folks: leave my dynamically typed languages alone and go coding with something that really suit your needs. If the answer is that Python, Ruby, JS, whatever are really much more pleasant to code with, my reply is that they are so precisely because we don't have to type type definitions. Tradeoffs.

So far I have been avoiding Pydantic as a huge-ass dependency. Instead I am relying on standard type annotations, lots of typed dicts and at service/program boundaries use a jsonschema. I like being able to specify the type of most functions, and get some hints, completions and so on, but I don't want to _have to_ specify every darn type. I also don't want to write a class for everything. Typing dicts is good and usually sufficient. If I wanted to write types for everything, then I could also just write Java or Rust or similar.

Unfortunately, I think the kingdom of nouns faction has long invaded the Python world and I see more and more companies demanding Pydantic and similar things. They are dragging us all the way to Java land, it seems.

Re: Are you expected to run five Python type-checkers now?

#149

Earlier quoted context omitted.

Very simplistic look, IMO. I'll add another one mostly as a counterpoint (not that I believe it is strictly true, but largely yes!). Python is a lot more expressive than other languages and has a very terse syntax, and thus requires LLM to output much fewer tokens to achieve the same job compared to other languages. Adding a few more tests to ensure data conformity on top of what you have to do anyway with a statical…

Does it have a terse syntax? I main F#, and when I have to work with Python I generally find myself complaining about how verbose it is. (Needing intermediate variables for what should have been a pipeline, the ceremony around parallelism, having to store constructor parameters as object fields, etc.)

It sure does in comparison with most mainstream statically typed languages — if you feel that way about Python, I wonder what you say about Java, C++ or even Rust or Go?

Checking some examples at https://learn.microsoft.com/en-us/dotnet/fsharp/tour, I'd say it's quite similar in verbosity — eg. no need to declare a module in Python since the code already lives in a file that is the module (plus one less indentation level for module level functions); inline function declaration and calling is thereabouts with F# slightly more terse (let vs lambda + spaces vs parenthesis); if-then more verbose in F# (no then in Python, just "if x:"); F# does not seem to need "return"...

In many cases you can avoid intermediate varibles: inline ifs, list comprehensions, lambdas, etc... Constructor arguments are a good point, but this is mostly about idiomatic use instead of language itself: you can simply do

  def __init__(self, **kwargs):
      self.args = kwargs
I'll give you one on the ceremony around concurrency, though! I have different ideas of how it should have been done to shift the cost to the language runtime instead of the developer, but alas... :)

Re: Are you expected to run five Python type-checkers now?

#150

Earlier quoted context omitted.

Static type checking catches a whole class of programming errors for free. Writing tests costs tokens or human time, so you end up needing more code (and probably more CPU time) to achieve the same level of error-checking in a dynamic language.

Very simplistic look, IMO. I'll add another one mostly as a counterpoint (not that I believe it is strictly true, but largely yes!). Python is a lot more expressive than other languages and has a very terse syntax, and thus requires LLM to output much fewer tokens to achieve the same job compared to other languages. Adding a few more tests to ensure data conformity on top of what you have to do anyway with a statical…

The expressiveness of a language and whether it does static/dynamic type checking are orthogonal. Type inference and generics are a thing in most modern languages. I also think you're underestimating the amount of code you need to guarantee that there are no type errors in your Python code.
Post reply on HN