Chances are 677,634 of those will be broken next week though :-P
The problem with package managers is that they encourage piling on dependencies and creating deep (and thus fragile and often hard to reason about) dependency trees.
I loathe having to install anything more complicated than simple scripts[0] based on Python because unless the developer constantly chases after all their dependencies to keep them in working order, i'll be the one who will have to do that when something inevitably breaks (assuming it wasn't already broken the time i decided to try it - which is sadly something i encountered more than a few times). And once the developer moves on, the bitrot spreads alarmingly fast.
[0] and even that isn't reliable if the scripts rely on more than whatever comes preinstalled with Python
I'm not going to write things like Django, flask, requests, urllib3, numpy, scipy, mathplotlib, dateutils, and psycopg2 on my own. That would take multiple lifetimes.
Sure, you can choose to write everything yourself, but you are limiting the size, scope, and complexity of the problems that you can solve. We have to stand upon the shoulders of others to get stuff done.
Package managers and libraries are orthogonal. if the language and the libraries are stable, you hardly need a package manager. And without one, I’d say you see much better quality in the wild.
The short version is: projects should vendor their deps and manually resolve package versions. I don't think he states his argument very clearly. But I do think he's basically correct.
Look at Rust and NPM... Insane amounts of dependencies for almost every library.
C and C++ famously don't have package managers, well, at least not blessed ones (although you could argue Linux/Unix is a C package manager).
The idea is to be more informed about the dependencies you're bringing in, to encourage libraries to be more standalone things, and just not to automate dependency hell.
On the plus side, the Odin compiler makes it very, very easy to compile your program with dependencies.
Hell, even in my Ruby journey I've realised that 99% of what's on Rubygems is absolute trash. I basically use Rails, Faraday, RubyLLM, and not much else.
GingerBill and the Odin community put tremendous effort into making sure that the Odin compiler ships with "batteries included". You get base, core and vendor library collection that cover almost everything a developer would need to the point that you can argue that you don't need a package manager for Odin.
> [dead keys] should be avoided for common operations in newly designed programming languages.
If that's the rationale for choosing which symbols should be allowed, then let's ban {} as they require AltGr+Shift in many layouts. And let's avoid <> (used as parentheses, e.g. for templates or XML tags, not as less-than/greater-than) because in ISO keyboards they loose all their symmetry. And what about shells, with /, one of the most used characters, relegated above 7 in many layouts?
Jokes apart, I like the choice of ^ or any other characters distinct from * for pointer dereference. To be more precise, I despise the use of the same symbol with different meaning. In C the same * is used for multiplication, pointer dereference and takes part in commments, too. You need full context to parse some cases, or you have to play with spaces:
So is ' for some keyboard layouts, but ' is still useful and evocative in many contexts.
There are not enough good symbols trivially typed on a keyboard to sacrifice half of them to dead keys. Either the dead key or the programming symbol can be mapped to a key combination.
Parentheses are inserted by pressing two keys simultaneously. Diacritics on layouts that use dead keys are inserted by pressing two keys in sequence. Or, often, two keys simultaneously and then a third key in sequence (E.g. Shift-6 then Space for ^)
I'm Portuguese but live in the UK. The Portuguese layout (especially on macs) is dreadful for programming (because a bunch of important characters like brackets require Alt Gr to type), the UK layout sucks for writing Portuguese (because of the diacritics), so I ended up having to get used to US International as the compromise layout. I've gotten kind of used to it over the years, but the exact behaviour for dead keys varies a fair bit by platform, and especially on Linux can get quite aggravating.
If you're a programmer you should know how to change keyboard layouts. I speak a couple languages that use accents, all my dead keys need to be combined with a compose key first.
I'll add another point i.e. Odin is effectively done from a language point of view unlike Zig or others. The project is currently working on improving the std library and toolchain but the language itself is finished according to it's BDFL.
From my experience so far, Odin is a delightful modern alternative to C.
Zig is still pre-1.0, and the creators have been VERY clear that they're not done breaking stuff on the way to getting things right. It's a fair contrast to draw.
Hi, are you interested in Zig? Then please check out my port of jsmn to Zig. I wanted to know if people will like it and if there are any downsides others might not.
to be fair at this point it seems like outside of reenabling async control flow, and eliminating cImport, the remaining major shifts are in the stdlib and not as much the language. they have cancelled the "forcing const f = fn..." plan. i think the interesting thing that andrew hinted at was keeping the "annoying errors that should be warnjngs" (like not using consts and vars) but not letting them prevent the creation of the executable/lib.
> In the code above, make([]proc(msg: string), len(arr)+1) generates a slice of procedure pointers with a length of len(arr)+1. Essentially, it allocates memory on the heap and returns a slice header, which includes a pointer to the allocated memory, along with the length and capacity of the slice.
I guess things get exciting when that allocation fails, given that such a failure is nowhere checked for and the possibility of such failure is nowhere mentioned.
One can use `@(require_results)` to force the user to check for error. That paired with `or_return` or `or_else` in Odin mostly take away all foot guns.
> No package manager
Ginger Bill famously hates package managers, so if the lack of one is a deal breaker for someone they might as well look for a different language.
Do you happen to know why? A package manager system seems essential for sharing and reusing code with other people.
For example, I don't particularly like Python as a language, but I will use it because it has 677,633 packages in PyPI.
> 677,633 packages in PyPI.
Chances are 677,634 of those will be broken next week though :-P
The problem with package managers is that they encourage piling on dependencies and creating deep (and thus fragile and often hard to reason about) dependency trees.
I loathe having to install anything more complicated than simple scripts[0] based on Python because unless the developer constantly chases after all their dependencies to keep them in working order, i'll be the one who will have to do that when something inevitably breaks (assuming it wasn't already broken the time i decided to try it - which is sadly something i encountered more than a few times). And once the developer moves on, the bitrot spreads alarmingly fast.
[0] and even that isn't reliable if the scripts rely on more than whatever comes preinstalled with Python
I'm not going to write things like Django, flask, requests, urllib3, numpy, scipy, mathplotlib, dateutils, and psycopg2 on my own. That would take multiple lifetimes.
Sure, you can choose to write everything yourself, but you are limiting the size, scope, and complexity of the problems that you can solve. We have to stand upon the shoulders of others to get stuff done.
I think the suggestion here is to take a copy of those that you know works with your software and package in that particular version?
instead of the user having to resolve conflicts or manage the dependencies
Those are properties of Python's package management strategy and language design, they're not inherent to package management.
Package managers and libraries are orthogonal. if the language and the libraries are stable, you hardly need a package manager. And without one, I’d say you see much better quality in the wild.
> I will use it because it has 677,633 packages in PyPI
Quality over quantity, please
He's written about it repeatedly. https://www.gingerbill.org/article/2025/09/08/package-manage...
The short version is: projects should vendor their deps and manually resolve package versions. I don't think he states his argument very clearly. But I do think he's basically correct.
Vendor your damn deps!
> Do you happen to know why?
Look at Rust and NPM... Insane amounts of dependencies for almost every library.
C and C++ famously don't have package managers, well, at least not blessed ones (although you could argue Linux/Unix is a C package manager).
The idea is to be more informed about the dependencies you're bringing in, to encourage libraries to be more standalone things, and just not to automate dependency hell.
On the plus side, the Odin compiler makes it very, very easy to compile your program with dependencies.
Hell, even in my Ruby journey I've realised that 99% of what's on Rubygems is absolute trash. I basically use Rails, Faraday, RubyLLM, and not much else.
Not that it stopped people in the past from adding their own. See JS.
and yet it never truly became an issue at all because there is an officially maintained, high quality package collection.
https://pkg.odin-lang.org/
GingerBill and the Odin community put tremendous effort into making sure that the Odin compiler ships with "batteries included". You get base, core and vendor library collection that cover almost everything a developer would need to the point that you can argue that you don't need a package manager for Odin.
That's great. But I need an Aerospike/YAML/JPEGXL/Slint libraries first thing in the morning.
Is it in vendor package yet? No? Then Odin vendor package will be a bottleneck for development.
I see binding, so maybe interops with C is trivial. And just like that, you’ll have the thousand existing C libraries.
Binding is one thing, having idiomatic library is another.
Doesn't this code leak memory? I mean, even after adding the deinit procs. The point is that when a new_arr is created, the old one is not deleted.
Besides, the duo make-delete is easy to understand, but I find disturbing that one has to call delete on objects allocated with
I think it breakes the symmetry.And is that such a bad thing? C's biggest drawback is its many surprises, I thought. Some boredom would do it good.
That's literally the point of the article:
> Odin kinda feels like a modernized somehow even more boring C but in the best way possible.
It helps to read the article before commenting.
He says the end "I'm using the word boring affectionately"
I believe Odin's `^` syntax is a direct nod to Pascal. I for example had a prior experience with Delphi so it wasn't not too obscure.
That's true, but the keyboard issue is real. ` ^ ~ are dead keys on many keyboard layouts, requiring two keypresses to type.
I think they should be avoided for common operations in newly designed programming languages.
> [dead keys] should be avoided for common operations in newly designed programming languages.
If that's the rationale for choosing which symbols should be allowed, then let's ban {} as they require AltGr+Shift in many layouts. And let's avoid <> (used as parentheses, e.g. for templates or XML tags, not as less-than/greater-than) because in ISO keyboards they loose all their symmetry. And what about shells, with /, one of the most used characters, relegated above 7 in many layouts?
Jokes apart, I like the choice of ^ or any other characters distinct from * for pointer dereference. To be more precise, I despise the use of the same symbol with different meaning. In C the same * is used for multiplication, pointer dereference and takes part in commments, too. You need full context to parse some cases, or you have to play with spaces:
Same with &So is ' for some keyboard layouts, but ' is still useful and evocative in many contexts.
There are not enough good symbols trivially typed on a keyboard to sacrifice half of them to dead keys. Either the dead key or the programming symbol can be mapped to a key combination.
() are dead keys by that definition on almost every keyboard layout.
Parentheses are inserted by pressing two keys simultaneously. Diacritics on layouts that use dead keys are inserted by pressing two keys in sequence. Or, often, two keys simultaneously and then a third key in sequence (E.g. Shift-6 then Space for ^)
I'm Portuguese but live in the UK. The Portuguese layout (especially on macs) is dreadful for programming (because a bunch of important characters like brackets require Alt Gr to type), the UK layout sucks for writing Portuguese (because of the diacritics), so I ended up having to get used to US International as the compromise layout. I've gotten kind of used to it over the years, but the exact behaviour for dead keys varies a fair bit by platform, and especially on Linux can get quite aggravating.
I think on Linux, I took one of the key I never use (insert) and put it as the compose key. That resolved most of my issues with writing French.
FWIW --- programmer dvorak lets you type () without "shift" but both ~ and ^ require shift. https://www.kaufmann.no/roland/dvorak/
highly recommend every programmer set up hold/tap for their modifiers, including space cadet style parentheses.
LISP in shambles
If you're a programmer you should know how to change keyboard layouts. I speak a couple languages that use accents, all my dead keys need to be combined with a compose key first.
!!
I'll add another point i.e. Odin is effectively done from a language point of view unlike Zig or others. The project is currently working on improving the std library and toolchain but the language itself is finished according to it's BDFL.
From my experience so far, Odin is a delightful modern alternative to C.
You mean the language is effectively finished and not subject to change.
What do you mean “unlike zig”?
Zig is still pre-1.0, and the creators have been VERY clear that they're not done breaking stuff on the way to getting things right. It's a fair contrast to draw.
Hi, are you interested in Zig? Then please check out my port of jsmn to Zig. I wanted to know if people will like it and if there are any downsides others might not.
https://github.com/Ferki-git-creator/jsmn_zig
to be fair at this point it seems like outside of reenabling async control flow, and eliminating cImport, the remaining major shifts are in the stdlib and not as much the language. they have cancelled the "forcing const f = fn..." plan. i think the interesting thing that andrew hinted at was keeping the "annoying errors that should be warnjngs" (like not using consts and vars) but not letting them prevent the creation of the executable/lib.
He's saying that the Odin language is effectively finished and not subject to change. That is not the case for Zig.
> In the code above, make([]proc(msg: string), len(arr)+1) generates a slice of procedure pointers with a length of len(arr)+1. Essentially, it allocates memory on the heap and returns a slice header, which includes a pointer to the allocated memory, along with the length and capacity of the slice.
I guess things get exciting when that allocation fails, given that such a failure is nowhere checked for and the possibility of such failure is nowhere mentioned.
Odin supports multiple returns and the `make` proc returns an error value that can be optionally checked.
Optional error checking based on a second return value is just asking for footgunnery, Go made this same (IMO) mistake.
One can use `@(require_results)` to force the user to check for error. That paired with `or_return` or `or_else` in Odin mostly take away all foot guns.
I can't decide whether the double spaced code samples in this blog post are intended or a mistake. I kind of hope it's a mistake.
good catch, appreciate it!
it was indeed a mistake on my part, line-height got applied to code blocks as well as the paragraphs
I fixed it now so that codeblocks do not have a very loose line height.
The whole article is like that ... it's not in fact double spaced, it's the line height.
seems to be single-spaced to me, and it is my own favourite code spacing