I just started “Build Your Own Text Editor”[0], but using Odin instead of C. So far, I’m impressed with Odin. It’s the most ergonomic C replacement I’ve tried. I wish it had been around 25 years ago when I was professionally working with unmanaged code.
As being able to use a language to write an editor is a personal must-have in a language, your mention of kilo caught my eye. I did a quick read through of the Odin overview and FAQ and my initial impressions are positive. Bonus points to them for multiple return values and no automatic fallthrough on switch.
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?
Zig's compiler error on unused variables is a deal breaker for me unfortunately. The language author also has an insulting attitude towards anyone who wants otherwise, categorizing them as bad programmers he doesn't want to work with and doesn't want using Zig.
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.
> Zig: Trust the programmer to manually manage memory, but not to clean up unused variables.
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.
Odin allows you to opt into the vetting tools through build flags (`-vet` and `-vet-*`) or even per-file build tags `#+vet unused`.
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.
Go refuses variables that are declared and not used as well.
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.
Meanwhile in Haskell they introduced typed holes in order to allow you to compile more types of programs that aren't yet fully finished.
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)?
Yeah, in C, you at least add the unused attribute and can grep for it. In some languages that do not support "_" prefix or the attribute meaning unused, you have to comment out parts. It is really annoying and I think it is worse.
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.
The solution is easy, have separate debug and release modes and only mandate variables to be used in the latter (though still provide a flag to disable the check, for the occasional debugging an issue that only happens with the release config).
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.
>Odin’s creator has some strong opinions around not prioritizing LSPs and QoL tools around Odin.
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.
I recall a thread from a few years ago where people were saying that zig had better LSO support than Odin and saying that Odin should prioritize that more.
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.
>Please don’t put words in my mouth. I’m trying to be very clear.
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.
> no, he does not. He just doesn't use LSP but never did he ever oppose QoL tools.
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.
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.
I am the creator of the Odin programming language. That's not even my opinion...
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.
If your goal is viral adoption, I agree, but it sounds like Odin is kind of geared towards the graphics programming world and doesn’t require vitality at this stage.
It's not just that they are a mess accidentally, but they will necessarily become that. I won't discuss the full position here but in short: not everything needs to be automated, especially the automation of dependency hell. And making such things easier to do, is not a good thing and WILL lead to what mess we have no due to human nature.
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.
Odin does have a pretty nice "package management" story. You can literally just throw a folder with Odin files into your project structure and it "just works". The compiler sees it and includes it automatically.
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...
> You can literally just throw a folder with Odin files into your project structure and it "just works". The compiler sees it and includes it automatically.
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.
Well, being able to simply chuck files into your project and not deal with actually importing, linking, etc... means that you can then just use something like git to manage files.
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.
No, the "C community" and creators aren't making a political stance on things at all. Lua doesn't either. The Zig creator is very outspoken on political matters.
Not making a political stance is implicitly embracing the status quo. That’s usually fine because most hot political issues are far away from programming language design and implementation. Others feel differently, that political issues which affect community members (or people who could become community members) are important to speak out on. Regardless, every community takes political stances, some are just more upfront about it
Andrew Kelley is just one guy and he’s allowed to express his own political opinions online, just as you are. What evidence is there that the community as a whole is “annoyingly political”?
I love Odin, and I'm glad to see it getting more attention. I've been working through Dave Churchill's COMP 4300 course[0] in Odin/Raylib rather than C++/SFML, and it's been a blast.
Flipped through the language overview on the website and noticed that matrices are limited in how large they can be because they're stack allocated [1]. Ergonomics of the language otherwise look solid but for my use case that would be fairly constraining
Actually we implement it manually ourselves the exact same way that the extensions work. This is because we have to support multiple different versions of LLVM which don't have those extensions.
Matrices, like any other primitive data type, are stack-allocated. Do you want matrices to be allocated on the heap? If you're looking to do Pandas-style data science, you'd have to write your own implementation, where you could adjust for exactly how you want to do the multiplication. The builtin matrices are typically pretty small (~4x4 or 3x3), a very common use case in graphics or games programming.
It looks like some borrowed Go convention, where package statements don't need to be quoted, but import statements may include URLs and, therefore, they are expected to be quoted.
As the docs do state, the package declaration has nothing to do with the import path. The package name is there for consistent ABI, so that the link names are prefixed with that. The import _path_ is just that, a path to where the package is stored. They can be different but it is conventional that they are similar-ish.
Any reading recommendations for introduction to the fundamentals of manual memory management specifically? I tried learning C in the past but didn’t get very far without a compelling need to learn it.
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.
Odin has a builtin heap allocator that works the same way you would expect any other high-level language to do memory allocation–it's just that you have to free the memory yourself. Plus, Odin's built in `context` system makes it really easy to change what kind of allocator is used for different sections of code. For my use cases, I've never needed any more than a heap and an arena, detailed in this talk:
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:
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++:
Curious, why? I hate pdfs because of their fixed size. Whatever device I happen to use to view a pdf, it's always got a different size than I'd like... either too large (ok I can fix that by zooming out!), wrong proportions, or too small...
I like that it looks like the print book. I have dual screen and when it comes to tech books. I few the pdf fullscreen on one monitor while trying things out actively on another. when I'm on the go, it looks great on a ipad.
for novels where I'm reading for story, I use a kindle but for textbooks, I strongly prefer 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.
While not a first class solution, the EPUB version of the book converts to PDF fairly well (I'm not noticing anything wrong). There are plenty of tools to do so.
I believe the issue is that things are not properly formatted, and does not look as good as it could. For text-only, EPUB is fine, otherwise I would rather prefer PDF, too.
I'm not particularly impressed by Odin but maybe i'm not the audience. If you like strictly procedural languages (or a die hard C fan) it's probably fine but it feels like a 'My First Language™' kind of project.
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.
i think you probably just aren't the audience. most of the things you miss are things i either am neutral on or actually enjoy (having written about ~20K lines of odin).
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.
Regarding internal compiler errors, I still hit on in MSVC every other month, and that's a compiler that has been in production for many decades at this point.
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.
Odin appears to only recently have been pressing the claim of Go alternative, as a new direction in its marketing hype. There are Go and Pascal influences, but Odin is arguably much more similar to and an alternative of Jai[1][2] (from Jon Blow). Maybe the strategy is to try to distance itself from the label of Jai-clone or Jai-lite.
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.
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.
I am the creator of the Odin programming language but Odin doesn't have a "killer feature". The lack of a "killer feature" does mean it is a very weird language to market for (see: https://www.gingerbill.org/article/2024/09/08/odin-weird-to-...), but to summarize that article, Odin isn't trying to be hypeable, it's trying to be an extremely productive language for people looking for a C alternative for high performance modern systems.
Fair enough. The reason I asked is there are many languages that aim to fill the gap that Odin fills (Nim, Zig, Crystal). My use of the word "hook" wasn't meant in the sense of "killer feature"; it is some vague sense of what people believe should excite me to take a detailed look at the language spec.
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 don’t think it’s trying to have some magical hook, it just feels better to program than C/C++ for most of their use cases.
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.
It may not be precise in its details but it's a very accessible explanation that's certainly "good enough." Maybe you could swap it in for "non-whole numbers" and still be reasonably accessible, but that's also not perfectly accurate since integers are stored just fine inside a float.
I'm certainly not going to fault them for using layman terms when addressing laymen.
Ideally for this work you want somebody who is capable of communicating in a way that doesn't feel dumbed down and yet also isn't actively wrong. This explanation of the floating point types does not hit that mark. I'm not in the market for an Odin book, so in some sense it doesn't matter what I think, but across fields it's better if what you're saying is able to both serve its immediate purpose and actually true.
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.
Hi, author here! I will update the book with a few clarifications surrounding my sloppy use of the word "decimal". As some have pointed out it is a bit of a "layman way" to view things, but nevertheless the reader should be made aware of whenever I use sloppy / simplified language.
I agree with OP that it's unnecessarily confusing. A "method" is a procedure. The floating point number is the result of that procedure, not the procedure itself.
"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".
Maybe it should've said "is a method of storing" instead of "for". It would make it clear it's not talking about a procedure, but a way or manner of doing something.
Maybe OP reacted because a float only looks like it is a way to store decimal numbers, when it's only an approximation of decimal numbers. If you really need decimal numbers you need something like mpmath¹.
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".
Very few numbers have decimals. They're not just numbers with whole and fractional parts, decimals are base 10 as well. .NET has them for monetary uses but I'm unaware of any other language(family) that has them built in.
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.
I see. Well, I believe AI will really be useful for programming (as opposed to gluing libraries together until it passes the tests) when it will acquire the ability to reason properly enough with new concepts. But then, they will also benefit from better languages, exactly like ourselves.
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)
I will go a step further, AI agents transpiling into existing languages is an intermediary step until they improve themselves, just like in the early days of Lisp, Fortran and COBOL, Assembly developers didn't trust them unless they could fully analyse generated Assembly.
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.
You can look at it this way. Or, you can see it as raising the bar for new entrants. If a new programming language has sufficient merits to overcome a poor level of AI assistance, then nothing will stop it, at least in some circles.
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.
[0] https://viewsourcecode.org/snaptoken/kilo/index.html