Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

When did Python go out of fashion? This is the second article I've seen talking about it as if it's some kind abomination.

I get that it's not the shiny new thing, but I don't understand people hating on it. Is this just junior devs who never learned it, or is there some new language out that I missed? (And please don't tell me Javascript....)



I have had a somewhat unearned distaste for Python for the last decade or so.

I mostly just don’t like some of the design decisions it made. I don’t like that lambdas can’t span multiple lines, I don’t like how slow loops are, I don’t like some functions seem to mutate lists and others don’t, and I am sure that there are other things I missed.

But it really comes down to the fact that my career hasn’t used it much. I occasionally have had to jump into it because of scripting stuff, and I even did teach it for a programming 101 course at a university, but I haven’t had a lot of exposure otherwise.

For scripting stuff for myself, I usually end up using Clojure with GraalVM (yes I know about babashka), or nowadays even just a static linked compiled language like Rust.

I don’t really understand why people think that compiled languages can’t be used for scripting (or at least task automation), honestly. Yes you have to add a compilation step. This involves maybe one extra step during development, but realistically not even that. With Rust I just do cargo run while developing, I don’t see how that’s harder than typing Python.


The most insane python feature is that for loops keep their intermediate variable.

for x in [1,2,3]: print(x)

x sticks around! So you'll always have these random variables floating around, and hope you don't use the wrong one.

And to add insult to insult to injury, if you're using mypy for type checking you'll get a nice error if you try to reuse x with a different type:

for x in ['a', 'b', 'c']: print(x) << Incompatible types in assignment (expression has type "str", variable has type "int") [assignment]

And the types I can never trust. I've used all the tooling and you still get type errors in runtime. It's also ridiculously slow.

I would also like optional chaining (e.g. foo?.bar?.baz) and a million other features that other high level programming languages have.


> The most insane python feature is that for loops keep their intermediate variable.

"Insane feature" is a generous way of describing this behavior. I would say it is just a stupid bug that has managed to persist. Probably it is impossible to fix now because of https://xkcd.com/1172/

How typecheckers and linters should deal with this is a tricky question. There is how the language ought to work, and then there is how the language actually does in fact work, and unfortunately they are not the same.


Comments like this basically should say "I want as much handholding as possible"

Lucky for you, LLMs are pretty good at that these days.

>And the types I can never trust. I've used all the tooling and you still get type errors in runtime. It's also ridiculously slow.

IDE integrated mypy checking does this in the background as you type. As for errors, it all has to do with how much typing you actually use. You can set the IDE to throw warning based around any types or lack of type annotation.

Again, handholding.


    msedit main.py && ./main.py
    !!
    !!
But indeed, pressing F5 solves that for both Rust and Python


why would you want a lambda to span multiple lines? How would that be any better than a function?


Because sometimes I want to have logic that spans multiple lines and I don't want to assign it a name. An easy example might be something with a `map` or a filter. For example, in JavaScript

    [1,2,3,4].filter(x => {
        let z = x * 2;
        let y = x * 3; 
        let a = x / 2; 
        return (z + x * a) % 27 == 2;
    });
Obviously I know I could name this function and feed it in, but for one-off logic like this I feel a lambda is descriptive enough and I like that it can be done in-place.

You're free to disagree, but I think there's a reason that most languages do allow multi-line lambdas now, even Java.


> Obviously I know I could name this function and feed it in, but for one-off logic like this I feel a lambda is descriptive enough and I like that it can be done in-place.

FWIW, you'd also have the benefit of being able to unit test your logic.


I mean, maybe, that's why your lambdas shouldn't be too long.

I have done a lot of Haskell and F#, and I'm very familiar with the concept of "lifting", and yeah being able to individually test the components is nice, but even within Haskell it's not too uncommon to use a lambda if the logic doesn't really need to be reused or is only a couple lines.

If you have a huge function, or you think there's any chance of the logic being reused, of course don't use a lambda, use a named function. I'm just saying that sometimes stuff that has 2-4 lines is still not worthy of having a name.


Off topic: you didn’t use y.


You are right! Obviously this is just an ad hoc thing I wrote to show a point but I shouldn't be using superfluous variables.


Honestly, I don't really see the appeal of unnamed functions in general. I so rarely use lambdas that I wouldn't really miss them if they were gone. Just occasionally as a sort key, or in a comprehension.

I have seen people do this in JavaScript quite often, but I always assumed there was some kind of underlying performance benefit that I didn't know about.

As I think about it I guess it makes sense if you're passing a function to a function and you just want it to be concise. I could imagine using something like that off the top of my head, but then pulling it apart and giving it a name the moment I had to troubleshoot it. Which is how I currently use nested comprehensions, just blurt them out in the moment but refactor at the first sign of trouble.

I think maybe I just have trouble seeing some of the braces and stuff, and it's easier for me to reason about if it's named. I guess that's why we have 32 flavors.

Thanks for answering me honestly I really do appreciate it, even if my tone came off as dismissive. Sometimes I don't realize how I sound until after I read it back.


Obviously it's totally fine to have a difference of opinion for something like this.

> I have seen people do this in JavaScript quite often, but I always assumed there was some kind of underlying performance benefit that I didn't know about.

I don't think so, at least I haven't heard of it if there is.

I tend to have a rule of thumb of "if it's more than 6-7 lines, give it a name". That's not a strict rule, but it's something I try and force myself to do.

Like in Python, most lambdas can be done in one line, but that also kind of gets into a separate bit of gross logic, because you might try and cram as much into an expression as possible.

Like, in my example, it could be written like this:

    [1,2,3,4].filter(x =>((x * 2) + x * (x/2)) % 27 == 2);
But now I have one giant-ass expression because I put it all into one line. Now where previously I had two extra names for the variables, I have the ad-hoc logic shoved in there because I wanted to squeeze it into a lambda.


And I think that's where the reasoning behind only allowing one line lambdas came from. I believe I read a thread a long time ago where GVR didn't even want to include lambdas at all, if I have time I might look for it and edit in a link.

At it's core, I think it's fair to say Python is about forcing the user into formatting their code in a readable way. It's gotten away from it over the years for practicality reasons, and to increase adoption by people who disagree on which ways are more readable.

Sometimes I wish they would take nested comprehensions away from me, I am too lazy to avoid them in the heat of the moment, and I get a thrill out of making it work, even though I know they're disgusting.


Naming things is one of the hard problems of computer science. It's nice not to be forced into naming something.


If your style is doing a lot of functional programming, multi-line lambda is a very natural thing to do. Other times you want to use a variable or several variables without actually passing it around as an argument. It makes sense especially if you are already used to it in Java/C++/JavaScript/Go.

Is it "better" than a named function? No, of course, they work mostly the same. But we are not talking about better or not. We are talking about syntax just for the sake for syntax, because some people prefer to write code in a way you don't necessarily care about.


This makes a lot of sense, I got to a similar conclusion in my other reply.

I always thought the appeal of functional programming was more about test-ability and concurrency, it never occurred to me that people actually preferred the syntax.


Can't speak for anyone else, obviously, but part of the reason that I got into functional programming is specifically because I found the syntax very expressive. I felt like I was able to directly express my intent instead of describing a sequence of steps and hope that my intent comes to fruition.

Different strokes and whatnot, not everyone likes functional programming and of course there are valid enough criticisms against it, but I've always appreciated how terse and simple it feels compared to imperative stuff.

Even with regards to testability, if your function is pure and not mucking with IO or something, then even using a multi line lambda shouldn't affect that much. You would test function calling it.

Keep in mind, Haskell doesn't really have "loops" like you'd get in Python; in Python you might not necessarily need the lambda because you might do your one-off logic inside a for loop or something. In Haskell you have map and filter and reduce and recursion, that's basically it.


> Haskell doesn't really have "loops"

weeell, you can still do stuff like this in Haskell:

     import Data.Vector.Mutable
     ...
     let n = length vec
     forM_ [0 .. n-1] $ \i -> do
       next <- if i < n-1 then read vec (i+1) else pure 0
       modify vec (+ next) i -- increase this value by next value
it's just in many cases the functional machinery is so accessible that you don't need to reach for for-loops.


Apparently the author used to be a Java person. I have this feeling - or prejudice - that people still in the Java World are a bit out of tune with the tech industry, working on huge legacy projects on big retail or US banking. These people tend to be conservative and resistant to change, so maybe that's where these types of articles are coming from.


Java shops are certainly where I've witnessed the most disdain for Python. IME the strongest feelings tend to come from people who didn't actually have any significant experience with Python, and perhaps don't even have much practical experience with any language that isn't Java. So they tended to consider it to be objectively inferior purely because it's interpreted and dynamically typed.

At a previous job I did manage to put a chip in that when I demonstrated replacing one of our Java services with a Python implementation. It was a fraction of the code, and achieved much better latency and throughput. Obviously not every Python program is going to do that. But my point isn't that Python is better, it's that these kinds of things are never so cut-and-dried. Many non-trivial Python programs are just thin shells around a large core of very well-optimized and battle-tested C/C++/Rust code. And Java, for its part, can also accumulate a lot of dynamic language-style performance losses to pointer chasing and run-time type lookups (and GC churn) if you're not careful about how you use generics. As always, the devil's in the details. It's also less able to pull the "actually I'm a C++" trick because using a compacting garbage collector makes it difficult to interop with native code without paying a hefty marshaling tax.


I have way more experience with Python than Java. In at least 4 companies (including Google that I wouldn't call a javashop) we used mainly Python.

Still I believe Java is a better application language. Python is a better scripting language (replacement for Bash). Small apps tend to be easier on Python, but large apps are way easier on Java, both for syntax (types) and ecosystem (libs).


Mostly agreed, though I would add that I'm generally happier with Python as a default for reasonably sized services that don't have a lot of (non-numpy-friendly) compute load and therefore don't have a pressing need for multithreading. Which is a lot of what happens now that we're all trapped in the cloud. Like you say, small apps tend to be easier in Python.


That is general take as well. A lot of small apps/simulators are in python. Ops scripts tend to be python. Java for the core/data. Refactoring/tooling is easier in Java when you are dealing with a 100k codebase imo. Typescript always.

Seen plenty of coding horrors in both ecosystems...


Algorithms are a lot easier to understand when they are written in Python. I'm actually right now documenting medium size Java codebase by writing pseudocode, which looks like Python. Just by doing that, I've already discovered multiple bugs, which I didn't catch by looking at the Java code.


That might be the big thing that I think gets glossed over in a lot of these discussions. I agree that I wouldn't want to maintain 100kloc of Python. But, I don't really view that as a realistic hypothetical for a business application. Idiomatic Python tends to require a fraction as much code as idiomatic Java to accomplish the same task. The only time it even gets close is when you have code written by people who go out of their way to make things look like old-school enterprisey Java. So it ends up accumulating a bunch of stuff like

  class IWantToBeABean:
    def init(self, arg1: int, arg2: str, arg4: str) -> None:
      self._field1: int = arg1
      self._field2: str = arg2
      self._field3: str = arg3

    def get_field1(self) -> int:
      return self._field1

    def set_field1(self, value: int) -> None:
      self._field1 = value
    
    def get_field2(self) -> str:
      return self._field2

    def set_field2(self, value: str) -> None:
      self._field2 = value

    def get_field3(self) -> str:
      return self._field3

    def set_field3(self, value: str) -> None:
      self._field3 = value

when it could have just been:

  @dataclass
  class IDontWantToBeABean:
    field1: int
    field2: str
    field3: str

The worse case for Python is when you get people doing the oldschool Python thing of acting like dynamic and duck typing means it's OK to be a type anarchist. Scikit-learn's a good one to put on blast here, with the way that the type and structure of various functions' return values, or even the type and structure of data they can handle, can vary quite a bit depending on the function's arguments. And often in ways that are not clearly documented. Sometimes the rules even change without fanfare on minor version upgrades.

The reason why large Python codebases are particularly scary isn't necessarily the size itself. It's that for a codebase to even get that large in the first place it's very likely to have been around so long that the probability of it having had at least one major contributor who likes to do cute tricks like this is close to 1. And I'd take overly verbose like the Java example above over that kind of thing any day.


Hey, you forgot useless comments for each method:

    get_field1(self) -> int:
      """
         Gets Field1.

         @rtype: int
         @return: the field1
      """
      self._field1
And use double underscores for private fields, because, you know, encapsulation.

Seriously though, in Java you don't need get*() either. Typically you either:

1. use `record` types (since Java14, 2020), or

2. use Lombok that auto-generates them [1], or

3. use Kotlin `data class`, or

4. just raw field access. I don't buy the encapsulation thing if my code is not a library for wide internet to use.

[1] https://projectlombok.org/features/GetterSetter


Try Kotlin then.

I wouldn't call it a new language, for me it's just a syntactic sugar over Java, but for any problem you would google "how to do X in Java", not "how to do X in Kotlin".

But there you can do way simpler syntax, like:

    0..100 meters with -45..45 deg within 3 seconds
Because "0..100 meters ..." is equivalent to "(0..100).meters(...)"

(0..100) is a built-in IntRange type, that you can extend:

    data class MyDistanceRange(val meters: ClosedRange<Double>)

    val IntRange.meters: MyDistanceRange
        get() = MyDistanceRange(first.toDouble()..last.toDouble())
and


IMO Kotlin has some features that take it way beyond just being syntactic sugar over Java. Like, I know you could probably use some eye-watering gang-of-four pattern to achieve the same effect as extension methods. But it's going to be such a PITA to maintain that calling the Kotlin feature syntactic sugar for the same thing is about as useful as saying that function definitions are just syntactic sugar over assembly language calling conventions.


I've played with it for a bit but it doesn't excite me enough to spend time learning it properly. I also don't care about Python beyond using it for learning algorithms and maybe some smaller Pyside UIs. However, together with Mojo it might become more interesting again.


> Java, for its part, can also accumulate a lot of dynamic language-style performance losses to pointer chasing and run-time type lookups (and GC churn) if you're not careful about how you use generics.

The worst thing about Java is the average quality of Java programmer.The same could probably be said about Python. However I think that there are fewer Python programmers trying to write AbstractFactoryFactory than in Java. Java has a terrible culture of overly verbose, deep inheritance trees that make debugging and development worse, with worse performance.


I certainly think so but wasn’t sure if it was just my unfamiliarity or lack of advanced programming knowledge but I attempted what seemed like a very simple patch to a Java project (guacamole) and it was insane how I ended up having to add the new function to like a base and abstract class and interface etc. it was crazy. All the same boilerplate too.


I have a related feeling or prejudice that people not in the Java World view their corner as "the tech industry" without realizing that they are living in a village compared to the giant metropolis that is the Java World.

Java programmers may not blog as much, and Java doesn't show up on Hacker News as much, but not being Extremely Online does not mean that it isn't extremely widely used by real people whose experiences are just as valid.


you could say the same thing about a dozen other languages, but there is definitely a stereotypical cranky java dev that is frustrated writing corporate crud apps that should in theory be blazingly fast, but never quite are for reasons. They revel in the verbosity, and look down on anyone they feel is taking the easy path. If you've never met one you're lucky, but they've been at every company I ever worked for.


> you could say the same thing about a dozen other languages

No, you could not. You could say it about maybe four others: PHP, C, C++, and C#.

No other languages have anywhere near the userbase size while being fairly quiet when it comes to online tech discussion.

I agree there are crusty old Java devs (as well as crusty old C, C++, PHP, etc. devs). In a decade or two, there will be crusty old TypeScript devs. It's just the nature of technology lifecycles and career paths. Some people get relatively tired of learning when they get older and just want to capitalize on what they already know for their remaining earning years.


I think I made a conscious effort in my 30s not to become a crusty old Python dev. But I predict that in another decade or two, I (now in my 40s) will be a crusty old Rust dev.


ok I may have exaggerated, but there are quite a bit of people silently writing and maintaining mission critical code in Fortran, Lisp, Cobal, Perl, Pascal, R, Assembly, the different BASICs, Lua, TCL, Erlang, and the list goes on. Plus those are just the ones off the top of my head where I have personally met people doing it in the last decade. I am always shocked by how much

Most of those rarely make to the top of HN, and other generalized forums. If anything, Java and Python are together at the popular kids table and we forget about the silent heros keeping the ship afloat.


I worked in .Net land before switching to Pythonville. It's very much like Java metropolis, but with less CS graduates.


If the TIOBE index is an even remotely useful indicator, Python's an even bigger giant metropolis.


Yes, but the difference here is that Python is talked about all the time, so the online tech world knows that Python is huge.

The comment I was replying to seems to believe Java is a tiny backwater, which is anything but true.


I read it less as "Java is tiny" and more as "Java developers can be peculiarly insular and conservative, by the standards of other communities."

Considering that as recently as 4 years ago I was working on a project where we still had a hard requirement to support running in Java 7, and this kind of thing was not considered unusual, I can't really disagree too strongly with that. Yes, that was still inside of Java 7's extended support period, so there was really nothing unusual or surprising about this, from a Java developer perspective. But that's kind of the point.

It's also not really a bad thing, considering what kinds of things run on Java. Mainframe developers have a similar thing going on, for a similar and similarly good reason.


I'm not sure if they refer to how large the language's reach is, but more about how advanced Java is once you stop looking at syntax bloat. The JVM can do stuff that's not easy to do in other environments.

I recall things like updating packages/code on the fly, recompiling fast paths on the fly. Maybe that's not necessary in a borg/kubernetes world where you can just restart things and have your load balancer infra take care, or just run slower code because compute isn't that expensive once you accelerate your CPU-heavy libraries, but cool anyways.


Lest we forget that Python is ~4 years older than Java.


This is absolutely correct as someone who has worked in a few Java shops. Although, the same thing is Java's failing, as it is well nigh impossible for people external to the Java ecosystem to learn what's inside it without having work-related exposure.


You may know all this and are just singling out the Hacker News crowd. But I read your comment and thought "surely he doesn’t think Java is much bigger than Python?" I’m not even sort of sure Python is smaller.

Edit more succinct


The reason that people still code in Java (or derivative) is because legacy code that they are working on is in Java, and nobody has either the skill or time to go through and translate it. Which means that the jobs where its used are basically just big enterprise, low tech software that just been around for a while.

The Log4shell incident is the perfect demonstrator of what kind of people are in Java world.


> nobody has either the skill or time to go through and translate it.

To what? Java is still a very efficient, productive language. Updating a legacy codebase to use newer Java features would probably be good, but migrating to another language is unlikely to significantly move the needle in terms of runtime performance or developer velocity.


Most of the use cases for java are in places where network latency dominates. If Python is fast enough for Uber and Youtube, its fast enough for your service.

When you work with a codebase that doesn't need compilation, the development velocity is quite fast. You don't need to compile, you can prototype features on the fly, you can even write real time updates while the web server is running.

And standard compilation in Java is done in a VERY inefficient manner with groovy - you have groovy that gets compiled to bytecode, which then gets JIT compiled to native, which then actually runs the compilation of the source code to bytecode, and then you have a first startup latency as it gets JIT compiled to native.

All you really need to write any modern app is Python + C. Anything that needs to go fast, just encapsulate in a small C program, and launch that from Python.


I feel like the opposite is also true. People view Java as enterprise Java from 2008; a clunky outdated language for bad, verbose spaghetti code.

In fact, a lot of the most interesting plt and compiler r&d going into real world applications is on the jvm (project loom, graal etc), and the features of modern Java (pattern matching, records, etc) make it a great choice for lots of projects that aren’t legacy enterprise apps.


I gave a talk recently at a conference about how modern Java doesn’t suck very much, and that the worst part of Java is Java developers, who seem to be completely intellectually unambitious.

I don’t think Java makes anyone unambitious, I think it’s that Java is taught in schools and unambitious people don’t feel the need to learn anything else, and they get jobs at unambitious corporations. It selection-biases towards unambitious people who don’t want to learn more than they have to.

Compare this to something like Clojure or Haskell or something, which isn’t routinely taught at schools and is not very employable. People who learn these languages generally seek out these things because they’re interested in it. This selection-biases towards intellectually ambitious people.

As a result, Java people can be insufferable for people like me.

The people who make Java have actually made the platform and language pretty ok in the last two decades, but I had to fight at a previous job to use NIO, which I think was introduced in Java 4, but none of my coworkers had really heard of it or used it because the regular Java blocking IO has been “good enough”.


>how modern Java doesn’t suck very much,

Given fact that Lombok is still pretty much widely used, with its under the hood functionality of essentially hacking the AST, or the fact that annotation processors write out Java code to files, or the fact that you could be using a standard library like Log4j and have a massive vulnerability on your system because someone decided that it would be a good idea if log statements could execute code and nobody said anything otherwise, or the fact that Kotlin and Groovy were literally made to address inefficiencies in Java, amongst other things....

Yeah not really sure how you came to that conclusion.


That gets to my point though. For example, Lombok isn't really necessary for a lot of stuff now, because Records give you a lot of what you would use with Lombok.

Kotlin and Groovy did come and address problems with Java, you should use use them if your employer allows it. I'm just saying that Java 21 is actually kind of fun to write.

Yes, some of the libraries have been unsafe, but that's one example of the 30 years of Java.

I just feel like Java has improved in the last twenty years. It's the engineers that haven't.


link to talk please if recorded.

I think one comment I saw here on HN that Java is better if written in Pythonic way. I agree completely with that stance.

but yeah within Java you've 'merchants of complexity' people who wanna do things in the most abstract way rather than the simple way.

btw Java can be as simple as Go.


I don't think that the talk has been released on public YouTube yet (and they made it clear to not share the unlisted links publicly), but here is the posting: [url-redacted]

And the slides are available here: [url-redacted]

I'm afraid that my humor isn't really reflected in the slides, but imagine everything here is said kind of snarkily.

Java can be mostly as nice as Go, the BlockingQueues and Virtual Threads can get you pretty far, though they're not quite as nice as Go channels because there's no real way to select across multiple BlockingQueues like you can with Go channels.

Overall though, I think Java 21 is actually not too bad. Shockingly, I even sometimes have fun writing it.


Github link is 404


Oops! Forgot to make the repo public!

Should be fixed now. Sorry about that.


> I have this feeling - or prejudice - that people still in the Java World are a bit out of tune with the tech industry

Other than being ageist, it’s wrong; or misattributed to Java. I work with Python every day, and what’s missing is static typing and IDEs that make use of it to greatly reduce the amount of code and context I have to store in my head. Python (a dynamically typed language obviously) is exhausting to maintain. But easy to write. Java/C#/whatever statically typed language with great IDE is easy to write and maintain by comparison.

Of course there are IDE for Python and dynamically typed languages, but everyone I’ve tried has fallen short compared to the best Java/c# IDEs.

Static vs dynamic used to be a huge flame war on the internet, but over the past few years I’ve encountered people who’ve never heard of it. This is it.


I think at least half of amazon.com and AWS run on Java.


I've always felt X was far superior to Y, and don't get me started on Z or W.


I personally dislike Python, but it does surprise me that anyone is acting like it's generally disliked because that has definitely not been my impression since time immemorial. I doubt that it's gone out of fashion. More likely, acting like something actually doesn't suck after all has become the clickbait framework du jour.


A decade ago, Python was pretty rough around the edges in production. Of course you could make it work, but you had to sacrifice a lot in terms of:

- Environment / dependency management

- Type safety

- Performance

As the author points out, these have largely been addressed now by uv, type hints, pydantic, FastAPI, etc.


>A decade ago, Python was pretty rough around the edges in production.

Not really.

Environment/dependency management is/was never an actual problem. People act like you update a version and stuff breaks. Even then, venv existed for this reason, and you could specify version in the setup.py or requirements.txt.

Type safety should in theory be covered by unit tests. If you assign a variable to another one in a dynamic setting accidentally, like a string to a dict, then your functionality breaks. In reality though, its really not that hard to use different variable names. In my experience, the only time things start getting confusing is if you start using Java concepts with things like Factories and a lot of OOP and inheritance in Python. None of that stuff is really necessary, you can get by with dicts for like 90% of the data transfer. And in very type safe languages, you spend a lot of time designing the actual type system instead of just writing code that does stuff.

Performance is still slow, but language performance doesn't really matter - you can launch natively compiled code easily from Python. Numpy was built around this concept and is also 10 years old. You will never beat C (with explicit processor instructions for things like vector math) or CUDA code, but most of your code doesn't require this level of performance.


Typing still sucks big time. Same for perf, unless you are working with numerics that fit with something like NumPy or JAX.


I haven't tried uv but my biggest pain point with Python has been the way env works. I always find it painful and odd.

Backward compatibility, which I suppose is closely related to needing to use env, is also a pain. In my experience you can't go forward or backward in many cases. It's especially painful on projects that don't change very often. I'm sure that an active codebase can probably be kept updated from version to version, but if you've waited a bunch of versions, it seems painful.

But, I'm not sure I've given it a fair shake because I haven't needed to. It's use in AI does make it an attractive option, now more than ever.


I think a combination of:

- statically typed languages got better, reducing the relative benefits of dynamic typing. people realized they didn't really hate static types, they hated the way [insert 90s-00s enterprise language here] did static types

- the GIL became more and more painful as computers got more cores

- it used to be a language for passionate hackers, like a latter-day lisp (cf that old pg essay). "written in python" used to be a signal of quality and craftsmanship. now it's the most commonly taught beginner language; millions of bootcamp devs put it in their CV. average skill level plunged.

- PSF was asleep at the wheel on the packaging / tooling problems for years. pip/venv are dinosaurs compared to cargo, nix, or even npm.


> Is this just junior devs who never learned it

Seems more like it's fallen out of favor with senior devs who have moved to Go/Rust.


I don’t know anything about go. But Rust is more of a competitor to C and C++, right? It is sort of bizarre if these languages are butting heads with a scripting language like Python.

Python compares fairly well to Bash or JavaScript or whatever, right? (Maybe JavaScript is better, I don’t know anything about it).


Rust has language features (often inspired by functional programming languages) that allow you to write pretty high level code.


I consider this self-inflicted. Pythons Async functionality is … unfortunate.

JavaScript has much more intuitive async syntax, which was actually borrowed from a Python framework.

For whatever reasons, the Python folks decided not to build on what they had, and reinvents things from scratch.


you'd be crazy (senior or not) not to use Go for Go stuff and Python for Python stuff


I use both, with a preference for Go but I feel like I should be doing more Python just to keep it fresh.

It seems like two of the main entries under “Python stuff” are “working with people who only know Python” and “AI/ML because of available packages.”

What are some others?


I mean... to oversimplify a bit, Python is for scripting and Go is for servers.


I think for a lot of us, it was very frustrating when it was being pushed with no real analog for the practices we had in other languages. Poetry used to be pushed as how to do dependency management, but it was not obvious that it was not necessarily your build manager, as well. Even today, I'm not entirely clear what the standard approach is for how to manage a project. :(


If I were to try again I'd go with uv, it seems way way better


I have been sticking with poetry for a while, now. What would make me want/need to move to uv?


- Performance: uv is so much faster that some operations become transparent. poetry's dependency resolver is notoriously slow. uv being a native binary also means it has a faster startup time.

- Interpreter version management: uv can handle separate python versions per project automatically. No need for pyenv/asdf/mise.

- Bootstrapping: you only need the uv binary, and it can handle any python installation, so you don't need to install python to install a management program.

- Environment management: uv will transparently create and update the environment. You don't need to source the venv either, you use `uv run...` instead of python directly.

Overall, it makes common Python project management tasks simple and transparent. It also follows standards (like project definition metadata and lock files), which poetry often doesn't.


I'll pay attention to poetry soon. As is, I don't recall my builds ever going slow because of poetry. I don't think I've noticed it have any impact on speed, at all.

I did just update the dependencies of some of my projects. I could see how that could be faster. I don't do that often enough for me to care about it, though. `poetry run pytest` is the slowest thing I have, and I'm confident most of that slowness is in my direct control already.

I'm intrigued on the lock file point. I thought that was literally one of the main reasons to use something like poetry, in the first place? Does uv have a better lock file mechanism?


uv supports the standardised lock file format. This means that you're not tied to uv for anything, as most project settings it uses (eg metadata, dependencies, extras, etc.) are based on PEPs. poetry has its own format for many things.

https://peps.python.org/pep-0751/


Ah, I see that this is a newer format than the projects I've been using poetry for. Are there advantages to move to it?


Interoperability being the major one. You can switch between uv and other tools (such as pdm and hatch) with minimal effort.


Maybe you'll find this series of articles interesting: https://www.loopwerk.io/articles/tag/uv/


Thanks! I'm not entirely sure I see a reason to change on there, oddly.

I'm very fortunate that my python projects are all relatively small, so maybe that colors things a bit. Certainly looks like something that would have swayed me to uv at the start, but as things are, I think I mainly just wish there was a more standard/accepted work flow for build and release.


Makes sense. I've stopped using python for development but I run into python utilities I want to use all the time. uv/uvx are perfect for someone like me.


yeah Poetry is fine


I coded happily in python for many years and fell out of love with it.

It doesn’t ship with a first party package manager so you got the community trying to fill this gap. Use any other language with good tooling like golang or rust and it is a breath of fresh air.

Python used as an actual PL is a footgun because it’s dynamic scripted. (Don’t tell me about using tools X, Y, Z, mypy, …) You essentially become the compiler checking types, solving basic syntax errors when uncommon paths are executed.

A programming language that’s only good for < 100 line scripts is not a good choice.

I honestly wish python were in a better state. I switched to rust.


> Don’t tell me about using tools X, Y, Z, mypy, …

What's wrong with using tools that improve on common issues? I don't think I'd use Python without them, but ruff and pyright make Python a very productive and reliable language if you're willing to fully buy into the static analysis.


> A programming language that’s only good for < 100 line scripts is not a good choice.

What a bunch of crap. It's so trivial to show very popular and useful programs written in Python that far exceed this number I'm not even going to do the work.

What a lazy criticism.


Hi rsyring, I made this comment out of experience.

As python projects grow and grow, you need to do lots of support work for testing and even syntactic correctness. This is automatic in compiled languages where a class of issues is caught early as compile errors, not runtime errors.

Personally I prefer to move more errors to compile time as much as possible. Dynamic languages are really powerful in what you can do at runtime, but that runtime flexibility trades off with compile time verification.

Of course, every project can be written in any language, with enough effort. The existence of large and successful python projects says nothing about the developer experience, developer efficiency, or fragility of the code.


All perfectly valid perspectives and I agree with most of what you wrote. But the comment above is pretty different from the tone/effort behind the comment I took issue with. :)

In hindsight, I should have just left it alone and not replied which is what I usually do. But Python's popularity isn't an aberration. It's tradeoffs make sense for a lot of people and projects. The low effort bad faith swipes at it from subsections of the HN community got me a bit riled today and I felt I had to say something. My apologies for a less than constructive critique of your comment.

Best.


Thanks for your comment. I definitely could have worded mine better too with a bit more effort and context.


From the community guidelines:

> In Comments

> Be kind. Don't be snarky. Converse curiously; don't cross-examine. Edit out swipes.

> Comments should get more thoughtful and substantive, not less, as a topic gets more divisive.

> When disagreeing, please reply to the argument instead of calling names. "That is idiotic; 1 + 1 is 2, not 3" can be shortened to "1 + 1 is 2, not 3."

> Please don't fulminate. Please don't sneer, including at the rest of the community.

> Please respond to the strongest plausible interpretation of what someone says, not a weaker one that's easier to criticize. Assume good faith.

https://news.ycombinator.com/newsguidelines.html


There are massive numbers of devs who would never even think of trying to code in a dynamically-typed language, even though the big players all have gradual typing. They don't know what they're missing.


I have no problem with dynamically-typed languages, my main problem with Python is the significant whitespace. I really do not like it. I can deal with everything else in Python, or any other programming language, but significant whitespace is what kills it for me.


Even after writing tons of python the whitespace is still the reason why I never reach for it by default.

Today the IDEs got much better, but I still can’t see the significant whitespace as anything than downside. With brackets I can indent, but also have automatic indenting succeed every single time.


Having gotten back into Python for a project after some time away, I found the solution (for me) is to automatically fix the whitespace every time I run the code.

I just have a line in my Justfile that does this. Probably would be better to format on save but I use different editors and haven’t gotten around to it.

Still doesn’t fix the creeping doubts about everything in a language conceived by people who made that whitespace call, but it removes the specific pain point.


do you mean requirement of whitespace or how much space that takes up? Because you can change how many spaces python needs for its indentation to get some reduction in whitespace


I've been writing code for 40+ years. I know how to set up my editor, thanks.

If you copy and paste some Python code and it isn't indented properly, it breaks the python program. It's the stupidest thing I've seen in any language, including javascript (which isn't as stupid as many claim it is).


