[HN Gopher] Go away Python
       ___________________________________________________________________
        
       Go away Python
        
       Author : baalimago
       Score  : 310 points
       Date   : 2025-12-30 08:50 UTC (14 hours ago)
        
 (HTM) web link (lorentz.app)
 (TXT) w3m dump (lorentz.app)
        
       | throw-12-16 wrote:
       | I've been meaning to port some dotfiles utils over to go, I think
       | I'll give this a shot.
        
       | llmslave2 wrote:
       | I love it. I'm using Go to handle building full stack javascript
       | apps, which actually works great since esbuild can be used
       | directly inside a Go program. The issue is that it's a
       | dependency, so I settled for having a go mod file and running it
       | directly with Go. If somehow these dependencies could be resolved
       | without an explicit module configured (say, it was inline in the
       | go file itself) it would be perfect. Alas, it will probably never
       | happen.
       | 
       | That being said...use Go for scripting. It's fantastic. If you
       | don't need any third party libraries this approach seems really
       | clean.
        
       | age123456gpg wrote:
       | Official stance about supporting interpreter mode for the
       | reference https://github.com/golang/go/issues/24118
        
       | w4rh4wk5 wrote:
       | Back in the days, I've seen that with C files, which are compiled
       | on the fly to a temporary file an run.
       | 
       | Something like //usr/bin/gcc -o main "$0"; ./main "$@"; exit
        
         | ernst_klim wrote:
         | Tcc even supports that with `#!/usr/local/bin/tcc -run`,
         | although I don't understand people who use c or go for
         | "scripting", when python, ruby, TCL or perl have much superior
         | ergonomics.
        
           | w4rh4wk5 wrote:
           | This was a relatively old project that used a C program as
           | build system / meta generator. All you needed was a working C
           | compiler (and your shell to execute the first line). From
           | there, it built and ran a program that generated various
           | tables and some source code, followed by compiling the actual
           | program. The final program used a runtime reflection system,
           | which was set up by the generated tables and code from the
           | first stage.
           | 
           | The main reason was to do all this without any dependencies
           | beyond a C compiler and some POSIX standard library.
        
       | hamishwhc wrote:
       | The author's point about "not caring about pip vs poetry vs uv"
       | is missing that uv directly supports this use case, including
       | PyPI dependencies, and all you need is uv and your preferred
       | Python version installed:
       | https://docs.astral.sh/uv/guides/scripts/#using-a-shebang-to...
        
         | benrutter wrote:
         | I thought that too, but I think the tricky bit is if you're a
         | non-python user, this isn't yet obvious.
         | 
         | If you've never used Clojure and start a Clojure project, you
         | will almost definitely find advice telling you to use
         | Leiningen.
         | 
         | For Python, if you search online you _might_ find someone
         | saying to use uv, but also potentially venv, poetry or hatch. I
         | definitely think uv is taking over, but its not yet ubiquitous.
         | 
         | Ironically, I actually had a similar thing installing Go the
         | other day. I'd never used Go before, and installed it using apt
         | only to find that version was too old and I'd done it wrong.
         | 
         | Although in that case, it was a much quicker resolution than I
         | think anyone fighting with virtual environments would have.
        
           | houzi wrote:
           | Do you think a non-python user would piece it together if the
           | shebang line reveals what tool to use?
        
           | idoubtit wrote:
           | That's my experience. I'm not a Python developer, and
           | installing Python programs has been a mess for decades, so
           | I'd rather stay away from the language than try another new
           | tool.
           | 
           | Over the years, I've used setup.py, pip, pipenv (which kept
           | crashing though it was an official recommendation), manual
           | venv+pip (or virtualenv? I vaguely remember there were 2
           | similar tools and none was part of a minimal Python install).
           | Does uv work in all of these cases? The uv doc pointed out by
           | the GP is vague about legacy projects, though I've just
           | skimmed through the long page.
           | 
           | IIRC, Python tools didn't share their data across projects,
           | so they could build the same heavy dependencies multiple
           | times. I've also seen projects with incomplete dependencies
           | (installed through Conda, IIRC) which were a major pain to
           | get working. For many years, the only simple and sane way to
           | run some Python code was in a Docker image, which has its own
           | drawbacks.
        
             | lexicality wrote:
             | > Does uv work in all of these cases?
             | 
             | Yes. The goal of uv is to defuck the python ecosystem and
             | they're doing a very good job at it so far.
        
               | aeurielesn wrote:
               | That's giving way too much credit to uv.
        
               | karel-3d wrote:
               | uv is really that good.
        
               | NeutralCrane wrote:
               | It really isnt
        
               | kraddypatties wrote:
               | I'm interpreting this as "uv was built off of years of
               | PEPs", which is true; that being said the UX of `uv` is
               | their own, and to me has significantly reduced the amount
               | of time I spend thinking about requirements, modules,
               | etc.
        
               | lexicality wrote:
               | They've definitely not done it _yet_ , but they're
               | getting there.
        
               | prox wrote:
               | What are the big offenders right now? What does uv
               | unfuck?
               | 
               | I only work a little bit with python.
        
               | kevin_thibedeau wrote:
               | pip and venv. The Python ecosystem has taken a huge step
               | backwards with the preachy attitude that you have to do
               | everything in a venv. Not when I want to have installable
               | utility scripts usable from all my shells at any time or
               | location.
               | 
               | I get that installing to the site-packages is a security
               | vulnerability. Installing to my home directory is not, so
               | why can't that be the happy path by default? Debian used
               | to make this easy with the dist-packages split leaving
               | site-packages as a safe sandbox but they caved.
        
               | kstrauser wrote:
               | Regarding why not your home directory: which version of
               | Foo do you install, the one that Project A needs or the
               | incompatible one that Project B needs?
               | 
               | The brilliant part about venvs is that A and B can have
               | their completely separate mutually incompatible
               | environments.
        
               | andoando wrote:
               | Why can't we just have something like npm/gradle/maven
               | dependencies? What makes python any different?
        
               | lexicality wrote:
               | A python virtualenv is just a slightly more complicated
               | node_modules. Tools like PDM, Poetry and uv handle them
               | automatically for you to the point where it effectively
               | is the same as npm.
               | 
               | The thing that makes Python different is that it was
               | never designed with any kind of per-project isolation in
               | mind and this is the best way anyone's come up with to
               | hack that behaviour into the language.
        
               | kevin_thibedeau wrote:
               | They have their place. But the default shouldn't force
               | you into a "project" when you want general purpose
               | applicability. Python should work from the shell as
               | readily as it did 20 years ago. Not mysteriously break
               | what used to work with no low-friction replacement.
        
               | halostatue wrote:
               | For years, pipx did almost all the work that I needed it
               | to do for safely running utility scripts.
               | 
               | uv has replaced that for me, and has replaced most other
               | tools that I used with the (tiny amount of) Python that I
               | write for production.
        
               | lexicality wrote:
               | In my experience every other python tool has a variety of
               | slightly to extremely painful behaviours that you have to
               | work around or at least be aware of.
               | 
               | Sometimes it's things like updating to Fedora 43 and
               | every tool you installed with `pipx` breaking because it
               | was doing things that got wiped out by the system
               | upgrade, sometimes it's `poetry update --only dep1`
               | silently updating dep2 in the background without telling
               | you because there was an update available and even though
               | you specified `--only` you were wrong to do that and
               | Poetry knows best.
               | 
               | Did you know that when you call `python -m venv` you
               | should always pass `--upgrade-deps` because otherwise it
               | intentionally installs an out of date version of pip and
               | setuptools as a joke? Maybe you're not using `python -m
               | venv` because you ran the pyenv installer and it
               | automatically installed `pyenv-virtualenv` without asking
               | which overrides a bunch of virtualenv features because
               | the pyenv team think you should develop things in the
               | same way they do regardless of how you want to delevop
               | things. I hate pyenv.
               | 
               | So far the only problem I've had with uv is that if you
               | run `uv venv` it doesn't install pip in the created
               | virtualenv because you're supposed to run `uv pip
               | install` instead of `pip install`. That's annoying but
               | it's not a dealbreaker.
               | 
               | Outside of that, I feel very confident that I could give
               | a link to the uv docs to a junior developer and tell them
               | to run `uv python install 3.13` and `uv tool install
               | ruff` and then run `uv sync` in a project and everything
               | will work out and I'm not going to have to help them
               | recover their hard drive because they made the foolish
               | mistake of assuming that `brew install python` wouldn't
               | wreck their macbook when the next version of Python gets
               | released.
        
               | lucideer wrote:
               | uv not only completely replaces all of pip, pyenv & venv,
               | but it also does a much better job than any of them at
               | their intended function, as well as a bunch of other
               | convenient, simple developer-friendly features.
               | 
               | 1. pip isn't entirely to blame for all of Python's bad
               | package management - distutils & setuptools gave us
               | setup.py shenanigans - but either way, UV does away with
               | that in favour of a modern, consistent, declarative,
               | parseable PEP 508 manifest spec, along with their own
               | well-designed lockfile (there was no accepted lockfile
               | PEP at the time UV was created - since PEP 715 has become
               | accepted UV has added support, though that PEP is still
               | limited so there's more work to do here).
               | 
               | 2. pyenv works fine but uv is faster & adds some nice
               | extra features with uvx
               | 
               | 3. venv has always been a pain - ensuring you're always
               | in the right venv, shell support, etc. uv handles this
               | invisibly & automatically - because it's one tool you
               | don't need to worry about running pip in the right venv
               | or whatever.
        
             | simonw wrote:
             | > IIRC, Python tools didn't share their data across
             | projects, so they could build the same heavy dependencies
             | multiple times.
             | 
             | One of the neatest features of uv is that it uses clever
             | symlinking tricks so if you have a dozen different Python
             | environments all with the same dependency there's only one
             | copy of that dependency on disk.
        
               | zahlman wrote:
               | Hard links, in fact. It's not hard to do, just (the Rust
               | equivalent of) `os.link` in place of `os.copy` pretty
               | much. The actually clever part is that the package cache
               | actually contains files that can be used this way,
               | instead of just having wheels and unpacking them from
               | scratch each time.
               | 
               | For pip to do this, first it would have to organize its
               | cache in a sensible manner, such that it could work as an
               | actual _download_ cache. Currently it is an _HTTP_ cache
               | (except for _locally-built_ wheels), where it uses a
               | vendored third-party library to simulate the connection
               | to files.pythonhosted.org (in the common PyPI case). But
               | it still needs to connect to pypi.org to figure out the
               | URI that the third-party library will simulate accessing.
        
             | runjake wrote:
             | I would not be putting up with Python if not for uv. It's
             | that good.
             | 
             | Before uv came along I was starting to write stuff in Go
             | that I'd normally write in Python.
        
               | QuercusMax wrote:
               | Coming from a mostly Java guy (since around 2001), I've
               | been away from Python for a while and my two most recent
               | work projects have been in Python and both switched to uv
               | around the time I joined. Such a huge difference in time
               | and pain - I'm with you here.
               | 
               | Python's always been a pretty nice language to work in,
               | and uv makes it one of the most pleasant to deal with.
        
               | runjake wrote:
               | I don't even like Python as a language (it's growing on
               | me, but only a little).
               | 
               | It's just so useful: uv is great and there are decent
               | quality packages for everything imaginable.
        
             | whimsicalism wrote:
             | uv solved it, it's safe to come back now.
        
             | kristianbrigman wrote:
             | That's partly because python has a very large installed
             | base, and ease of entry (including distribution). This
             | leads to people running into issues quicker, and many
             | alternative solutions.
             | 
             | Unlike something like Rust, which has much fewer users
             | (though growing) and requires PhDs in Compiler Imprecation
             | and Lexical Exegetics.
             | 
             | Or C++ which has a much larger installed base but also no
             | standard distribution method at all, and an honorary degree
             | in Dorsal Artillery.
        
           | zahlman wrote:
           | > you might find someone saying to use uv, but also
           | potentially _venv_ , poetry or hatch.
           | 
           | This is sort of like saying "You might find someone saying to
           | drive a Ford, but also potentially _internal combustion
           | engine_ , Nissan or Hyundai".
        
             | evilduck wrote:
             | Only to those already steeped in Python. To an outsider
             | they're all equally arbitrary non-descriptive words and
             | there's not even obvious proper noun capitalization to tell
             | apart a component from a tool brand.
        
               | zahlman wrote:
               | It's always rather irritating to me that people make
               | these complaints without trying to understand any of the
               | under-the-hood stuff, because the ultimate conclusion is
               | that it's _somehow a bad thing_ that, on a FOSS project,
               | multiple people tried to solve a problem concurrently.
        
               | NetMageSCW wrote:
               | That's especially ironic given that inside Python part of
               | the philosophy is "There should be one-- and preferably
               | only one --obvious way to do it." So why does Python's
               | external environment seem more like something that escape
               | from a Perl zoo?
        
               | kstrauser wrote:
               | The one obvious way is the underlying virtualenv
               | abstraction. Everything else just makes that part easier
               | or more transparent.
        
               | zahlman wrote:
               | What kstrauser said.
               | 
               | But with much more detail: it seems complicated because
               | 
               | * People refuse to learn basic concepts that are readily
               | explained by many sources; e.g.
               | https://chriswarrick.com/blog/2018/09/04/python-virtual-
               | envi... [0].
               | 
               | * People cling to memories of long-obsolete issues. When
               | people point to XKCD 1987 they overlook that Python 2.x
               | has been EOL for almost six years (and 3.6 for over four,
               | but whatever)[1]; only Mac users have to worry about
               | "homebrew" (which I understand was directly interfering
               | with stuff back in the day) or "framework builds" of
               | Python; easy_install is similarly a long-deprecated
               | dinosaur _that you also would never need once you have
               | pip set up_ ; and fewer and fewer people actually need
               | Anaconda for anything[2][3].
               | 
               | * There is never just one way to do it, depending on your
               | understanding of "do". Everyone will always imagine that
               | the underlying functionality can be wrapped in a more
               | user-friendly way, and they will have multiple
               | incompatible ideas about what is the most user-friendly.
               | 
               | But there _is_ one _obvious_ "way to do it", which is to
               | set up the virtual environment and then launch the
               | virtual environment's Python executable. _Literally
               | everything else is window dressing on top of that_. The
               | only thing that  "activating" the environment does is
               | configure environment variables so that `python` means
               | the virtual environment's Python executable. All your
               | various alternative tools are just presenting different
               | ways to ensure that you run the correct Python (under the
               | assumption that you don't want to remember a path to it,
               | I guess) and to bundle up the virtual environment
               | creation with some other development task.
               | 
               | The Python community did explicitly provide for multiple
               | people to provide such wrappers. This was not by
               | providing the "15th competing standard". It was by
               | providing _the standard_ (really a set of standards
               | designed to work together: the virtual environment
               | support in the standard library, the PEPs describing
               | `pyproject.toml`, and so on), which replaced a Wild West
               | (where Setuptools was the sheriff and pip its deputy).
               | 
               | [0]: By the way, this is by someone who _doesn 't like_
               | virtual environments and was one of the biggest backers
               | of PEP 582.
               | 
               | [1]: Of course, this is not Randall Munroe's fault. The
               | comic dates to 2018, right in the middle of the period
               | where the community was trying to sort things out and
               | figure out how to not require the often problematic
               | `setup.py` configuration for every project including
               | pure-Python ones.
               | 
               | [2]: The SciPy stack has been installable from wheels for
               | almost everyone for quite some time and they were even
               | able to get 3.12 wheels out promptly despite being
               | hamstrung by the standard library `distutils` removal.
               | 
               | [3]: Those who _do_ need it, meanwhile, can generally
               | live within that environment entirely.
        
             | fwip wrote:
             | I imagine by this they meant `python -m venv` specifically,
             | using that interface directly, rather than through another
             | wrapper CLI tool.
        
               | zahlman wrote:
               | Fair.
               | 
               | The way I teach, I would start there; then you always
               | have it as a fallback, and understand the system better.
               | 
               | I generally sort users into aspirants who really should
               | learn those things (and will benefit from it), vs.
               | complete end users who just want the code to run (for
               | whom the developer should be expected to provide, if they
               | expect to gain such a following).
        
           | regularfry wrote:
           | There's definitely a philosophical shift that you can observe
           | happening over the last 12-15 years or so, where at the start
           | you have the interpreter as the centre of the world and at
           | the end there's an ecosystem management tool that you use to
           | give yourself an interpreter (and virtual environments, and
           | so on) per project.
           | 
           | I think this properly kicked off with RVM, which needed to
           | come into existence because you had this situation where the
           | Ruby interpreter was going through incompatible changes, the
           | versions on popular distributions were lagging, and Rails,
           | the main reason people were turning to Ruby, was relatively
           | militant about which interpreter versions it would support.
           | Also, building the interpreter such that it would
           | successfully run Rails wasn't trivial. Not _that_ hard, but
           | enough that a convenience wrapper mattered. So you had a
           | whole generation of web devs coming up in an environment
           | where the core language wasn 't the first touchpoint, and
           | there wasn't an assumption that you could (or should) rely on
           | what you could apt-get install on the base OS.
           | 
           | This is broadly an extremely good thing.
           | 
           | But the critical thing that RVM did was that it broke the
           | circular dependency at the core of the problem: it didn't
           | itself depend on having a working ruby interpreter. Prior to
           | that you could observe a sort of sniffiness about tools _for_
           | a language which weren 't implemented _in_ that language, but
           | RVM solved enough of the pain that it barged straight past
           | that.
           | 
           | Then you had similar tools popping up in other languages -
           | nvm and leiningen are the first that spring to mind, but I'd
           | also throw (for instance) asdf into the mix here - where the
           | executable that you call to set up your environment has a
           | '#!/bin/bash' shebang line.
           | 
           | Go has sidestepped most of this because of three things: 1)
           | rigorous backwards compatibility; 2) the simplest possible
           | installation onramp; 3) being timed with the above timeline
           | so that having a pre-existing `go` binary provided by your OS
           | is unlikely unless you install it yourself. And _none_ of
           | those are true of Python. The backwards compatibility breaks
           | in this period are legendary, you almost always _do_ have a
           | pre-existing Python to confuse things, and installing a new
           | python without breaking that pre-existing Python, which your
           | OS itself depends on, is a risk. Add to that the sniffiness I
           | mentioned (which you can still see today on `uv` threads) and
           | you 've got a situation where Python is catching up to what
           | other languages managed a decade ago.
           | 
           | Again.
        
             | bee_rider wrote:
             | It is sort of funny, if we squint just the wrong way,
             | "ecosystem management tool first, then think about
             | interpreters" starts to look a lot like... a package
             | manager, haha.
        
           | NeutralCrane wrote:
           | uv has been around for less than two years. It's on track to
           | become the default choice, it's just a matter of time.
        
           | MarsIronPI wrote:
           | > If you've never used Clojure and start a Clojure project,
           | you will almost definitely find advice telling you to use
           | Leiningen.
           | 
           | I thought the current best practice for Clojure was to use
           | the shiny new built-in tooling? deps.edn or something like
           | that?
        
             | codemonkey-zeta wrote:
             | deps.edn is becoming the default choice, yes. I interpreted
             | the parent comment as saying "you will see advice to use
             | leiningen (even though newer solutions exist, simply
             | because it _was_ the default choice when the articles were
             | written)"
        
             | fulafel wrote:
             | Clojure CLI (aka deps.edn) came out in 2018 and in the
             | survey "how do you manage your dependencies?" question
             | crossed 50% usage in early 2020. So for 6-8 years now.
        
         | meander_water wrote:
         | Actually you can go one better:                 #!/usr/bin/env
         | -S uv run --python 3.14 --script
         | 
         | Then you don't even need python installed. uv will install the
         | version of python you specified and run the command.
        
           | rikafurude21 wrote:
           | alternatively, uv lets you do this:
           | #!/usr/bin/env -S uv run --script       #       # /// script
           | # requires-python = ">=3.12"       # dependencies = ["foo"]
           | # ///
        
             | semi-extrinsic wrote:
             | The /// script block is actually specified in PEP 723 and
             | supported by several other tools apart from uv.
        
               | yjftsjthsd-h wrote:
               | That's good to hear; do you know what other tools support
               | it?
        
               | semi-extrinsic wrote:
               | From what I can tell, Hatch, PDM, pipx and pip-run also
               | support it.
        
               | nemosaltat wrote:
               | The last time I commented extolling the virtues of uv on
               | here, I got a similar reply, pointing out that PEP 723
               | specs this behavior, and uv isn't the only way. So I'll
               | try again in this thread: I'm bullish on uv, and waiting
               | for Cunningham.
        
               | semi-extrinsic wrote:
               | I am all in on uv as well, and advocating for its use
               | heavily at $dayjob. But I think having as much as
               | possible of these things encoded in standards is good for
               | the ecosystem. Maybe in a few years time, someone will
               | make something even better than uv. And in the meantime,
               | having things standardised speeds up adoption in e.g.
               | syntax highlighting in editors and such.
        
             | zahlman wrote:
             | This isn't really "alternatively"; it's pointing out that
             | in addition to the shebang you can add a PEP 723 dependency
             | specification that `uv run` (like pipx, and some other
             | tools) can take into account.
        
             | ncouture wrote:
             | This is an awesome features for quick development.
             | 
             | I'm sure the documentation of this featureset highlights
             | what I'm about to say but if you're attracted to the
             | simplicity of writing Python projects who are initialized
             | using this method, do not use this code in staging/prod.
             | 
             | If you don't see why this is not production friendly it's
             | for the simple a good.reaaon that creating deployable
             | artifacts packaging a project or a dependency of a project
             | this uses this method, creating reproducible builds becomes
             | impossible.
             | 
             | This will also lead to builds that pass your CI but fail to
             | run in their destination environment and vice versa due to
             | the fact that they download heir dependencies on the fly.
             | 
             | There may be workarounds and I know nothing of this feature
             | so investigate yourself if you must.
             | 
             | My two cents.
        
             | nemosaltat wrote:
             | I've started migrating all of my ~15 years of one-off
             | python scripts to have this front matter. Right now, I just
             | update when/if I use them. I keep thinking if were handier
             | with grep/sed/regex etc, I'd try to programmatically update
             | .pys system-wide. But, many aren't git tracked/version
             | controlled, just laying in whatever dir they service(d).
             | I've several times started a "python script dashboard" or
             | "hacky tools coordinator" but stop when I remember most of
             | these are unrelated (to each-other) and un/rarely used. I
             | keep watching the chatter and thinking this is probably an
             | easy task for codex, or some other agent but these pys are
             | "mine" (and I knew^ how they worked when I wrote^ them) and
             | also, they're scattered and there's no way I'm turning an
             | agent loose on my file system.
             | 
             | ^mostly, some defs might have StackOverflow copy/pasta
        
               | giancarlostoro wrote:
               | You could run ripgrep on your file system root to find
               | most of them, its insanely fast, then feed it to claude
               | or something to generate a script to do it for you.
        
           | dietr1ch wrote:
           | Yeah, but you need `uv`. If we are reaching out for tools
           | that might not be around, then you can also depend on nix-
           | shell,                   #! /usr/bin/env nix-shell         #!
           | nix-shell -i python3 --packages python3
        
             | mystifyingpoi wrote:
             | Yeah, but you need Nix. If we are reaching out for tools
             | that might not be around, then you can also depend on `curl
             | | sudo bash` to install Nix when not present.
             | 
             | (this is a joke btw)
        
               | jonhohle wrote:
               | Yeah, but you need curl, sudo, and bash...
        
               | lioeters wrote:
               | "Give me a 190-byte hex0 seed of x86 assembly, and I
               | shall compile the rest of the world." - Archimedes
        
               | JodieBenitez wrote:
               | _... you must first invent the universe_
        
             | Cyph0n wrote:
             | This comes with the added benefit that your environment is
             | reverted as soon as you exit the Nix shell.
        
             | kokada wrote:
             | The issue I have with `nix-shell` is that the evaluation
             | time is long, so if you need to run the script repeatedly
             | it may take a long time. `nix shell` at least fix this
             | issue by caching evaluations, but I think uv is still
             | faster.
        
           | jonhohle wrote:
           | That shebang will work on GNU link based systems, but might
           | not work elsewhere. I know that's the most popular target,
           | but not working on macOS, BSDs, or even busybox.
        
             | rented_mule wrote:
             | I just tried the one you are replying to and it worked
             | great on macOS. I frequently use a variant of this on my
             | Mac.
        
           | Supermancho wrote:
           | > Then you don't even need python installed. uv will install
           | the version of python you specified and run the command
           | 
           | What you meant was, "you don't need python pre-installed".
           | This does not solve the problem of not wanting to have (or
           | limited from having) python installed.
        
         | tgv wrote:
         | Won't those dependencies then be global? With potential
         | conflicts as a result?
        
           | stephenlf wrote:
           | Nope! uv takes care of that. uv is a work of art.
        
             | tgv wrote:
             | Then I should seriously take a look at it. I figured it was
             | just another package manager.
        
           | auxym wrote:
           | uv uses a global cache but hardlinks the dependencies for
           | your script into a temp venv that is only for your script, so
           | its still pretty fast.
        
         | embedding-shape wrote:
         | I've moved over mostly to uv too, using `uv pip` when needed
         | but mostly sticking with `uv add`. But as soon as you start
         | using `uv pip` you end up with all the drawbacks of `uv pip`,
         | namely that whatever you pass after can affect earlier
         | dependency resolutions too. Running `uv pip install dep-a` and
         | then `... dep-b` isn't the same as `... dep-b` first and then
         | `... dep-a`, or the same as `uv pip install dep-a dep-b` which
         | coming from an environment that does proper dependency
         | resolution and have workspaces, can be really confusing.
         | 
         | This is more of a pip issue than uv though, and `uv pip` is
         | still preferable in my mind, but seems Python package
         | management will forever be a mess, not even the bandaid uv can
         | fix things like these.
        
           | sieep wrote:
           | Ive been away from python for awhile now, I was under the
           | impression uv was somehow solving this dependency hell. Whats
           | the benefit of using uv/pip together? Speed?
        
             | chuckadams wrote:
             | `uv pip` is still uv, it's just uv's compatibility layer
             | for pip.
        
             | embedding-shape wrote:
             | As far as I can tell, `pip` by itself still doesn't even do
             | something basic as resolving the dependency tree first,
             | then download all the packages in parallel, as an basic
             | example. The `uv pip` shim does.
             | 
             | And regardless if you use only uv, or pip-via-uv, or
             | straight up pip, dependencies you install later steps over
             | dependencies you installed earlier, and no tool so far
             | seems to try to solve this, which leads me to conclude it's
             | a Python problem, not a package manager problem.
        
           | micik wrote:
           | i found uv frustrating. i dont know what problem is it trying
           | to solve. it's not a tool for managing virtualenvs, but it
           | does them as well. i guess it's a tool for dependency
           | management. the "uv tool" stuff. kinda weird. i gave it an
           | honest try but i was working around it with shell functions
           | all the time.
           | 
           | in the end i went back to good old virtualenvwrapper.sh and
           | setting PYTHONPATH. full control over what goes into the venv
           | and how. i guess people like writing new tools. i can
           | understand that.
        
             | embedding-shape wrote:
             | Maybe I "entered" the Python ecosystem at a different time,
             | but I never used virtualenvwrapper.sh nor sat PYTHONPATH
             | manually ever. When I first came into contact with Python,
             | I think doing `virtuelenv venv && source venv/bin/activate`
             | was what was recommended to me at the time. Eventually I
             | used `python -m venv` but always also with `pip` and a
             | `requirements.txt`. I pretty much stuck with that until
             | maybe 1 year ago I started playing around with `uv`, and
             | for me, I just use `uv venv|pip|init|add` from uv, and
             | nothing else from any other tools, and generally do pretty
             | basic stuff.
             | 
             | Maybe for more complex projects and use cases it's harder,
             | but it's a lot faster than just pip and pyproject.toml is a
             | lot nicer to manage than `requirements.txt`, so that's two
             | easy enough wins for me to move over.
        
         | t43562 wrote:
         | ....but you have to be able to get UV and on some platforms
         | (e.g. a raspberry pi) it won't build because the version of
         | rust is too old. So I wrote a script called "pv" in python
         | which works a bit like uv - just enough to get my program to
         | work. It made me laugh a bit, but it works anywhere, well
         | enough for my usecase. All I had to do was embed a primitive AI
         | generated TOML parser in it.
        
           | zahlman wrote:
           | > All I had to do was embed a primitive AI generated TOML
           | parser in it.
           | 
           | The standard recommendation for this is `tomli`, which became
           | the basis of the standard library `tomllib` in 3.11.
        
         | zahlman wrote:
         | There are really so many things about this point that I don't
         | get.
         | 
         | First off, in my mind the kinds of things that are "scripts"
         | don't have dependencies outside the standard library, or if
         | they do are highly specific to my own needs on my own system.
         | (It's also notable that one of the advantages the author cites
         | for Go in this niche is a standard library that avoids the need
         | for dependencies in quick scripts! Is this not one of Python's
         | major selling points since day 1?)
         | 
         | Second, even if you have dependencies you don't have to learn
         | differences between these tools. You can pick one and use it.
         | 
         | Third, virtual environments are literally just a place on disk
         | for those dependencies to be installed, that contains a config
         | file and some stubs that are automatically set up by a one-
         | liner provided by the standard library. You don't need to go
         | into them and inspect anything if you don't want to. You don't
         | need to use the activation script; you can just specify the
         | venv's executable instead if you prefer. None of it is
         | conceptually difficult.
         | 
         | Fourth, sharing an environment for these quick scripts
         | _actually just works fine an awful lot of the time_. I got away
         | with it for years before proper organization became second
         | nature, and I _would usually still_ be fine with it (except
         | that having an isolated environment for the current project is
         | the easiest way to be sure that I 've correctly _listed_ its
         | dependencies). In my experience it 's just not a thing for your
         | quick throwaway scripts to be dependent on incompatible Numpy
         | versions or whatever.
         | 
         | ... And really, to avoid ever having to think about the
         | dependencies you provide dynamically, you're going to switch to
         | a compiled language? If it were such a good idea, nobody would
         | have thought of making languages like Python in the first
         | place.
         | 
         | And uh...
         | 
         | > As long as the receiving end has the latest version of go,
         | the script will run on any OS for tens of years in the future.
         | Anyone who's ever tried to get python working on different
         | systems knows what a steep annoying curve it is.
         | 
         | The pseudo-shebang trick here isn't going to work on Windows
         | any more than a conventional one is. And no, when I switched
         | from Windows to Linux, getting my Python stuff to work was not
         | a "steep annoying curve" _at all_. It came more or less
         | automatically with acclimating to Linux in general.
         | 
         | (I guess referring to ".pyproject" instead of the actually-
         | meaningful `pyproject.toml` is just part of the trolling.)
        
           | kstrauser wrote:
           | > Third, virtual environments are literally just a place on
           | disk for those dependencies
           | 
           | I had a recent conversation with a colleague. I said how nice
           | it is using uv now. They said they were glad because they
           | hated messing with virtualenvs so much that preferred
           | TypeScript now. I asked them what node_modules is, they
           | paused for a moment, and replied "point taken".
           | 
           | Uv still uses venvs because it's the official way Python
           | stores all the project packages in one place. Node/npm,
           | Go/go, and Rust/cargo all do similar things, but I only
           | really here people grousing about Python's version, which as
           | you say, you can totally ignore and never ever look at.
        
             | zahlman wrote:
             | From my experience, it seems like a lot of the grousing is
             | from people who don't like the "activation script" workflow
             | and mistakenly think it's mandatory. Though I've also seen
             | aesthetic objections to the environment actually having
             | internal structure rather than just being another `site-
             | packages` folder (okay; and what are the rules for telling
             | Python to use it?)
             | 
             | The _very_ long discussion
             | (https://discuss.python.org/t/pep-582-python-local-
             | packages-d...) of PEP 582
             | (https://peps.python.org/pep-0582/ ; the "__pypackages__"
             | folder proposal) seems relevant here.
        
               | kstrauser wrote:
               | I've heard those objections, too. I do get that specific
               | complaint: it's another step you have to do. That said,
               | things like direnv and mise make that disappear. I
               | personally like the activation workflow and how explicit
               | it is, as you're activating that specific venv, or maybe
               | one in a different location if you want to use that
               | instead. I don't like sprinkling "uv run ..." all over
               | the place. But the nice part is that both of those work,
               | and you can pick whichever one you prefer.
               | 
               | It'll be interesting to see how this all plays out with
               | __pypackages__ and friends.
        
               | zahlman wrote:
               | > But the nice part is that both of those work, and you
               | can pick whichever one you prefer.
               | 
               | Yep. And so does the pyenv approach (which I understand
               | involves _permanently_ adding a _relative_ path to $PATH,
               | wherein the system might place a stub executable that
               | invokes the venv associated with the current working
               | directory).
               | 
               | And so do hand-made subshell-based approaches, etc. etc.
               | 
               | In "development mode" I use my activation-script-based
               | wrappers. When just hacking around I generally just give
               | the path to the venv's python explicitly.
        
               | kstrauser wrote:
               | I use your "hacking around" method for things like cron
               | jobs, with command lines like:                 * * * * *
               | /path/to/project/.venv/python /path/to/project/foo.py
               | 
               | It's more typing one time, but avoids a whole lot of
               | fragility later.
        
         | JodieBenitez wrote:
         | you don't even need you prefered python version, uv will
         | download it.
        
         | the__alchemist wrote:
         | I solved this in 2019 with PyFlow, but no one used it, so I
         | lost interest. It's an OSS tool written in rust that
         | automatically and transparently manages python versions and
         | venvs. You just setup a `pyproject.toml`, run `pyflow main.py`
         | etc, and it _just works_. Installs and locks dependencies like
         | Cargo, installs and runs the correct Python version for the
         | project etc.
         | 
         | At the time, Poetry and Pipenv were the popular tools, but I
         | found they were not sufficient; they did a good job abstracting
         | dependencies, but not venvs and Python version.
        
           | greensh wrote:
           | sounds awesome. Just out of interest, why do you think pyflow
           | didn't catch on, but UV did?
        
             | the__alchemist wrote:
             | My best guess: I'm bad at marketing, and gave up too soon.
             | The feedback I received was generally "Why would I use this
             | when Pip, Pipenv and Poetry work fine?". To me they didn't;
             | they were a hassle due to not handling venvs and Py
             | versions, but I didn't find many people to also have had
             | the same problem.
        
             | the_mitsuhiko wrote:
             | Polish and that uv gets you entire python interpreters
             | automatically without having to compile or manually install
             | them.
             | 
             | That in retrospective was what made rye temporarily
             | attractive and popular.
        
       | magicalhippo wrote:
       | You can do the same[1] with .Net Core for those of us who like
       | that.
       | 
       | [1]: https://learn.microsoft.com/en-
       | us/dotnet/csharp/fundamentals...
        
         | rr808 wrote:
         | dotnet was always really good for this. There were a bunch of
         | third party tools that have done this since the 90s like
         | toolsack.
         | 
         | I think Java can run uncompiled text scripts now too
        
         | zahlman wrote:
         | That's explicit support rather than using the same // hack. The
         | language is specifically ignoring a shebang even though it
         | doesn't match the usual comment syntax.
        
       | PaulRobinson wrote:
       | Mad genius stuff, this.
       | 
       | However... scripting requires (in my experience), a different
       | ergonomic to shippable software. I can't quite put my finger on
       | it, but bash feels very scriptable, go feels very shippable,
       | python is somewhere in the middle, ruby is closer to bash, rust
       | is up near go on the shippable end.
       | 
       | Good scripting is a mixture of OS-level constructs available to
       | me in the syntax I'm in (bash obviously is just using OS commands
       | with syntactic sugar to create conditional, loops and variables),
       | and the kinds of problems where I don't feel I need a whole lot
       | of tooling: LSPs, test coverage, whatever. It's languages that
       | encourage quick, dirty, throwaway code that allows me to get that
       | one-off job done the guy in sales needs on a Thursday so we can
       | close the month out.
       | 
       | Go doesn't feel like that. If I'm building something in Go I want
       | to bring tests along for the ride, I want to build a proper build
       | pipeline somewhere, I want a release process.
       | 
       | I don't think I've thought about language ergonomics in this
       | sense quite like this before, I'm curious what others think.
        
         | dingdingdang wrote:
         | Talking about Python "somewhere in the middle" - I had a demo
         | of a simple webview gtk app I wanted to run on vanilla Debian
         | setup last night.. so I did the canonical-thing-of-the-month
         | and used uv to instantiate a venv and pull the dependencies.
         | Then attempted to run the code.. mayhem. Errors indicating that
         | the right things were in place but that the code still couldn't
         | run (?) and finally Python Core Dumped.. OK. This is (in some
         | shape or form) what happens every single time I give Python a
         | fresh go for an idea. Eventually Golang is more verbose (and I
         | don't particularly like the mod.go system either) but once
         | things compile.. they run. They don't attempt running or
         | require xyz OS specific hack.
        
           | logicallee wrote:
           | I haven't had the same issue with anaconda. Give it a try.
        
             | dns_snek wrote:
             | I've had similar issues with anaconda, once upon a time.
             | I've hit a critical roadblock that ruined my day with every
             | single Python dependency/environment tool except basic venv
             | + requirements.txt, I think. That gets in the way the least
             | but it's also not very helpful, you're stuck with
             | requirements.txt which tends to be error-prone to manage.
        
           | zelphirkalt wrote:
           | How were the dependencies specified? What kind of files were
           | provided for you to instantiate the venv?
        
           | fireflash38 wrote:
           | Gtk makes that simple python program way more complex since
           | it'll need more than pure-python dependencies.
           | 
           | It's really a huge pain point in python. Pure python
           | dependencies are amazingly easy to use, but there's a lot of
           | packages that depend on either c extensions that need to be
           | built or have OS dependencies. It's gotten better with wheels
           | and manylinux builds, but you can still shoot your foot off
           | pretty easily.
        
           | skeledrew wrote:
           | I'm pretty sure the gtk dependencies weren't built by Astral,
           | which, yes, unfortunately means that it won't always just
           | work, as they streamline their Python builds in... unusual
           | ways. A few months ago I had a similar issue running a
           | Tkinter project with uv, then all was well when I used conda
           | instead.
        
         | cl3misch wrote:
         | > bash obviously is just using OS commands with syntactic sugar
         | 
         | No, bash is technically not "more" OS than e.g. Python. It just
         | happens that bash is (often) the default shell in the terminal
         | emulator.
        
           | xg15 wrote:
           | Have to disagree, "technically" yes, both are interpreted
           | languages, but the ergonomics and mental overhead of doing
           | certain things are wildly different:
           | 
           | In python, doing math or complex string or collection
           | operations is usually a simple oneliner, but calling shell
           | commands or other OS processes requires fiddling with the
           | subprocess module, writing ad-hoc streaming loops, etc -
           | don't even start with piping several commands together.
           | 
           | Bash is the opposite: As long as your task can be structured
           | as a series of shell commands, it absolutely shines - but as
           | soon as you require custom data manipulation in any form,
           | you'll run into awkward edge cases and arbitrary restrictions
           | - even for things that are absolutely basic in other
           | languages.
        
             | t43562 wrote:
             | The subprocess module is horrendous but even if it was
             | great bash is simpler. I just think about trying to create
             | a pipe of processes in python without the danger of
             | blocking.
        
             | nr378 wrote:
             | > In python, ..., calling shell commands or other OS
             | processes requires fiddling with the subprocess module,
             | writing ad-hoc streaming loops, etc - don't even start with
             | piping several commands together.
             | 
             | You inspired me to throw something simpler together -
             | https://pypi.org/project/shell-pilot/
        
           | skeledrew wrote:
           | I love Python and dislike Bash, but just look at the
           | difference between listing a folder in Bash vs Python, for
           | example.
        
             | DrewADesign wrote:
             | Right. Figure out if other users are logged in using
             | Python. Get a human-readable remaining space on each
             | partition.
             | 
             | It's not like you _can't_ do in Python, but it's a whole
             | lot more work than typing  <10 characters directly into
             | shell.
        
         | skybrian wrote:
         | Maybe the ergonomics of _writing_ code is less of a problem if
         | you have a quick way of asking an LLM to do the edits? We can
         | optimize for readability instead.
         | 
         | More specifically, for the readability of code written by an
         | LLM.
        
         | pragma_x wrote:
         | I know what you mean.
         | 
         | For me, the dividing line is how compact the language
         | representation is, specifically if you can get the job done in
         | one file or not.
         | 
         | I have no doubt that there's a lot of Go jobs that will fit in
         | a 500 line script, no problem. But the language is much more
         | geared towards modules of many files that all work together to
         | design user-defined types, multi-threading, and more. None of
         | that's a concern for BASH, with Python shipping enough native
         | types to do most jobs w/o need for custom ones.
         | 
         | If you need a whole directory of code to make your bang-line-
         | equipped Go script work, you may as well compile that down and
         | install it to /usr/local/bin.
         | 
         | Also the lack of bang-line support in native Go suggests that
         | everyone is kinda "doing it wrong". The fact that `go run` just
         | compiles your code to a temporary binary anyway, points in that
         | direction.
        
           | dolmen wrote:
           | I think there is still space for an alternate Go syntax for
           | scripting with the following constraints:
           | 
           | * a single file exposing a "main" package and its "func
           | main()"
           | 
           | * import syntax that merges requires from go.mod (import both
           | packages and modules)
           | 
           | * simplified error handling (just ignore returned errors in
           | code, and they are caught by the transpiler to be handled as
           | fatal)
           | 
           | Those are my ideas to go beyond my own goeval that already
           | allows to run Go oneliners. https://github.com/dolmen-
           | go/goeval
        
       | solumos wrote:
       | > I started this post out mostly trolling, but the more I've
       | thought about it's not a terrible idea.
       | 
       | I feel like this is the unofficial Go motto, and it almost always
       | ends up being a terrible idea.
        
         | hu3 wrote:
         | for more terrible ideas in 2026 then!
        
       | chrismorgan wrote:
       | One suggestion: change `exit` to `exit $?` so an exit code is
       | passed back to the shell.
        
       | emersion wrote:
       | The following would probably be more portable:
       | ///usr/bin/env go run "$0" "$@"; exit
       | 
       | Note, the exit code isn't passed through due to:
       | https://github.com/golang/go/issues/13440
        
         | incognito124 wrote:
         | To quote the blog in question:
         | 
         | > How true this is, is a topic I dare not enter.
        
           | loosescrews wrote:
           | The blog says that in regard to finding bash with env. My
           | reading is that it does not make the same claim regarding
           | finding go with env. bash is commonly found at /bin/bash (or
           | a symlink there exists) as it is widely used in scripts and
           | being available at that path is a well known requirement for
           | compatibility. Go does not so much have a conical path and I
           | have personally installed it at a variety of paths over the
           | years (with the majority working with env). While I agree
           | with the author of the blog that using env to find bash may
           | or may not improve compatibility, I also agree with the
           | parent comment that using env to find go probably does
           | improve compatibility.
        
         | zahlman wrote:
         | Does the third leading slash do something?
        
           | emersion wrote:
           | No, it just felt a tad cleaner to have the comment slashes
           | separate from the path leading slash.
        
       | flufluflufluffy wrote:
       | I don't really understand the initial impetus. I _like_ scripting
       | in Python. That's one of the things it's good at. You can
       | extremely quickly write up a simple script to perform some task,
       | not worrying about types, memory, yada yada yada. I _don't like_
       | using Python as the main language for a large application.
        
         | graemep wrote:
         | It seems to be Linux specific (does it even work on other unix
         | like OSes?) and Linux usually has a system Python which is
         | reasonably stable for things you need scripting for, whereas
         | this requires go to be installed.
         | 
         | You could also use shell scripting or Python or another
         | scripting language. While Python is not great at backward
         | compatibility most scripts will have very few issues. Shell
         | scripts are backward compatible as are many other scripting
         | languages are very backward compatible (e.g. TCL) and they areG
         | more likely to be preinstalled. If you are installing Go you
         | could just install uv and use Python.
         | 
         | The article does say "I started this post out mostly trolling"
         | which is part of it, but mostly the motivation would be that
         | you have a strong preference for Go.
        
         | mr_toad wrote:
         | I love scripting in Python too. I just hate trying to install
         | other people's scripts.
        
           | flanked-evergl wrote:
           | If they use https://packaging.python.org/en/latest/specificat
           | ions/inline... then it becomes a breeze to run with uv. Not
           | even a thing.
        
             | hu3 wrote:
             | but then you need uv
             | 
             | it's not as portable
        
               | networked wrote:
               | Inline script metadata itself is not tied to uv because
               | it's a Python standard. I think the association between
               | the two comes from people discovering ISM through uv and
               | from their simultaneous rise.
               | 
               | pipx can run Python scripts with inline script metadata.
               | pipx is implemented in Python and packaged by Linux
               | distributions, Free/Net/OpenBSD, Homebrew, MacPorts, and
               | Scoop (Windows):
               | https://repology.org/project/pipx/versions.
        
               | zahlman wrote:
               | Yes, many things can use inline script metadata.
               | 
               | But a script only has one shebang.
        
               | networked wrote:
               | Perhaps a case for standardizing on an executable name
               | like `python-script-runner` that will invoke uv, pipx,
               | etc. as available and preferred by the user. Scripts with
               | inline metadata can put it in the shebang line.
               | 
               | I see it has been proposed:
               | https://discuss.python.org/t/standardized-shebang-for-
               | pep-72....
        
               | zahlman wrote:
               | I get the impression that others didn't really understand
               | your / the OP's idea there. You mean that the user should
               | locally configure the machine to ensure that the
               | standardized name points at something that can solve the
               | problem, and then accepts the quirks of that choice, yes?
               | 
               | A lot of people seem to describe a PEP 723 use case where
               | the recipient maybe doesn't even know what Python is (or
               | how to check for a compatible version), but could be
               | instructed to install uv and then copy and run the
               | script. This idea would definitely add friction to that
               | use case. But I think in those cases you really want to
               | package a standalone (using PyInstaller, pex, Briefcase
               | or any of countless other options) anyway.
        
               | networked wrote:
               | > You mean that the user should locally configure the
               | machine to ensure that the standardized name points at
               | something that can solve the problem, and then accepts
               | the quirks of that choice, yes?
               | 
               | I was thinking that until I read the forum thread and
               | Stephen Rosen's comments. Now I'm thinking the most
               | useful meta-runner would just try popular runners in
               | order.
               | 
               | I have put up a prototype at
               | https://github.com/dbohdan/python-script-runner.
        
               | zahlman wrote:
               | Neat. Of course it doesn't have much value unless it's
               | accepted as a standard and ships with Python ;) But I
               | agree with your reasoning. Might be worth reviving that
               | thread to talk about it.
        
           | zahlman wrote:
           | > I just hate trying to install other people's scripts.
           | 
           | This notion is still strange to me. Just... incompatible with
           | how I understand the term "script", I guess.
        
             | Brian_K_White wrote:
             | You don't understand the concept of people running software
             | written by other people?
             | 
             | One of my biggest problems with python happens to be caused
             | by the fact that a lot of freecad is written in python, and
             | python3 writes _pycache_ directories everywhere a script
             | executes (which means everywhere, including all over the
             | inside of all my git repos, so I have to add _pycache_ to
             | all the .gitignore ) and the env variable that is supposed
             | to disable that STUPID behavior has no effect because
             | freecad is an appimage and my env variable is not
             | propagating to the environment set up by freecad for
             | itself.
             | 
             | That is me "trying to install other people's scripts" the
             | other people's script is just a little old thing called
             | FreeCAD, no big.
        
               | zahlman wrote:
               | > That is me "trying to install other people's scripts"
               | the other people's script is just a little old thing
               | called FreeCAD, no big.
               | 
               | What I don't understand is why you call it a "script".
               | 
               | > and python3 writes _pycache_ directories everywhere a
               | script executes (which means everywhere, including all
               | over the inside of all my git repos, so I have to add
               | _pycache_ to all the .gitignore )
               | 
               | You're expected to do that anyway; it's part of the
               | standard "Python project" .gitignore files offered by
               | many sources (including GitHub).
               | 
               | But you mean that the repo contains plugins that FreeCAD
               | will import? Because otherwise I can't fathom why it's
               | executing .py files that are within your repo.
               | 
               | Anyway, this seems like a very tangential rant. And this
               | is essentially the same thing as Java producing .class
               | files; I can't say I run into a lot of people who are
               | this bothered by it.
        
           | enriquto wrote:
           | > hate trying to install other people's scripts.
           | 
           | This phrasing sounds contradictory to me. The whole idea of
           | scripts is that there's nothing to install (besides one
           | standard interpreter). You just _run_ them.
        
             | lucb1e wrote:
             | By that logic, you don't _install_ an OS, you just put the
             | bootloader and other supporting files on your storage
             | medium of choice and run it
        
         | Kuinox wrote:
         | You do have to worry about types, you always do. You have to
         | know, what did this function return, what can you do with it.
         | 
         | When you know well the language, you dont need to search for
         | this info for basic types, because you remember them.
         | 
         | But that's also true for typed languages.
        
           | phantasmish wrote:
           | This is more than just trivially true for Python in a
           | scripting context, too, because it doesn't do things like
           | type coercion that some other scripting languages do. If you
           | want to concat an int with a string you'll need to cast the
           | int first, for example. It also has a bunch of list-ish and
           | dict-ish built in types that aren't interchangeable. You have
           | to "worry about types" more in Python than in some of its
           | competitors in the scripting-language space.
        
         | Brian_K_White wrote:
         | Python is great for the coder, and unholy garbage for everyone
         | else.
         | 
         | If you care about anyone but yourself, don't write things in
         | python for other people to distribute, install, integrate, run,
         | live with.
         | 
         | If you don't care about anyone else, enjoy python.
        
           | wiseowise wrote:
           | Nonsense.
        
         | andoando wrote:
         | I just don't get how JS is any worse as a scripting language.
         | 
         | bla bla bla
         | 
         | node bla.js
        
           | wiseowise wrote:
           | It's not worse, but Python has better batteries out of the
           | box. Toml, csv, real multi-threading (since 3.13),
           | rudimentary gui, much better repl (out of the box and
           | excellent, installable ipython), argparse and a lot more.
        
       | jas39 wrote:
       | May I...
       | 
       | augroup fix autocmd! autocmd BufWritePost *.go \ if getline(1)
       | =~# '^// usr/bin/' \ | call setline(1, substitute(getline(1),
       | '^// ', '//', '')) \ | silent! write \ | endif augroup END
        
       | rtpg wrote:
       | You don't even need to end the file in `.go` or the like when
       | using shebangs, and any self-respecting editor will be good at
       | parsing out shebangs to identify file types (... well, Emacs
       | seems to do it well enough for me)
       | 
       | no need to name your program foo.go when you could just name it
       | foo
        
         | kbolino wrote:
         | The `go run` tool will not execute (or even recognize) a file
         | that does not end in .go, so this is not good advice.
        
       | flanked-evergl wrote:
       | Using `uv` with python is significantly safer and better. At
       | least you get null safety. Sure, you can't run at the speed of
       | light, but at least you can have some decent non-halfarsed-
       | retrofitted type checking in your script.
        
         | tgv wrote:
         | I think you're mistaking Go for some other language.
        
         | kbolino wrote:
         | In what way does Python have more null safety than Go? Using
         | None will cause exceptions in basically all the same places
         | using nil will cause panics in Go, and Python similarly lacks
         | the usual null-safe operators like traversal (?.), coalescing
         | (??), etc.
         | 
         | You can _abuse_ the falsity of None to do things like `var or
         | ""`, but this ground gets quite shaky when real bools get
         | involved.
        
       | api wrote:
       | Tangent but... I kinda like the Python language. What I don't
       | like about Python is the way environments are managed.
       | 
       | This is something I generally believe, but I think it's
       | particularly important for things like languages and runtimes:
       | the idea of installing things "on" the OS or the system needs to
       | die.
       | 
       | Per-workspace or per-package environment the way Go, Rust, etc.
       | does it is correct. Installing packages globally is wrong.
       | 
       | There should not be such a thing as "globally." Ideally the
       | global OS should be immutable or nearly so, with the only
       | exception being maybe hardware driver stuff.
       | 
       | (Yes I know there's stuff like conda, but that's yet another
       | thing to fix a fundamentally broken paradigm.)
        
         | zahlman wrote:
         | > This is something I generally believe, but I think it's
         | particularly important for things like languages and runtimes:
         | the idea of installing things "on" the OS or the system needs
         | to die.
         | 
         | Python has been trying to kill it for years; or at least, the
         | Linux distros have been seeking Python's help in killing it on
         | Linux for years. https://peps.python.org/pep-0668/ is the
         | latest piece of this.
        
           | api wrote:
           | I feel like this principle could be codified as "the system
           | is not a workspace."
           | 
           | The use of the system as a workspace goes back to when
           | computers were either very small and _always_ personal only
           | to one user, or when they were very big and administrated by
           | dedicated system administrators who were the only ones with
           | permission to install things. Both these conditions are
           | obsolete.
        
             | NetMageSCW wrote:
             | But the system is not a workspace acts like resources are
             | free. Everything that's wrong with a modern computer being
             | slower than one from 30 years ago at running user
             | applications has its roots in this kind of thing. It's more
             | obvious on mobile devices but desktops still suffer.
             | Android needs more RAM and had worse power utilization
             | until a lot was done to move toward native compiled code
             | and background process control. Meanwhile Electron apps
             | think it's okay to run multiple copies of Javascript
             | environments like working RAM is free and performance isn't
             | hurt.
        
               | kstrauser wrote:
               | Perhaps, but that's not really relevant here. Python's
               | virtualenvs wouldn't increase RAM usage any more than
               | using the system-wide environment.
        
       | avidphantasm wrote:
       | Now try to call some C++ code from your Go script...
        
         | dana321 wrote:
         | Rust can do that
        
       | xg15 wrote:
       | So the entire reason why this is not a "real" shebang and instead
       | takes the roundtrip through the shell is because the Go runtime
       | would trip over the # character?
       | 
       | I think this points to some shortcomings of the shebang mechanism
       | itself: That it expects the shebang line to be present and
       | adhering a specific structure - but then passes the entire file
       | _with_ the line to the interpreter where the interpreter has to
       | process (and hopefully ignore) the line again.
       | 
       | I know that situations where one piece of text is parsed by
       | multiple different systems are intellectually interesting and
       | give lots of opportunities for cleverness - but I think the
       | straightforward solution would be to avoid such situations.
       | 
       | So maybe the linux devs should consider adding a new form for the
       | shebang where the first line is just stripped before passing the
       | file contents to the interpreter.
        
         | wyufro wrote:
         | It doesn't pass the file contents at all, it passes the file
         | path.
        
           | kbolino wrote:
           | Yep, this is a common misunderstanding, and the blog post
           | itself repeats it.
           | 
           | The only way to "pass the file contents" would be through the
           | standard input stream, but the script might want to use stdin
           | like normal, so this isn't an option.
        
         | eichin wrote:
         | Linux already did one better: binfmt_misc (see
         | https://blog.cloudflare.com/using-go-as-a-scripting-language...
         | for using it for a much cleaner way of using it to use gorun on
         | executable *.go files.)
        
       | esjeon wrote:
       | Expected a rant, got a life-pro-tip. Enough for a good happy new
       | year.
       | 
       | That said, we can abuse the same trick for any languages that
       | treats `//` as comment.
       | 
       | List of some practical(?) languages: C/C++, Java, JavaScript,
       | Rust, Swift, Kotlin, ObjC, D, F#, GLSL/HLSL, Groovy
       | 
       | Personally, among those languages, GLSL sounds most interesting.
       | A single-GLSL graphics demo is always inspiring. (Something like
       | https://www.shadertoy.com/ )
       | 
       | Also, let's not forget that we can do something similar using
       | block comment(`/* ... */`). An example in C:
       | 
       | /*/../usr/bin/env gcc "$0" "$@"; ./a.out; rm -vf a.out; exit; */
       | 
       | #include <stdio.h>
       | 
       | int main() { printf("Hello World!\n"); return 0; }
        
         | frizlab wrote:
         | For Swift there's even a project[1] that allows running scripts
         | that have external dependencies (posting the fork because the
         | upstream is mostly dead).
         | 
         | I think it's uv's equivalent, but for Swift.
         | 
         | (Also Swift specifically supports an actual shebang for Swift
         | scripts.)
         | 
         | [1] https://github.com/xcode-actions/swift-sh
        
         | kibwen wrote:
         | You don't need to abuse comments like this for Rust, because it
         | supports shebangs directly.
        
         | thechao wrote:
         | For C/++ just use "#!". When TCC first came out, we used this
         | exact technique for "C scripting". It requires a dirty SO
         | methodology (you can't really control linking well).
         | 
         | For larger projects (the exe), the shebang points to a C build
         | file, which when compiled, knows the root path; that C build
         | script then looks for a manifest, builds, links, and fork()s. A
         | good a/m timestamp library with direct ccache support can spin
         | up as fast as a script even on big projects.
         | 
         | Again, this is all a bad idea bc it's hard to control your
         | environment.
         | 
         | I guess we were doing all this in the mid 2000s? When did TCC
         | come out?
        
       | networked wrote:
       | You can use https://github.com/erning/gorun as a Go script
       | runner. It lets you embed `go.mod` and `go.sum` and have
       | dependencies in Go scripts. This is more verbose than Python's
       | inline script metadata and requires manual management of
       | checksums. gorun caches built binaries, so scripts start quickly
       | after the first time.
       | 
       | Example:                 #! /usr/bin/env gorun       //       //
       | go.mod >>>       // module foo       // go 1.22       // require
       | github.com/fatih/color v1.16.0       // require
       | github.com/mattn/go-colorable v0.1.13       // require
       | github.com/mattn/go-isatty v0.0.20       // require
       | golang.org/x/sys v0.14.0       // <<< go.mod       //       //
       | go.sum >>>       // github.com/fatih/color v1.16.0
       | h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=       //
       | github.com/fatih/color v1.16.0/go.mod
       | h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=       //
       | github.com/mattn/go-colorable v0.1.13
       | h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=       //
       | github.com/mattn/go-colorable v0.1.13/go.mod
       | h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=       //
       | github.com/mattn/go-isatty v0.0.16/go.mod
       | h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=       //
       | github.com/mattn/go-isatty v0.0.20
       | h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=       //
       | github.com/mattn/go-isatty v0.0.20/go.mod
       | h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=       //
       | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod
       | h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=       //
       | golang.org/x/sys v0.6.0/go.mod
       | h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=       //
       | golang.org/x/sys v0.14.0
       | h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=       //
       | golang.org/x/sys v0.14.0/go.mod
       | h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=       // <<<
       | go.sum            package main            import
       | "github.com/fatih/color"            func main() {
       | color.Green("Hello, world!")       }
       | 
       | The shebang line can be replaced for compatibility with standard
       | Go tooling:                 /// 2>/dev/null ; gorun "$0" "$@" ;
       | exit $?       //       // go.mod >>>       // ...
        
         | karel-3d wrote:
         | I was looking for something like this a few times! great
        
       | liveoneggs wrote:
       | what's even cooler is when the language comes with first class
       | support for this: https://www.erlang.org/docs/18/man/escript
       | 
       | Or the venerable https://babashka.org/
        
       | g947o wrote:
       | While you are at it, might as well do this for C++ or assembly.
       | You hate scripting so much and would rather go to great lengths
       | to use a complied language and throw away all the benefits of a
       | scripting language and scripting itself, just because you don't
       | like the language, not because of technical merit.
       | Congratulations, you just wasted yourself many hours of precious
       | time.
       | 
       | > The price of convenience is difficulties to scale
       | 
       | Of course, they never scale. The moment you start thinking about
       | scaling, you should stop writing code as throwaway scripts but
       | build them properly. That's not an argument to completely get rid
       | of Python or bash. The cost of converting Python code to Go is
       | near zero these days _if there is a need to do so_. Enough has
       | been said about premature optimization.
       | 
       | > Anyone who's ever tried to get python working on different
       | systems knows what a steep annoying curve it is.
       | 
       | If you need 10 libraries of certain versions to run a few lines
       | of Python code, nobody calls that a script anymore. It becomes a
       | proper project that requires proper package management, _just
       | like Go_.
        
         | BobbyJo wrote:
         | There is a much larger gap in language ergonomics between
         | python and C++ than between python and golang. Compile time and
         | package management being some of the major downsides to C++.
         | 
         | "You'd rather drive a compact car than an SUV? Might as well
         | drive a motorcycle then!"
        
         | array_key_first wrote:
         | The main problem with python for system scripts is that's even
         | in that domain it's not a very good choice.
         | 
         | Perl is right there, requires no installation, and is on
         | practically every unix-like under the sun. Sure it's not a good
         | language, or performant, or easy to extend, but neither is
         | python, so who cares. And, if anything, it's a bit more
         | expressive and compact than python, maybe to a fault.
        
       | rubymamis wrote:
       | What about Mojo?
        
         | lgas wrote:
         | What about it?
        
       | marifjeren wrote:
       | > don't want to have virtual environments and learn what the
       | difference between pip, poetry and uv is
       | 
       | Oh come on, it's easy:
       | 
       | Does the project have a setup.py? if so, first run several other
       | commands before you can run it. python -m venv .venv && source
       | .venv/bin/activate && pip install -e .
       | 
       | else does it have a requirements.txt? if so python -m venv .venv
       | && source .venv/bin/activate && pip install -r requirements.txt
       | 
       | else does it have a pyproject.toml? if so poetry install and then
       | prefix all commands with poetry run ...
       | 
       | else does it have a pipfile? pipenv install and then prefix all
       | commands with pipenv run ...
       | 
       | else does it have an environment.yml? if so conda env create -f
       | environment.yml and then look inside the file and conda activate
       | <environment_name>
       | 
       | else does it have a uv.ock? then uv sync (or uv pip install -e .)
       | and then prefix commands with uv run.
        
         | 9dev wrote:
         | And you consider that easy?
        
           | marifjeren wrote:
           | No, I'm being cheeky. It's not fun. It's a "15 standards"
           | situation https://xkcd.com/927/
        
         | zahlman wrote:
         | > Oh come on, it's easy: (satire)
         | 
         | If you've checked out a repo or unpacked a tarball without
         | documentation, sure.
         | 
         | If you got it from PyPI or the documentation indicates you can
         | do so, then you just use your tooling of choice.
         | 
         | Also, the pip+venv approach works fine with pyproject.toml,
         | which was designed for interoperability. Poetry is oriented
         | towards your own development, not working with someone else's
         | project.
         | 
         | Speaking of which, a project that has a pipfile,
         | environment.yml, uv.lock etc. _and doesn 't have
         | pyproject.toml_ is not being seriously distributed. If this is
         | something internal to your team, then you should already know
         | what to do anyway.
        
           | NetMageSCW wrote:
           | Any time you have to resort to the no true scotsman fallacy
           | you are telling me everything I need to know to run in the
           | other direction.
        
             | zahlman wrote:
             | It is not "no true scotsman" to point out that tons of
             | projects are put on GitHub etc. without caring about
             | whether others will actually be able to download and
             | "install" and use the code locally, and that it's
             | unreasonable to expect ecosystems to handle those cases by
             | magic. To the extent that a Python ecosystem exists and
             | people understand development within that ecosystem, the
             | expectations for packaging are clear and documented and
             | standard.
             | 
             | Acting as if these projects using whatever custom tool (and
             | its associated config, by which the tool can be inferred),
             | where that tool often isn't even advertised as an end-user
             | package installer, are legitimate distributions is
             | dishonest; and acting as if it reflects poorly on Python
             | that this is possible, far more so. Nothing prevents anyone
             | from creating a competitor to npm or Cargo etc.
        
       | itopaloglu83 wrote:
       | > Sidetrack: I actually looked up what the point of arg0 even is
       | since I failed to find any usecases some months back and found
       | this answer.
       | 
       | I think arg0 was always useful especially when developing
       | multifunctional apps like busybox that changes its behavior
       | depending on the name it was executed as.
        
       | fsmv wrote:
       | I made one of these too! I decided not to use // because I use
       | gofmt auto formatting in my editor and it puts a space between
       | the // and the usr. This one isn't changed by gofmt:
       | /*?sr/bin/env go run "$0" "$@"; exit $? #*/
        
         | tandr wrote:
         | It works, but the best in me I cannot explain fully first 3
         | symbols. /*?sr/bin/env finds /usr by expanding *? to a first
         | matching directory. But why not just /*usr/ instead?
        
       | jxbdbrhcb wrote:
       | argv0 is very necessary for use cases like busybox
        
       | petercooper wrote:
       | Cute trick! I pointlessly wondered if I could make it work with
       | Ruby and you _kinda_ can, if you can tolerate a single error
       | message before the script runs (sadly # comments don 't work as
       | shells consider them comments too):                   =begin
       | ruby $0; exit         =end              puts "Hello from Ruby"
       | 
       | Not immediately useful, but no doubt this trick will pop up at
       | some random moment in the future and actually be useful. Very
       | basic C99 too, though I'm not sure I'd want to script with it(!):
       | //usr/bin/cc $0 && ./a.out && exit
        
       | Zababa wrote:
       | >This second method is, by the way, argued to increase
       | compatibility as we utilize env to locate bash, which may not be
       | located at /bin/bash. How true this is, is a topic I dare not
       | enter.
       | 
       | At least it seems important on NixOS, I had to rewrite a few
       | shebangs on some scripts that used /bin/bash and didn't work on
       | NixOS.
        
         | benchloftbrunch wrote:
         | And on macOS if you need bash > 3.2
        
       | codelikeawolf wrote:
       | > Did you (rightfully) want to tear your eyes out when some LLM
       | suggested that you script with .mjs?
       | 
       | I respectfully disagree with this sentiment. JS is a fantastic
       | Python replacement for scripts. Node.js has added all kinds of
       | utility functions that help you write scripts without needing
       | external dependencies. Bun, Deno, and Node.js can execute TS
       | files (if you want to bring types into the mix). All 3 runtimes
       | are sufficiently performant. If you do end up needing external
       | dependencies, they're only a package.json away. I write all my
       | scripts in JS files these days.
        
       | chrisweekly wrote:
       | Related tangent: I recently learned about Mise^1 -- a tool for
       | managing multiple language runtime versions. It might ease some
       | of the python environment setup/mgmt pains everyone complains
       | about. It apparently integrates with uv, and can do automatic
       | virtualenv activation....
       | 
       | 1. https://mise.jdx.dev/lang/python.html
       | 
       | via https://gelinjo.hashnode.dev/you-dont-need-nvm-sdkman-
       | pyenv-...
        
       | bushbaba wrote:
       | This is great. Means my scripts in a golang repo can also be
       | written in Golang vs bash/python. It can even import libs from my
       | project.
       | 
       | Awesome!
        
       | arccy wrote:
       | i tried this and security pinged me about behavior based security
       | rules firing because it looks like an infostealer...
        
       | forgotpwd16 wrote:
       | Go has explicitly rejected adding shebang support, mandating this
       | hack, due to being considered "abuse of resources"[0]. Rather
       | `gorun`, which is also called a mistake by Pike, is recommended
       | instead. And can alter this method so not to need to hardcode a
       | path.                   /// 2>/dev/null ; gorun "$0" "$@" ; exit
       | $?
       | 
       | >Good-old posix magic. If you ask an LLM, it'll say it's due to
       | Shebangs.
       | 
       | Well, ChatGPT gives same explanation as article, unsurprising
       | considering this mechanic has been repeated many times.
       | 
       | >none other fits as well as Go
       | 
       | Nim, Zig, D, all have `-run` argument and can be used in similar
       | way. Swift, OCaml, Haskell can directly execute a file, no need
       | to provide an argument.
       | 
       | [0]: https://groups.google.com/d/msg/golang-
       | nuts/iGHWoUQFHjg/_dbL...
        
         | clktmr wrote:
         | There is also yaegi, a Go interpreter, which might be a better
         | choice for small scripts than 'go run'.
         | 
         | https://github.com/traefik/yaegi
        
           | dolmen wrote:
           | Also, for Go oneliners: https://github.com/dolmen-go/goeval
           | 
           | (Disclaimer: author here)
        
       | dare944 wrote:
       | > I started this post out mostly trolling
       | 
       | So your goal was to waste your reader's time. Thanks.
        
       | trvv wrote:
       | You can lose the ugly "exit" at the end and space it right for
       | formatting too                   // 2>/dev/null; exec go run "$0"
       | "$@"
        
       | adonovan wrote:
       | > The one big problem: gopls. We need the first line of the
       | script to be without spaces...
       | 
       | Specifically the problem here is automated reformatting. Gopls
       | typically does this on save as you are editing, but it is good
       | practice for your CI system to enforce the invariant that all
       | merged *.go files are canonically formatted. This ensures that
       | the user who makes a change formats it (and is blamed for that
       | line), instead of the hapless next person to touch some other
       | spot in that file. It also reduces merge conflicts.
       | 
       | But there's a second big (bigger) problem with this approach: you
       | can't use a go.mod file in a one-off script, and that means you
       | can't specify versions of your dependencies, which undermines the
       | appeal to compatibility that motivated your post:
       | 
       | > The primary benefit of go-scripting is [...] and compatibility
       | guarantees. While most languages aims to be backwards compatible,
       | go has this a core feature. The "go-scripts" you write will not
       | stop working as long as you use go version 1.*, which is perfect
       | for a corporate environment.
       | 
       | > In addition to this, the compatibility guarantees makes it much
       | easier to share "scripts". As long as the receiving end has the
       | latest version of go, the script will run on any OS for tens of
       | years in the future.
        
         | kardianos wrote:
         | True, but major versions are locked in through the import path
         | and _should_ be compatible.
        
         | arccy wrote:
         | > which undermines the appeal to compatibility that motivated
         | your post
         | 
         | not really? this is about the language / core runtime rather
         | than any dependencies.
        
       | knodi wrote:
       | Yes, you can but should you?
        
       | sharno wrote:
       | You can also use jbang to run java scripts with dependencies
       | 
       | https://www.jbang.dev/
        
       | paulddraper wrote:
       | Go is poor for cheap scripts for one reason: error handling.
       | 
       | It's great for "robust" code, not for quick things that you're
       | okay with exploding in the default way.
        
       | df0b9f169d54 wrote:
       | See also https://blog.cloudflare.com/using-go-as-a-scripting-
       | language... and
       | https://gist.github.com/posener/73ffd326d88483df6b1cb66e8ed1... .
       | They explained the direct use of "go run" was not good in some
       | scenario. Is that still applied today?
       | 
       | > go run does not properly return the script error code back to
       | the operating system and this is important for scripts, because
       | error codes are one of the most common ways multiple scripts
       | interact with each other and the operating system environment.
        
       | evanmoran wrote:
       | In a similar way I changed all of my build and deployment scripts
       | to Go not long ago. The actual benefit was utility functions used
       | by the service could be shared in deployment. So I could easily
       | share code to determine if services/dbs were online or to access
       | cloud secrets in a uniform way. It also improved all the error
       | checks to be much clearer (did the curl fail because it's offline
       | or malformed).
       | 
       | Additionally, it is even more powerful when used with go modules.
       | Make every script call a single function in the shared "scripts"
       | module and they will all be callable from anywhere symmetrically.
       | This will ensure all scripts build even if they aren't run all
       | the time. It also means any script can call
       | scripts.DeployService(...) and they don't care what dir they are
       | in, or who calls it. The arguments make it clear what
       | paths/configuration is needed for each script.
        
       | fiyec30375 wrote:
       | I thought this was going to be a longer rant about how python
       | needs to... Go away. Which, as a long time python programmer and
       | contributor, and at one time avid proponent of the language, I
       | would entertain the suggestion. I think all of ML being in Python
       | is a collosal mistake that we'll pay for for years.
       | 
       | The main reasons being it is slow, its type system is
       | significantly harder to use than other languages, and it's hard
       | to distribute. The only reason to use it is inertia. Obviously
       | inertia can be sufficient for many reasons, but I would like to
       | see the industry consider python last, and instead consider
       | typescript, go, or rust (depending on use case) as a best
       | practice. Python would be considered deprecated and only used for
       | existing codebases like pytorch. Why would you write a web app in
       | Python? Types are terrible, it's slow. There are way better
       | alternatives.
        
         | krzyk wrote:
         | Typescript?
         | 
         | Why replace a nice language like python with anything coming
         | out of javascript?
        
           | christophilus wrote:
           | Typescript is a really nice language even though it sits on a
           | janky runtime. I'd love a subset of typescript that compiles
           | to Go or something like that.
        
             | polynomial wrote:
             | Isn't that what Project Corsa is supposed to solve?
        
               | nish__ wrote:
               | Project Corsa is a rewrite of the TypeScript compiler in
               | Go. I don't think that's what's being asked for.
        
           | fiyec30375 wrote:
           | Typescript is ubiquitous in web, and there are some amazing
           | new frameworks that reuse typescript types on the server and
           | client (trpc, tanstack). It's faster (than python), has
           | ergonomic types, and a massive community + npm ecosystem. Bun
           | advances the state of the art for runtime performance (which
           | anthropic just bought and use for Claude code).
        
             | bdangubic wrote:
             | Did you just write both:
             | 
             | > The only reason to use it is inertia
             | 
             | and
             | 
             | > Typescript is ubiquitous in web
             | 
             | :-)
        
               | sinkasapa wrote:
               | Those are both valid reasons to use both languages. The
               | "only" (whether true or not) is what the argument hinges
               | on. It is roughly the same as saying that the only
               | advantage of X is that it is popular, but Y is also
               | popular and has additional advantages, therefore, Y is
               | better than X. That is a valid argument, whether the
               | premises are true or not.
        
               | bdangubic wrote:
               | I do not disagree but if you are going to say that "X" is
               | only used because of "Y", maybe if you are pitching "Z"
               | instead of "X" do not start with the "Y" :)
        
               | Xeronate wrote:
               | Agree to disagree. He's setting up the argument that Z is
               | strictly better than X.
        
           | hu3 wrote:
           | TypeScript is great!
           | 
           | Has shortcomings like all languages but it brought a lot of
           | advanced programming language concepts to the masses!
        
           | IshKebab wrote:
           | Typescript is a lot nicer than Python in many ways.
           | Especially via Deno, and especially for scripting (imports
           | work like people want!).
           | 
           | There are some things that aren't as good, e.g. Python's
           | arbitrary precision integers are definitely nicer for
           | scripting. And I'd say Python's list comprehension syntax is
           | often quite nice even if it is weirdly irregular.
           | 
           | But overall Deno is a much better choice for ad-hoc scripting
           | than Python.
        
             | chpatrick wrote:
             | https://developer.mozilla.org/en-
             | US/docs/Web/JavaScript/Refe...
        
               | IshKebab wrote:
               | I am aware, but Python has that by default. In Javascript
               | it's opt-in and less ergonomic. E.g. try loading a 64-bit
               | integer from JSON.
        
               | josephg wrote:
               | I agree, but bigints are missing from json because the
               | json spec defines all numbers as 64 bit floats. Any other
               | kind of number in JSON is nonstandard.
               | 
               | JavaScript itself supports bigint literals just fine.
               | Just put an 'n' after your number literal. Eg
               | 0xffffffffffffffn.
               | 
               | There's a whole bunch of features I wish we could go in
               | and add to json. Like comments, binary blobs, dates and
               | integers / bigints. It would be so much nicer to work
               | with if it has that stuff.
        
               | IshKebab wrote:
               | > the json spec defines all numbers as 64 bit floats
               | 
               | It absolutely doesn't. It doesn't impose any limits on
               | number precision or magnitude.
        
           | chpatrick wrote:
           | Its type system is miles better than Python and it has some
           | basic stuff Python doesn't have like block scope. Functional
           | programming is also intentionally kind of a pain in Python
           | with the limited lambdas.
           | 
           | If TypeScript had the awesome python stdlib and the Numpy/ML
           | ecosystem I would use it over Python in a heartbeat.
        
             | tehjoker wrote:
             | you can define a named closure in python, i do it from time
             | to time, though it does seem to surprise others sometimes.
             | i think maybe it's not too common.
        
             | josephg wrote:
             | Typescript also has significantly better performance. This
             | is largely thanks to the browser wars funnelling an insane
             | amount of engineering effort toward JavaScript engines over
             | the last couple decades. Nodejs runs v8, which is the
             | JavaScript engine used by chrome. And Bun uses JSC, written
             | for safari.
             | 
             | For IO bound tasks, it also helps that JavaScript has a
             | much simpler threading model. And it ships an event based
             | IO system out of the box.
        
         | dkarl wrote:
         | I'd love to replace Python with something simple, expressive,
         | and strongly typed that compiles to native code. I have a habit
         | of building little CLI tools as conveniences for working with
         | internal APIs, and you wouldn't think you could tell a
         | performance difference between Go and Python for something like
         | that, but you can. After a year or so of writing these tools in
         | Go, I went back to Python because the LOC difference is stark,
         | but every time I run one of them I wish it was written in Go.
         | 
         | (OCaml is probably what I'm looking for, but I'm having a hard
         | time getting motivated to tackle it, because I dread dealing
         | with the tooling and dependency management of a 20th century
         | language from academia.)
        
           | fiyec30375 wrote:
           | I suppose you could try typescript which can compile to a
           | single binary using node or bun. Both bun and node do type
           | stripping of ts types, and can compile a cli to a single file
           | executable. This is what anthropic does for Claude code.
        
           | Hasnep wrote:
           | I bounced off OCaml a few years ago because of the state of
           | the tooling, despite it being almost exactly the language I
           | was looking for. I'm really happy with Gleam now, and
           | recommended it over OCaml for most use cases.
        
             | dkarl wrote:
             | I always assumed a runtime specialized for highly
             | concurrent, fault-tolerant, long-running processes would
             | have a noticeable startup penalty, which is one of the
             | things that bothers me about Python. Is that something you
             | notice with Gleam?
        
               | antsinmypants wrote:
               | I tried out Gleam for Advent of Code this year. There was
               | a significant difference in startup times, about 13 ms
               | for Python and 120 ms for Gleam.
               | 
               | If you want something with minimal startup times then you
               | need a language that complies to native binaries like
               | Zig, Rust or OCaml.
        
             | IshKebab wrote:
             | Can you use Gleam for ad-hoc scripting? In my mind that
             | means two requirements that most languages fail at.
             | 
             | 1. You can import by relative file path. (Python can't.)
             | 
             | 2. You can specify third party dependencies in a single
             | file script and _have that work properly with IDEs_.
             | 
             | Deno is the best option I've found that has both of those
             | and is statically typed.
             | 
             | I'm hoping Rust will eventually too but it's going to be at
             | least a year or two.
        
             | ZenoArrow wrote:
             | Did you consider using F#? The language is very similar to
             | OCaml, but it has the added benefit of good tooling and a
             | large package ecosystem (can use any .NET package).
        
           | eru wrote:
           | Yes, Go can hardly be called statically typed, when they use
           | the empty interface everywhere.
           | 
           | Yes, OCaml would be a decent language to look into. Or
           | perhaps even OxCaml. The folks over at Jane Street have put a
           | lot of effort into tooling recently.
        
             | jcgl wrote:
             | > Yes, Go can hardly be called statically typed, when they
             | use the empty interface everywhere.
             | 
             | How often are you using _any_ / _interface {}_? Yes,
             | sometimes it 's the correct solution to a problem, but it's
             | really not that common in my experience. Certainly not
             | common in ways that actually make life hard.
             | 
             | Also, since generics, I've been able to cut down my use of
             | the empty interface even further.
        
           | rangerelf wrote:
           | Have you tried Nim? Strong and static typed, versatile,
           | compiles down to native code via C, interops with C
           | trivially, has macros and stuff to twist your brain if you're
           | into that, and is trivially easy to get into.
           | 
           | https://nim-lang.org
        
             | dkarl wrote:
             | That looks very interesting. The code samples look like
             | very simple OO/imperative style code like Python. At first
             | glance it's weird to me how much common functionality
             | relies on macros, but it seems like that's an intentional
             | part of the language design that users don't mind? I might
             | give it a try.
        
           | archargelod wrote:
           | You can replace Python with Nim. It checks literally all your
           | marks (expressive, fast, compiled, strong-typing). It's as
           | concise as Python, and IMO, Nim syntax is even more flexible.
           | 
           | https://nim-lang.org
        
             | kevin_thibedeau wrote:
             | And compilation is fast enough that you can run it as a
             | script with shebang methods.
        
           | yawaramin wrote:
           | https://dev.to/yawaramin/practical-ocaml-314j
        
           | loic-sharma wrote:
           | You might want to try Dart. It is simple, has great tooling,
           | and compiles to native code.
           | 
           | Disclaimer: I work on Flutter at Google.
        
           | ufmace wrote:
           | Rust might be worth a look. It gets much closer to the line
           | count and convenience of the dynamic languages like Python
           | than Go, plus a somewhat better type system. Also gets a
           | fully modern tooling and dependency management system. And
           | native code of course.
        
           | wiseowise wrote:
           | Modern Java with Graalvm.
        
         | vovavili wrote:
         | This is a needlessly dismissive and narrow-minded attitude.
         | Have you ever tried to use FastAPI?
        
           | fiyec30375 wrote:
           | Yes. Have you ever tried trpc?
        
             | vovavili wrote:
             | Implying that existence of your tool of preference in
             | another programming language makes other equally impressive
             | tools something akin to "[colossal] mistake that we'll pay
             | for for years" "simply motivated by inertia" is way below
             | the level of discussion I would expect from Hacker News.
        
               | carderne wrote:
               | To be fair, your comment didn't add much either.
               | 
               | Their main criticisms of Python were:
               | 
               | > it is slow, its type system is significantly harder to
               | use than other languages, and it's hard to distribute
               | 
               | Your comment would have been more useful if it had
               | discussed how FastAPI addresses these issues.
        
               | vovavili wrote:
               | I would have given the OOP the effort and due respect is
               | formulating my response if it was phrased in the way
               | you're describing. It's only fair that comments that
               | strongly violate the norms of substantive discourse don't
               | get a well-crafted response back.
        
           | yunnpp wrote:
           | You say he's narrow-minded, but you focus on the least
           | relevant thing of everything he said, speed, and suggest
           | that, somehow, something with "fast" in its name will fix it?
           | 
           | Speed is the least concern because things like numpy are
           | written in C and the overhead you pay for is in the glue code
           | and ffi. The lack of a standard distribution system is a big
           | one. Dynamic typing works well for small programs and teams
           | but does not scale when either dimension is increased.
           | 
           | But pure Python is inherently slow because of language
           | design. It also cannot be compiled efficiently unless you
           | introduce constraints into the language, at which point
           | you're tackling a subset thereof. No library can fix this.
        
             | spockz wrote:
             | > But pure Python is inherently slow because of language
             | design. It also cannot be compiled efficiently unless you
             | introduce constraints into the language, at which point
             | you're tackling a subset thereof. No library can fix this.
             | 
             | A similar point was raised in the other python thread on
             | cpython the other day, and I'm not sure I agree. For sure,
             | it is far from trivial. However, GraalVM has shown us how
             | it can be done for Java with generics. Highover, take the
             | app, compile and run it. The compilation takes care of any
             | literal use of Generics, running the app takes care of
             | initialising classes and memory, instrumentation during
             | runtime can be added to add runtime invocations of generics
             | otherwise missed. Obviously, this takes a lot of details
             | getting it right for it to work. But it can be done.
        
             | vovavili wrote:
             | Very little of what you're claiming is relevant for FastAPI
             | specifically, which in terms of speed isn't too far from an
             | equivalent app written in Go for writing a web app. You
             | need to research the specifics of a problem at hand instead
             | of making broad but situationally incorrect assumptions.
             | The subject here is web apps, and Python is very much a
             | capable language in this niche as of the end of 2025, both
             | in terms of speed, code elegance and support for static
             | typing (FastAPI is fully based on Pydantic) - https://www.t
             | echempower.com/benchmarks/#section=test&runid=7...
        
         | strunz wrote:
         | I swear the only the people who care about Python types are on
         | Hacker News comments. I've never actually worked with or met
         | someone who cared so much about it, and the ones that care at
         | all seem just fine with type hints.
        
           | hu3 wrote:
           | Perhaps some people that cared moved to other languages.
           | 
           | And part of those who still complain are momentarily stuck
           | with it.
           | 
           | Just like survivorship bias. It's productive to ponder on the
           | issues experienced by those who never returned.
        
           | josephg wrote:
           | The people we happen to work with is an incredibly biased
           | sample set of all software engineers.
           | 
           | As an example, almost everyone I've worked with in my career
           | likes using macOS and Linux. But there are entire software
           | engineering sub communities who stick to windows. For them,
           | macOS is a quaint toy.
           | 
           | If you've never met or worked with people who care about
           | typing, I think that says more about your workplace and
           | coworkers than anything. I've worked with plenty of engineers
           | who consider dynamic typing to be abhorrent. Especially at
           | places like FAANG.
           | 
           | Long before typescript, before nodejs, before even
           | "JavaScript the good parts", Google wrote their own
           | JavaScript compiler called Closure. The compiler is written
           | in Java. It could do many things - but as far as I can tell,
           | the main purpose of the compiler was to add types to
           | JavaScript. Why? Because googlers would rather write a
           | compiler from scratch than use a dynamically typed language.
           | I know it was used to make the the early versions of Gmail.
           | It may still be in use to this day.
        
         | rahen wrote:
         | "> I think all of ML being in Python is a colossal mistake that
         | we'll pay for for years.
         | 
         | Market pressure. Early ML frameworks were in Lisp, then
         | eventually Lua with Torch, but demand dictated the choice of
         | Python because "it's simple" even if the result is cobbled
         | together.
         | 
         | Lisp is arguably still the most suitable language for neural
         | networks for a lot of reasons beyond the scope of this post,
         | but the tooling is missing. I'm developing such a framework
         | right now, though I have no illusions that many will adopt it.
         | Python may not be elegant or efficient, but it's simple, and
         | that's what people want.
        
           | Joker_vD wrote:
           | Gee, I wonder why the tooling for ML in Lisp is missing even
           | though the early ML frameworks were in Lisp. Perhaps there is
           | something about the language that stifles truly wide
           | collaboration?
        
             | rahen wrote:
             | I doubt it considering there are massive Clojure codebases
             | with large teams collaborating on them every day. The lack
             | of Lisp tooling and the prevalence of Python are more a
             | result of inertia, low barrier to entry and ecosystem lock-
             | in.
        
           | wild_egg wrote:
           | What sort of tooling is missing in Lisp? I'd love to check
           | out your framework if you've shared it somewhere
        
             | rahen wrote:
             | Lisp isn't missing anything, it's a natural fit for AI/ML.
             | It's the ecosystem's tooling that needs catching up.
             | 
             | The code hasn't reached RC yet, but I'll definitely post a
             | Show HN once it's ready for a preview.
        
         | tayo42 wrote:
         | How much does python really impact ml? All of the libraries are
         | wrappers around C code that uses gpus any way, it's distributed
         | and inference can be written in faster languages for serving
         | anyway?
        
           | roadside_picnic wrote:
           | You're thinking only about the final step where we're just
           | doing a bunch of matrix computation. The real work Python
           | does in the ML world is _automatic differentiation_.
           | 
           | Python has multiple _excellent_ options for this: JAX,
           | Pytorch, Tensorflow, autograd, etc. Each of these libraries
           | excels for different use cases.
           | 
           | I also believe these are cases where Python the _language_ is
           | part of the reason these libraries exist (whereas, to your
           | point, for the matrix operations pretty much any language
           | could implement these C wrappers). Python does make it easy
           | to perform meta-programming and is very flexible when you
           | need to manipulate the language itself.
        
         | CamperBob2 wrote:
         | _I think all of ML being in Python is a colossal mistake that
         | we 'll pay for for years._
         | 
         | If ML fulfills its promise, it won't matter in the least what
         | language the code is/was written in.
         | 
         | If it doesn't, it won't matter anyway.
        
         | solatic wrote:
         | 100%.
         | 
         | With that said... there _is_ a reason why ML went with Python.
         | GPU programming requires C-based libraries. NodeJS does not
         | have a good FFI story, and neither does Rust or Go. Yes, there
         | 's _support_ , but Python's FFI support is actually better
         | here. Zig is too immature here.
         | 
         | The world deserves a Python-like language with a better type
         | system, a better distribution system, and not nearly as much
         | dynamism footguns / rope for people to hang themselves with.
        
           | NetMageSCW wrote:
           | C#/.Net? (Their too strong focus on worthless backwards
           | compatibility and slow (very slow) development speed on basic
           | language features not withstanding.)
        
             | Xeronate wrote:
             | Admittedly I haven't used C# in a few years, but to my
             | knowledge it is much more ergonomic than java and
             | personally it's my preferred language. Only thing stopping
             | me from using it more is it has a much smaller community
             | than java/python etc. Wondering what you think is missing.
        
           | uxcolumbo wrote:
           | What about Elixir?
           | 
           | https://pragprog.com/titles/smelixir/machine-learning-in-
           | eli...
           | 
           | A Practical Guide to Machine Learning in Elixir - Chris
           | Grainger
           | 
           | https://www.youtube.com/watch?v=Es08MRtSkoE
        
           | wiseowise wrote:
           | It's called Java.
        
           | gspr wrote:
           | > NodeJS does not have a good FFI story, and neither does
           | Rust or Go. Yes, there's support, but Python's FFI support is
           | actually better here.
           | 
           | Huh. I've found Rust's FFI very pleasant to work with. I
           | understand that Zig's is second to none, but what does Python
           | offer in this domain that Rust (or Go) doesn't?
        
           | seanw444 wrote:
           | > The world deserves a Python-like language with a better
           | type system, a better distribution system, and not nearly as
           | much dynamism footguns / rope for people to hang themselves
           | with.
           | 
           | Nim. The tooling is still immature though.
        
         | robomartin wrote:
         | > I think all of ML being in Python is a collosal mistake that
         | we'll pay for for years.
         | 
         | > The main reasons being it is slow, <snip>, and it's hard to
         | distribute.
         | 
         | Don't forget that Python consumes approximately 70x more power
         | when compared to C.
        
           | fwip wrote:
           | Not really applicable to ML. The massive amount of compute
           | running on the GPU is not executing in Python, and is
           | basically the same regardless of host language.
        
       | vovavili wrote:
       | >I don't want to have virtual environments and learn what the
       | difference between pip, poetry and uv is. I don't care. I just
       | want to run the code.
       | 
       | So this is skill issue, the blog post. `uv run` and PEP 723
       | solved every single issue the author is describing.
        
         | oceansky wrote:
         | Any old enough language will have competing libraries that you
         | need to learn in the long run too.
        
           | saghm wrote:
           | Libraries, yes. Tooling around packages/building/managing
           | runtimes? I'm not convinced. Perl has been using CPAN like
           | two decades now, and I wouldn't consider that ecosystem to
           | exactly be an example of "there's only one way to do it". I
           | feel like you're extrapolating in the wrong direction; older
           | languages are less likely to have first party tooling for
           | this, so they're more likely to have multiple ways of doing
           | it, but I don't think there's much evidence that a language
           | that started out with first party tooling will always follow
           | that same trend. I don't think the issue with Python is it's
           | age as much as the tooling it has was just really not good
           | for a long time. People will probably want to replace subpar
           | tooling regardless of the official status if there's a better
           | alternative, but I'd expect that I'm the presence of good
           | enough first-party tooling, people will eventually stop
           | bothering.
           | 
           | I do actually think Go is a bit of an illustrative example
           | here because it started out with just `go get` and liberal
           | use of vendoring, then accumulated a variety of attempted
           | replacements (e.g. godep and dep, which confusingly were not
           | the same thing), but eventually the first party tooling
           | around modules became a thing and after some time it seems
           | like pretty much everyone dropped those interim tools and
           | standardized on the official tooling. I feel like this
           | actually shows that the proliferation of tooling can actually
           | be stopped even if it didn't exist early on, provided that
           | there's a process for making it official.
        
         | rufius wrote:
         | While this is true, it is often stunning to me how long it took
         | to get to `uv run`.
         | 
         | I have worked with Python on and off for 20+ years and I
         | _always_ dreaded working with any code base that had external
         | packages or a virtual environment.
         | 
         | `uv run` changed that and I migrated every code base at my last
         | job to it. But it was too late for my personal stuff - I
         | already converted or wrote net new code in Go.
         | 
         | I am on the fence about Python long term. I've always preferred
         | typed languages and with the advent of LLM-assisted coding,
         | that's even more important for consistency.
        
           | callc wrote:
           | Well said. I'm in the same boat of being on the fence about
           | python. I've been burned too many times in the past.
           | 
           | And even if uv was perfectly solves all of our woes, it still
           | seems worse than languages that solve packaging and
           | deployment with a first-party built tools.
           | 
           | There's only so much lipstick and makeup you can put on a
           | pig...
        
         | Mawr wrote:
         | It's a UX issue. The author is correct -- _nobody cares_ about
         | all the mumbo-jambo virtualenvs or whatever other techno-
         | babble.
         | 
         | The user
         | 
         | just
         | 
         | wants
         | 
         | to run
         | 
         | the damn program.
         | 
         | > `uv run` and PEP 723 solved every single issue the author is
         | describing.
         | 
         | PEP 723 eh? "Resolution: 08-Jan-2024"
         | 
         | Sure, so long as you somehow magically gain the knowledge to
         | use uv, then you will have been able to have a normal, table-
         | stakes experience for whole 2 years now. Yay, go Python
         | ecosystem!
         | 
         | Is uv the _default_ , officially recommended way to run Python?
         | No? Remember to wave goodbye to all the users passing the
         | language by.
        
           | worksonmine wrote:
           | > The user just wants to run the damn program.
           | 
           | I don't agree, the user wants to run the program in a way the
           | user wants to, but is frustrated when it doesn't.
           | 
           | If all dependencies were installed on the machine the script
           | would run no problem. I have some scripts with dependencies
           | that are installed on the system.
           | 
           | The author writes:
           | 
           | > The built in tooling within the go ecosystem is another
           | large selling point. We don't need a .pyproject or
           | package.json to configure ad-hoc formatting and linters,
           | backed by pipelines to ensure consistency.
           | 
           | Maybe shebangs is not the solution to that problem? It's a
           | convenience to run scripts as executable, but the user is
           | supposed to setup the environment. Then he continues to
           | explain that go has a great stdlib which makes it perfect for
           | scripting. This is the reason I usually reach for python for
           | complex scripts, the stdlib is big enough to solve most my
           | problems.
           | 
           | Now that node includes sqlite the choice isn't as easy, but I
           | wouldn't be pissed at node and javascript if I have to setup
           | the environment to make sure the script runs. I understand
           | how it runs, where it gets the dependencies. If I forget to
           | run `npm i` before running the scripts that's my error, I
           | prefer errors that remind me of my stupidity over magic.
        
           | vovavili wrote:
           | I don't see your point. The kind of user who will struggle to
           | type out `uv run` will find it even more difficult to type
           | out `//usr/local/go/bin/go run "$0" "$@"; exit`. Neither
           | approaches are the "default, officially recommended ways to
           | run" scripts.
           | 
           | I strongly encourage you to read the article to acquire the
           | context for the conversation before commenting, which is what
           | I assume is happening here.
        
           | wiseowise wrote:
           | > Is uv the default, officially recommended way to run
           | Python?
           | 
           | Yes, seems like it is de facto default, officially
           | recommended way.
        
           | lucideer wrote:
           | > _Is uv the default, officially recommended way to run
           | Python? No? Remember to wave goodbye to all the users passing
           | the language by._
           | 
           | uv was invented basically yesterday. But it is becoming the
           | default faster than any tool I've ever seen.
           | 
           | So I'd say: Yes - it is, effectively, the default now.
        
       | chamomeal wrote:
       | For another excellent scripting solution that has - fast startup
       | (no compilation) - uses a real language - easy to upgrade beyond
       | a script - has tons of excellent dependencies baked-in
       | 
       | Look no further than babashka! It's a clojure interpreter that
       | has first class support scripting stuff. Great built in libs for
       | shelling out to other programs, file management, anything http
       | related (client and server), parsing, html building, etc.
       | 
       | Babashka is my go-to tool for starting all new projects now. It
       | has mostly everything you need. And if it's missing anything, it
       | has some of the most interesting and flexible dependency
       | management of any runtime I've ever seen. Via the "pod protocol"
       | any process (written in go/rust/java whatever) can be exposed as
       | a babashka dependency and bundled straight in. And no separate
       | "install dependencies" command is required, it installs and
       | caches things as needed.
       | 
       | And of course you keep all of the magic of REPL based
       | development. It's got built in nrepl support, so just by adding
       | on '--nrepl-server 7888' to your command, you can connect to it
       | from your editor and edit the process live. I'm building my
       | personal site this way and it's just SO nice.
       | 
       | Sorry for the rant but when superior scripting solutions come up,
       | I have to spread the love for bb. It's too good to not talk
       | about!!
        
       | rewilder12 wrote:
       | I've tried Go scripting but would still still prefer python (uv
       | is a game changer tbh). My go-to for automation will always be
       | powershell (on linux) though. It's too bad PowerShell has the
       | MSFT ick keeping people away from adopting it for automation. I
       | can convince you to give it a try if you let me
        
       | spacecow wrote:
       | > Sidetrack: I actually looked up what the point of arg0 even is
       | since I failed to find any usecases some months back and found
       | this answer[0]. Confused, and unsatisfied by the replies, I gave
       | up trying to understand "why arg0?" as some sort of legacy
       | functionality.
       | 
       | I struggle to think of how the answers provided here could be
       | clearer or more satisfactory. Why write an article if you're
       | going to half-ass your research? Why even mention this
       | nothingburger sidetrack at all...? (Bait?)
       | 
       | [0] https://stackoverflow.com/questions/24678056/linux-exec-
       | func...
        
       | mlmonkey wrote:
       | I remember when I first experienced golang, I tried compiling it.
       | 
       | The compilation command returned immediately, and I thought it
       | had failed. So I tried again and same result. WTF? I thought to
       | myself. Till I did an `ls` and saw an `a.out` sitting in the
       | directory. I was blown away by how fast the golang compiler was.
        
       | shevy-java wrote:
       | Try the following in sh:              ////////usr/local/go/bin/go
       | 
       | Well, how about this: I use ruby or python. And not shell.
       | 
       | Somehow I have been doing so since +25 years. Never regretted it.
       | Never really needed shell either. (Ok, that's not entirely true;
       | I refer to shell scripts. I do use bash as my primary shell,
       | largely due to simplicity; I don't use shell scripts though, save
       | for keeping a few legacy ones should I be at a computer that has
       | no support for ruby, python or perl. But this is super-rare
       | nowadays.)
        
       | commandersaki wrote:
       | One thing I hate about Python executables, at least the ones I've
       | seen installed in Debian/Ubuntu is that the ones in /usr/bin are
       | wrappers to execute somewhere in your site-packages.
       | 
       | I just want to see the full script where I execute it.
        
         | kstrauser wrote:
         | Can you show an example of that?
        
       | ikrenji wrote:
       | I never had any trouble setting up or working with venvs. I don't
       | even feel the need to learn what uv is because it's such a non
       | problem for me.
        
       | semiinfinitely wrote:
       | skill issue
        
       | dherman wrote:
       | Ha, I just tried the same trick with Rust:
       | //$HOME/.cargo/bin/rustc "$0" && ${0%.rs} "$@" ; exit
       | use std::env;              fn main() {           println!("hello,
       | world!");           for arg in env::args() {
       | println!("arg: {arg}");           }       }
       | 
       | Total hack, and it litters ./ with the generated executable. But
       | cute.
        
         | eolpin wrote:
         | Fortunately this hack isn't necessary for rust, shebangs are
         | syntactically valid and single-file scripts can be executed
         | with cargo nightly: https://doc.rust-
         | lang.org/nightly/cargo/reference/unstable.h...
        
           | dherman wrote:
           | Cool!
        
       | yawaramin wrote:
       | I have a better idea: `ocaml script.ml` ;-)
       | 
       | Get started here: https://dev.to/yawaramin/practical-ocaml-314j
        
       | alkh wrote:
       | Have to post this monstrocity that let's you either run a python
       | script with uv or with python directly if uv is not installed(for
       | some of my collegues)
       | 
       | #!/usr/bin/env bash
       | 
       | """:"
       | 
       | if command -v uv > /dev/null
       | 
       | then exec uv run --script "$0" "$@"
       | 
       | else
       | 
       | exec python3 "$0" "$@"
       | 
       | fi
       | 
       | ":"""
        
       | kazinator wrote:
       | That's a neat trick; I don't think I've seen that before. It can
       | be made to work for just about any language that has // comments.
       | 
       | It does rely on // which is implementation-defined according to
       | POSIX. In some system //usr could refer to some kind of network
       | path.
       | 
       | Last sentence here:
       | 
       |  _3.254 Pathname
       | 
       | A string that is used to identify a file. In the context of
       | POSIX.1-2024, a pathname may be limited to {PATH_MAX} bytes,
       | including the terminating null byte. It has optional beginning
       | <slash> characters, followed by zero or more filenames separated
       | by <slash> characters. A pathname can optionally contain one or
       | more trailing <slash> characters. Multiple successive <slash>
       | characters are considered to be the same as one <slash>, except
       | it is implementation-defined whether the case of exactly two
       | leading <slash> characters is treated specially._
       | 
       | [IEEE Std 1003.1, 2024 Edition]
       | 
       | It really is better for a language to either have # comments, or
       | else support #! as a special case in a file that is presented for
       | execution. You're also not launching an extra shell instance.
       | (Too bad this // trick cannot use the "exec" shell command to
       | replace the shell with the go program.)
        
       | utf_8x wrote:
       | If you want a more... ergonomic language, you can also use the
       | new "run file directly" functionality in .NET 10. It supports
       | shebangs directly and it will even install packages referenced in
       | the script!                 #!/usr/bin/env dotnet run
       | #:package Newtonsoft.Json@13.0.3              using
       | Newtonsoft.Json;              Console.WriteLine(
       | JsonConvert.SerializeObject(new { Hello = "world" })       );
       | 
       | Even better, with the #:sdk directive, you can even serve a tiny
       | web app directly from your "fancy shell script"...
       | #!/usr/bin/env dotnet run       #:sdk Microsoft.NET.Sdk.Web
       | WebApplication         .Create()         .MapGet("/", () =>
       | "Hello from a shell script!")         .Run();
        
         | zmj wrote:
         | I wrote my first one of these today (making a tool for agents
         | in a c# codebase). Pretty good experience, though AOT does
         | still have some rough edges.
        
       | lucideer wrote:
       | > _I don 't want to have virtual environments and learn what the
       | difference between pip, poetry and uv is. I don't care. I just
       | want to run the code._
       | 
       | The author is right that every user approaching Python shouldn't
       | need to figure this out. However, I do strongly believe every
       | blogger setting out to write an opinion piece on this topic
       | should at least attempt to figure this out before writing their
       | article.
       | 
       | Obvious ignorance does not a compelling point make. Especially
       | when uv solves literally all of the problems you're describing.
        
         | abbadadda wrote:
         | > Especially when uv solves literally all of the problems
         | you're describing.
         | 
         | How does uv solve the "write once, run anywhere" problem like
         | go?
         | 
         | (I'm not being sarcastic, I don't know that much about uv and
         | perhaps am lacking the mental model for understanding this)
        
           | lucideer wrote:
           | > _How does uv solve the "write once, run anywhere" problem
           | like go?_
           | 
           | Here's an examply Python script from the uv website[0]:
           | #!/usr/bin/env -S uv run --script       #       # /// script
           | # requires-python = ">=3.12"       # dependencies = ["httpx"]
           | # ///            import httpx
           | print(httpx.get("https://example.com"))
           | 
           | This will auto-install Python 3.12 (or greater) in a per-
           | script virtual environment, along with the httpx package from
           | pypi & immediately execute the script, on any system that has
           | uv.
           | 
           | [0] https://docs.astral.sh/uv/guides/scripts/#using-a-
           | shebang-to...
        
           | Quothling wrote:
           | UV is a drop-in for pip, rather than a replacement. It
           | functions differently than pip behind the scenes, which is
           | why it's faster, but when you use it, it's basically still
           | pip. Except it makes everything easy. You create your venv
           | with uv venv, you update packages with uv sync, you run
           | things without activating your venv with uv run... It uses
           | the pyproject.toml, so it's very easy to share things like
           | linters and build tools. Then when it's time to deploy, you
           | can compile your pyproject.toml to a requirements.txt file
           | and use it in any Python container image. Which is very handy
           | when you work with something like Azure Container Functions
           | which don't come with UV (and you probably don't want to use
           | an UV image or install UV in your build process).
           | 
           | I've been using it for so long now that I recently couldn't
           | remember how to use Python without it, when one of our BI
           | guys needed some help. Which was ridiculously embarrassing.
           | 
           | I don't think it really compares to Go though. It's not as
           | straight forward if you work on different python
           | distributions. It's also not as easy to work with something
           | like micro Python compared to targeting a specific embedded
           | platform with Go.
        
       ___________________________________________________________________
       (page generated 2025-12-30 23:00 UTC)