Live data from Hacker News

Writing Python like it's Rust

kobzol.github.io

251–260 of 369 posts

Re: Writing Python like it's Rust

#251
post #40

Earlier quoted context omitted.

It's not that many steps. You already have CI - adding mypy is one extra line, you should already have a way to keep track of versions in your project - keeping track of the mypy version isn't any additional overhead. If your team uses VSCode, you can have a devcontainer for the project ( https://code.visualstudio.com/docs/devcontainers/containers ) to make sure that it's in everyone's IDE along with your other linte…

> You already have CI Don't worry about me. I mean all projects that do not have people and resources for this stuff. People just want to write Python and be done with it. Without type hints they wrote Python and if they run it and tests pass then it works. Now they write Python code that can be wrong but they don't find out unless they also run an extra tool. The fact that it requires CI now is a good illustration o…

I don't understand who the "just want to write Python and be done with it" demographic is. If you're a developer, it makes sense to do things well, if you aren't and you're writing small one-off scripts, you can do fine without type hints.

Anyone who can write and run a test can also call "mypy ." on their project.

Re: Writing Python like it's Rust

#252
post #170

Earlier quoted context omitted.

> it never comes up because when you know what domain you're working in it's always immediately obvious what types the arguments are. Oh this one is hilariously wrong. Is it InvoiceLine that we are getting here? Or Maybe LineInvoice? Nope those aren't the same. But the only argument is called «line». How shameful. Much sadness. Better add a print statement, push a new build and comeback in twenty minutes

It sounds like the codebase sucks or you haven't taken enough time to understand it.

Suppose it sucks, and you are expected to contribute to it already. Welcome to the real world?

Re: Writing Python like it's Rust

#253

I went through a similar journey, without the Rust part. Started using type hints, data classes, pydantic to get the benefit of static typing after dealing with the pain of refactoring dynamically typed projects. It was better, but it _feels_ like lipstick on a pig. I love Python, but types are not what it's best at. It's missing features that makes typing easier. I've realized if was going to write typed Python, I m…

I'm also 100% convinced most people who use mypy don't realize the myriad ways it just silently stopps typing things or just silently crashes with a 0 exit code. Even if you configure it to warn untyped functions etc. It will still just not work properly in some of circumstances and you will literally never know until you debug a bug that just happened to trigger it. There are over 1.4k open bug tickets it's such a b…

I think it's probably no mere coincidence that the article recommends pyright, not mypy.

Re: Writing Python like it's Rust

#255

Earlier quoted context omitted.

I find it hard to understand how you can believe something like Dropbox isn't "serious production" just because it involves websites and apps.

the program that does the synchronization of files in the background is.

Last time I checked, that part was written in Python...

Re: Writing Python like it's Rust

#256
post #210

Earlier quoted context omitted.

> But it can also be an impediment to iteration. Sometimes the code you're working on is still so experimental that you don't really know what the best structure and flow of data will be yet, and it's easier to just bodge it together with maps and heterogeneous lists for the first few iterations so you can let the code tell you how it wants to be structured. Having to start with static types subtly anchors you to you…

That was what I originally thought, as someone who grew up on static typing and then migrated to Python. But what I've discovered in practice is that, during those early iterations, I don't really need the compiler to help me predict what will break, because it's already in my head. The more common problem is that static typing results in more breaks than there would be in the code that just uses heterogeneous maps a…

As someone who has primarily gone in the other direction, my anecdata supports the opposite conclusion: static typing tends to help me to prototype over more dynamic languages, even if it takes (slightly) longer to physically write things down. I think this is because of two things:

1. If I'm prototyping things, I find I spend a lot of time trying to figure out what sorts of shapes the data in my program will have - what sort of states are allowed, what sort of cases are present, what data will always exist vs what data will be optional, etc. If I'm doing that in my head, I may as well write it down at the same time, and voila, types. So I'm not usually doing much extra works by adding types.

2. If I change my code, which I often do when prototyping (some name turns out to be wrong, some switch needs extra cases, some function needs more data), then that is much easier in typed languages than untyped ones. Many times my IDE can do the refactoring for me, and if that isn't possible, I can start making the change somewhere (e.g. in a type declaration) and just follow the red lines until I've made the change everywhere. One of the big results of this is that statically typed prototypes are often immediately ready to be developed into a product, whereas in dynamic languages, the prototype already bears so many scars from refactoring and the natural back-and-forth that comes from prototyping, that it needs to be rewritten over more from scratch. (The corollary to that being that I have never once had a chance to rewrite a prototype before releasing it to production.)

I can imagine that some of this comes down to programming/architectural style. I tend to want to define my types up front, even in dynamic languages, because types and data are how I best understand the programs I work on. But if that's not how you work, the tradeoffs might not be the same. The other side is that the type systems I regularly use are almost exclusively modern ones, with decent support for things like product and sum types, so that I can use relatively simple types to model a lot of invariants.

Re: Writing Python like it's Rust

#257

I went through a similar journey, without the Rust part. Started using type hints, data classes, pydantic to get the benefit of static typing after dealing with the pain of refactoring dynamically typed projects. It was better, but it _feels_ like lipstick on a pig. I love Python, but types are not what it's best at. It's missing features that makes typing easier. I've realized if was going to write typed Python, I m…

> I can do almost all the dynamics things that I can do in Python with C#, but in a type safe way. If you like flexibility with a good type system, give Typescript a try, its miles ahead of mypy and its designed by same person who’s behind C#.

I'm a full stack dev so I'm also using TS at the same time. While the flexibility is nice, it's too flexible for my taste. To give a one basic example, I want to go to the definition of a symbol with a single action. Not possible with the current TS tooling and all the crazy things you can do with it's type system.

I want the type system to be predictable, so it can support whatever I want to build on top of.

There are features I'm missing with C#, but still I'll choose it over TS any day.

Re: Writing Python like it's Rust

#258

Earlier quoted context omitted.

That's only until you've grokked Rust. I find iterating in Rust to be faster than Python.

Iterating in Python is always faster than iterating in Rust. If you do indeed find what you are saying then you simply speaking aren't able to write Python code.

No, because to iterate in Python, you have run the program and get it into the right state. For many things in Rust, I can just use `cargo check`.

Re: Writing Python like it's Rust

#259

Earlier quoted context omitted.

> I can do almost all the dynamics things that I can do in Python with C#, but in a type safe way. If you like flexibility with a good type system, give Typescript a try, its miles ahead of mypy and its designed by same person who’s behind C#.

Even better would be to try F#, it will be able to use all the .NET libraries, has Python's succinctness, but with a strong type system (and inference).

I may switch to it eventually, but at this point in my career 16 years in, I try to avoid seemingly niche things when I just want to get stuff done. "Boring" is good. I know it's the same platform under the hood but I decided to spend my "innovation tokens"[0] on the stuff I'm buildin.

[0]: https://mcfunley.com/choose-boring-technology

Re: Writing Python like it's Rust

#260
post #210

Earlier quoted context omitted.

> But it can also be an impediment to iteration. Sometimes the code you're working on is still so experimental that you don't really know what the best structure and flow of data will be yet, and it's easier to just bodge it together with maps and heterogeneous lists for the first few iterations so you can let the code tell you how it wants to be structured. Having to start with static types subtly anchors you to you…

That was what I originally thought, as someone who grew up on static typing and then migrated to Python. But what I've discovered in practice is that, during those early iterations, I don't really need the compiler to help me predict what will break, because it's already in my head. The more common problem is that static typing results in more breaks than there would be in the code that just uses heterogeneous maps a…

> But what I've discovered in practice is that, during those early iterations, I don't really need the compiler to help me predict what will break, because it's already in my head.

Reading this, I have the feeling that you're talking mostly of single-person (or at least small team) projects. Am I wrong?

> The more common problem is that static typing results in more breaks than there would be in the code that just uses heterogeneous maps and lists, because I've got to set up special types, constructors, etc. for different states of the data such as "an ID has/has not been assigned yet". So it kind of ends up being the best solution to a problem largely of its own making.

There is definitely truth to this. I feel that this is a tax I'm absolutely willing to pay for most of my projects, but for single-person highly experimental projects, I agree that it sometimes feels unnecessary.

> I'm also working from the assumption here that one will go through and clean up code before putting it into production. That could be as simple as replacing dicts with dataclasses and adding type hints, but might also mean migrating modules to cython or Rust when it makes sense to do so. So you should still have good static type checking of code by the time it goes into production.

Just to be sure that we're talking of the same thing: do we agree that dataclasses and type hints are just the first step towards actually using types correctly? Just as putting things in `struct` or `enum` in Rust are just the first step.

Post reply on HN