Yes, I'd say Python's crown as the go-to lightweight scripting and web development language was mostly ceded to JS.

It's still reigning champion of data science, and of course it has a huge number of uses and users still around, but it's not really cool or in vogue outside of those circles.


Python has never been THE web development language, that's always been JavaScript. Python is one of the more popular server-side languages, and JavaScript has move from frontend to backend in the last decade too. Not sure whether this has really taken the crown of any backend-language.

And what is lightweight scripting? Isn't scripting by definition lightweight?

But Python overall is still very popular outside the Data Science-circles. Not sure where this claim is coming from.


> It's still reigning champion of data science, and of course it has a huge number of uses and users still around, but it's not really cool or in vogue outside of those circles.

This is a wild take. You're never going to get a fully accurate measurement but every source I've seen[0][1][2] puts Python as the most common programming language by a country mile.

If it doesn't seem "cool" or "in vogue", that's because everyone is already using it.

[0] https://www.tiobe.com/tiobe-index/ [1] https://pypl.github.io/PYPL.html#google_vignette [2] https://www.pluralsight.com/resources/blog/upskilling/top-pr...


Do people really turn to JS (instead of Python) for lightweight scripting? Are we talking about the "better Bash" use case?


JS devs do, and there are a lot of them


I use "tsx script.ts" often and it's very nice good due to gradual typing you can use (plus I know lang well)


