[HN Gopher] I'm switching to Python and actually liking it
       ___________________________________________________________________
        
       I'm switching to Python and actually liking it
        
       Author : cesarsotovalero
       Score  : 302 points
       Date   : 2025-07-16 07:44 UTC (15 hours ago)
        
 (HTM) web link (www.cesarsotovalero.net)
 (TXT) w3m dump (www.cesarsotovalero.net)
        
       | messe wrote:
       | > the Python interpreter is natively integrated in all Unix
       | distros
       | 
       | It's included in the default install of most desktop/server Linux
       | distros (with plenty of exceptions), but I don't believe any of
       | the BSDs ship it in their base system.
       | 
       | IIRC macOS used to have python 2 in its default install, but I
       | vaguely recall that being deprecated and removed at some point.
       | My only Mac is on the other side of the country at the moment, so
       | I can't check myself.
        
         | blitzar wrote:
         | I dont think python is pre-installed on macOS now. (uv has
         | replaced it for me)
         | 
         | Edit: Unlike older versions of macOS that came with Python 2.7
         | pre-installed, newer macOS versions (Catalina and later) no
         | longer include Python pre-installed.
        
           | oneeyedpigeon wrote:
           | macOS dropped PHP recently too--doing a wonderful job of
           | losing all that developer share that Apple was slowly
           | building up.
        
             | frizlab wrote:
             | Why? Installing python and php can be done in 2 seconds
             | with brew, and you have control over what you install
             | instead of using whatever is in the system, with deprecated
             | versions, etc. It is actually _much_ better now. System
             | tool should be left to the system.
        
             | est wrote:
             | if you install commandline tools there's
             | 
             | /Library/Developer/CommandLineTools/Library/Frameworks/Pyth
             | on3.framework/
        
             | wiseowise wrote:
             | Virtually zero professional developers that I know use
             | built in Python or PHP. Maybe it's good enough for
             | occasional scripting purposes, though.
        
             | stby wrote:
             | I much prefer installing it myself, with the required
             | version for my project and at a known and common location.
        
             | comradesmith wrote:
             | I think it's better for developers to not have conflicting
             | system distributions.
             | 
             | Though for a while there having built in interpreters was
             | great for kids and learners.
        
           | latexr wrote:
           | Technically macOS doesn't come with Python pre-installed, but
           | it does provide you with a simple path to do it.
           | 
           | https://news.ycombinator.com/item?id=44580198
           | 
           | The removal was in Monterey. Catalina and its successor Big
           | Sur very much still had it. Catalina was the one that removed
           | 32-bit support.
        
             | tovazm wrote:
             | I think they realised the security implications,
             | 
             | you could just take a random person macbook, open the
             | terminal and launch python3 -m http.server 3000 --directory
             | ~
             | 
             | then on the local network you could download all his files
        
               | latexr wrote:
               | If you have access to their MacBook and can open a
               | terminal, even `rsync` (which comes preinstalled) would
               | do the job.
               | 
               | It seems much more likely to me they were just tired of
               | having to manage the languages (and being constantly
               | criticised they were behind) and simply chose to remove
               | them.
        
         | latexr wrote:
         | Python 2 was removed in Monterey 12.3, which was incredibly
         | stupid and disruptive as it caught everyone by surprise. We all
         | knew Apple said they would remove it, but everyone was
         | expecting them to be sensible and do it on a new major OS
         | release, like they did with PHP, not mid-cycle.
         | 
         | https://developer.apple.com/documentation/macos-release-note...
         | 
         | I wonder if that kerfuffle is why they ended up not removing
         | Ruby and Perl yet, despite the same promise. macOS' Ruby is
         | around 2.6. Perl I somehow doubt they'll get to, as it's such
         | an important part of Unix admin I bet they themselves use it
         | somewhere.
         | 
         | There is still a /usr/bin/python3 which is a shim. When you
         | call it, if you don't have the Xcode Developer Tools you'll be
         | asked to install them (it's a non-scary GUI dialog which takes
         | two clicks) and then you're set. That is also a few versions
         | behind the cutting edge, but it does get updated sometimes.
        
           | WesolyKubeczek wrote:
           | I think that by now we shouldn't take a .0 major release as a
           | sign of what is really going to be present in macOS and
           | what's not. The OS stabilizes around .4 or so, and in the
           | meantime some deprecated things may get removed, too.
           | 
           | They also have a habit of sometimes add or change some APIs
           | mid-cycle, so you may see requirements for the latest Xcode
           | being a mid-cycle version of the OS. Or how was it with Mac
           | App Store, that not only itself, but the relevant APIs for
           | programs distributed in it appeared in 10.6.4?
        
       | v5v3 wrote:
       | "the second best language for any job"
        
         | tim-kt wrote:
         | Meaning the first best language depends on the job?
        
           | stefcoetzee wrote:
           | Of course :)
        
         | bravesoul2 wrote:
         | There are many jobs where the .Net/Java/Go triad would be in
         | the top 3. I lump them together as typed languages that are
         | mainstream, performant, have a GC and a featured library.
        
           | eurekin wrote:
           | I'm at a java shop. All customer facing apps are in java. Our
           | tools and glue code is mostly in python. Similar for data
           | processing workflows
        
             | bravesoul2 wrote:
             | Yes that might demonstrate the point. Would Python be your
             | second choice for the customer facing apps?
        
               | eurekin wrote:
               | Unfortunately, might not be easy in practice. It took
               | years of effort to pass some certifications and audits
               | and I don't think adding another language could be
               | recouped now
        
       | reedf1 wrote:
       | > Python has done a good job of hiding its legacy ugliness (such
       | as __init__, __new__, and similar aberrations), swettening its
       | syntax to accomodate developers with good taste.
       | 
       | What exactly is the problem with __init__ or __new__? @dataclass
       | is very nice syntactic sugar, but are we arguing here that having
       | _access_ to initializer /allocator/constructor dunder methods is
       | "legacy ugliness"? This is the core of pythonic built-in aware
       | python. Bizarre.
        
         | wiseowise wrote:
         | Bizarre is that you don't consider it ugly.
         | 
         | Kotlin: constructor is either part of class definition or
         | keyword constructor.
         | 
         | Ruby: initialize
         | 
         | JS: constructor
         | 
         | Python: ______new______, _______init_______
         | 
         | Literally this meme: https://knowyourmeme.com/memes/three-
         | headed-dragon
        
           | reedf1 wrote:
           | I had honestly not considered that the author might have been
           | talking about the _visual aesthetic_ of the dunder methods
           | themselves. Honestly that has me a bit stumped; all I can say
           | is that if you don 't like underscores, don't pick python.
        
           | t43562 wrote:
           | You don't call __init__ directly so the ugliness is limited
           | to the definition which seems fairly minimal to me. It seems
           | to be a naming convention for methods that are not invoked by
           | name anywhere and that's at least informative when you're
           | reading the class definition.
           | 
           | IMO this is less horrendous than e.g. go's insistence that
           | exported functions are indicated by a capital letter - that
           | really affects code using the module not just the definition.
        
           | NoboruWataya wrote:
           | I like that magic method names generally all follow the same
           | form so it's obvious that they are magic methods and not
           | intended to be part of the public API. Whether that form uses
           | double underscores or something else doesn't really matter to
           | me as they are not being called directly.
        
             | 63stack wrote:
             | Would you consider a constructor magic though?
        
               | lou1306 wrote:
               | "Magic methods" is just the name people use for these
               | special methods (another is dunder methods). They're
               | "magic" because you do not call them by name, rather they
               | are invoked by the interpreter in specific situations.
        
               | dragonwriter wrote:
               | Yes, it is magic the same way other magic methods are,
               | that is, because it is syntactically special and callable
               | (and primarily called by) a syntax other than
               | <instance>.<method>(...) or <class>.<method>(instance,
               | ...)
               | 
               | Specifically, in the case of constructors, via
               | <class>(...).
        
             | fiedzia wrote:
             | > it's obvious that they are magic methods and not intended
             | to be part of the public API
             | 
             | Is there an alternative API? No. This is public API
             | regardless of anyone's intentions. Though "it's weird" is
             | really not a very strong argument against it.
        
               | trylist wrote:
               | Public API refers to the user of the class, not the
               | implementer. You never call __init__ directly. __new__
               | allows modifying object creation itself for the
               | implementer, but the user of the class will never call
               | it.
        
               | freehorse wrote:
               | There are private and public methods. Private methods are
               | only supposed to be called within other methods, as in
               | privately. Public methods are the ones that are normally
               | called through the code, repl, by the user or whatever.
               | You are not supposed to write `myclass.__add__(x)`
               | anywhere except where you define the class itself and its
               | methods.
        
               | Izkata wrote:
               | There's actually 4 kinds:                 def foo(... #
               | public       def _foo(... # internal       def __foo(...
               | # munged       def __foo__(... # magic
               | 
               | Internal is more convention as the language doesn't
               | really do anything with it, but it does with munged, and
               | magic methods are specifically for things implemented in
               | the language.
               | 
               | Internal and munged don't exactly map to private and
               | protected, but are kinda similar ish.
        
               | freehorse wrote:
               | Oh right. I am not really into python, had read some doc
               | about naming conventions some poitns.
               | 
               | In any case I actually like how one can use underscores
               | to point on how exposed some method is supposed to be.
               | Makes it simpler to actually know what to skip and what
               | not.
        
               | __MatrixMan__ wrote:
               | There are several alternative API's. @dataclass is one,
               | Pydantic offers another, there's also attrs, plus less
               | general things like namedtuple.
               | 
               | Admittedly it's obnoxious when you've got habits for one
               | and you're on a team that uses another--totally flies in
               | the face of the zen re: "there should be only one obvious
               | way to do things".
               | 
               | ...but that was always a rather ambitious goal anyway.
               | I'm ok navigating the forest of alternative API's if it
               | means not being locked into something that I can only
               | change by choosing an entirely different language. I'm
               | happy that it's very easy to tell when somebody is
               | mucking about with python internals vs when they're
               | mucking about with some library or other.
        
               | yunwal wrote:
               | @dataclass does a very specific subset of what overriding
               | dunder methods does. It's not duplicating an abstraction
               | it's layering them
        
           | dncornholio wrote:
           | I have found to believe that ugly and beautiful are
           | irrelevant. As long as it's doing the job and not cause major
           | headaches. Life is too short to worry about syntax.
        
             | orphea wrote:
             | Right? I'm kind of surprised that a few underscores invoke
             | such strong emotions in people.
        
             | nottorp wrote:
             | > Life is too short to worry about syntax.
             | 
             | Every programming language you use will annoy you in some
             | way. You stop caring after a few of them.
        
           | timeon wrote:
           | Can you elaborate bit what is the problem here? Is it shape
           | of the characters or something else?
        
             | brabel wrote:
             | Amazing. If you need to ask this question I am guessing you
             | have spent too long with Python . No other language uses
             | this underscore madness for special methods or otherwise.
             | Because it's just , I don't know a more appropriate word
             | for it , stupid.
        
               | Octoth0rpe wrote:
               | Oh yes they do:
               | https://www.php.net/manual/en/language.oop5.magic.php
               | 
               | The programming languages world is broad/varied enough
               | that any statement like "no other language does this!" is
               | almost certainly wrong (outside of esoteric languages,
               | which python and php most certainly are not)
        
               | deathanatos wrote:
               | Lua, too:                 __add, __sub, __mul, __div,
               | __mod, __pow, __unm, __idiv       __band, __bor, __bxor,
               | __bnot, __shl, __shr       __concat, __len       __eq,
               | __lt, __le       __index, __newindex, __call       __gc,
               | __close, __mode, __name
        
               | Twirrim wrote:
               | What's actually amazing is how you're unable to answer a
               | straight question.
               | 
               | If you call something "stupid" it doesn't really convey
               | anything meaningful, especially not in the way you're
               | using there, it comes across as "I don't actually have a
               | reason I don't like it, I just don't".
        
               | DrJosiah wrote:
               | I mean, Python is dynamic. Here, have this: https://gist.
               | github.com/josiahcarlson/39ed816e80108093d585df...
               | 
               | Now you don't need to write your double-underscore
               | methods ever again, if you don't want to.
        
               | thesuperbigfrog wrote:
               | Most C and C++ compilers use similarly named macros:
               | 
               | https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-
               | Macro...
        
           | dumah wrote:
           | I'm not sure why you're comparing __new__ to constructors in
           | other languages.
           | 
           | Ruby has the same thing but it's called 'new'.
           | 
           | Implementing the type of customization (idiomatically) that
           | __new__ provides in Kotlin and JS isn't any cleaner.
        
           | parentheses wrote:
           | That's kind of the point. These methods are never meant to be
           | called directly. They're used to desugar.
           | 
           | I think it's fairly short sighted to criticize these. FWIW, I
           | also did that the first time I wrote Python. Other languages
           | that do similar things provide a useful transparency.
        
             | NewsaHackO wrote:
             | I don't think anyone is criticizing its utility, just that
             | the syntax of 2-5(?) underscores in a row isn't something
             | that is DX friendly.
        
               | dragonwriter wrote:
               | The syntax is exactly two, not 2-5.
        
               | JKCalhoun wrote:
               | I think the point was: who can know by looking at it.
        
               | gcbirzan wrote:
               | I mean, maybe you should use a font that doesn't make it
               | hard to figure that out. Next you're gonna say we should
               | ban 0s and Os, Is and ls, because your font doesn't allow
               | you to figure out which one it is.
        
               | dragonwriter wrote:
               | Anyone using a monospacdd font, a font where underscores
               | are separated, or a run-together proportional font that
               | they are even a little bit familiar with, because of the
               | relative width of underscores and other characters.
               | 
               | Which, between them, covers approximately everyone.
        
               | hiAndrewQuinn wrote:
               | The ugliness is intentional. Nobody _wants_ to name their
               | cool new variable __hot__singleton__in__your__area__.
        
           | __MatrixMan__ wrote:
           | It's like the bright orange garments that hunters wear, the
           | ugliness is sort of the point. It says "this is a different
           | sort of thing."
        
             | ddejohn wrote:
             | > It's like the bright orange garments that hunters wear,
             | the ugliness is sort of the point.
             | 
             | Ugliness is not the point of hi-vis vests lol, the point is
             | to not get shot by other hunters.
        
               | __MatrixMan__ wrote:
               | ...by being as shockingly contrasting with their
               | environment as possible. Maybe your aesthetics differ,
               | but I find it quite ugly. If it wasn't, it wouldn't grab
               | my attention so well. Wearing something shockingly ugly
               | is a great way to not be mistaken for a deer.
               | 
               | By contrast, I find a well camouflaged deer quite
               | beautiful--once I notice it at all. The beauty comes from
               | the way that it is so clearly a thing of its
               | surroundings. Nothing at all like a bright orange hat.
        
               | ddejohn wrote:
               | > Wearing something shockingly ugly is a great way to not
               | be mistaken for a deer.
               | 
               | Sure... yes the bright orange is ugly, but it's not the
               | _ugliness_ that prevents you from getting shot, it 's the
               | bright unnatural color. Other hunters aren't thinking "oh
               | that's really ugly, it must not be something I can shoot"
               | they're thinking "bright orange means person, I should
               | not fire my rifle in that direction".
               | 
               | > If it wasn't, it wouldn't grab my attention so well.
               | 
               | Are you saying that if you thought the bright orange was
               | pretty it wouldn't occur to you not to fire your gun in
               | its direction?
        
           | guhcampos wrote:
           | Some-other-language-user complaining about python
           | ugliness:_____new_____ and _____init_____
           | 
           | Same-other-language-user:
           | 
           | ((()))()()()({}{}{{(((())){}}}}{}{}{};;;;();)(;}}}
           | 
           | *not supposed to be correct syntax, it's just a joke
        
           | slightwinder wrote:
           | As if other language don't have their warts.. Ruby and
           | Javascript for example have hideous syntax, comparing this
           | with some special naming is quite bizarre.
           | 
           | But who cares? It's syntax, it has its purpose.
        
           | moffkalast wrote:
           | I would think the dumber thing is having to create an empty
           | file called __init__.py for a package to register as a
           | package. And relative imports being completely fubar.
        
             | kolanos wrote:
             | > I would think the dumber thing is having to create an
             | empty file called __init__.py for a package to register as
             | a package.
             | 
             | This hasn't been true since Python 3.3. You no longer need
             | a __init__.py for Python to recognize a module, but it can
             | still be useful in many cases.
        
               | maleldil wrote:
               | This is incorrect.
               | 
               | > The __init__.py files are required to make Python treat
               | directories containing the file as packages (unless using
               | a namespace package, a relatively advanced feature).
               | 
               | https://docs.python.org/3/tutorial/modules.html
        
           | mixmastamyk wrote:
           | The point is to keep them out of the object namespace, and
           | works well for that.
        
           | DrJosiah wrote:
           | I mean, it's never been a problem for me in my 26 years of
           | Python, but if it is such a big deal for you, maybe you
           | should consider this: https://gist.github.com/josiahcarlson/3
           | 9ed816e80108093d585df...
           | 
           | I wrote it in about an hour and a half. It seems to work in
           | Python 3.6 and 3.12. Now you never need to write another
           | double-underscore magic method again.
        
           | adw wrote:
           | Fewer characters than "initialize" or "constructor", clearly
           | marked as being "not a normal method". Python is _better_
           | here.
        
           | dragonwriter wrote:
           | If you felt your argument about __new__ and __init__ was
           | valid, you probably would have used the actual names and not
           | hyperbolic exaggerations.
        
         | thaumasiotes wrote:
         | Probably the system of giving special meaning to what are
         | otherwise ordinary identifiers. __ isn't a reserved keyword in
         | Python or anything. But there's a set of conventions you're
         | supposed to follow when naming methods and attributes, and
         | they're visibly artificial. It would be cleaner to make the
         | features that are a special part of the language definition
         | also a special part of the language syntax instead of running
         | them in indistinguishably with other nonsimilar things.
         | 
         | In C++, if you want to define the binary + operator on a class,
         | you give the class a method with the special name `operator+`.
         | In Python, to do the same thing, you give the class a method
         | with the pseudo-special name `__add__`. You don't think the
         | Python way is worse?
        
           | reverius42 wrote:
           | I'm not sure how "operator+" is supposed to be appreciably
           | different from "__add__".
        
             | brabel wrote:
             | One is a sensible choice a human might pick. The other is
             | not.
        
               | orphea wrote:
               | Both are doing their job just fine?
        
               | acdha wrote:
               | So who were the non-humans who picked the one you don't
               | like?
        
               | dragonwriter wrote:
               | They are both sensible choices that a human _did_ pick,
               | that 's how they got into their respective languages.
        
             | WesolyKubeczek wrote:
             | They have different locality of behavior, for one.
        
           | acdha wrote:
           | > You don't think the Python way is worse?
           | 
           | Have you considered how much familiarity might shape your
           | reaction to the two? Both are specific patterns with
           | arbitrary restrictions which new learners have to
           | internalize, and that's a fairly advanced task most people
           | won't hit until they are familiar with the language syntax.
           | 
           | Here's a counter argument: the Python methods are normal
           | method declarations whereas C++ developers have to learn that
           | "operator=" means something different than what "operator ="
           | (or any other assignment statement) would mean, and that this
           | is the only context where you can use those reserved symbols
           | in method names.
           | 
           | To be clear, I don't think either of these is a big deal -
           | the concepts and usage are harder to learn than the
           | declaration syntax - but I think it's incredibly easy to
           | conflate familiarity with ease of acquisition for things like
           | this.
        
             | thaumasiotes wrote:
             | > Have you considered how much familiarity might shape your
             | reaction to the two?
             | 
             | It doesn't.
             | 
             | > Both are specific patterns with arbitrary restrictions
             | which new learners have to internalize, and that's a fairly
             | advanced task most people won't hit until they are familiar
             | with the language syntax.
             | 
             | No, the Python methods are just ordinary methods with valid
             | names. What 'arbitrary restrictions' are you referring to?
        
               | acdha wrote:
               | The arbitrary restriction is that you have to just learn
               | a specific pattern and follow it. I can't have my Python
               | class use "addition" if I hate underscores or my C++ code
               | use "mathematical_division" if I'm horribly pedantic. In
               | both cases, it's just a particular design decision by the
               | language developers I have to learn, and in both cases I
               | won't think much of it after the initial acclimation.
        
               | yunwal wrote:
               | Python you have to learn something arbitrary for each
               | dunder method you want to define/override. + --> __add__,
               | * ---> __mul__, etc
               | 
               | C++ it's just one pattern to learn, x -> operatorx
        
           | kemayo wrote:
           | Funnily enough, _just_ starting your class method /variable
           | name with __ does do magic things as a pseudo-keyword.
           | Specifically, it mangles the name for callers outside of that
           | class -- `self.__foo` would need to be accessed as
           | `obj._ClassName__foo`. It's python's approach to having
           | private methods, while remaining somewhat ideologically
           | opposed to them existing.
           | 
           | This doesn't apply to the dunder methods, though. They're
           | magically exempt from this magical mangling, so you could
           | call them directly if you wanted. -\\_(tsu)_/-
           | 
           | > You don't think the Python way is worse?
           | 
           | They seem about equivalent? I don't see any real reason to
           | pick one or the other, beyond personal preferences.
        
             | wasabi991011 wrote:
             | What's the use case for __foo -> _ClassName__foo? I've used
             | python a bunch but never this feature, so I'm curious.
        
               | kstrauser wrote:
               | It makes it nearly impossible to reference that attribute
               | by accident. Basically, if class Foo defines
               | "self.__bar", the Python interpreter sees the leading
               | "__" and mangles it. It's the lightweight equivalent of a
               | private attribute in other languages, with the difference
               | that Python will _let_ you attempt to access it anyway.
               | But if you do, and it makes your code utterly brittle and
               | prone to explosion, no one will give you sympathy or help
               | you fix it. They 're much more likely to tell you not to
               | do that.
        
               | dragonwriter wrote:
               | It prevents accidentally overriding the member in
               | subclasses which can prevent private implementation
               | details of parent classes from being accidentally
               | interfered with by child classes.
               | 
               | As composition over inheritance becomes more idiomatic,
               | there are probably less places where this matters, but as
               | long as inheritance is used at all it can be useful.
        
               | antod wrote:
               | It's as close as they'll get to private methods while
               | still having the "we're all consenting adults" philosophy
               | that doesn't prevent you doing something dumb. Or if you
               | use this and it breaks, you can't say you weren't warned.
        
           | DrJosiah wrote:
           | Not when this can be done: https://gist.github.com/josiahcarl
           | son/39ed816e80108093d585df...
           | 
           | Take a deep breath.
        
         | andyjohnson0 wrote:
         | > What exactly is the problem with __init__ or __new__?
         | @dataclass is very nice syntactic sugar, but are we arguing
         | here that having access to initializer/allocator/constructor
         | dunder methods is "legacy ugliness"?
         | 
         | My read was that the "ugliness" was in the method naming, and
         | specifically the double underscores, not the availability of
         | the methods themselves.
        
         | lenerdenator wrote:
         | I've been doing Python professionally for a while (~10-ish
         | years in backend web dev and file processing), and while I
         | don't like how exactly the author described dunder methods as
         | "legacy", it's still not a language facility I reach out to
         | often because, well, it's sort of odd coming from a C#
         | background. The author has blog posts about Java, which isn't
         | that different from C#, so maybe that's the reason.
         | 
         | Maybe as I grow to think of the "big picture" architecture-wise
         | with my code, I will start incorporating dunders, but until
         | then...
        
       | smcleod wrote:
       | Python as a language is nice. Python's version and package
       | management is nothing short of a nightmare.
        
         | est wrote:
         | Python's package management is OK. The main culprit is .so
         | libraries
         | 
         | Think JNI or cgo management.
        
           | t43562 wrote:
           | Yes, I've never really understood the complaint about python
           | packaging - building native code is not something that is
           | ever easy to guarantee across multiple distributions and
           | operating systems.
           | 
           | Those native packages can be in any language and require any
           | odd combination of tools to build. Who has truly solved that
           | problem?
        
             | nikisweeting wrote:
             | wheels, conda, docker, firecracker, unikernel, flatpak
        
               | t43562 wrote:
               | flatpak, docker ? i.e. include an almost complete
               | distribution just to make one package work? but what if
               | you want that package to work in the distribution you
               | have now? What if you need 2 different packages that are
               | in different flatpacks or different docker images?
        
               | staunton wrote:
               | Set them up, each in its own container, and use GRPC to
               | communicate between them...
               | 
               | (Not even kidding, I've seen people do this)
        
               | t43562 wrote:
               | Goodness gracious!
        
               | staunton wrote:
               | Well, if you're using GRPC _anyway_ , and have the
               | protocol buffers _already_... It 's hard to resist the
               | temptation after a few hours of installing broken package
               | versions.
               | 
               | Incidentally, I suspect this is the spiritual origin of
               | microservoces...
        
               | nikisweeting wrote:
               | obviously don't try those _first_ I 'm just saying
               | there's a stack of options to work with for any level of
               | isolation you desire.
               | 
               | start with wheels if you just want pre-built binaries,
               | move up to conda if you need arch and OS-specific C libs
               | that depend on system packages, flatpack or docker if you
               | dont want those to mess up your host, or
               | unikernel/firecracker/VMs if you need kernel modules or
               | hardware virtualization.
        
             | Orygin wrote:
             | If you don't need to link C lib, you can build any
             | combination of arch and OS for a golang program. The
             | default tooling allows you to do so easily.
             | 
             | If you need to link a C lib, there are ways to set it up to
             | compile other OS (and maybe other archs).
        
           | RamblingCTO wrote:
           | I'll throw in BLAS and LAPACK. Fuck, what a nightmare it
           | always has been to get scipy running. I've always ended up
           | with a wild mix of conda and pip installed shit that just
           | wouldn't work.
        
           | macawfish wrote:
           | It is not okay (maybe uv fixes this?)
        
         | jcattle wrote:
         | Going to be honest: With uv it really isn't that bad anymore.
         | Sure, the whole packaging ecosystem is still really bad, but uv
         | abstracts over most of it. Unless you're doing some really
         | esoteric stuff you'll be just fine.
        
         | xyzsparetimexyz wrote:
         | Using a nix devshell has worked out well for scripts for me so
         | far. I haven't figured out what that workflow is like for
         | larger projects though. I'm not interested in learning Uv
        
           | smallerfish wrote:
           | There's nothing to learn. Get Claude code to install uv into
           | your devshell and cut over your requirements. 5 minutes.
        
             | expenses3 wrote:
             | AI? :vomit_emoji:
        
               | __MatrixMan__ wrote:
               | Or do it yourself, 10 minutes
        
           | __MatrixMan__ wrote:
           | As a nix user, you hardly need to know uv, but you might
           | later need to know how to work together with non-nix-users
           | who use uv. It's easy.
           | 
           | There will be a file: uv.lock You can use uv2nix to get a
           | single nix package for all the project's python dependencies,
           | which you can then add to your devshell like anything else
           | you find in nixpkgs (e.g. right alongside uv itself). It ends
           | up being two or three lines of code to actually get the
           | package, but you can just point a LLM at the uv2nix docs and
           | at your flake.nix and it'll figure them out for you.
           | 
           | Your devshell will then track with changes that other devs
           | make to that project's dependencies. If you want to modify
           | them...                  edit pyproject.toml # package names
           | and versions        uv lock             # map names and
           | versions to hashes (nix needs hashes, finds them in uv.lock)
           | nix flake lock      # update flake.lock based on uv.lock
           | nix develop         # now your devshell has it too
           | 
           | This way you're not maintaining separate sources of truth for
           | what the project depends on, and the muggles need not think
           | about your nix wizardy at all.
        
             | expenses3 wrote:
             | Didn't I say I wasn't interested?
        
               | __MatrixMan__ wrote:
               | You created a place where the interaction between nix
               | devshells and uv was relevant, I put something there to
               | help passers-by that might be interested in those topics.
               | It wasn't actually _for_ you.
        
         | lazzlazzlazz wrote:
         | This hasn't really been true for a while now. `uv` has
         | radically improved the experience.
        
           | cedws wrote:
           | There's still 20 years of projects using everything that
           | became before uv. They didn't upgrade the moment uv came into
           | existence. Data science-land still uses other rubbish too.
        
             | zimpenfish wrote:
             | > They didn't upgrade the moment uv came into existence.
             | 
             | There's also projects that can't use `uv` because it
             | doesn't like their current `requirements.txt`[0] and I have
             | no bandwidth to try and figure out how to work around it.
             | 
             | [0] We have an install from `git+https` in there and it
             | objects strongly for some reason. Internet searches have
             | not revealed anything helpful.
        
               | bootsmann wrote:
               | Unrelated to uv but the problem with having a git ref in
               | requirements.txt is that pip will treat it as a fixed
               | version so it will strictly narrow the other dependencies
               | it can resolve, which gets exceptionally difficult to
               | reason about once that packages also loads a package from
               | another git ref. Throwing everything into codeartifact
               | (or equivalent on other clouds) is better longterm.
        
               | zanie wrote:
               | If you open even a brief issue and tag me @zanieb I'm
               | happy to take a look!
        
           | bborud wrote:
           | For the last 20 years that has been the mantra. Some X
           | "solves" all the problems.
           | 
           | Except it doesn't. It just creates another X that is popular
           | for a while, and doesn't somehow retroactively "fix" all the
           | chaotic projects that are a nightmare to install and upgrade.
           | Yes, I understand people like Python. Yes, I understand the
           | LLM bros love it. But in a real production environment, for
           | real applications, you still want to avoid it because it
           | isn't particularly easy to create robust systems for
           | industrial use. You may survive if you can contain the
           | madness in a datacenter somewhere and have people babysit it.
        
             | bodge5000 wrote:
             | I can get that Pythons not for everyone, it certainly has
             | its flaws and maybe uv is just another transient solution
             | which will come and go and others have. I might disagree,
             | but I can accept that. What I can't accept is the idea that
             | it should be avoided for real production environments,
             | which is frankly a bit ridiculous considering all the real
             | applications and real production environments running on
             | Python.
        
             | bbkane wrote:
             | I think that's true until it isn't, and people are really
             | rallying around uv.
             | 
             | Here's to hoping it manages to actually solve the Python
             | packagig issue (and lots of people are saying it already
             | has for their use cases)!
        
             | turtlebits wrote:
             | I've ignored the trends and just used the bog standard
             | requirements.txt with pip and a virtualenv and have had no
             | problems in the past 10+ years. Either way, you always want
             | to catch production deploys if something breaks.
        
             | davepeck wrote:
             | > But in a real production environment, for real
             | applications, you still want to avoid it because it isn't
             | particularly easy to create robust systems for industrial
             | use.
             | 
             | This is silly and seems to discount the massive Python
             | codebases found in "real production environment"s
             | throughout the tech industry and beyond, some of which are
             | singlehandedly the codebases behind $1B+ ventures and, I'd
             | wager, many of which are "robust" and fit for "industrial
             | use" without babysitting just because they're Python.
             | 
             | (I get not liking a given language or its ecosystem, but I
             | suspect I could rewrite the same reply for just about any
             | of the top 10-ish most commonly used languages today.)
        
             | zanellato19 wrote:
             | Some of the biggest codebases in the world are in Python,
             | this is a bizarre statement that reeks of the hn
             | superiority complex.
        
             | viccis wrote:
             | >Except it doesn't.
             | 
             | That is only true if you never reexamine the universality
             | of your statement. I promise that it is possible to "solve"
             | the mess that was Python's ecosystem, that uv has largely
             | done so, and that your preconceptions are holding you back
             | from taking advantage of it.
        
         | timw4mail wrote:
         | It's like the (usually) interpreted equivalent to C/C++. There
         | are lots of 'standard' package management choices.
         | 
         | And it seems like the package resolution is finally local by
         | default, although that requires a 'virtualenv', which seems to
         | be a legacy of the global packaging system.
        
         | __MatrixMan__ wrote:
         | I expect that for every two python users who know what `pip`
         | is, there are three who are discouraged from thinking about the
         | environment at all. Given that, focusing on the language and
         | not the packaging is the right choice. Packaging is most often
         | somebody else's problem.
         | 
         | It's just HN users are more likely to be that somebody else.
         | Probably we have to deal with non-python dependencies _anyway_
         | so we 're reaching for bigger hammers like docker or nix. It
         | would be nice if there wasn't a mess of python package
         | managers, but whichever one I use ends up being a somewhat
         | unimportant middle-layer anyway.
        
       | polotics wrote:
       | It's funny, I'm the opposite: LLMs have made it easy to draft
       | something in Python, then translate to a more appropriate
       | language for the target problem-domain, for example Go.
        
         | brabel wrote:
         | Agree . We had training to learn how LLM applications can be
         | developed and it was obviously in Python. Never liked Python
         | but between dependencies issues (the demo project used uv but
         | somehow the author forgot to declare some dependencies which
         | she probably had installed globally) which cost hours of
         | everyone's time, and the persistent magic going on (pipe
         | operators that do nothing similar to unix pipes, wtf!,
         | puydantic shit just to declare a data type with metadata and
         | lots of things like this) nearly everyone immediately switched
         | to a typed language like Kotlin (they have a nice AI framework)
         | as soon as we got the basics of how things work.
        
         | LtWorf wrote:
         | Is go the language that doesn't include a module to do mmap and
         | doesn't include a module to place binary data into a struct?
         | 
         | If you want to read binary files, you can use C or python, but
         | not go (unless you use segfault prone 3rd party libraries of
         | very dubious quality, of course).
        
       | revskill wrote:
       | So, i don't get it, now i still need to have a uv venv ?
        
         | akkad33 wrote:
         | The principle of uv as much as I understand is to not tinker
         | with virtual environments. With commands like uv run, uv sync
         | etc you shouldn't have to worry about the virtual env and
         | whether it's activated etc. if you are in a project, it will
         | automatically pick up the right Python version . However if you
         | want to do something not possible through those commands you
         | can still get down to the virtual env. Plus for auto complete
         | in IDEs you generally need to select the venv
        
           | mpeg wrote:
           | I use this vscode extension called "python envy" that changes
           | venv automatically depending on which folder of a monorepo
           | you are in, it's great! Wish vscode had it built-in
        
             | akkad33 wrote:
             | Never heard of it, will try. Thanks
        
         | blitzar wrote:
         | You install uv not python, you use "uv run <file>" instead of
         | "python <file>", you dont think about anything else.
        
         | Vaslo wrote:
         | If you are working in Data Science/ML its the best bet for
         | handling dependencies in your project compared to the rest of
         | the tools. Its use has exploded, especially because you can do
         | 'uv pip whatever' if you insist on using pip.
        
       | andrewstuart wrote:
       | Said with a note of surprise?
       | 
       | Made me think this is probably normally a Ruby developer
       | indoctrinated against Python. The article doesn't seem to say
       | what they have come from.
        
         | drewcoo wrote:
         | > Ruby developer indoctrinated against Python
         | 
         | Ruby devs think about code differently. Like Perl, they embrace
         | TIMTOWTDI.
         | 
         | https://perl.fandom.com/wiki/TIMTOWTDI
         | 
         | Also, there's a pride in writing elegant code as opposed to
         | following "Pythonic" conventions. Excellence is not conformity.
         | 
         | I use Python a lot more often now because it's seen as simpler
         | and more approachable and easier to force compliance. I miss
         | Ruby.
        
           | t43562 wrote:
           | IMO "pythonic" is mostly about using the features the
           | language has rather than trying to treat it as if it was Java
           | or C++.
           | 
           | Having said that, in reviews you do get lazy comments like
           | "not pythonic" or "not best practises" which often boil down
           | to the reviewer just not liking something and being too much
           | of an *** to say why. This is supposed to be a total shutdown
           | that you cannot argue with and it's the kind of thing that
           | might put you off the term "pythonic" for life.
           | 
           | "There should be one-- and preferably only one --obvious way
           | to do it."
           | 
           | This is probably the core thing you might have issue with but
           | I think its not really about conforming in how you write your
           | own code but about the thing you make being easy for others
           | to use.
        
             | greener_grass wrote:
             | I love this sentiment:
             | 
             | > There should be one-- and preferably only one --obvious
             | way to do it.
             | 
             | But I often _don 't_ think the Pythonic way is a very good
             | way to do it. And this leaves you a bit stuck!
        
           | Mawr wrote:
           | > Like Perl, they embrace TIMTOWTDI.
           | 
           | Yeah, and it's the wrong approach. Of course, you can have
           | whatever preference you want, but in terms of engineering,
           | it's plain wrong.
        
         | wiseowise wrote:
         | There's a footnote:
         | 
         | > If you know me, you know I used to be mostly a
         | Java/JavaScript/R kind of guy. -
        
         | riffraff wrote:
         | It's in the footnotes, they're a java/javascript/R dev.
        
         | xandrius wrote:
         | So, if you don't fancy Python you must be labeled a Ruby
         | developer? Weird take.
        
       | bravesoul2 wrote:
       | I like Python for the language, and for a lot of jobs the
       | threading model limitations do not matter. Its a great language
       | to get stuff done. I find the package management story
       | challenging but I will try uv next time!
        
         | sudosays wrote:
         | If you haven't already you should check out uv:
         | https://github.com/astral-sh/uv
         | 
         | It solves a lot of the package management headaches for me.
        
         | rich_sasha wrote:
         | I resisted pipx, poetry, anaconda and probably some other
         | things, as I didn't see the point over venv+pip. But uv is just
         | so damn good, there's no going back.
        
           | gjvc wrote:
           | pipdeptree is all you need for many things, but uv is such a
           | joy to use it's hard to resist, sure.
        
           | bootsmann wrote:
           | Feel like pipx walked so uv could run, it popularized the
           | idea of abstracting the environment management away from the
           | user.
        
             | zeppelin101 wrote:
             | pipx is still the best tool for standalone utility type of
             | packages: "yt-dlp", "glances" (like htop), etc.
        
               | asa400 wrote:
               | You can, however, use uv for this, e.g., `uvx yt-dlp`
               | works like it would in pipx.
               | 
               | https://docs.astral.sh/uv/guides/tools/
        
       | Roark66 wrote:
       | From what? It would be useful to mention towards the front of the
       | post so we know what is the context in which you approach python.
       | 
       | I've switched to python primarily (from perl) in early 2010s (I
       | think my first "seriously" used version was 2.6. This is mostly
       | for system management, monitoring, and data transformation
       | /visualisation. Nothing fancy like AI back then in a work
       | setting.
       | 
       | I found the biggest impact was not so much on writing code but on
       | it remaining readable for a very long time, even if it was
       | created hastily "just get this working now" style. Especially in
       | a team.
       | 
       | Python is still one of my favourites and the first tool I reach
       | if bash is not enough for what I'm trying to do.
        
       | pyman wrote:
       | From what I was told, Python was originally seen as a Swiss Army
       | knife for sysadmins. It started gaining more traction when
       | Canonical adopted it as the main language for Ubuntu 4.10 in
       | 2004.
       | 
       | Then, in 2005, Guido van Rossum was hired by Google to work on
       | Google Cloud. That opened the door for wider adoption in
       | academia, since Python had strong math libraries and integrated
       | well with tools researchers were already using, like Hadoop,
       | right around the time big data and ML were starting to take off.
       | 
       | Also, between 2005 and 2006, two important things happened: Ruby
       | on Rails came out and inspired Django, which was starting to gain
       | popularity, and web developers were getting tired of Perl's messy
       | syntax. That's how Python quickly became a solid choice not just
       | for server-side scripts, but for building proper web apps. In the
       | meantime, another language that could be embedded directly into
       | HTML was storming the web: PHP. Its syntax was similar to
       | JavaScript, it was easy to pick up, lowered the barrier to entry
       | for software development, worked straight out of the box, and
       | didn't require thousands of print statements to get things done.
       | 
       | The 3 Ps made history. According to programmers from 20 years
       | ago, they were like religions. Each had its own philosophy and a
       | loyal group of followers crusading online, getting into heated
       | debates, all trying to win over more adopters. The new generation
       | of devs is more pragmatic. These days it's less about language
       | wars and more about picking the right tool for the job.
        
         | darkstar_16 wrote:
         | > These days it's less about language wars and more about
         | picking the right tool for the job
         | 
         | You should talk to the Java advocates in my company :) The
         | language wars are still around, it's just Java vs the rest now.
        
           | pyman wrote:
           | One of my colleagues, a retired programmer who spent 20 years
           | at Microsoft, told my students that it used to be Java vs
           | Visual Basic, until Microsoft brought in the big guns, like
           | Anders Hejlsberg. That's when it turned into Java vs .NET,
           | and things really started to heat up :)
        
             | wiseowise wrote:
             | Java unequivocally won the war, though.
        
               | adw wrote:
               | C# is the Java of Lua (thanks to Unity) which will never
               | not be weird.
        
         | tgv wrote:
         | Python's success is entirely due to entry-level programming
         | courses. They all switched to Python, because you have to
         | explain less. I don't think I heard about web servers in Python
         | before 2012. I suppose a 2005 computer wouldn't be able to
         | serve a Python backend smoothly.
         | 
         | PHP's popularity isn't really from 2005-2006. It was popular at
         | the end of the 90s, and it looks like JS as much as it looks
         | like a potato.
        
           | theshrike79 wrote:
           | With python you can just go: 'print "hello, world!"' and
           | that's a full-ass program
           | 
           | You run it by saying `python hello.py`.
           | 
           | Compare that to the amount of crap you need(ed) with 2005
           | Java just to have something running.
           | 
           | The shittiness of ActivePython and generally getting python
           | to run on Windows were a bit of a hurdle, but still it was
           | easier than the competition
        
             | taeric wrote:
             | I mean, it isn't like you couldn't get similarly terse
             | scripts in other languages. Common LISP, as an easy example
             | people love to beat up on.
        
             | nottorp wrote:
             | You could, but then they deprecated the paranthesis less
             | form in 3.x :)
        
             | icedchai wrote:
             | Sure, but you could've done the same thing with perl in the
             | 80's and 90's.
        
           | pyman wrote:
           | > Python's success is entirely due to entry-level programming
           | courses.
           | 
           | Yeah, after 2008. And by 2014, it had overtaken Java in many
           | CS programs. But I was referring to the events that led to
           | that.
        
           | stevesimmons wrote:
           | > I suppose a 2005 computer wouldn't be able to serve a
           | Python backend smoothly.
           | 
           | Python had web servers from 2000, including Jim Fulton's Zope
           | (really a full framework for a content management system) and
           | in 2002 Remi Delon's CherryPy.
           | 
           | Both were useful for their day, well supported by web hosting
           | companies, and certainly very lightweight compared to
           | commercial Java systems that typically needed beefy Sun
           | Solaris servers.
        
             | antod wrote:
             | I'd forgotten about CherryPy until Turbogears was mentioned
             | the other day in the Django birthday thread.
             | 
             | But yeah Python was on an upswing for webdev and sysadmin
             | (early DevOps?) tooling, but took quite a hit with Ruby eg
             | Rails, Puppet, Vagrant and Chef etc.
             | 
             | But Python hung on and had a comeback due to data science
             | tooling, and Ruby losing it's hype to node for webdev and
             | golang for the devops stuff.
        
           | sylens wrote:
           | In my experience AWS also contributes a lot to this. Boto3 is
           | a great library for interacting with AWS services
        
           | wiseowise wrote:
           | > Python's success is entirely due to entry-level programming
           | courses. They all switched to Python, because you have to
           | explain less.
           | 
           | Nonsense.
           | 
           | > I don't think I heard about web servers in Python before
           | 2012.
           | 
           | More nonsense.
           | 
           | > I suppose a 2005 computer wouldn't be able to serve a
           | Python backend smoothly.
           | 
           | Extreme nonsense.
           | 
           | https://medium.com/signal-v-noise/ruby-has-been-fast-
           | enough-...
           | 
           | And this is when Python was edging Ruby performance wise.
        
           | MoreQARespect wrote:
           | This is entirely backward. They all started switching when
           | python was already immensely popular after the popularity
           | boosts given by sysadmin, django and numerical/datascience
           | users.
        
             | __rito__ wrote:
             | This is what I have seen as well. When Python became
             | ubiquitous in the industry, they started teaching it in the
             | colleges.
             | 
             | I come from a core science background. I studied Physics.
             | And it was like this in my institute: FORTRAN -> A lot of
             | C, small amount of FORTRAN -> C -> Python. I was taught C,
             | but from the exact next year, it was switched to the Python
             | ecosystem.
             | 
             | It was done much later when Python became the standard in
             | research universities, the language of recent research
             | papers, etc.
             | 
             | A generation of Scienctists learned C/FORTRAN/MATLAB in
             | college/grad school as it was taught, but they switched to
             | Python early/mid career. Teaching Python in undergrad
             | _followed_.
             | 
             | I also taught a mid-career Economics professor Python. She
             | used SPSS before for her papers. Humanities professors
             | doing data crunching are now switching to Python, too.
             | There is a clear trend.
        
           | taeric wrote:
           | I argue that Python's success was almost entirely due to it
           | not adopting any best practices on dependency management and
           | being installed by default on systems.
           | 
           | Being default installed was almost certainly the larger
           | factor. As evidenced by how much pain it caused people when
           | they started using dependencies that were not stable. They
           | had to add specific support for it to not let you pip install
           | things to the system install.
        
           | runjake wrote:
           | 1. Python was pretty popular well before entry-level
           | programming courses adopted it. I think they adopted Python
           | because it was a good general purpose scripting language,
           | multiplatform, easy to install and get going, that taught
           | programming concepts in a more approachable way for
           | beginners.
           | 
           | 2. Python on web servers was a thing _long before_ 2012. You
           | had Zope in 1998 or so, and it was pretty popular for a
           | while, and hugely influential to subsequent web frameworks.
           | Django came out in about 2005. TurboGears, Pylons in about
           | 2005 or so. Flask in 2010... and these are just the more
           | popular frameworks.
           | 
           | 3. I think the author meant that PHP was also vaguely C-like
           | in syntax, like JS. Keyword: _vaguely_. You had a common way
           | of declaring stuff with curly braces and semi-colons.
        
           | dragonwriter wrote:
           | > Python's success is entirely due to entry-level programming
           | courses.
           | 
           | No, entry-level courses were in a mix of Scheme, C, and other
           | languages until Java's industrial ubiquity ended up in it
           | becoming a popular choice, but not completely displacing the
           | others. Then as Python (along with the broader class of
           | dynamic OO scripting languages) became quite popular, Python
           | got added to the mix, but, unlike Java, it fairly quickly
           | displaced not only Java but a lot of what had been around
           | longer in introductory courses.
           | 
           | Python's industrial success drove its initial use in
           | introductory courses, but doesn't fully explain it, as it
           | doing what Java never did indicates.
           | 
           | I think the people teaching introductory courses find it less
           | of a compromise to industrial popularity than they did with
           | Java.
           | 
           | Python's success is multifaceted, some of it is right-place
           | right-time, a lot of it is the ecosystem it built because of
           | that, but a lot of it is, I think, that it turns out to be a
           | language that has been designed (both initially and in how it
           | is been managed over time) to be a very good language for
           | real people solving real problems, despite not adhering to
           | any of what various typing and performance and paradigm
           | purists like to posit as the essential features of a good
           | language.
        
           | adw wrote:
           | Peak PHP was Facebook around 2008!
        
           | JodieBenitez wrote:
           | > I don't think I heard about web servers in Python before
           | 2012
           | 
           | Excuse me but... what ? Django is 20 years old.
        
           | alexjplant wrote:
           | > They all switched to Python, because you have to explain
           | less
           | 
           | I think this could be generalized to ergonomics. Java 1.6 is
           | an absolute nightmare for a newb compared to Python. No top-
           | level statements, explicit typing, boxing, verbose
           | declaration syntax, long import statements, curly braces
           | everywhere... and, most importantly, no out-of-the-box REPL.
           | Java has since made strides and borrowed from Kotlin and
           | Lombok but my understanding is that it was too little too
           | late.
           | 
           | Depending upon preference and application one might consider
           | ~half of these things anti-features at the expense of
           | stability but it speaks volumes to why people join and stay
           | in a software ecosystem. If I had to work on a Python project
           | again I'd use mise with uv and viciously lint the codebase
           | down to a reasonable fully-typed subset of the language
           | devoid of custom decorator magic and dunder abuse.
        
             | pron wrote:
             | > but my understanding is that it was too little too late.
             | 
             | Too little too late to be the #1 language of choice for
             | serious server-side software that it is today?
             | 
             | The weird thing about Java is that people naturally compare
             | its popularity today to its dominance in the early '00s,
             | which was an aberration. The ecosystem has long since
             | returned to its fragmented self, and while Java is not
             | nearly as dominant as it was during that very short period,
             | no other language is, either.
        
         | stevesimmons wrote:
         | The key factor imo was Travis Oliphant merging the competing
         | numeric and numarray libraries into numpy in 2005. That quickly
         | became the foundation of Python as the key environment for open
         | source numeric processing.
         | 
         | It brought across a ton of users from R and Matlab.
         | 
         | Pandas, Matplotlib and ScikitLearn then consolidated Python's
         | place as the platform of choice for both academic and
         | commercial ML.
        
         | troad wrote:
         | > According to programmers from 20 years ago, they were like
         | religions. Each had its own philosophy and a loyal group of
         | followers crusading online, getting into heated debates, all
         | trying to win over more adopters.
         | 
         | It's very weird reading something you lived through described
         | in these terms, as though it were being described by an
         | anthropologist.
         | 
         | Can't help but wonder what the future will have to say about
         | today.
         | 
         | "In 2025, programmers used 'frameworks' to hang 'apps' from
         | some kind of 'web'. They believed these frameworks gave them
         | magic powers. Many even fought in 'flame wars' on this topic,
         | which experts believe involved the use of fire to destroy webs
         | woven by competing programmers."
        
         | Twirrim wrote:
         | > The 3 Ps made history. According to programmers from 20 years
         | ago, they were like religions. Each had its own philosophy and
         | a loyal group of followers crusading online, getting into
         | heated debates, all trying to win over more adopters. The new
         | generation of devs is more pragmatic. These days it's less
         | about language wars and more about picking the right tool for
         | the job.
         | 
         | I feel like the religious wars aspects of this is completely
         | overblown. The conversations around languages really hasn't
         | changed all that much in the last 20 years. Look at the way you
         | see things happening in HN, heck even in the comment thread
         | right here. It's the exact same kinds of discussions as
         | happened back 20 years ago, with exactly the same kind of
         | pragmatism.
         | 
         | I think the gulf comes about from the fact that the primary
         | sources are conversations occurring between people that are
         | largely anonymous behind an online handle, interacting with
         | people that aren't face to face. There's always been an element
         | of exaggeration in the interactions. What might be a "Umm, no"
         | with a maybe a shake of the head, becomes "Your mother was a
         | hamster and your father smells of elderberries". Almost every
         | party involved comes to recognise the particular cultural
         | quirks (which varied from forum to forum) and how to translate
         | what was said, to what was actually meant.
        
         | adw wrote:
         | Python was everywhere in science by earlier than that (Numeric
         | and numarray, Numpy's predecessors, are from the late 90s/early
         | 2000s).
        
         | spiderxxxx wrote:
         | >From what I was told, Python was originally seen as a Swiss
         | Army knife for sysadmins.
         | 
         | Yea, I was a sysadmin around 2000 (before that too) and I knew
         | it as such.
         | 
         | >between 2005 and 2006, two important things happened:
         | 
         | Somewhat - I used it in 2001 for Plone which is based on Zope,
         | which was somewhat popular around that time. Writing all the
         | web stuff with Python made sense, since Plone provided a CMS
         | and could include a wiki. Adding on some sql calls to it in
         | python just made sense. The competition was between PHP and
         | Python, though there were some other less popular choices. Ruby
         | on Rails definitely was getting a lot more popular around those
         | times. PHP didn't start getting popular around 2005, if
         | anything, people started using Python more, and started
         | criticizing the crappy code that was circulating in the PHP
         | community.
         | 
         | In any case, it was a fun time, but what's the point of looking
         | back like that?
        
         | snapetom wrote:
         | This aligns with what I remember and Guido going to Google
         | explains things. Mid 2000's was all about PHP
         | (Cake/Symphony/CodeIgniter/etc) vs Ruby (Rails) in the open
         | source world. I remember hearing about Python only in sysadmin
         | work and Plone. Then, suddenly were suddenly a lot of articles
         | from Google about just about everything, all in Python.
         | 
         | I remember saying to a coworker, "Google is single-handedly
         | keeping Python alive."
         | 
         | Then bam. It was everywhere. Mid 2010's, I took a cybersec job
         | and they told me to learn Python in the two weeks between
         | accepting and starting. "Python is all over cybersec," I was
         | told. It was then I realized Python took over academia, which
         | positioned it perfectly for ML. It's features made it easy to
         | start, but it also benefited from right place, right time.
        
       | t43562 wrote:
       | I'm glad someone else discovered they can like python.
       | 
       | I got forced to learn it for a project where I was proposing Ruby
       | and the customer insisted on Python. This was years ago when Ruby
       | was much slower. I was annoyed but I got used to it and here I am
       | enjoying it many years later.
       | 
       | I take issue with the description and use of make though! :-D
       | What is the point of it if you're not going to use dependencies?
       | One might as well just write a script with a case statement.....
       | I'm adding smileys because I don't mean to be all that serious
       | but I really do think that the failure of the youth of today to
       | get to grips with Make is a sad reflection on our culture.......
       | and get off my lawn, ok? :-)
        
         | pphysch wrote:
         | > One might as well just write a script with a case
         | statement.....
         | 
         | I started with this and evolved into simple flat Makefiles,
         | because they're basically the same but Make feels more standard
         | (there's a Makefile here vs. there's a random bash script
         | here).
        
       | DataDaoDe wrote:
       | Python has done an impressive job over the years of making steady
       | robust improvements. The typing and tooling has just gotten
       | better and better. There are still plenty of problems though,
       | imho async is still a much bigger pain than it should be
       | (compared to other runtimes with a very nice experience like go
       | or elixir, even dotnet has been less pain in my experience).
       | Overall I like python, but it mainly boils down to the robust
       | libraries for things I do (ML, Data munching/analysis)
        
         | dmz73 wrote:
         | I don't know what I am doing wrong but nothing written in
         | Python has ever worked for me. I download the .py repo from
         | from github or wherever and try to run it - errors. I try to
         | install missing libraries pip this and that - errors. I battle
         | fixing endless error with dependencies and when the .py finally
         | runs - errors - wrong version of whatever library or wrong
         | patch of this or that or the "production ready" .py does not
         | work correctly on Windows or single file script uses excel
         | library that has changed in incompatible ways 3 times in 2
         | years. I Download all the files from the flashy looking web
         | site and follow all the instructions to the letter - errors.
         | Python is anything but "robust". It is the most fragile
         | environment in the universe, worse than c, c++ and javascript
         | put togeter, at least this is my experience with it.
        
           | vrighter wrote:
           | This is exactly my experience too. I avoid python software
           | like the plague, because even when it does work, I can not
           | rely on it continuing to work when python gets updated on my
           | system.
        
             | zeppelin101 wrote:
             | This is where uv comes in to save the day.
        
           | DataDaoDe wrote:
           | That's wild. The last time I had that experience with Python
           | must have been more than 10 years ago. I'll admit a decade
           | ago you definitely did need to know way to many details about
           | way too many tools from virtualenvs to setuotools to wheels,
           | etc. to get things working from somebody else's project, but
           | imho, poetry and uv have really changed all that.
        
           | ActorNightly wrote:
           | can you give at least one example? You are probably just
           | expecting too much. No manual checkout/install process is
           | easy as installing an application.
        
             | jbreckmckye wrote:
             | What about Go?
             | 
             | "go install github.com/org/repo/x"
        
               | dkdcio wrote:
               | `pip install git+https://github.com/org/repo/x`
        
       | latexr wrote:
       | > I started to code more in Python around 6 months ago. Why?
       | Because of AI, obviously. It's clear (to me) that big money
       | opportunities are all over AI these days.
       | 
       | I find this depressing. Not only are LLMs covertly reducing our
       | ability to think and make decisions, they're now also making
       | people voluntarily conform to some lower common denominator.
       | 
       | It's like humanity decided to stagnate at this one point in time
       | (and what a bad choice of point it was) and stop exploring other
       | directions. Only what the LLM vomits is valid.
        
         | mrpopo999999 wrote:
         | humanity tried to save time and allocate it to other pursuits,
         | don't worry
        
       | taosx wrote:
       | Unpopular opinion: I think I'm going to wait for version 4 /jk.
       | But honestly, I've been spoiled by modern languages like Rust,
       | Go, and even TypeScript with modern tooling, strong typing,
       | stability, and performance out of the box. Right now, I'm just
       | interacting with LLMs, not building them.
       | 
       | That said, I remember writing myself a note a few years ago to
       | avoid Python projects. I had to clean up code from all over the
       | company and make it ready for production. Everyone had their own
       | Python version, dependencies missing from requirements.txt, three
       | way conflicts between 2 dependencies and the python version,
       | wildly different styles, and a habit of pulling in as many
       | libraries as possible [1]. Even recalling those memories makes my
       | stomach turn.
       | 
       | I believe constraints make a project shine and be maintainable.
       | I'd prefer if you throw at me a real python instead of a python
       | project.
       | 
       | [1] Yes, I'm aware of containers, I was the unlucky guy writing
       | them.
        
         | bigiain wrote:
         | > Unpopular opinion: I think I'm going to wait for version 4
         | 
         | In my personal timeline, people giving up waiting for Perl 6
         | were a huge source of early Python developers.
        
         | 1ncunabula wrote:
         | What makes TypeScript better than Python? I don't get it..
        
           | Philpax wrote:
           | Much more capable and reliable type system, paired with
           | comparatively sane package management. This is getting better
           | in the Python world (thank you Astral), but it's still not
           | anywhere near the same.
        
         | theLiminator wrote:
         | I don't have a strong love for python, but all the tooling the
         | author mentioned has actually made python fairly decent to use
         | now.
         | 
         | Still could be better, but I think Python's really hit its
         | stride now.
        
       | Surac wrote:
       | have fun!
        
       | CoolCold wrote:
       | > Not only because the syntax is more human-friendly, but also
       | because the Python interpreter is natively integrated in all Unix
       | distros
       | 
       | That's kind of very optimistic evaluation - literally anything
       | beyond "import json" will likely lead you into the abyss of
       | virtual envs. Running something created with say Python 3.13.x on
       | Ubuntu 22.04 or even 24.04 (LTSs) / Rocky 9 and the whole can of
       | worms opened.
       | 
       | things like virtual envs + containers (docker like)/version
       | managers become a must quickly.
        
         | nikisweeting wrote:
         | this is solved by uv
        
           | CoolCold wrote:
           | > things like virtual envs
           | 
           | I consider my point as still valid with UV, what you wanted
           | to express?
           | 
           | On UV specifically - say 'asdf' compiles python right on your
           | system from official sources - means using your ssl libs for
           | example. UV brings Python binary - I feel worried on this.
        
             | charliermarsh wrote:
             | uv works just as well with whatever Python you want to
             | bring -- you're not required to use the Pythons that uv is
             | capable of installing on your machine.
        
         | acdha wrote:
         | "import json" is the kind of thing which requires picking and
         | installing libraries in batteries-not-included languages, and
         | it's just one of many modules which are in the standard
         | library. That's not a compelling basis for large projects but
         | over the years I've shipped a ton of useful production code
         | which never needed more than the stdlib and thus spent no time
         | at all thinking about deployment or security patching.
         | 
         | Also, it's not the 2000s any more. Using venv to isolate
         | application installs is not very hard anymore and there have
         | been decent package managers for a long time.
        
           | frollogaston wrote:
           | The official package manager is pip, it's broken, and there
           | has been a new "permanent solution" replacement for it each
           | year.
        
             | acdha wrote:
             | "broken" is hyperbole. It works fine for millions of people
             | every day. If you have some specific scenarios where you
             | want it be better, it's better to say those rather than
             | just complain about an open source project.
        
               | frollogaston wrote:
               | Millions of people put it into Docker, or they just deal
               | with it and you see the results with tons of
               | Stackoverflow questions
        
               | BeetleB wrote:
               | > Millions of people put it into Docker, or they just
               | deal with it and you see the results with tons of
               | Stackoverflow questions
               | 
               | Arrogantly wrong.
               | 
               | I've coded in Python for almost 20 years. Many of those
               | years I've had it as my primary language at work.
               | 
               | 2024 was the first year I actually _needed_ a virtualenv.
               | Before that, I 'd happily use pip to install whatever I
               | want, and never had a version conflict that caused
               | problems.
               | 
               | I often encounter junior folks who default to using a
               | virtualenv, not because they _need_ to, but because they
               | 've been brainwashed into believing that "you're doing it
               | wrong if you don't use one".
               | 
               | In any case, people should use uv these days.
        
             | underdeserver wrote:
             | Poetry has been decent for years. uv is new but great and
             | will likely continue to be.
        
               | icedchai wrote:
               | uv is soooo much faster than Poetry, especially for
               | dependency resolution.
        
         | wpm wrote:
         | I have a silly theory that I only half joke about that
         | docker/containers wouldn't've ever taken off as fast as it did
         | if it didn't solve the horrible python dependency hell so well.
         | You know something is bad when fancy chrooting is the only
         | ergonomic way of shipping something that works.
         | 
         | My first taste of Python was as a sysadmin, back in 2012 or so,
         | installing a service written in Python on a server. The
         | dependency hell, the stupid venv commands, all this absolute
         | pain just to get a goddamn webserver running, good lord. It
         | turned me off of Python for over a decade. Almost any time I
         | saw it I just turned and walked away, not interested, no
         | thanks. The times I didn't, I walked right back into that pile
         | of bullshit and remembered why I normally avoided it. The way
         | `brew` handles it on macOS is also immensely frustrating,
         | breaking basic pip install commands, installing libraries as
         | commands but in ways that make them not available to other
         | python scripts, what a goddamn disaster.
         | 
         | And no, I really have no clue what I'm talking about, because
         | as someone starting out this has been so utterly stupid and
         | bewildering that I just move on to more productive, pleasant
         | work with a mental note of "maybe when Python gets their shit
         | together I'll revisit it".
         | 
         | However, uv _has_ , at least for my beginner and cynical eyes,
         | swept away most of the bullshit for me. At least superficially,
         | in the little toy projects I am starting to do in Python
         | (precisely because its such a nicer experience), it sweeps away
         | most of the horrid bullshit. `uv init`, `uv add`, `uv run`. And
         | it just works*.
        
           | stanleydrew wrote:
           | > I have a silly theory that I only half joke about that
           | docker/containers wouldn't've ever taken off as fast as it
           | did if it didn't solve the horrible python dependency hell so
           | well.
           | 
           | I don't think this is a silly theory at all. The only
           | possibly silly part is that containers specifically helped
           | solve this problem just for python. Lots of other software
           | systems built with other languages have "dependency hell."
        
           | asa400 wrote:
           | > However, uv has, at least for my beginner and cynical eyes,
           | swept away most of the bullshit for me.
           | 
           | uv is _much_ better than what came before. As someone who has
           | only had only glancing contact with Python throughout my
           | career (terrible experiences at jobs with conda and pip), uv
           | feels like Python trying to actually join the 21st century of
           | package management. It's telling that it's in Rust and
           | clearly takes inspiration from Cargo, which itself took
           | inspiration from Ruby and Bundler.
        
             | paradox460 wrote:
             | The funniest thing for me is that you can use uv in mise to
             | install Python cli programs in a surprisingly elegant
             | manner.
        
               | Ringz wrote:
               | Just curious: how?
        
               | asa400 wrote:
               | They may be referring to uvx:
               | https://docs.astral.sh/uv/guides/tools/
               | 
               | Or it could be something else, not sure.
        
               | macawfish wrote:
               | `uv tool install` I believe
        
           | frollogaston wrote:
           | Yeah, if you look at a big Python vs Node vs Rust repo side
           | by side, you'll notice Python is often the only one with a
           | Dockerfile.
        
           | 762236 wrote:
           | I won't touch Python either, but because I've been burned
           | debugging large Python programs. Something that would have
           | taken a minute in a statically typed language took hours of
           | tracing data through the program to understand what was
           | supposed to be in a dict. There are alternative languages
           | that are pithy, statically typed, can write programs quickly,
           | and can grow into large code bases that are maintainable; so
           | there is never a reason to start a new project with Python
           | today.
        
         | turtlebits wrote:
         | You should always use virtual envs. They're a single directory,
         | how are they an abyss? Pip now complains if you try to install
         | a package system wide.
        
           | unethical_ban wrote:
           | For shadow IT, anything that requires "installation" vs.
           | being in the base system or being added as a file to a
           | project is an inconvenience.
           | 
           | It's why I like using Bottle for small Python frontends:
           | download the file and import.
           | 
           | (I'm ranting based on personal experiences with IT in the
           | past. Yes in general virtualenv is the baseline)
        
             | ActorNightly wrote:
             | Compile python to executable is always an option.
        
               | shakna wrote:
               | If you're dealing with a managed system, chances are,
               | compilers are banned. You'll have to be unsafe and work
               | outside the constrained environment - potentially
               | violating policies, contracts, regulations and laws.
        
           | nomel wrote:
           | > You should always use virtual envs.
           | 
           | If you're not using dependencies, and are writing 3.x code,
           | there's very little justification.
        
           | frollogaston wrote:
           | I don't have to deal with this in JS or I think in other
           | stuff like Golang. I give someone a package.json with
           | versions of everything. npm install always sets deps up
           | locally, but doesn't need to copy the entire NodeJS runtime.
        
             | deathanatos wrote:
             | ... node_modules is your venv.
             | 
             | If we use uv from TFA, like the commands are nearly 1:1:
             | npm install     <=> uv sync       npm install foo <=> uv
             | add foo
             | 
             | > _It doesn 't have to also store a local copy of NodeJS_
             | 
             | ... which Node devs _do_ have a thing for, too, called nvm,
             | _written in bash_.
        
               | frollogaston wrote:
               | The difference is it's default, it always works the same
               | everywhere, it actually writes down the deps, and I don't
               | have to manually switch between them (or set up fancy
               | bashrc triggers) like venvs.
        
               | deathanatos wrote:
               | > _it 's default_
               | 
               | This point is true; the ecosystem simply can't change
               | overnight. uv is getting there, I hope.
               | 
               | > _it always works the same everywhere_
               | 
               | `uv` works the same, everywhere?
               | 
               | > _it actually writes down the deps_
               | 
               | `uv add` does that, too.
               | 
               | > _I don 't have to manually switch between them (or set
               | up fancy bashrc triggers) like venvs._
               | 
               | You don't have to do that with `uv`, either?
        
               | frollogaston wrote:
               | That's great, I hope they make it default, then Python
               | package management won't be broken anymore (for new
               | projects at least, not all the legacy). Default has been
               | pip for years, and there are tons of hard-to-build repos
               | cause the author missed something in their manual
               | requirements.txt gathering.
        
         | ziml77 wrote:
         | Yes, please use virtual envs or containers. I know it seems
         | overly heavy and hard to manage, but you don't want to end up
         | in a situation where you're afraid to update the system because
         | the library upgrades might break some of your Python code.
        
         | ActorNightly wrote:
         | No and no. I don't know how you even get to this level of
         | "making it harder for yourself".
         | 
         | Say you want to use a specific version of python that is not
         | available on Ubuntu.
         | 
         | 1. Install build dependencies
         | https://devguide.python.org/getting-started/setup-building/#...
         | 
         | 2. Download whichever Python source version you want,
         | https://www.python.org/downloads/source/. Extract it with tar
         | 
         | 3. run ./configure --enable-optimizations --with-lto
         | 
         | 4. run make -s -j [num cores]
         | 
         | 5. sudo make altinstall
         | 
         | This will install that specific version without overwriting
         | default system python.
         | 
         | You can then bash alias pip to python3.xx -m pip to make sure
         | it runs the correct one.
         | 
         | All the libraries and any pip install executable will be
         | installed locally to ~/.local folder under the specific python
         | version.
         | 
         | Alternatively, if you work with other tools like node and want
         | to manage different versions, you can use asdf, as it gives you
         | per folder version selection.
         | 
         | virtual environments are really only useful for production
         | code, where you want to test with specific versions and lock
         | those down.
        
           | icedchai wrote:
           | Personal preference, but I prefer to use 'mise' instead of
           | 'asdf' these days: https://mise.jdx.dev/
        
           | dragonwriter wrote:
           | Virtual environments are useful for isolating dependencies
           | for different projects, not just isolating the interpreter.
           | 
           | (I mean, except on Windows, your venvs default to symlinking
           | the interpreter and other shared bits, so you aren't really
           | isolating the interpreter at all, _just_ the dependencies.)
        
             | ElectricalUnion wrote:
             | AFAIK, it's the same even on POSIX, when you create a venv,
             | "./bin/python" are symlinks and the pyvenv.cfg has a
             | hardcoded absolute path of the current python interpreter
             | the venv module was using at the time of creation. It
             | really doesn't isolate the interpreter.
             | 
             | (also one of the reasons why, if you're invoking venv
             | manually, you absolutely need to invoke it from the correct
             | python as a module (`python3.13 -m venv`) to make sure
             | you're actually picking the "correct python" for the venv)
        
               | dragonwriter wrote:
               | I meant that the symlink behavior is default except on
               | Windows (though it may just be on POSIX platforms and I
               | think of it as "except Windows" because I don't
               | personally encounter Python on non-Windows non-POSIX
               | platforms.)
        
           | MintPaw wrote:
           | > making it harder for yourself
           | 
           | Looking at just the first link, looks way more complicated
           | than venv. And I'm a C++ developer, imagine someone who less
           | experienced, or even who just isn't familiar with C
           | toolchains.
        
             | ActorNightly wrote:
             | The first link is a sudo apt install command that you copy
             | paste into terminal. in what world is that more complicated
             | than venv?
             | 
             | Here it is for clarity
             | 
             | sudo apt-get install build-essential gdb lcov pkg-config \
             | libbz2-dev libffi-dev libgdbm-dev libgdbm-compat-dev
             | liblzma-dev \ libncurses5-dev libreadline6-dev
             | libsqlite3-dev libssl-dev \ lzma lzma-dev tk-dev uuid-dev
             | zlib1g-dev libmpdec-dev libzstd-dev
        
             | sevensor wrote:
             | It's really not hard; the person you're replying to put a
             | lot of details in. I've lost track of how many times I've
             | built a Python interpreter. Virtual envs used to work badly
             | with some tools and dependencies, so I had to do it a lot.
             | It's gotten better and now I only compile Python to get a
             | version that's not provided by my Linux distribution.
        
         | frollogaston wrote:
         | Also in some older cases the pre-included Python is v2 and the
         | system relies on it, which is more of a liability.
        
         | geysersam wrote:
         | Just use uv
        
       | igor47 wrote:
       | Good write up, and solid choices. As someone primarily working in
       | python in the last few years, I have a very similar stack.
       | 
       | Two additional suggestions:
       | 
       | * mise to manage system dependencies, including uv version and
       | python itself
       | 
       | * just instead of make; makefile syntax is just too annoying.
       | 
       | Mise actually has a command runner as well which I haven't tried
       | yet, and might work better for running commands in the context of
       | the current environment. It's pretty nice when your GitHub
       | actions workflow is just:
       | 
       | * Install mise
       | 
       | * mise install everything else
        
       | elemcontrib wrote:
       | I don't see how the OP layering utilities on top of python
       | remediates on the claim that the language is not "production
       | ready". Which it clearly is.
        
       | flyinghamster wrote:
       | I've avoided Python for a long time, but I'm getting roped in
       | myself, mainly because certain tasks seem to require a lot less
       | code than Java or Perl.
       | 
       | That said, call me old-fashioned, but I really take issue with
       | "curl $URL | bash" as an installation method. If you're going to
       | use an install script, inspect it first.
        
         | limagnolia wrote:
         | If your going to execute the code anyway, you either have to
         | inspect everything or trust whoever is providing it. There is
         | nothing special about bash that makes it more dangerous to
         | execute than python.
        
         | drdrey wrote:
         | do you also inspect binary installers?
        
       | Mawr wrote:
       | Just a small note on the code in the linked script:
       | API_KEY = os.environ.get("YOUTUBE_API_KEY")         CHANNEL_ID =
       | os.environ.get("YOUTUBE_CHANNEL_ID")                  if not
       | API_KEY or not CHANNEL_ID:             print("Missing
       | YOUTUBE_API_KEY or YOUTUBE_CHANNEL_ID.")             exit(1)
       | 
       | Presenting the user with "Missing X OR Y" when there's no reason
       | that OR has to be there massively frustrates the user for the
       | near zero benefit of having one fewer if statement.
       | if not API_KEY:             print("Missing YOUTUBE_API_KEY.")
       | exit(1)         if not CHANNEL_ID:             print("Missing
       | YOUTUBE_CHANNEL_ID.")             exit(1)
       | 
       | Way better user experience, 0.00001% slower dev time.
        
         | niux wrote:
         | Why not add a boolean flag and use a single exit(1) at the end?
         | That way the user can see all the environment variables that
         | have not been set.
        
         | gvalkov wrote:
         | This is nitpicking, but this is a good usecase for the :=
         | operator:                 if not (API_KEY :=
         | os.getenv("API_KEY")):           ...
         | 
         | For internal tools I just let os.environ["API_KEY"] raise a
         | KeyError. It's descriptive enough.
        
           | arthurcolle wrote:
           | I always forget this syntax exists. When was this introduced?
        
             | gvalkov wrote:
             | In Python 3.8 - https://peps.python.org/pep-0572/
        
             | DangitBobby wrote:
             | October 2019 in Python 3.8
             | 
             | https://docs.python.org/3/whatsnew/3.8.html
        
             | cranium wrote:
             | The Walrus operator! Introduced in Python 3.8 according to
             | the PEP 572.
             | 
             | Really nice to combine 1) checking if something exists and
             | 2) act on it
        
               | indymike wrote:
               | You forgot to end with "goo goo g'joob" or the less
               | correct Simon and Garfunkel version "coo coo ca choo".
        
           | tyrust wrote:
           | I write a decent amount of Python, but find the walrus
           | operator unintuitive. It's a little funky that API_KEY is
           | available outside of the `if`, perhaps because I had first
           | seen the walrus operator in golang, which restricts the scope
           | to the block.
        
             | bobbylarrybobby wrote:
             | This isn't really unique to the walrus operator, it's just
             | a general python quirk (albeit one I find incredibly
             | annoying). `for i in range(5): ...` will leave `i` bound to
             | 4 after the loop.
        
               | yread wrote:
               | Maybe Python will get a let one day
        
               | nomel wrote:
               | Oddly enough, "except" variables don't remain bound!
               | try:             x = int('cat')         except Exception
               | as e:             pass         print(e)  # <- NameError:
               | name 'e' is not defined
               | 
               | So, it appears Python actually has _three_ variable
               | scopes (global, local, exception block)?
        
               | agumonkey wrote:
               | exceptions being the exception is funny somehow
        
               | tough wrote:
               | very recursive
        
               | mananaysiempre wrote:
               | Also true of JavaScript pre-ES5, another language that on
               | first glance seems to only have function scope: it
               | actually does have block scope, but only for variables
               | introduced in `catch` blocks. AFAIU that was the standard
               | way for a dumb transpiler to emulate `let`.
        
               | SerpentJoe wrote:
               | I wonder if that was ever popular, considering the
               | deoptimization effects of try/catch, and given that block
               | scope can also be managed by renaming variables.
        
               | suspended_state wrote:
               | > Oddly enough
               | 
               | It's not that odd, since it's the only situation where
               | you cannot keep it bounded, unless you enjoy having
               | variables that may or may not be defined (Heisenberg
               | variable?), depending on whether the exception has been
               | raised or not?
               | 
               | Compare with the if statement, where the variable in the
               | expression being tested will necessarily be defined.
        
               | NekkoDroid wrote:
               | While somewhat true, what would this be bound to?
               | for i in range(0):             pass
        
               | suspended_state wrote:
               | Well, after writing my comment, I realized that a python
               | interpreter could define the variable and set it to None
               | between the guarded block and the except block, and
               | implicitly assign it to the raised exception right before
               | evaluating the except block, when the exception as been
               | raised. So technically, it would be possible to define
               | the variable e in GP example and have it scoped to
               | "whatever is after the guarded block", just like what is
               | done with for blocks.
               | 
               | Is there any chance this would cause trouble though?
               | Furthermore, what would be the need of having this
               | variable accessible after the except block? In the case
               | of a for block, it could be interesting to know at which
               | point the for block was "passed".
               | 
               | So, maybe "None" answers your question?
        
               | MyOutfitIsVague wrote:
               | > Compare with the if statement, where the variable in
               | the expression being tested will necessarily be defined.
               | if False:             x = 7         print(x)
               | print(x)               ^         NameError: name 'x' is
               | not defined
               | 
               | Ruby does this sort of stuff, where a variable is defined
               | more or less lexically (nil by default). Python doesn't
               | do this. You can have local variables that only maybe
               | exist in Python.
        
               | MyOutfitIsVague wrote:
               | Nope, it's more complicated than that:
               | e = 'before'         try:             x = int('cat')
               | except Exception as e:             e2 = e
               | print(e)         print(e2) # <- This works!
               | print(e)  # <- NameError: name 'e' is not defined
               | 
               | It's not a scoping thing, the bound exception variable is
               | actually deleted after the exception block, even if it
               | was already bound before!
        
               | rolandog wrote:
               | I may be rusty, but wasn't there a "finally" scope for
               | those situations?
               | 
               | edit: writing from phone on couch and the laptop... looks
               | far, far away...
        
               | tyrust wrote:
               | Oh yeah, that's a good point.
               | 
               | Python really is a bit of a mess haha.
        
               | dec0dedab0de wrote:
               | I find it incredibly intuitive and useful that it does
               | that. sometimes it drives me nuts that it doesn't do it
               | for comprehensions but I can see why.
               | 
               | But if something fails in a loop running in the repl or
               | jupyter I already have access to the variables.
               | 
               | If I want to do something with a loop of data that is
               | roughly the same shape, I already have access to one of
               | the the items at the end.
               | 
               | Short circuiting/breaking out of a loop early doesn't
               | require an extra assignment.
               | 
               | I really can't see the downside.
        
               | bobbylarrybobby wrote:
               | Python 2 actually did let comprehension variables leak
               | out into the surrounding scope. They changed it for
               | Python 3, presumably because it was too surprising to
               | overwrite an existing variable with a comprehension
               | variable.
        
               | pletnes wrote:
               | It would be utterly nuts otherwise. For loops over all
               | elements in a sequence. If the sequence is a list of str,
               | as an example, what would the <<item after the last
               | item>> be?
        
               | setr wrote:
               | the issue isn't the value of i, the issue is that i is
               | still available after the loop ends. in most other
               | languages, if it was instantiated by the for-each loop,
               | it'd die with the for-each loop
        
               | all2 wrote:
               | I cannot tell you how many times I've hit issues
               | debugging and it was something like this. "You should
               | know better" -- I know, I know, but I still snag on this
               | occasionally.
        
             | slightwinder wrote:
             | This is just Pythons scoping, which is not restricted by
             | block, but function. You have the same effect with every
             | other element.
        
             | MyOutfitIsVague wrote:
             | There's no block scope in Python. The smallest scope is
             | function. Comprehension variables don't leak out, though,
             | which causes some weird situations:                   >>> s
             | = "abc"         >>> [x:=y for y in s]         ['a', 'b',
             | 'c']                  >>> x         'c'
             | >>> y         Traceback (most recent call last):
             | File "<stdin>", line 1, in <module>         NameError: name
             | 'y' is not defined
             | 
             | Comprehensions have their own local scope for their local
             | variables, but the walrus operator reaches up to the
             | innermost "assignable" scope.
        
           | lucb1e wrote:
           | Why would you use it though? I always thought it a bad thing
           | that legacy code (such as in C or C++) had these side effects
           | inside of checks happening
        
           | make3 wrote:
           | no one uses walrus
        
         | wcrossbow wrote:
         | Even better is to try to fetch all the env variables and then
         | report on all of the missing ones.
        
         | pyuser583 wrote:
         | It would be better to do both: print out the detailed string or
         | strings, then exit if either are printed.
        
         | danielrico wrote:
         | Even better, check all the conditions and report all the
         | errors. Don't make me add the first variable, run it again and
         | get another error.
         | 
         | Sometimes that's inevitable, bit noisy of the time it isn't.
        
         | taeric wrote:
         | I'm surprised there isn't an argparse like thing for
         | documenting expected environment variables.
        
         | paisawalla wrote:
         | Taking ephemeral arguments like channel ID from the environment
         | is more offensive to observability and user comfort
        
         | conductr wrote:
         | I feel like use case and audience matters when making these
         | decisions. In this case, the user is probably someone
         | interacting with a python script they're running in a console
         | (I assume by print), then I really don't think it matters - the
         | user will check that both things are set. Should you also give
         | them some documentation about setting env vars? Should you
         | customize that documentation to the OS they're running? etc.
         | 
         | If the user is a typical consumer using a typical consumer
         | interface, then yes you want to handhold them a bit more.
        
         | bjourne wrote:
         | Neophytes take notice. Attention to details like this is what
         | separates truly great programmers from merely good ones. That
         | said, for scripts reusable by others you should use command
         | line arguments . Environment variables in lieu of command line
         | arguments is a huge code smell.
        
           | shakna wrote:
           | You don't generally want API keys accidentally recorded into
           | someone's bash history.
        
           | RadiozRadioz wrote:
           | For this example, don't just command line arguments. There's
           | an API key there, you don't want an API key visible in your
           | cmdline.
        
             | bjourne wrote:
             | Then how would you SET the API key in the first place? :)
             | The argument doesn't make any sense at all.
        
               | medstrom wrote:
               | In some .profile or .envrc or what you'd call such a
               | file, I suppose.
        
         | JohnKemeny wrote:
         | exit("Missing ...")
         | 
         | This prints the message and exits with code 1.
        
         | cristoperb wrote:
         | Even slightly better is to first check both
         | if not API_KEY and not CHANNEL_ID:             print("Missing
         | both YOUTUBE_API_KEY and YOUTUBE_CHANNEL_ID.")
         | exit(1)         if not API_KEY:             print("Missing
         | YOUTUBE_API_KEY.")             exit(1)         if not
         | CHANNEL_ID:             print("Missing YOUTUBE_CHANNEL_ID.")
         | exit(1)
         | 
         | That way you don't end up fixing one just come back and be told
         | you're also missing another requirement
        
           | delusional wrote:
           | Even better would be to only check each once and buffer the
           | decision:                   valid = True         if not
           | API_KEY:             print("Missing YOUTUBE_API_KEY.")
           | valid = False         if not CHANNEL_ID:
           | print("Missing YOUTUBE_CHANNEL_ID.")             valid =
           | False         if not valid:             exit(1)
           | 
           | This way you only check each value once (because your logic
           | might be more complicated than just checking it's not set,
           | maybe it can be wrongly formatted) and you still get to do
           | whatever logic you want. It also removed the combinatorial
           | problems.
           | 
           | This is a pretty general principle of separating decision
           | from action.
        
         | make3 wrote:
         | why print then exit(1) instead of raising an exception?
        
       | firecall wrote:
       | "I started to code more in Python around 6 months ago. Why?
       | Because of AI, obviously. It's clear (to me) that big money
       | opportunities are all over AI these days. And guess what's the de
       | facto programming language for AI? Yep, that sneaky one."
       | 
       | Why is that?
       | 
       | Why Python for AI?
        
         | johnisgood wrote:
         | Possibly because many available LLMs run your Python code in a
         | sandbox, which means less friction for vibe coders, or it may
         | be a contributing factor at the very least.
        
           | AlexeyBrin wrote:
           | > Because many available LLMs run your Python code in a
           | sandbox, which means less friction for vibe coders.
           | 
           | This is false, a lot of non "vibe coders" are using Python
           | for AI because of PyTorch and a many other AI libraries have
           | first class Python support.
        
             | johnisgood wrote:
             | How do you know that it is not the reason or not ONE of the
             | reasons? Seems pretty reasonable to me to use ChatGPT,
             | Claude, or whichever one supports it.
             | 
             | I am pretty sure some people (maybe this individual, too)
             | may be using Python because their scripts can be executed
             | in a sandbox on one of these websites.
             | 
             | Heck, if it was as good at Factor or Forth as it is at
             | Python, I would be writing more of them, too.
             | 
             | In any case, you cannot claim that it is not one of the
             | reasons. Can you?
        
               | AlexeyBrin wrote:
               | I read your initial message, now edited, as this is THE
               | reason. Of course it can be one of the reasons for which
               | the author chose Python.
               | 
               | Also the _vibe coding_ part gave me the impression that
               | you were implying that people that use /chose Python for
               | AI are all vibe coders which is again false. Sorry if I
               | misunderstood you, but this is what I got from your
               | initial message.
        
               | johnisgood wrote:
               | No worries. I think there was a misunderstanding because
               | even with my original message, I did not intend to
               | suggest that people who use or choose Python for AI are
               | all vibe coders, or at least I didn't think I did hint at
               | that.
        
         | AlexeyBrin wrote:
         | Because you get first class support in many AI libraries like
         | PyTorch, TensorFlow and so on ... Most of these libraries can
         | be used from other programming languages too, but it is easier
         | to find good documentation and examples for Python.
        
       | Hizonner wrote:
       | I wonder what the poor guy is switching from.
        
       | moribvndvs wrote:
       | I don't understand "switching" to anything. The job picks the
       | tool, not the other way around.
        
         | Bridged7756 wrote:
         | I think it's mostly boredom-driven career choices.
        
       | 1vuio0pswjnm7 wrote:
       | "And guess what's the de facto programming language for AI? Yep,
       | that sneaky one."
       | 
       | Is this referring at all to to PyTorch. If not, any guesses what
       | the author has in mind
       | 
       | "Not only because the syntax is more human-friendly, but also
       | because the Python interpreter is natively integrated in all Unix
       | distros."
       | 
       | Is this referring to GNU/Linux.
       | 
       | UNIX (UNIX-like) includes more than Linux; some UNIX
       | distributions do not include Python in the base system
       | 
       | Where it is left as choice to the user whether to install it
       | 
       | I know this because I use such distributions and, unless some
       | software needs it, I do not install Python
       | 
       | In such case, when I am done using that software I uninstall it^1
       | 
       | For example, he mentions retrieving YouTube channel metadata
       | 
       | I do not use Python for this; I use a 19-line shell script (ash
       | not bash), its startup time is faster
       | 
       | Unlike Python, it is included in the base system of the UNIX
       | distributions (both Linux and BSD) that I use
       | 
       | But if I need to test something using yt-dlp, then I might
       | temporarily install Python
       | 
       | 1. I compile Python from source and one annoying aspect of the
       | project , in addition to the slow startup time, is their failure
       | to include an uninstall target in their Makefile
        
         | megaloblasto wrote:
         | "And guess what's the de facto programming language for AI?
         | Yep, that sneaky one."
         | 
         | He's referring to Python in general
         | 
         | "Not only because the syntax is more human-friendly, but also
         | because the Python interpreter is natively integrated in all
         | Unix distros."
         | 
         | I think he means that its available or readily available in
         | many major linux distributions like Ubuntu, Fedora, NixOS, etc.
         | I don't think native is the right word.
         | 
         | I use bash too but Python is amazing. You're right, there are
         | problems related to packaging and speed, but it is still very
         | often the right tool for the job. It's powerful, easy to use,
         | and open source.
        
           | 1vuio0pswjnm7 wrote:
           | "I use bash too but Python is amazing."
           | 
           | I do not use bash. I use ash. Bash is too slow for me, like
           | Python.
        
         | donkeybeer wrote:
         | What is the reason you prefer not to simply let python lie
         | around? Security?
        
           | 1vuio0pswjnm7 wrote:
           | Storage space usually. Even when I have surplus space I still
           | like to have minimal userlands with only the utilities I am
           | actually using.
        
       | ic_fly2 wrote:
       | pydantic basemodel has made dataclasses redundant.
        
         | _Wintermute wrote:
         | Dataclasses have the one massive benefit of not being an
         | additional dependency.
        
           | ddejohn wrote:
           | This. You also don't really need Pydantic unless you're
           | de/serializing data from external sources. A dataclass is
           | perfectly cromulent if you're just passing around data
           | internally.
        
       | yomismoaqui wrote:
       | Python is the 2nd best language at everything.
        
         | nilamo wrote:
         | And the first best is python3!
        
       | runjake wrote:
       | I really don't find the Python language elegant at all. I prefer
       | the Ruby syntax.
       | 
       | But Python's tooling, particularly with what Astral is doing (uv,
       | ruff, ty), is so good, I'm always using Python and virtually
       | never using Ruby. And yeah, the rich libraries, too.
        
       | Arch-TK wrote:
       | Ubiquitous VSCode - honestly a tragedy.
        
       | Night_Thastus wrote:
       | I love writing Python. However, there are caveats:
       | 
       | 1: I don't like dealing with language crossing boundaries with it
       | - it's painful, especially if to/from a compiled language -
       | there's just too much friction. It's easy to _write_ but hard to
       | _maintain_.
       | 
       | 2: Debugging python can be...painful. If you have a pure perfect
       | environment dedicated to pure python and all the tooling set up,
       | it can be breezy. But if you have something messier like C++ that
       | calls Python or vice-versa and are using an editor not made for
       | Python like QTCreator then suddenly it becomes hell.
       | 
       | Who owns this data!? Where was this initialized!? What calls this
       | function!? What type is this data!?!?!?!? These questions are so
       | effortless in C++ for me and so very painful in Python. It slows
       | efforts to a crawl.
       | 
       | It feels exhausting to have to go back to print statements, grep,
       | and hand-drawing a graph that shows what functions call what just
       | to figure out WTF went wrong. It's painful to a degree that I
       | avoid it as much as possible.
       | 
       | ...and don't even get me started on dealing with dependency
       | problems in deployments...
        
         | gh02t wrote:
         | I've long lusted after a smooth debugging workflow writing
         | Cython that would let you seamlessly debug between Python and
         | C/C++. I think there are some hacks to do it, but nothing
         | really well integrated.
        
         | miguel_martin wrote:
         | Python debugging is great when you're strictly debugging Python
         | code. Placing a `breakpoint` or spinning up an IPython instance
         | to investigate the issue via `import IPython; IPython.embed()`
         | makes life breezy. For neovim, you can send code to the ipython
         | REPL easily via vim-slime.
         | 
         | I've never found myself debugging the underlying C++ code
         | unless developing a C++ extension. But is it really that hard?
         | Just point lldb to the python process and run your script in
         | lldb.
         | 
         | If the C++ is not yours & assuming it's a mature lib (e.g.
         | PyTorch): it's probably an error caused by you in Python land.
        
           | Night_Thastus wrote:
           | Both the C++ and Python are mine. I have cases of both C++
           | calling Python, and Python calling C++. Problems could be on
           | either side.
           | 
           | The problem is how to step into one from the other, you
           | really can't as far as I know.
           | 
           | The python parts aren't standalone enough that it could just
           | be run on its own, there's so much setup involved prior to
           | that point that it can really only be run from the top-level
           | user controls.
        
       | jlarocco wrote:
       | 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....)
        
         | wk_end wrote:
         | 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.
        
           | jraph wrote:
           | Do people really turn to JS (instead of Python) for
           | lightweight scripting? Are we talking about the "better Bash"
           | use case?
        
             | ajkjk wrote:
             | that would be very surprising
        
             | tempest_ wrote:
             | JS devs do, and there are a lot of them
        
             | roflchoppa wrote:
             | 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_.
        
           | mjr00 wrote:
           | > 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...
        
           | slightwinder wrote:
           | 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.
        
         | ravenstine wrote:
         | 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.
        
         | vinceguidry wrote:
         | 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.
        
           | leptons wrote:
           | 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.
        
             | biztos wrote:
             | 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.
        
             | yoz-y wrote:
             | 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.
        
             | daedrdev wrote:
             | 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
        
               | leptons wrote:
               | 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).
        
         | guhcampos wrote:
         | 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.
        
           | tombert wrote:
           | 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".
        
             | dzonga wrote:
             | 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.
        
               | tombert wrote:
               | 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:
               | https://www.lambdadays.org/lambdadays2025/thomas-gebert
               | 
               | And the slides are available here: https://github.com/Tom
               | bert/lambda_days_2025/blob/main/slides...
               | 
               | 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.
        
               | _dain_ wrote:
               | Github link is 404
        
               | tombert wrote:
               | Oops! Forgot to make the repo public!
               | 
               | Should be fixed now. Sorry about that.
        
             | ActorNightly wrote:
             | >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.
        
               | tombert wrote:
               | 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.
        
           | munificent wrote:
           | 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.
        
             | bunderbunder wrote:
             | If the TIOBE index is an even remotely useful indicator,
             | Python's an even bigger giant metropolis.
        
               | dietr1ch wrote:
               | 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.
        
               | munificent wrote:
               | 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.
        
               | bunderbunder wrote:
               | 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.
        
             | trchek wrote:
             | 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
        
             | dec0dedab0de wrote:
             | 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.
        
               | munificent wrote:
               | _> 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.
        
             | PeterStuer wrote:
             | I worked in .Net land before switching to Pythonville. It's
             | very much like Java metropolis, but with less CS graduates.
        
             | camcil wrote:
             | Lest we forget that Python is ~4 years older than Java.
        
             | supriyo-biswas wrote:
             | 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.
        
             | ActorNightly wrote:
             | 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.
        
               | munificent wrote:
               | _> 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.
        
           | bunderbunder wrote:
           | 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.
        
             | deepsun wrote:
             | 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).
        
               | mey wrote:
               | 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...
        
               | zeroc8 wrote:
               | 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.
        
               | bunderbunder wrote:
               | 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.
        
               | deepsun wrote:
               | 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
        
               | bunderbunder wrote:
               | 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.
        
             | ecshafer wrote:
             | > 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.
        
           | NomDePlum wrote:
           | I've always felt X was far superior to Y, and don't get me
           | started on Z or W.
        
           | rs186 wrote:
           | I think at least half of amazon.com and AWS run on Java.
        
           | pea wrote:
           | 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.
        
           | le-mark wrote:
           | > 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.
        
         | callc wrote:
         | 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.
        
           | rsyring wrote:
           | > 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.
        
             | rendall wrote:
             | 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
        
             | callc wrote:
             | 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.
        
               | rsyring wrote:
               | 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.
        
               | callc wrote:
               | Thanks for your comment. I definitely could have worded
               | mine better too with a bit more effort and context.
        
           | maleldil wrote:
           | > 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.
        
         | stanleydrew wrote:
         | > 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.
        
           | ajkjk wrote:
           | you'd be crazy (senior or not) not to use Go for Go stuff and
           | Python for Python stuff
        
             | biztos wrote:
             | 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?
        
               | ajkjk wrote:
               | I mean... to oversimplify a bit, Python is for scripting
               | and Go is for servers.
        
           | pyuser583 wrote:
           | 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.
        
           | bee_rider wrote:
           | 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).
        
             | maleldil wrote:
             | Rust has language features (often inspired by functional
             | programming languages) that allow you to write pretty high
             | level code.
        
         | tombert wrote:
         | 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.
        
           | Joker_vD wrote:
           | msedit main.py && ./main.py         !!         !!
           | 
           | But indeed, pressing F5 solves that for both Rust and Python
        
           | dec0dedab0de wrote:
           | why would you want a lambda to span multiple lines? How would
           | that be any better than a function?
        
             | tombert wrote:
             | 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.
        
               | frutiger wrote:
               | Off topic: you didn't use y.
        
               | tombert wrote:
               | 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.
        
               | ddejohn wrote:
               | > 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.
        
               | tombert wrote:
               | 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.
        
               | dec0dedab0de wrote:
               | 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.
        
               | tombert wrote:
               | 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.
        
               | _dain_ wrote:
               | Naming things is one of the hard problems of computer
               | science. It's nice not to be forced into naming
               | something.
        
             | rs186 wrote:
             | 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.
        
               | dec0dedab0de wrote:
               | 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.
        
               | tombert wrote:
               | 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.
        
           | bko wrote:
           | 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.
        
             | nickdrozd wrote:
             | > 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.
        
             | ActorNightly wrote:
             | 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.
        
         | m0llusk wrote:
         | The v2 to v3 transition threw a lot of people.
        
           | codethief wrote:
           | 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.
        
             | FredPret wrote:
             | 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.
        
             | ewoodrich wrote:
             | 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.
        
         | dec0dedab0de wrote:
         | 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.
        
           | verandaguy wrote:
           | > 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 :)
        
             | dec0dedab0de wrote:
             | HA! Alright Fair enough :-)
        
         | macawfish wrote:
         | 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.
        
         | jonas21 wrote:
         | 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.
        
           | dccsillag wrote:
           | Typing still sucks big time. Same for perf, unless you are
           | working with numerics that fit with something like NumPy or
           | JAX.
        
           | ActorNightly wrote:
           | >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.
        
         | codazoda wrote:
         | 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.
        
         | taeric wrote:
         | 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. :(
        
           | macawfish wrote:
           | If I were to try again I'd go with uv, it seems way way
           | better
        
             | taeric wrote:
             | I have been sticking with poetry for a while, now. What
             | would make me want/need to move to uv?
        
               | cdelsolar wrote:
               | yeah Poetry is fine
        
               | macawfish wrote:
               | Maybe you'll find this series of articles interesting:
               | https://www.loopwerk.io/articles/tag/uv/
        
               | taeric wrote:
               | 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.
        
               | maleldil wrote:
               | - 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.
        
               | taeric wrote:
               | 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?
        
         | whatever1 wrote:
         | 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.
        
         | _dain_ wrote:
         | 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.
        
         | photonthug wrote:
         | 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/
        
       | whinvik wrote:
       | Out of curiosity, why would I use Dataclass vs a Pydantic
       | Basemodel. If we did not have a PyDantic dependency I could
       | imagine wanting to use Dataclass. But if I have it, why not use
       | everywhere?
        
         | rsyring wrote:
         | To help answer your question, here's a detailed comparison from
         | the attrs project:
         | 
         | https://www.attrs.org/en/stable/why.html
         | 
         | There's some obvious potential for bias there, but I thought
         | most of the arguments were well reasoned.
         | 
         | Edit: found another that I thought was helpful:
         | https://threeofwands.com/why-i-use-attrs-instead-of-pydantic...
        
         | intalentive wrote:
         | Performance hit from data validation at construction time. I
         | like msgspec which is much leaner and faster.
        
         | lysecret wrote:
         | Main reason is (used to be) performance. But since pydantic 2.0
         | it's not an issue anymore I default to use pydantic for
         | everything.
        
         | maleldil wrote:
         | Unnecessary baggage if you don't need validation or
         | serialisation.
         | 
         | My rule of thumb is to use Pydantic if I need serialisation,
         | otherwise I default to dataclasses.
        
         | adammarples wrote:
         | The Chad answer is to use pydantic.dataclass
        
         | afiodorov wrote:
         | My rule of the thumb is that Dataclasses are for compile-time
         | type-checking, pydantic classes are for run time type checking.
        
         | tauroid wrote:
         | Why would I use a Pydantic model when
         | `TypeAdapter(MyDataclass)` exists?
        
       | simonw wrote:
       | > I would like to have a tool that generates the project
       | structure for me, but I haven't found one that fits me yet.
       | 
       | I recommend cookiecutter for this. I have a few templates I've
       | built with that which I use frequently:
       | 
       | python-lib: https://github.com/simonw/python-lib
       | 
       | click-app: https://github.com/simonw/click-app
       | 
       | datasette-plugin: https://github.com/simonw/datasette-plugin
       | 
       | llm-plugin: https://github.com/simonw/llm-plugin
       | 
       | You can run them like this:                 uvx cookiecutter
       | gh:simonw/python-lib
        
         | timkpaine wrote:
         | Copier is the new hotness for this
         | 
         | https://copier.readthedocs.io/en/stable/
        
         | oezi wrote:
         | My take on this (using Ruby) is
         | https://github.com/coezbek/baker
         | 
         | It doesn't copy template repos, but rather creates a list of
         | imperative steps to perform. Steps can be both manual (obtain
         | an API key and store it here) and automatic (run 'uv init').
         | Markdown syntax, ruby string interpolation and bash.
         | 
         | It came from a deep hate for yml based configs.
        
         | mmcnl wrote:
         | Am I the only one who actually likes setting up new projects? I
         | don't want to automate that.
        
           | serial_dev wrote:
           | It depends on your work, though...
           | 
           | If you work at an agency or as a freelancer and you build
           | various similar apps with similar tooling and base setup,
           | being able to scaffold and have them all setup quickly, not
           | having to do it manually and waste hours id important.
           | Similarly, if you work on various small open source packages,
           | you want the tooling to be the same, READMEs look the same,
           | etc, a script or tool to "spit out" the basic structure can
           | be nice.
           | 
           | On the other hand, if you set up the app or larger open
           | source package and you'll work only on that project for
           | potentially years, setting up a project individually,
           | organically makes a lot of sense.
        
         | consumer451 wrote:
         | This type of thing seems ripe for building into agentic LLM dev
         | workflows, doesn't it?
        
         | didip wrote:
         | Honestly, these days, just tell AI to generate one for you.
        
       | manofmanysmiles wrote:
       | I make projects following almost identical patterns. It's a
       | little uncanny. Maybe the people in the python developer
       | ecosystem are converging on a pretty uniform way to do most
       | things? I though some of my choices were maybe "my own", it
       | seeing such consistency makes me question my own free will.
       | 
       | It's like when people pick a "unique" name for their baby along
       | with almost everyone else. What you thought was a unique name is
       | the #2 most popular name.
        
         | bobson381 wrote:
         | as though subsurface pilot waves in every spectrum hold human
         | egos as constituent particles - becoming-being lol
        
         | solumos wrote:
         | This sort of architecture has been in favor with python for at
         | least 10 years or so, but I think you're right -- the structure
         | just makes sense, so many reasonable engineers converge on
         | using it.
        
       | 0xbadcafebee wrote:
       | Maybe I'm the only one that finds Python simultaneously verbose
       | and lacking? Either you need 500 dependencies to do something in
       | a simple way, or you need dozens (if not hundreds) of lines to do
       | trivial things. I avoid writing Python because there's so much
       | bullshit to add. Much prefer Perl, I can actually get things done
       | quickly. Python feels like programming for the sake of
       | programming.
        
         | supportengineer wrote:
         | dang the backend is leaking old comments from 2007
        
         | mystifyingpoi wrote:
         | Could you share an example, where Perl is quicker to use and
         | more powerful?
        
           | lucb1e wrote:
           | And not write-only (https://handwiki.org/wiki/Write-
           | only_language)
        
         | wslh wrote:
         | YMMV, but in my experience, Python's top use cases tend to
         | require fewer dependencies, not more. Many trivial tasks are
         | already built into the language. Not saying Python is perfect,
         | but it's definitely well-oriented in that regard. I'm curious
         | in what kinds of use cases have you found the opposite to be
         | true?
         | 
         | I think the classic Python vs. Perl question ultimately comes
         | down to using what you feel most comfortable with. People are
         | different, and that's totally fine.
        
         | nickjj wrote:
         | I have a bunch of zero dependency projects. You can get a lot
         | done with the standard library and single file projects which
         | you can run on most systems without needing to do anything
         | except curl it down and run it since Python is available.
         | 
         | For example here's a ~2k line Python project which is a command
         | line finance income and expense tracker:
         | https://github.com/nickjj/plutus/blob/main/src/plutus
         | 
         | It uses about a dozen stdlib modules.
         | 
         | About 25% of the code is using argparse to parse commands and
         | flags. With that said, I tend to prefer code that yields more
         | lines for the sake of clarity. For example this could
         | technically be 1 or 2 lines but I like each parameter being on
         | its own line.                   parser_edit.add_argument(
         | "-s",             "--sort",             default=False,
         | action="store_true",             help="Sort your profile and
         | show a diff if anything changed",         )
        
         | dndurbah wrote:
         | > Much prefer Perl, I can actually get things done quickly
         | 
         | Python lets you just nest data structures without having to
         | twist your brain. You want a tuple in a list in a dictionary
         | value: you just write it down and can access it with a unified
         | notation. Bam. No reference madness and thinking about
         | contexts. It's a big part of what I typically need to get
         | things done quickly and understand how I did it 5 years later.
         | That has to count for something. Python is boring in that
         | sense, Perl is fun. But that's exactly my problem with it. It's
         | too clever for it's own good and writing it does things to your
         | brain (well at least mine).
        
         | bobsmooth wrote:
         | The best part about python is that there's a library for
         | everything.
        
         | milin wrote:
         | Have you met Java?
        
         | mekoka wrote:
         | When you say "I actually can get things done quickly", does
         | that include reading that same source a year from now?
        
       | CraigJPerry wrote:
       | I keep meaning to write something like this but exploring the
       | "how simple can you make it" angle - a lot of my world is kube
       | (which is great in the right scenario) but could you shave
       | complexity out of a stack designed for solo dev rapid iteration:
       | 
       | e.g. rather than:                 > It's important not to do any
       | heavy data processing steps in the project-ui ... we keep the
       | browser application light while delegating the heavy lifting and
       | business logic to the server
       | 
       | Chomp the complexity, serve HTML from the backend directly
       | > ty
       | 
       | Im curious where ty goes but for a min-complexity stack i couldnt
       | spend complexity tokens on pre release tools                 >
       | pydantic ... dataclasses
       | 
       | One or the t'other, plus i'll forever confuse myself: is it
       | post_init (dataclasses) or is it post_model_init (pydantic) - i
       | had to check!                 > docker
       | 
       | if we already have uv, could we get away without docker? uv sync
       | can give an experience almost akin to static compiled binaries
       | with the right setup. Its not going to handle volumes etc so if
       | you're using docker features, this concept isnt going to fly. If
       | you're not wedded to docker though, can you get away with just uv
       | in dev and prod? in an enterprise prob not, i wouldn't expect to
       | be able to download deps in prod. For flying solo though...
       | > compose
       | 
       | You've a frontend, a backend and presumably a database. Could you
       | get away with just uv to manage your backend and a local sqlite
       | db?
       | 
       | So a broadly feature comparable stack for rapid iteration with
       | less complexity but still all the bells and whistles so you dont
       | need to cook everything yourself, might look like:
       | - uv       - fastapi + jinja + htmx + surreal + picocss       -
       | sqlite
       | 
       | You could probably sketch a path to hyper scale if you ever
       | needed it:                 - v1 = the above stack       - v2 =
       | swap sqlite for postgres, now you unlocked multiple writers and
       | horizontal scaling, maybe py-pglite for test envs so you can
       | defer test-containers adoption for one more scaling iteration.
       | WAL streaming would add some complexity to this step but worth it
       | - v3 = introduce containers, a container registry and test-
       | containers. I dont think you really unlock much in this step for
       | all that additional complexity though...       - v4 = rke2 single
       | node cluster, no load balancer needed yet       - v5 = scale to
       | triple node, we need a load balancer too       - v6 = add agent
       | nodes to the rke cluster       - v7 = can you optimise costs,
       | maybe rewrite unchanging parts in a more resource efficient stack
       | ...
        
         | jackbravo wrote:
         | if you want to serve HTML from the backend, why not use
         | FastHTML then ;-)
        
           | CraigJPerry wrote:
           | i experimented with it, i'm a fan of the concept. Ironically
           | the bit i thought id like most (swap jinja extends
           | shenanigans for just composing functions or callables more
           | generally) is the bit that i didnt warm to. I dont really
           | know why, on paper it ticks boxes for me. In practice i felt
           | slow.
        
       | mmcnl wrote:
       | Ofcourse the most used programming language in the world is not a
       | pain to use. How could it be #1 if it was?
        
       | callc wrote:
       | Funnily enough, I made the opposite switch recently, and am also
       | liking it.
       | 
       | My thoughts about python here:
       | https://calvinlc.com/p/2025/06/10/thank-you-and-goodbye-pyth...
       | 
       | Next time I get into Python I'll try uv, ruff, ty.
        
         | frollogaston wrote:
         | I switched from Python to JS for backend stuff a while back,
         | thoroughly enjoying it. I agree that "Python installation and
         | package management is broken," but the async stuff was the
         | biggest improvement to productivity. Yes I know Python got
         | asyncio, but there's a big difference between having one well-
         | accepted way of doing things vs multiple competing,
         | incompatible ways, where the good one has the least momentum.
         | 
         | The rest is small stuff that adds up like Py whitespace
         | scoping, or Py imports somehow not taking relative paths, or JS
         | object syntax is nicer:
         | https://news.ycombinator.com/item?id=44544029
        
       | frollogaston wrote:
       | I was like, switched from what, then eventually found a footnote
       | "I used to be mostly a Java/JavaScript/R kind of guy"
        
       | osigurdson wrote:
       | >> I prefer to use a monorepo structure
       | 
       | There is nothing more annoying than tons of little repos all of
       | which containing tiny projects with a few hundred lines of code
       | but (of course) you need most / all of them to do anything. Use a
       | mono repo until there is some obvious reason to split it up imo.
        
         | sethammons wrote:
         | in my experience, repo by "area" works the best. This usually
         | means by team, but you don't want a team restructure to cause
         | code relocation issues. And, yes, only when the org pressures
         | push for it.
         | 
         | On the flip side, we have an org with 50+ teams and our
         | operations team is pinning for a monorepo. They are just fine
         | with one team's push forcing N teams to have an unexpected
         | deploy and recycling of caches, connections, etc. Not to
         | mention what will happen when team A doesn't have time to deal
         | with team B's merge due to other org pressures.
        
         | MonkeyClub wrote:
         | I got the impression that TFA speaks of a monorepo in the sense
         | of not splitting the backend and the frontend into two
         | different repos.
         | 
         | For personal projects, though, I get the value of an actual
         | small projects monorepo.
        
       | bognition wrote:
       | I'm on board with most of this. The one suggestion I'd add is to
       | replace "make" with "just"
        
         | underdeserver wrote:
         | I hear about it every now and again and I can't seem to grok
         | the benefit. What's the killer feature over make?
        
           | BeetleB wrote:
           | If you're an expert in make and already have a Makefile, I
           | would not recommend switching to just for that project.
           | 
           | The benefit of just is that it's designed to be a command
           | runner, whereas make is designed to be a build tool. justfile
           | syntax is much simpler and more ergonomic. It also has nice
           | features: Private recipes, submodules, recipes that you can
           | specify to run only in a particular OS (we use the same
           | justfile for both Windows and Linux), writing your recipes in
           | a language other than your shell language, and many many
           | other niceties.
           | 
           | A new user can start doing "advanced" stuff in just in a
           | couple of hours. They'll take a lot longer if trying to do it
           | via make.
        
           | kstrauser wrote:
           | First, I grok make. I'm saying this from a position of
           | familiarity, not of ignorance and fear.
           | 
           | Make is great at compiling code in languages that don't have
           | bespoke build systems. If you want to compile a bunch of C,
           | awesome. For building a Rust or JavaScript project, no way.
           | Those have better tooling of their own.
           | 
           | So for the last 15 years or so, I've used make as a task
           | runner (like "make test" shelling out to "cargo test", or
           | "make build" calling "cargo build", etc.). As a task
           | runner... it kinda sucks. Of course it's perfectly capable of
           | running anything a shell script can run, but it was designed
           | for compiling large software projects and has a lot of
           | implicit structure around doing that.
           | 
           | Just doesn't try to be a build system. It's optimized for
           | running tasks. Here, that means it provides a whole lot of
           | convenient functions for path manipulation and other common
           | scripty things. It also adds dozens of quality-of-life
           | features that devs might not even realize they wanted.
           | 
           | For example, consider this trivial justfile:
           | # Delete old docs       clean:           rm -rf public
           | # This takes arguments       hello name:           @echo
           | Hello, {{name}}
           | 
           | If you're in a directory with it and run `just --list`, it'll
           | show you the list of targets in that file:                 $
           | just --list       Available recipes:           clean      #
           | Delete old docs           hello name # This takes arguments
           | 
           | That second recipe takes a required command line argument:
           | $ just hello       error: Recipe `hello` got 0 arguments but
           | takes 1       usage:           just hello name            $
           | just hello underdeserver       Hello, underdeserver
           | 
           | You can do these things in make! I've seen it! Just doesn't
           | add things that were impossible before. But I guarantee you
           | it's a lot harder to implement them in make than it is in
           | just, where they're happy native features.
           | 
           | There are a zillion little niceties like this. Just doesn't
           | try to do everything make does. It just concentrates on the
           | smaller subset of things you'd put in .PHONY targets, and
           | makes them really, really ergonomic to use.
           | 
           | You wouldn't use just to replace make in a large, complicated
           | build. I would unhesitatingly recommend it for wrapping
           | common targets in repos of newer languages, so that `just
           | clean build test` does the same things whether you're in
           | Python or TS or Rust or whatever, and you don't want to hack
           | around all of make's quirks just to build a few simple entry
           | points.
        
         | pletnes wrote:
         | Just is fantastic for any project - also non-code ones!
        
       | tk90 wrote:
       | Is there a Rust equivalent to this? I'd like to dive into a rust
       | "api_starter" as someone with mostly NodeJS experience!
        
       | noncoml wrote:
       | Switched to python from what? R? Java? Javascript?
        
       | yunwal wrote:
       | For me, python is the closest thing to writing pseudocode that
       | functions. Every time I have the instinct to gloss over a thing
       | when writing it down (because it feels obvious in my head), it
       | turns out that python has an intuitive abstraction for it.
       | 
       | Coming from a mathy background I found it incredibly satisfying,
       | although I've come around to other languages since.
        
         | odyssey7 wrote:
         | As a mathy person myself, I find the OOP leaning difficult to
         | think about. Better equational reasoning, better lambdas, fewer
         | side effects to worry about, avoiding mutation so that I can
         | define something and still know what it is later during
         | runtime, those are what help me think clearly. To me OOP is
         | about the furthest paradigm from math that I've used.
        
       ___________________________________________________________________
       (page generated 2025-07-16 23:00 UTC)