1
Fork 0

log/2022/dependencies.md: grammar

main
Motiejus Jakštys 2022-04-26 19:31:24 +03:00
parent 27059b8d8a
commit d4838bb558
1 changed files with 26 additions and 21 deletions

View File

@ -11,7 +11,7 @@ draft: true
<!-- o_ -->
TLDR: modern programming languages make it very easy to add many dependencies.
TLDR: Modern programming languages make it very easy to add many dependencies.
That is nice for development, but a nightmare for maintenance. Unfortunately,
zig is following suit. I wish we could accept that adding dependencies does not
have to be trivial. If we accept that, thanks to ubiquity of git, we may have
@ -20,8 +20,8 @@ almost solved the dependency problem.
Adding dependencies
-------------------
All of the programming languages I've used professionally whose name does not
start with "c"[^1] have package managers[^2], which make "dependency
All of the programming languages I've used professionally, the names of which do not
start with "c"[^1], have package managers[^2], which make "dependency
management" easy. These package managers will, as part of the project's build
process, download and build the dependencies, which makes adding and using
third-party dependencies easy.
@ -29,10 +29,10 @@ third-party dependencies easy.
Because C/C++ still does not have a universal package manager, not adding
external dependencies to C/C++ is the path of least resistance; instead, one
relies on libraries already installed in the system. Therefore, there is a
plethora of dependency managers that will discover, but not install
dependencies: autotools, cmake, pkg-config and others. As a result, C/C++
projects I've been involved usually had 0-5 non-system dependencies, whereas
non-C/C++ projects -- tens, hundreds or thousands[^3]. Having many system
plethora of dependency managers that will discover but not install
dependencies: autotools, cmake, pkg-config, and others. As a result, C/C++
projects I've participated in usually had 0-5 non-system dependencies, whereas
non-C/C++ projects -- tens, hundreds, or thousands[^3]. Having many system
dependencies is painful for *every user* of the package (because they have to
make sure the libraries, and their correct versions, are installed), so C/C++
projects avoid having too many of them.
@ -48,14 +48,19 @@ will gain a lot of dependency "weight" with time.
hint="photo"
>}}
In Go and Python small number of dependencies is often a sign of care and
In Go and Python, a small number of dependencies is often a sign of care and
quality. [mattn/go-sqlite3](https://github.com/mattn/go-sqlite3),
[uber/zap](https://github.com/uber-go/zap),
[apenwarr/redo](https://github.com/apenwarr/redo) and
[django](https://djangoproject.com) are good examples. Making it easy to depend
on external code is is convenient during development, but frees developers from
their basic right (or obligation?) to audit understand them. And adds real
long-term maintenance costs.
[django](https://djangoproject.com) are good examples. I've built and used
these projects in a number of environments without issues. Conversely, projects
with many dependencies often fail to build even in the environment they are
developed and at and thus had received most testing (e.g. a specific
OS+architecture, like `Ubuntu 16.04 x86_64`). It's even worse to do on a
non-standard environment, no matter how trivially different (e.g. they would
build on Ubuntu 16.04, but fail on Ubuntu 18.04), not to mention a different
OS. This, obviously, leads to both user frustation, packagers' frustation, and
developer long-term frustration and costs.
The costs of just having dependencies are huge. I haven't done a survey and
have only my experience to base this on (read: "many anecdotes of me failing to
@ -66,7 +71,7 @@ self. Here is it:
1. Does the dependency do what I want, does it work at all?
2. Is it well written? API surface, documentation, tests, error handling, error
signaling, logging, metrics, memory usage (if applicable).
3. How easy is it to build, run and run it's tests? Related: can it be used
3. How easy is it to build, run, and run it's tests? Related: can it be used
outside the default package manager?
4. It's system dependencies.
5. It's transitive dependencies.
@ -78,7 +83,7 @@ dependencies or it's build complexity, if the package manager will take care of
it all anyway?
Except it will only when you are adding it. Package manager will not help you
when the dependency disappears, it's API changes, it stops doing what it has
when the dependency disappears, its API changes, it stops doing what it has
advertised and many other [problems][crash-of-leftpad].
I am trying to do all 5. If a dependency is well written, but has more
@ -87,7 +92,7 @@ fork and trim it. My recent example is
[sql-migrate](https://github.com/motiejus/sql-migrate).
To sum up, the "modern" languages optimize for initial development experience,
not maintenance. And as [Corbet says][linux-rust]. "We can't understand why
not maintenance. And as [Corbet says][linux-rust], "We can't understand why
Kids These Days just don't want to live that way". Kids want to build, John,
not maintain. A 4-letter Danish corporation made a fortune by selling toys that
do not need to be maintained: they are designed to be disassembled and built
@ -113,7 +118,7 @@ make our dependency unavailable, change without notice. And it will keep the
size of the repository in check, because it's all there when you pull it.
Because `git-subtrac` is a vendoring tool, not a package manager, it only
vendors, but does not help building packages. Therefore, with `git-subtrac` it
vendors but does not help building packages. Therefore, with `git-subtrac` it
is harder to add and "make work" (build, test, add transitive deps) a
dependency than with a language-specific package manager. Oh, what about the
transitive dependencies?
@ -133,18 +138,18 @@ weeks ago in a park in Milan my conversation with [Andrew
Kelley](https://andrewkelley.me/) was something like:
- me: "git-subtrac yadda yadda yadda submodules but better yadda yadda yadda".
- Andrew: "if I clone a repository that uses it with no extra parameters, will
- Andrew: "If I clone a repository that uses it with no extra parameters, will
it work as expected?"
- me: "no, you have to pass `--recursive`, so git will checkout submodules...
- me: "No, you have to pass `--recursive`, so git will checkout submodules...
even if they are already fetched."
- Andrew: "then it's a piece-of-shit-approach."
- Andrew: "Then it's a piece-of-shit-approach."
Uh, I agree. People have not grown muscle memory to clone repositories with
`--recursive` flag and never will, so it's impossible to adopt git-subtrac
beyond well-controlled silos. Which is why we will have a
yet-another-programming-language-specific-package-manager. Or at least my
argument for using and advertising `git-subtrac` (and saving a lot of time for
Zig folks, and a lot of inevitable misery for it's users) stops right there.
Zig folks, and a lot of inevitable misery for its users) stops right there.
Conclusion
----------
@ -157,7 +162,7 @@ stop after 5 seconds?
[^2]: Usually written in the same language. Zoo of package managers (sometimes
a couple of popular ones for the same programming language) is a can of worms
in an on itself worth another blog post.
[^3]: `go.sum` of a project I am currently involved clocks around 6k lines.
[^3]: `go.sum` of a project I am currently involved in clocks around 6k lines.
This is quite a lot for Go, but still peanuts to Node.js.
[git-subtrac]: https://github.com/apenwarr/git-subtrac/