29 ms·
The problem is that anything that's _apparent_ and not _enforced_ will be messed up over time. Maybe not in a project with few people where everyone is an exper
by jmmv 1y ago
The problem is that anything that's _apparent_ and not _enforced_ will be messed up over time. Maybe not in a project with few people where everyone is an expert on how "things are supposed to be", but it will inevitably happen when you add more and more people.
And the whole point of the article is to say that import statements do actually _not_ solve this issue, because import statements are at the file level, not at the module level (whatever module means in your mind).
In any case. As I mentioned in the article en passing, other languages _do_ provide similar features to Bazel's build files though, and I explicitly called out Rust as one of them. When you are defining crates and expressing dependencies via Cargo, you are _essentially doing the same_ as what I was describing in the article. Same with Go if you are breaking your code apart into multiple modules
But then we all know that there are some huge repos out there that are just "one module" and you can't make anything out of their internal structure. Hence you start breaking them apart into Crates, Go modules, NPM packages, you name it or... you know, add Bazel and build files. They are the same tool -- and that's why I didn't write Bazel in the title, because I imagined "build files" more generically. I guess I needed to be clearer there.
- NomDePlum 1y agoAdding more and more people is often the thing to avoid. I'm not going to say it can be avoided in all cases but modularity, team structure and architecture both system and organisational can avoid this in a lot of cases.
- xyzzy_plugh 1y ago> The problem is that anything that's _apparent_ and not _enforced_ will be messed up over time We already have the tools to enforce these things in many mainstream languages. Breaking things apart into crates/modules certainly makes sense sometimes, but other times it does not? If you have a monorepo, do you really need multiple modules? And if you don't, does that mean your architecture is difficult to understand? I don't think that tracks at all, so I don't really agree with where you're headed. > But then we all know that there are some huge repos out there that are just "one module" and you can't make anything out of their internal structure. There's always some shitty code out there, sure. But I don't like the suggestion that "one module" can't be coherent. It's orthagonal to the architecture. Not everything needs to be made generic and reusable. > And the whole point of the article is to say that import statements do actually _not_ solve this issue, because import statements are at the file level, not at the module level (whatever module means in your mind). This is not true for Go, for example. Import statements absolutely do solve this problem in Go. I rarely need to ever look at module files which are in some ways a byproduct of the import statements.
- jmmv 1y ago> This is not true for Go, for example. Import statements absolutely do solve this problem in Go. I rarely need to ever look at module files which are in some ways a byproduct of the import statements. Go imports still work at the Go package level. If you have multiple .go source files in one package, you have the exact same issue I described for Java. .../pkg1/foo.go -> import .../pkg2 .../pkg1/bar.go -> import .../pkg3 If I'm editing / reviewing a change to pkg1/foo.go, I cannot tell that pkg1 _already_ depends on pkg3. Can I?
- deleted 1y ago[deleted]
- ghthor 1y agogo list can tell you that pkg1 imports pkg2. At work, go list was too slow and depended on a git checkout so we wrote our own import graph parser using the go std lib parser and operate on byte slices of the files we read directly from git. It’s speed of light fast and we can compute go import graphs in parallel from multiple commits to determine what has changed in the graph so we can reduce the scope of what is tested.