←back to thread

272 points abdisalan | 7 comments | | HN request time: 0.293s | source | bottom
Show context
vessenes ◴[] No.42175536[source]
This will always be an issue for the node community - it’s endemic to the JavaScript shipping / speed culture and the package management philosophy.

Go is much, much better on these terms, although not perfect.

I’d venture a guess that Perl 5 is outstanding here, although it’s been a few years since I tried to run an old Perl project. CPAN was dog slow, but other than that, everything worked first try.

I’d also bet Tcl is nearly perfect on the ‘try this 10 year old repo’ test

replies(6): >>42175774 #>>42175778 #>>42177239 #>>42181293 #>>42181469 #>>42182989 #
1. skybrian ◴[] No.42175778[source]
Go’s minimum version selection is the way and I don’t understand why other ecosystems haven’t adopted it. You’re be able to compile an old project with all the library dependencies it had at the time it was released. It might have security issues, but at least you start with a version that works and then can go about upgrading it.

It also helps that if some library dependency generated Go code using a tool, the Go source code is checked in and you don’t have to run their tool.

replies(2): >>42176210 #>>42176443 #
2. vessenes ◴[] No.42176210[source]
I truly think it's just because the engineers that started working with node were ... young. They wanted to rapidly iterate, and so crufty old habits like this weren't what they wanted or felt they needed.

What's been interesting is watching these devs age 10 years, and still mostly decide it's better to start new frameworks rather than treat legacy code as an asset. That feels to me like a generational shift. And I'm not shaking my cane and saying they're wrong -- a modern LLM can parse an API document and get you 95% of the way to your goal most of the time pretty quickly -- but I propose it's truly a cultural difference, and I suspect it won't wash out as people age, just create different benefits and costs.

3. Macha ◴[] No.42176443[source]
Getting the exact dependencies it had at release is a solved problem in Node and most other languages with lock files too.

It's just no guarantee that those old versions work on the new system, or with the outside world as it exists by time of installation - which can be as true for Go as any other language. If the XYZ service API client still gets you version 1.2.37, that's not actually any help if 1.2.37 calls endpoints that the XYZ service has removed. Or a cgo package that binds to a version of OpenSSL that is no longer installed on your system, etc.

replies(3): >>42177130 #>>42178518 #>>42181430 #
4. tgv ◴[] No.42177130[source]
Some time ago, I wanted to update Arch, on a server running some python project I had inherited. Long story short, it relied on something that relied on something that etc., and then it turned out certain components that were needed for the upgrade process had been taken offline. Now the system can’t be changed, unless there’s significant work done to the code, and that’s too expensive. It runs on request in a container now, while it lasts.
replies(1): >>42177275 #
5. baq ◴[] No.42177275{3}[source]
back in the day you were supposed to check in your compiler into version control (not the lockfile, the whole distribution).

I used to think that people emailing screenshots of corporate dashboards were idiots. I now think that's actually genius - a frozen in time view which you can't regenerate but will be available until the end of time if you need it. (Hello, Exchange admins!)

6. vessenes ◴[] No.42178518[source]
This is why I say it's a cultural problem, not a technical problem. In goland, changing API calls in minor versions is pretty much a sin. At least it's something you'd do .. carefully, probably with apologies. In node, it's extremely routine to re-pin to newer modules without worry.
7. zokier ◴[] No.42181430[source]
My hot take is that lock files and nested dependencies induce fragility. If packages were required to work with wide range of dependencies then that would force the ecosystem to build the packages in more robust way. Basically I think the dependency trees built with modern package managers in a sense over-constrain the environment, making it all sorts of difficult to work with.

On the other hand, the other extreme induces stuff like autoconf which is not that great either. Trying to have your code be compatible with absolutely everything is probably not good, although arguably platforms these days are generally much more stable and consistent than they were in the heydays of autoconf.