Understanding the Odin Programming Language
odinbook.com
odinbook.com
Have you tried zig? I'm casually looking for a C replacement and I took a quick look at zig but came away not liking the community vibe (some things were too dictatorial for my tastes).
If you did anything with zig, how would you say the languages compare?
Both are very nice people as long as you’re nice yourself, imo.
My opinions:
Odin’s creator has some strong opinions around not prioritizing LSPs and QoL tools around Odin.
Zig’s is a little more hard nosed about simplicity. Zig is a very small language for a reason.
I’m on my zig arc now, but Odin is next.
no, he does not. He just doesn't use LSP but never did he ever oppose QoL tools.
Odin has great support for LSP and they are working on other tools as well. Do note that Odin doesn't have a foundation like Rust or Zig so their pace of development will be at their own discretion. Please don't expect it to be similar to Zig or other well funded languages.
He's somewhat against package managers (doesn't want Odin ecosystem turning into NPM or Crates.io where a single package draws in a thousand dependencies).
But yeah, Odin's LSP is used by most Odin users, including staff at JangaFX.
yes and that is a design decision.
Its not just the dependencies bloatware, there is also an issue of accidentally pulling in a GLP license code base and several others. But if one wishes to make a package manager for Odin, they can do so and other Odin users may use it if they found it to be really helpful but from what I know, Ginger Bill will never officially support it as it doesn't align with his vision of the language.
The decision, which is not design per se, is to not have an OFFICIAL package manager, nor even endorse a third party one.
I recall gingerBill saying that he’d rather work on the language than adoption. Which is a fine position to have.
Never did I say he was morally against LSPs or anything, just that he has strong opinions on prioritizing its development vs the language itself.
Please don’t put words in my mouth. I’m trying to be very clear.
The Odin lsp I found (ols) is not official and not made by gingerBill. Which, again, is fine. It’s good that the community took up the burden of making an LSP.
my bad then
>The Odin lsp I found (ols) is not official and not made by gingerBill. Which, again, is fine
Ginger Bill is just the creator of the language. He is already hands full with the front end and back end of the language alone. You pointing out "its fine" makes it seem like you expect him to work on LSP, web site, marketing and everything else all by himself, which he can't and I personally think he won't. LSP is a big mess and it is alright to not prioritize LSP and focus on working on the core language itself, especially if marketing is not a serious concern.
For example: > You pointing out "its fine" makes it seem like you expect him to work on LSP, web site, marketing and everything else all by himself
How you extrapolated all that from me saying “it’s fine” is beyond me.
I’m not here to argue, just to state my opinion that both language creators are pretty nice people with some particular opinions.
I literally said that it’s fine that ols is community made. I even said it’s good that the community is willing to put in that work.
I also passed no judgement on his choice to not prioritize an LSP.
Take your outrage elsewhere, please.
I mean strong as in I don’t believe his opinion will be easily swayed.
FWIW it's the same for Zig. ZLS is not official and not made by andrewrk.
Gingerbill is mainly against package managers because ecosystems like NPM and Crates.io are a mess...
I don't hate cargo either, I've also used Ruby for years, gem is nice, but in both ecosystems there's also a ton of abandoned packages, some that haven't been touched in years...
This is true of most modern languages. That's not the problem package management is solving. Package management is solving the problem of how you decide which versions of which files to put into your project, considering the fact that dependencies may form a complex graph, not a simple tree.
A language can decide that it simply won't support complicated dependency graphs, which is a valid decision but is the opposite of having a nice package management story.
Anyhow, I've used Odin, it's easy, never found the lack of package manager to be annoying. I've also used Rust, cargo is nice. I think I maybe lean a tad to the way Odin works, if for no other reason than crates.io is a graveyard of dead projects and you constantly have to see what's active and what's not, I find myself going to each project's GitHub anyway. With Odin I just import librairies straight from GitHub.
And both are easier than C/C++'s lack of, well, anything.
Odin could trivially have a package manager and even one of the best support for it at the language level too because of how I designed what a package is in the language itself. I choose to not officially support a package manager because I don't want to encourage the path to hell.
The compiler error on variables which are mutable when could be const is almost as annoying. Zig does not acknowledge that not all code is production code, that sometimes you want to prototype without having to backtrack and fix compiler errors to irrelevant things when the goal is prototyping and figuring out what you are building.
It also adds friction to learning the language because statements you write will immediately get flagged as wrong -- is it actually wrong due to your unfamiliarity with the language, or is it just the lsp immediately flagging and underlining all unused as red. Better take a moment to check.
Super annoying to me. I can't get past it, nor do I trust the author of Zig to not go even further in this direction. He has made it clear he will not compromise on this issue.
There are more planned similar errors on the way here. At least it looks like they are no loner planning to do compiler errors on unused pub functions if they are not accessible from outside the package.
Zig: Trust the programmer to manually manage memory, but not to clean up unused variables.
The language is weirdly pedantic, in ways orthogonal to Rust.
That's such a good tagline, actually one of the things that annoyed me with zig as well. The other one is the lack of attention to syntax aesthetics and ergonomics, it's a bit all over the place and I am also not fond of semicolons.
> Compile error: This variable of type `Foo` is unused
Ok then, I'll just remove that, and...
> Compile error: This function you're calling expects an argument of type `Foo`
Just kill me.
"Oh and I have to do this one too"
"Oh and this five as well"
"Almost there"
"Nope"
And honestly, I like the fact that it forces the source code to not include bloat. Lines of code that are there, but don't do anything, and can be misleading.
And in Zig, the language server can be configured to automatically add and remove `_ = variable;` statements, so this is frictionless.
I'm all for preventing this kind of thing from making it into the main branch, but a compiler error by its nature blocks compilation, which forces weird shenanigans like commenting out lines of code or adding arbitrary meaningless uses. Why is that better than a compiler warning (made mandatory in CI)?
In some C code where I have to suppress an unused variable warning (for example to a pthread callback), I just do (void)arg at the top of the function.
Alsl, automatic `_ = var` is the worst of all, now instead of the compiler showing me one-by-one the few variables I'm not using temporarily so I can fix those, I instead have made n modifications all across the codebase (remember, this is all recursive) that are syntactically correct and won't be shown by the compiler.
This is one thing that really annoys me about Go, I am a competent programmer and I don't want be treated like an incompetent one. If I want vetting tools, I'll enable then when it suits me.
Others try Odin or C3 instead.
I do not personally use an LSP for my own personal reasons (I found I PERSONALLY was less productive with such tools). I am not against the concept of autocompletion tools like an LSP. If you are more productive using one, that is great!!! OLS exists but OLS is just not "official"—even if it is very good from what many people have told me. The only reason it is not official is that none of the core team worked on it, including myself.
As for QoL tools? Of course we want these but our philosophy is make sure the foundations are brilliant first before half-arsing the tool built on top of the foundations.
[0] https://www.youtube.com/playlist?list=PL_xRyXins84_Sq7yZkxGP...
[1] https://odin-lang.org/docs/overview/#technical-information-o...
When the actual code examples begin, the very first couple of lines confused me:
package hellope
import "core:fmt"
Is the quoting of package names optional?This doesn't strike me as odd at all. It's an identifier, not a string. The quoting of the import, on the other hand...
I’ve toyed with Odin a bit and the language in syntax is right up my alley, but the idea of manually managing memory is pretty foreign to me. I understand it broadly, but have no good idea about how to actually do it practically and properly.
I will give this book a look as well since I see it covers the topic in some chapters.
here is a series written by the creator of Odin programming language about memory allocation https://www.gingerbill.org/series/memory-allocation-strategi...
The core:mem package in standard library is a very great resource for memory management in Odin. The standard library's basically got it all.
https://www.youtube.com/watch?v=nZNd5FjSquk
Personally, my large Odin project uses a series of arrays to store specific data, and then everything else is stored in a temporary allocator, which is wiped between frames. Besides some graphics initialization & path resolution at initialization time, the heap allocator is never used. I never really have to worry about memory. That's similar to the design detailed in this talk by Ryan Fluery:
https://www.youtube.com/watch?v=TZ5a3gCCZYo
Odin also has a tracking allocator which can be used to check for leaks or double frees. In debug mode, my program will print out all un-freed memory left after shutdown. If you're working outside of Odin, I've heard good things about Valgrind for C/C++:
for novels where I'm reading for story, I use a kindle but for textbooks, I strongly prefer pdf
The HTML version can be "printed to PDF".
There is no "manually layouted" PDF available however. That requires manual typesetting the whole book, which is weeks or months of extra work. I will do that if I ever make it into a physical book. At that point an official PDF would also become available.
That said, many of my readers like having the HTML version in a window next to their code window. I think it is the best experience on a computer. On the iPad I would probably read the EPUB. But if you prefer PDF, then print the HTML version to PDF.
Have a nice day! /Karl Zylinski
What I really miss are methods on structs a'la Go. Just simple receivers would be a great addition imho. Because of this choice, it's affected the entire stdlib and boy does it look old. Creating a typed variable to pass it to a stdlib init function (for allocation, etc) is terrible decision and it's everywhere. The stdlib looks muddled too.
Odin is obviously heavily inspired by Go (among others) but it's learned nothing of the lessons of the Go authors. For example, Odin is a larger language and has fewer features.
I got an ICE while compiling once and it reported something like `TODO(bill) support this`. Not a good look.
Odin isn't trying to be "impressive", it's trying to be productive as an alternative for C on modern systems.
Odin isn't my "First Language" and closer to my 20th.
Odin is just not for you. Your complaint about the lack of methods means you don't want a C alternative, and that is absolutely fine. I have nothing inherently against methods but I believe that if you are to add them, you cannot just have _mere methods_ but also have something to take advantage of them. But by the time you need such a feature (like typeclasses/traits), it becomes far from being a C alternative now and being something closer in the realm of Rust.
And what about the core library is muddled?
What lessons from Go did I not learn?—I'll take "fewer features" as a compliment too.
> I got an ICE while compiling once and it reported something like `TODO(bill) support this`. Not a good look.
Did you make an issue for this? And how long ago was this? Because this most likely fixed/implement now, and was probably fixed very quickly too.
the creating a variable and passing to the `init` procedure is something i actually like since it allows me to decouple my allocations and initializations in most cases (barring things that are backed by dynamic arrays like `core:container/queue`). it also ensures that the memory allocated by `init` procedures can outlive the structure that it was tied to, which is especially useful in the case of something like the string builder.
if you simply want "method-style" autocomplete (i'm neutral on that), ols also does support that with `fake_method_completion` where you type `<variable>.<whatever>` and all procedures that take a `T` or `^T` as the first parameter show up as options.
as far as having fewer features, i think it just depends on which ones you're talking about. imo, the odin generic system is much nicer to work with and the presence of real enums, bit_sets, enumerated arrays, `or_return` + friends, and a proper scoped-based defer (instead of go's function based) make it really nice to program in compared to go for me. that being said, the `core:thread` `Thread_Pool` is not a complete replacement for goroutines and i will say that the concurrency model of go works really well for a garbage-collected language. of course, the garbage-collected part there shows why something like goroutines don't really fit well in odin.
on internal compiler errors, unfortunately, in a pre-1.0 language, those are bound to happen. fortunately, the time to fix can often be measured in a matter of hours rather than days/weeks.
But as I said to him, did he file an issue and when was this? Because it was probably fixed by now, and if not, we'll try to fix it straightaway.
If Jai goes public beta or releases books (upcoming from Ivo Balbaert), then Jai has the potential to kill off Odin, which appears to only been able to keep a smallish following (relatively fewer GitHub stars and lack of Wikipedia page) since its birth in 2015 or 2016. Odin's popularity, seems dependent on Jai not being public yet.
The languages which are truly close to Go, are: Go+ (goplus)[3], V (vlang)[4], and Borgo[5]. V has the methods on structs, as you have mentioned. Go+ and Borgo compile to Go. V compiles to C, along with other backend options, and has a Go2V transpiler. These languages are more of an evolution of Go, that provide additional features and functionality, and where the influence is much more obvious.
[1]: https://github.com/Jai-Community/Jai-Community-Library/wiki
[2]: https://youtu.be/M763xHjsPk4 (Jai vs Odin)
[3]: https://goplus.org
[4]: https://vlang.io
[5]: https://borgo-lang.github.io (note- weird issues over lack of license)
That being said, I find the error handling via multiple return values + or_return pretty nifty, and the vendored libraries give it a very “batteries-included” feel.
For example, you can render hardware accelerated graphics and de/serialize JSON without downloading any packages.
For example, I'd say "If you are a python programmer, you should take a look at Nim. Same syntax, automatic memory management, fast execution, and meta programming".
For crystal, it would be the same set, except for the syntax (which resembles Ruby)
Anyhoo, having read some more about Odin, I'll attempt an answer to my own question. These are the features -- the hooks -- that stood out from the competition for me
1. Array programming on fixed sized arrays. Very nice. 2. quaternion and matrix in-built types. This alone is worth the price 3. "where" clauses including numeric constraints on types (in parametric polymorphism) 4. relatively pain-free linking to C code of admission. 5. Small arrays for dynamically sized stack allocated arrays 6. Multiple return values that can be named.
Consider me hooked! Thank you for all the hard work and sharing it generously with the world.
I'm sorry, what?
What is it you don't understand: "method" (a representation) or "decimal" (a number that consists of a whole and a fractional part)?
As a shorthand to explain what a float is to someone, "a decimal number" is an OK start though.
But sometimes that approximation breaks down even for simple examples, i.e. 0.1 cannot be represented as a float. This can be quite unexpected if your mental model is that "floats are decimal numbers with a certain precision".
"Most decimal fractions cannot be represented exactly as binary fractions." - from the Python tutorial
The word "decimal" does not simply mean "a number that consists of a whole and a fractional part".
"Decimal" implies a ten based system, even though it's perfectly fine to say "binary decimal".
Using your own replacement words, it would be clearer to write "A floating point number is a representation of a number with a fractional part".
I'm certainly not going to fault them for using layman terms when addressing laymen.
People are going to remember (some of) what you taught them and even if it felt peripheral at the time they may have centred it. When they return to this teaching again, it's not surprising that they assume you meant what you said, even if in your mind it was figurative or targeted at a superficial understanding of the subject.
Decimal representations do exist in machines. Representations that can manage 1.2 exactly but can't handle a third, or pi, or the square root of 2 for example. But the floating point numbers aren't that, they're a weird (but useful) binary fraction and if we're going to mention them at all we need to make it clear what's going on here.
For example the "float" (32-bit IEEE floating point type) called 1.2 is actually 5033165 divided by 4194304 which isn't actually six over five (1.2) but it's pretty close.
AI coding assistants are closing the door. They need a lot of training data to be good and useful. Established programming languages have a tremendous amount of that, so AI coding agents will do a good job there. C, PHP, Python, Java, etc.
Garden variety and new programming languages have much less examples in the wild, so AI assistants will do a lesser job with those, unless their lineage leads to one of the established languages.
Finally, the bulk of future developers will be lured to AI assisted coding and therefore won’t generate much training data for new programming languages.
A vicious circle.
All of the above is speculation on my part, obviously. Maybe AI assistants will get smart enough to master languages they have not been trained on.
But, if mainstream developers have become totally dependent on AI, it is going to be a high bar indeed.
It would be interesting to bake AI into compilers of any new language, so that auto-correction and education of the programmer happens every time they compile.
In general, though, I think people are too quick to surrender to AI.
Nowadays while generating Assembly is an expected option, it is mostly a niche use case, largely ignored by most developers, many don't even know how to look into Assembly generated by JIT compilers, although that is an available option.
Same will happen with AI tools, they will perform desired actions, and eventually output some kind of data where we can cross-check the quality of generated actions, but not everyone will care to look into them.
One day they may even design their own languages or their own cpus.
(and decide that, since we stupidly unearthed and burned in the atmosphere the best reserve of chemical energy that was easily available on this planet, it's just fair to use us as combustible to power the whole thing)