I mean if its really light weight, and I want to avoid bash, then JS is not too bad. The downside being that the built-ins are not really there compared to Python.

The famous answer.... _it depends_.


that would be very surprising


When it got big enough that companies were forcing people to learn it. People automatically hate things they didn't choose themselves.

Plus there has been a rising sentiment against dynamic typing by masochists over the last decade or so.


    > by masochists
Hey! The masochism pays dividends. I can't do anything with duck typing that I can't also do with `dyn Trait` abuse :)


HA! Alright Fair enough :-)


It's not out of fashion. We're just seeing the long tail finally picking it up. It's becoming somewhat of a lingua franca of programming.


After using Rust's tooling, Python's tooling is obscenely painful. Like intolerable. Which makes some of us feel overwhelmingly frustrated with the language itself. The amount of time I've squandered on Python because of its tooling... I'm never getting that back.

But then uv came along. It's not just another poetry or pipenv or whatever. It works well and it has uvx and `uv tool install` and other nice things.

Previously when I saw that something was written in Python I'd curse under my breath because I don't have the mental energy to make a virtual environment and source its shell script and remember where I put it just to try something out. On arch Linux I can't just pip install something without going through some crazy setup that I used to have patience for but as I get older it's been better to just curse that snake language altogether and spend time doing something more chill like writing rust.

But now I can just type "uvx" and it works. I'm probably not going to start writing python again any time soon, but at least now I have less reason to be disappointed with people who themselves choose to write Python.


The v2 to v3 transition threw a lot of people.


Can we please stop reiterating the same old stories? That was years ago. Most Python devs these days never wrote a single line of Python 2. I learned it 16 years ago and, while frameworks like Django were still in the middle of the transition back then, I pretty much started learning & writing Python 3 right away.


This might be true but I still find myself typing:

print "xyz"

now and then. It's not a big deal, but it reminds me of struggling with pip->pip3 and many other things for a long time years ago.


Hah that brings back memories of me smugly insisting to my freshman roommate that using Python 3 tutorials to learn programming was a complete waste of his time and he should be using 2.7 for life like the rest of us l33t hax0rs.

Tbf at that point Django was still pretty shaky with 3 and basically none of the 3rd party Django libraries supported it at all, plus I was using Google AppEngine which at the time was tightly coupled to the 2.7 runtime. But really I was just parroting the Slashdot hivemind which was 100% convinced the transition was the new Perl 6 and would kill Python, and that Python.org was dishonestly teaching newbies who didn't know better a dead language and worthless skill when they changed the default.

Fortunately for him he ignored me and most of the big Django libraries were ported like a year later at which point I had to switch anyway to get updates. Fully agreed that in 2025 it's pretty much irrelevant, and honestly despite some legitimate pain the transition was much more successful than the cynics assumed it would be at the time.


Python is probably too awesome and versatile to go out of fashion, but as a long time user.. the ecosystem is frustrating. Dependencies and packaging have been, and still are a nightmare after thousands of years. Problems are fixable sure but the thing is that they never end. After you get plenty of practice fixing all the related problems, you'll have to keep fixing them for yourself, your less savvy teammates, and in third-party code pretty much forever. This is worth it in exchange for "import antigravity" for the first 100 years, but it's frustrating eventually.

Everyone will mention uv/pyenv/poetry/conda/virtualenvs, so fine, let's pretend it's not a problem that you tried each of those in desperation and they are all household names. Suppose the packaging wars actually ended and everyone uses what you use without you needing to tell them, and suppose further that every pypa problem isn't blaming debian maintainers for obvious regressions. Pypi will still yank[0] packages at the source to perhaps randomly break deterministic behaviour, smashing anything in the blast radius rather than only clients using a --strict flag or something. You can pin your own dependencies but who knows what they will pin (nothing, or the wrong stuff, or the wrong way probably!) or what they will yank. Now for repeatability you need to host a mirror for everything you use- which is fine for corporate but a nonstarter for the novice and annoying for FOSS projects.

If you have zero dependencies or a slowly changing environment that is receiving constant care and feeding, you'll probably never notice how bad things are. If you put down most projects for a month though and pick them back up, perhaps with a different environment, machine, or slightly different python version it's broken, bitrotted, and needs serious attention to be rehabilitated.

People might argue.. that's just software dev. Nope. I say it with lots of love and gratitude for the efforts of the community.. but most langs/ecosystems would never tolerate this level of instability. One has to eventually just admit that working, portable, and actually repeatable environments with python basically just require docker. Can we talk about how "--break-system-packages" is hilarious? After you retreat to docker you can type this a few times a day, push the container up, pull it down months/years later, and then realize that literally the only way to get a stable working environment is to request a broken one. QED

[0]: https://docs.pypi.org/project-management/yanking/


I think during the python 2-> 3 transition period (which was almost a decade long) a lot of people started looking into alternatives, because frankly that mess was the last straw. In the scientific domain this is when Julia started growing.

Of course then crypto bros happened and the rest is history.


[flagged]


would be great if you manage to substantiate your "terribly designed" statement. any pointers? :-)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: