13 ms·
Odin: A programming language made for me
- mrkeen 1y ago> In Odin all variables are automatically zero initialized. Not just integers and floats. But all structs as well. Their memory is filled with zeroes when those variables are created. > This makes ZII extra powerful! There is little risk of variables accidentally being uninitialized. The cure is worse than the problem. I don't want to 'safely' propagate my incorrect value throughout the program. If we're in the business of making new languages, why not compile-time error for reading memory that hasn't been written? Even a runtime crash would be preferable.
- ratatoskrt 1y ago> why not compile-time error for reading memory that hasn't been written? so... like Rust?
- Timwi 1y agoCuriously, C# does both. It uses compile-time checks to stop you from accessing an uninitialized local and from exiting a struct constructor without initializing all fields; and yet, the CLR (the VM C# compiles to) zero-initializes everything anyway.
- dontlaugh 1y agoThat’s likely because p/invoke is quite common.
- neonsunset 1y agoNo, that's just the memory model of CLI and the choice made by C#. By default, it emits localsinit flag for methods which indicates that all local variables must be zero-initialized first. On top of that, you can't really access unitialized memory in C# and F# anyway unless you use unsafe. It's a memory safety choice indeed but it has nothing to do with P/Invoke.
- dontlaugh 1y agoThe main motivation to use unsafe is p/invoke. Without unsafe, zero init is not needed.
- neonsunset 1y ago> The main motivation to use unsafe is p/invoke. This is opposite to the way unsafe (either syntax or known unsafe APIs) is used today.
- dontlaugh 1y agoExplicit use of unsafe is used for things like avoiding allocation, sure. All use of p/invoke is also unsafe though, even if the keyword isn’t used. And it’s much more common to wrap a C library than to write a buffer pool.
- mrkeen 1y agoThis is a pain. I recently switched from Java (and its whole Optional/null mess) to C#. I was initially impressed by its nullable checks, but then I discovered 'default'. Now I gotta check that Guids aren't 0000...? It makes me miss the Java situation.
- electroly 1y agoYou don't need the "default" keyword to run into that. A simple "new Guid()" gives you all-zeroes (try it!). Nice and foot-gunny.
- masfoobar 1y ago> A simple "new Guid()" gives you all-zeroes In C#, to have all zeroes, you would do "Guid.Empty"
- masfoobar 1y ago(continued from my comment above) Apologies, I am missing some text on here. No sure what happened. I might have deleted before I submitted. I cannot edit this comment, but I need to clarify and correct it... "new Guid()" is equiverlant "Guid.Empty" Personally, I would prefer writing "Guid.Empty" as it is cleaner. It also helps ensure you understand reading other developers code... their intensions. Afterall, a lesser experienced developer may not know (or simply forgot) that "new Guid()" does not create a new, unique value. So writing "new Guid()" looks more misleading. var myGuid1 = new Guid(); // all zeroes, or a value? var myGuid2 = Guid.Empty; // Ah.. all zeroes. It is ESPECIALLY cleaner when doing comparison :- if(myGuid2 == Guid.Empty) { } To set a Guid, you would do :- myGuid2 = Guid.NewGuid(); // This makes sense.
- neonsunset 1y agoOnly if you go out of your way to author a method with (Guid someGuid = default) argument. I've never seen it happen with Guids, if someone gives you default(Guid) - they did it on purpose, it's no different to explicitly setting `0` to an integer-typed UserID property. If supplying Guid is optional, you just make it Guid?. To be fair, I don't think offering default(T) by default (ha) is the best choice for structs. In F#, you have to explicitly do `Unchecked.defaultOf` and otherwise it will just not let you have your way - it is watertight. I much prefer this approach even if it can be less convenient at times.
- deleted 1y ago[deleted]
- munificent 1y agoIt has to because the analysis to detect that fields are initialized in the constructor body is unsound. Since you have access to `this` inside the constructor, you can call other instance methods which may access fields before they have been initialized. Java has the same problem. (Dart, which I work on, does not. In Dart, you really truly can't observe an instance field before it has been initialized.)
- thasso 1y agoI agree that zero-initializing doesn't really help avoid incorrect values (which is what the author focuses on) but at least you don't have UB. This is the main selling point IMO.
- yusina 1y agoThen why not just require explicit initialization? If "performance" is your answer then adding extra optimization capabilities to the compiler that detects 0 init would be a solution which could skip any writes if the allocator guarantees 0 initialization of allocated memory. A much safer alternative. Replacing one implicit behavior with another is hardly a huge success...
- 90s_dev 1y agoI'd guess it was because 0 init is desired often enough that this is a convenient implicit default?
- yusina 1y ago"Often enough" is what's introducing the risk for bugs here. I "often enough" drive around with my car without crashing. But for the rare case that I might, I'm wearing a seatbelt and have an airbag. Instead of saying "well I better be careful" or running a static analyzer on my trip planning that guarantees I won't crash. We do that when lives are on the line, why not apply those lessons to other areas where people have been making the same mistakes for decades?
- johnnyjeans 1y agoFor the same reason you wear a seatbelt and not a 7-point crash harness.
- sph 1y agoPlease, can we stop assuming every single software has actual lives on the line? These comment threads always devolve into implicit advertisement of Rust/Ada and other super strict languages because “what about safety?!” It is impossible to post about a language on this forum before the pearl clutching starts if the compiler is a bit lenient instead of triple checking every single expression and making your sign a release of liability. Sometimes, ergonomics and ease-of-programming win over extreme safety. You’ll find that billion dollar businesses have been built on zero-as-default (like in Go) and often people reaching for it or Go are just writing small personal apps, not cruise missile navigation system. It gets really tiring. /rant
- tlb 1y agoBeing initialized to zero is at least repeatable, so if you forget to initialize something you'll notice it immediately in testing. The worst part about uninitialized variables is that they frequently are zero and things seem to work until you change something else that previously happened to use the same memory.
- thasso 1y ago> The worst part about uninitialized variables is that they frequently are zero and things seem to work until you change something else that previously happened to use the same memory. This is not the whole story. You're making it sound like uninitialized variables _have_ a value but you can't be sure which one. This is not the case. Uninitialized variables don't have a value at all! [1] has a good example that shows how the intuition of "has a value but we don't know which" is wrong: use std::mem; fn always_returns_true(x: u8) -> bool { x < 120 || x == 120 || x > 120 } fn main() { let x: u8 = unsafe { mem::MaybeUninit::uninit().assume_init() }; assert!(always_returns_true(x)); } If you assume an uninitialized variable has a value (but you don't know which) this program should run to completion without issue. But this is not the case. From the compiler's point of view, x doesn't have a value at all and so it may choose to unconditionally return false. This is weird but it's the way things are. It's a Rust example but the same can happen in C/C++. In [2], the compiler turned a sanitization routine in Chromium into a no-op because they had accidentally introduced UB. [1]: https://www.ralfj.de/blog/2019/07/14/uninit.html https://www.ralfj.de/blog/2019/07/14/uninit.html [2]: https://issuetracker.google.com/issues/42402087?pli=1 https://issuetracker.google.com/issues/42402087?pli=1
- gingerBill 1y ago> You're making it sound like uninitialized variables _have_ a value but you can't be sure which one. Because that's a valid conceptualization you could have for a specific language. Your approach and the other person's approach are both valid but different, and as I said in another comment, they come with different compromises. If you are thinking like some C programmers, then `int x;` can either have a value which is just not known at compile time, or you can think of it having a specialized value of "undefined". The compiler could work with either definition, it just happens that most compilers nowadays do for C and Rust at least use the definition you speak of, for better or for worse.
- gingerBill 1y agoYou're assuming that's the style of programming others want to program in. Some people want the "ZII" approach. Your approach is a trade-off with costs which many others would not want to make. So it's not "preferable", it's a different compromise.
- iainmerrick 1y agoThat's clearly correct, as e.g. Go uses this style and there are lots of happy Go users. I want to push back on the idea that it's a "trade-off", though -- what are the actual advantages of the ZII approach? If it's just more convenient because you don't have to initialize everything manually, you can get that with the strict approach too, as it's easy to opt-in to the ZII style by giving your types default initializers. But importantly, the strict approach will catch cases where there isn't a sensible default and force you to fix them. Is it runtime efficiency? It seems to me (but maybe not to everyone) that initialization time is unlikely to be significant, and if you make the ZII style opt-in, you can still get efficiency savings when you really need them. The explicit initialization approach seems strictly better to me.
- gingerBill 1y ago> It seems to me... that initialization time is unlikely to be significant The thing is, initialization cost is a lot more than you think it is, especially when it's done on a per-object level rather than a "group" level. This is kind of the point of trying to make the zero value useful, it's trivially initialized. And in languages that are much more strict in their approach, it is done at that per-object level which means instead of the cost of initialization being anywhere from free (VirtualAlloc/mmap has to produce zeroed memory) to trivially-linear (e.g. memset), to being a lot more nested hierarchies of initialization (e.g. for-loop with constructor for each value). It's non-obvious why the "strict approach" would be worse, but it's more about how people actually program rather than a hypothetical approach to things. So of course each style is about trade-offs. There are no solutions, only trade-offs. And different styles will have different trade-offs, even if they are not immediately obvious and require a bit of experience. A good little video on this is from Casey Muratori, "Smart-Pointers, RAII, ZII? Becoming an N+2 programmer": https://www.youtube.com/watch?v=xt1KNDmOYqA https://www.youtube.com/watch?v=xt1KNDmOYqA
- slowmovintarget 1y agoHere's Casey Muratori on his habit of moving to ZII: https://www.youtube.com/watch?v=xt1KNDmOYqA https://www.youtube.com/watch?v=xt1KNDmOYqA Much better outcomes and failure modes than RAII. IIRC, Odin mentions game programming as one of its use cases.
- CyberDildonics 1y agoThese are not very good arguments and Casey Muratori is hugely biased against RAII and C++ techniques for some reason, probably familiarity with C. He thinks that every RAII variable is a failure point and that you only have to think about ownership if you are using RAII, so it incurs mental overhead. The reality is that you have to understand the lifetime and ownership of your allocations no matter what. If the language does nothing for you the allocation will still have a lifetime and a place where the memory is deallocated. He also talks about combining multiple allocations in to a single allocation that then gets split into multiple pointers, but that could easily be done in C++.
- adamrezich 1y ago> He also talks about combining multiple allocations in to a single allocation that then gets split into multiple pointers, but that could easily be done in C++. But this is explicitly the opposite of how the language is designed to be used, because that's the whole point of RAII.
- CyberDildonics 1y agoBut this is explicitly the opposite of how the language is designed to be used, because that's the whole point of RAII. Says who? If they all have the same lifetime multiple allocations can be combined into one allocation and deallocation. I've done it before, it makes perfect sense, although I would say it is a somewhat niche optimization.
- adamrezich 1y agoIt's only a “somewhat niche optimization” because the language emphasizes RAII. There are other ways of writing code—which other languages can incentivize by being designed differently—where it is not a niche optimization, but rather the default.
- lerno 1y agoI always find this opinion intriguing, where it's apparently fine that globals are initialized to zero, but you are INSANE to suggest it's the default for locals. What kind of programs are y'all writing? Clearly the lack of zeroing in C was a trade-off at the time. Just like UB on signed overflow. And now people seem to consider them "obvious correct designs".
- Tuna-Fish 1y agoI'd prefer proper analysis for globals too, but that is substantially harder. "Improperly using a variable before it is initialized" is a very common class of bug, and an easy programming error to make. Zero-initializing everything does not solve it! It just converts the bugs from ones where random stack frame trash is used in lieu of the proper value into ones where zeroes are used. If you wanted a zero value, it's fine, but quite possibly you wanted something else instead and missed it because of complex initialization logic or something. What I want is a compiler that slaps me when I forget to initialize a proper value, not one that quietly picks a magic value it thinks I might have meant.
- nickpsecurity 1y agoIt might be easier to detect a zero value. It might be easier to debug. People used to use hard-coded, human-visible values for debugging for that reason.
- Tuna-Fish 1y agoSure, and I'm not against belt-and-suspenders here. It's just that "all values are defined to be zero-initialized, and you can use them as such" is a horrible decision. It means that you cannot even get best effort warnings for lack of initialization, because as far as the compiler knows you might have meant to use the zero value.
- fc417fc802 1y agoI suspect it's even worse than UB. At least in that case a sanitizer can prevent optimizations and detect the later usage. If default zero initialization is guaranteed then as you say you lose any chance of an automated system detecting the programmer error.
- dooglius 1y ago> why not compile-time error for reading memory that hasn't been written https://en.wikipedia.org/wiki/Rice%27s_theorem?useskin=vector https://en.wikipedia.org/wiki/Rice%27s_theorem?useskin=vecto...
- TheCoelacanth 1y agoA compiler doesn't have to accept all possible programs. If it can't prove that a variable is initialized before being read, then it can simply require that you explicitly initialize it.
- dooglius 1y agoSure, but then not accepting many programs would be the answer to parent's question "why not"
- jerf 1y agoNot accepting many C programs, maybe. It's pretty easy to create a language where declaration is initialization of some sort, as evidenced by the large number of languages in common use where, one way or another, that's already the case. This isn't some whacko far out idea. Most languages already today don't have any way (modulo "unsafe", or some super-carefully declared and defined method that is not the normal operation of the language) of reading uninitialized memory. It's only the residual C-likes bringing up the rear where this is even a question. (I wouldn't count Odin's "explicitly label this as not getting initialized"; I'm talking about defaults being sharp and pointy. If a programmer explicitly asks for the sharp and pointy, then it's a valid choice to give it to them.)
- dooglius 1y agoI think we are in agreement? Odin works the way you describe, and GP in response expressed a preference that the compiler instead fail at compile time if it detected that memory had not been explicitly initialized; my response was to explain why this is not (in the general case) feasible.
- drannex 1y agoNot sure if anyone has mentioned it, but you can additionally disable ZII in any variable by describing the value as "---" in your declaration, useful when writing high performance code, here is an example: number: int = ---
- lblume 1y agoYes, this is mentioned explicitly in the article.
- melodyogonna 1y agoYou're talking about Mojo there. Even memory allocated with UnsafePointer must be explicitly initialised before it can be written to or read from.
- variadix 1y agoThis is certainly an interesting argument for making certain behavior (in this case, uninitialized access) the default and UB. There’s a similar argument for making signed overflow UB instead of defined to wrap, even if you’re only targeting two’s-complement machines, that is: leaving the behavior undefined enables analyzers to detect the behavior and making it the default can make otherwise silent errors detectable across all programs. I think I’ve come around to wanting these to be undefined and the default, it’s unintuitive but defined wrapping or zero initialized may be undesirable behaviors anyway.
- jimbob45 1y agoThe dangerous behavior should be opt-in, not opt-out. I appreciate that C gives you all of these neat footguns but they need to be hidden to find for only those who need them. Stuff like implicitness being the default for functions, int wrapping, and non-initialized variables just give rise to bugs. And for what? So first-year students can have their unoptimized code be 0.00001% faster by default? It's dumb.
- variadix 1y agoIf it’s opt-in then code written for the default (ie most code that wasn’t written to use the unintuitive behavior for some performance reason) will be either well-formed code that relies on the behavior (fine, but for signed int wrapping this is rare, for zero init this is common but not always the case) or ill-formed code that subtly fails (e.g. no check for overflow or zero is an invalid value). The code that is ill-formed cannot be checked by present or future static or dynamic analyzers, since the failure condition (signed overflow or access before assignment) is _defined to be something valid_ thereby preventing analyzers from determining whether the programmer intended the signed arithmetic to overflow or not, or for that value to be zero or not, etc. Hopefully I’m communicating why it is useful to leave the default behavior undefined or invalid. It doesn’t really have to have anything to do with performance, signed wrapping is no less performant on two’s-complement machines (barring compiler optimizations enabled by assuming no overflow) since it is the result produced by add instructions on overflow. The benefit is that it enables instrumentation and analyzers to detect this behavior because it is known to be invalid and not something the programmer intended. As an analogy, consider what would happen if you defined out of bounds array access to be _something_, now analyzers and instrumentation cannot detect this as an error, since the programmer may have intended for whatever that defined result is to occur in that case.
- canucker2016 1y agoSo fixing approx. 5-10% of CVEs (by zero-initializing all stack vars) is a worse cure than letting these uninitialized stack vars be possible sources of exploits? see https://msrc.microsoft.com/blog/2020/05/solving-uninitialized-stack-memory-on-windows/ https://msrc.microsoft.com/blog/2020/05/solving-uninitialize... Initializing the stack var to zero would have helped mitigate the recently discovered problem in GTA San Andreas (the real problem is an unvalidated data file) - see https://cookieplmonster.github.io/2025/04/23/gta-san-andreas-win11-24h2-bug/ https://cookieplmonster.github.io/2025/04/23/gta-san-andreas...
- Arnavion 1y ago>So fixing approx. 5-10% of CVEs (by zero-initializing all stack vars) is a worse cure than letting these uninitialized stack vars be possible sources of exploits? Read the comment you responded to again, carefully. It's not presenting the dichotomy you think it is.
- the__alchemist 1y agoSame. Rust's `Default` (Both derive, and custom) is my favorite way of handling a quick init, of any language. The key part is I can initialize quickly and without effort, with values that make sense based on the context.
- thasso 1y agoYou can do lot's of the same things in C too, as the author mentions, without too much pain. See for example [1] and [2] on arena allocators (which can be used exactly as the temporary allocator mentioned in the post) and on accepting that the C standard library is fundamentally broken. From what I can tell, the only significant difference between C and Odin mentioned in the post is that Odin zero-initializes everything whereas C doesn't. This is a fundamental limitation of C but you can alleviate the pain a bit by writing better primitives for yourself. I.e., you write your own allocators and other fundamental APIs and make them zero-initialize everything. So one of the big issues with C is really just that the standard library is terrible (or, rather, terribly dated) and that there is no drop-in replacement (like in Odin or Rust where the standard library seems well-designed). I think if someone came along and wrote a new C library that incorporates these design trends for low-level languages, a lot of people would be pretty happy. [1]: https://www.rfleury.com/p/untangling-lifetimes-the-arena-allocator https://www.rfleury.com/p/untangling-lifetimes-the-arena-all... [2]: https://nullprogram.com/blog/2023/10/08/ https://nullprogram.com/blog/2023/10/08/
- arp242 1y ago> I think if someone came along and wrote a new C library that incorporates these design trends for low-level languages, a lot of people would be pretty happy. I suppose glib comes the closest to this? At least the closest that actually sees fairly common usage. I never used it myself though, as most of my C has been fairly small programs and I never wanted to bother people with the extra dependency.
- gingerBill 1y agoThe author literally says that they used to do that in C. And I've done a lot of those things in C too, it just doesn't mean that C has good defaults nor good ergonomics for many of the tasks other languages have be designed to be good with.
- 9dev 1y agoI am not a C programmer, but I have been wondering this for a long time: People have been complaining about the standard library for literal decades now. Seemingly, most people/companies write their own abstractions on top of it to ease the pain and limit exposure to the horrors lurking below. Why has nobody come along and created an alternative standard library yet? I know this would break lots of things, but it’s not like you couldn’t transition a big ecosystem over a few decades. In the same time, entire new languages have appeared, so why is it that the C world seems to stay in a world of pain willingly? Again, mind you, I’m watching from the outside, really just curious.
- Fraterkes 1y ago[flagged]
- gingerBill 1y agoMy hobbies would not be suitable for __HackerNews__. What do you think HackerNews is for?
- christophilus 1y agoKeep posting, gingerBill. I love Odin threads when they pop up here. And I love Odin. Keep up the good work.
- latexr 1y agoWhile I don’t agree with the criticism of the person you replied to, it’s worth pointing out that Hacker News is very explicitly¹ for more than computer talk. > On-Topic: Anything that good hackers would find interesting. That includes more than hacking and startups. If you had to reduce it to a sentence, the answer might be: anything that gratifies one's intellectual curiosity. ¹ https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html
- gingerBill 1y agoExactly. That's what I meant with my question about what did he think HackerNews was for.
- CrimsonRain 1y agoFor many people, hacking away is (the) hobby. It's a sad situation when people like you pollute this field with your "computer is just a tool for me to make money" attitude.
- yusina 1y agoAs long as programmers view a program as a mechanism that manipulates bytes in flat memory, we will be stuck in a world where this kind of topic seems like a success. In that world, an object puts some structure above those memory bytes and obviously an allocator sounds like a great feature. But you'll always have those bytes in the back of your mind and will never be able to abstract things without the bytes in memory leaking through your abstractions. The author even gives an example for a pretty simple scenario in which this is painful, and that's SOA. As long as your data abstraction is fundamentally still a glorified blob of raw bytes in memory, you'll be stuck there. Instead, data needs to be viewed more abstractly. Yes, it will eventually manifest in memory as bytes in some memory cell, but how that's layouted and moved around is not the concern of you as the programmer that's a user of data types. Looking at some object attributes foo.a or foo.b is just that - the abstract access of some data. Whether a and b are adjacent in memory should be insubstantial or are even on the same machine or are even backed by data cells in some physical memory bank. Yes, in some very specific (!) cases, optimizing for speed makes it necessary to care about locality, but for those cases, the language or library need to provide mechanisms to specify those requirements and then they will layout things accordingly. But it's not helpful if we all keep writing in some kind of glorified assembly language. It's 2025 and "data type" needs to mean something more abstract than "those bytes in this order layed out in memory like this", unless we are writing hand-optimized assembly code which most of us never do.
- Philpax 1y agoWhile I agree with you to some extent - working with a higher-level language where you _don't_ have that kind of visibility is its own kind of liberating - Odin is very specifically not that kind of language, and is designed for people who want or need to operate in a machine-sympathetic fashion. I don't think that's necessary all the time, but some form of it does need to exist.
- gingerBill 1y ago> As long as programmers view a program as a mechanism that manipulates bytes in flat memory... > Yes, it will eventually manifest in memory as bytes in some memory cell... So people view a program how the computer actually deals with it? And how they need to optimize for since they are writing programs for that machine? So what is an example of you abstraction that you are talking about? Is there a language that already exists that is closer to what you want? Otherwise you are talking vaguely and abstractly and it doesn't really help anyone understand your point of view.
- jkercher 1y agoWhen I first heard about Odin, I thought, why another C replacement?! What's wrong with rust or zig? Then, after looking into it, I had a very similar experience to the author. Someone made a language just for me! It's for people who prefer C over C++ (or write C with a C++ compiler). It has the things that a C programmer has to implement themselves like tagged unions, slices, dynamic arrays, maps, and custom allocators. While providing quality of life features like distinct typing, multiple return values, and generics. It just hits that sweet spot. Now, I'm spoiled.
- christophilus 1y agoYep. It’s my favorite C-replacement. It compiles fast. It has all of the pieces and abstractions I care about and none of the cruft I don’t.
- karl_zylinski 1y agoIt's indeed some kind of sweet spot. It has those things from C I liked. And it made my favorite workflows from C into "first class citizens". Not everyone likes those workflows, but for people like me it's pretty ideal.
- lblume 1y agoMay I ask what specifically you dislike about Rust (and Zig)? All the features you mentioned are also present in these languages. Do you care about a safety vs. simplicity of the language, or something else entirely?
- ithkuil 1y agoZig is similar in spirit but I think it tapped a bit more into the "innovation budget" and thus it might not click to all
- sph 1y agoCall it a niche use-case, but every time I had the chance to evaluate Rust, I had to write a function taking a callback, sometimes across to a C library. Every time I have to deal with an Fn/FnOnce/FnMut trait signature, remember if I need to box it with dyn, mayhaps it takes a reference as argument so I also need to deal with lifetimes signatures, then remember the `for<'a>` syntax, then it blows up because I need to add `+ 'static` at the end which still makes no sense to me, then I just rage quit. I am decently handy with (unsafe) Rust, wrote a minimal OS in it, but dealing with function pointers makes me want to carve my eyes out. C doesn’t even care. You can cast an int to a function pointer if you want. With Odin it’s taken me like 5 minutes including reading the section of the docs for the first time.
- jay_kyburz 1y agoI've been messing around with Odin and Raylib for a few weeks. I've been interested in trying Raylib for a long time, it has a huge list language bindings. I chose Odin for different reasons than I think many would. Perhaps superficial reasons. I'm a game-play programmer and not really into memory management or complex math. I like things to be quick and easy to implement. My games are small. I have no need for custom allocators or SOA. All I want is a few thousand sprites at ~120fps. I normally just work in the browser with JS. I use Odin like it's a scripting language. I really like the dumb stuff like... no semicolons at the end of lines, no parentheses around conditionals, the case statement doesn't need breaks, no need to write var or let, the basic iterators are nice. Having a built in vector 2 is really nice. Compiling my tiny programs is about as fast as refreshing a browser page. I also really like C style procedural programing rather than object oriented code, but when you work in a language that most people use as OO, or the standard library is OO, your program will end up with mixed paradigms. It's only been a few weeks, but I like Odin. It's like a statically typed and compiled scripting language.
- karl_zylinski 1y agoI like this aspect about Odin. It doesn't try to fundamentally solve any new problems. Instead it does many things right. So it becomes hard to say "this is why you should use Odin". It's more like, try it for yourself and see if you like it :)
- weiwenhao 1y agoI don't mean to promote it because the nature programming language version 0.5 is not ready yet, but the nature programming language https://github.com/nature-lang/nature https://github.com/nature-lang/nature basically meets your expectations, except for the use of var to declare variables, probably because I also really like simplicity. Here's an example of how I use the nature and raylib bindings. https://github.com/weiwenhao/tetris https://github.com/weiwenhao/tetris
- sph 1y agoLooks ergonomic enough at first sight. The important thing for new languages is mindshare, so keep at it, post a Show HN when you feel it’s ready and perhaps it’ll pick up steam. (Personally I have spent my weekend evaluating C-like languages and I need a break and to reset my palate for a bit)
- jmull 1y agoThe author is excited that they can do all the things in Odin that they can do in C. So it strikes me that a new language may be the wrong approach to addressing C's issues. Can they truly not be addressed with C itself? E.g., here's a list of some commonly mentioned issues: * standard library is godawful, and composed almost entirely of foot guns. New languages fix this by providing new standard libraries. But that can be done just as well with C. * lack of help with safety. The solutions people put forward generally involve some combination of static analysis disallowing potentially unsafe operations, runtime checks, and provided implementations of mechanisms around potentially unsafe operations (like allocators, and slices). Is there any reason these cannot be done with C (in fact, I know they all have been done). * lack of various modern conveniences. I think there's two aspects of this. One is aesthetics -- people can feel that C code is inelegant or ugly. Since that's purely a matter of personal taste, we have to set that aside. The other is that C can often be pretty verbose. Although the syntax is terse, its low-level nature means that, in practice, you can end up writing a relatively large number of lines of code to do fairly simple things. C alternatives tend to provide syntax conveniences that streamline common & preferred patterns. But it strikes me that an advanced enough autocomplete would provide the same convenience (albeit without the terseness). We happen to have entered the age of advanced autocomplete. Building a new language, along with the ecosystem to support it, is a lot of fun. But it also seems like a very inefficient way to address C's issues because you have to recreate so much (including all the things about C that aren't broken), and you have to reach some critical mass of adoption/usage to become relevant and sustainable. And to be frank, it's also a pretty ineffective way to address C's issues because it doesn't actually do anything to help all the existing C code. Very few projects are in a position to be rewritten. Much better would be to have a fine-grained set of solutions that code bases could adopt incrementally according to need and opportunity Of course, I realize all this has been happening with C all along. I'm just pointing out that seems like the right approach, while these C alternatives, while fun and exciting (as far as these things go), they are probably just sound and fury that will ultimately fade away. (In fact, it might be worse if some catch on... C and all the C code bases will still be there, we'll just have more fragmentation.)
- gingerBill 1y agoI'm the creator of the Odin programming language and I originally tried to approach it by fixing C. And my conclusion was that C could not be fixed. I made my own standard library to replace libc. The lack of safety is hard to do when you don't have a decent enough type system. C's lack of a proper array type is a good example of this. Before making Odin, I tried making my own C compiler with some extensions, specifically adding proper arrays (slices) with bounds checking, and adding `defer`. This did help things a lot, but it wasn't enough. C still had fundamentally broken semantics in so many places that just "fixing" the problems of C in C was not enough. I didn't want to make Odin initially, but it was the conclusion I had after trying to fix something that cannot be fixed.
- codr7 1y agoWhich parts of the C standard library has any need for allocators?
- gingerBill 1y agoLoads of libc allocate. The trivial ones being malloc/calloc/free/strdup/etc, but many other things within it will also allocate like qsort. And that means you cannot change how those things allocate either.
- uecker 1y agomalloc/calloc/free is the allocator, so it makes no sense to pass it an allocator to it. qsort does not allocate. I think strdup is the only other function that allocates and it is a fairly new convenience function that would not be as convenient if you had to pass an allocator.
- gingerBill 1y agoMany implementations of qsort do allocate using malloc. And I know malloc/free is the allocator, but you cannot override it either.
- uecker 1y agoCan you point me to a qsort that does call malloc? This is news to me as the API is designed to not require this. There is no standard way to overwrite malloc/free (which would be a limitation when using other libraries that do not make the allocator configurable), but it is often supported (e.g. malloc_hook in GNU libc) or can be done using the linker.
- broken_broken_ 1y agoGlibc’s one does and it caused a security vulnerability: https://www.qualys.com/2024/01/30/qsort.txt https://www.qualys.com/2024/01/30/qsort.txt TBH it was also news to me, I discovered it randomly while browsing vulnerabilities… Printf also allocates, and a ton of other stdlib functions as well.
- leecommamichael 1y agoOdin was made for me, also. It has been 4 years and I’m still discovering little features that give me the control and confidence I wish I’d had writing C++. I returned to the language after a stint of work in other tech and to my utter amazement, the parametric polymorphism that was added to the language felt “right” and did not ruin the comprehensibility of the core library. Thank you gingerBill!
- drannex 1y agoBy far one of the best languages I have ever used professionally and as a hobbyist, which is why I donate every month to keep the project alive. I am dropping the link here so for those who can, should donate, and even if you don't use it, you should consider supporting this and other similar endeavors so they can't stop the signal, and keep it going: https://github.com/sponsors/odin-lang https://github.com/sponsors/odin-lang
- macintux 1y agoOdin has been hitting HN semi-regularly. A recent thread: https://news.ycombinator.com/item?id=43939520 https://news.ycombinator.com/item?id=43939520
- knowitnone 1y agoYou're saying you like Odin because it provided this feature in stdlib but how hard would it be if C provided this? And if C provided this, you'd stay with C? So this is a failure of the C community to not evolve and improve?
- karl_zylinski 1y agoThere are many additional annoying things with C. Odin just happens to choose my preferred solutions to many of those issues. It's a lot of tiny things that are right rather than a single "killer feature". I recommend just trying it and see if it makes any sense to you.
- joejoo 1y agoWhat's the vibe coding landscape look like for Odin?
- spicyusername 1y agoWhat... does that question mean? Like... how easy is it to not know how anything works and generate a "working" program, using the loosest possible definition of "working", using LLMS?
- JoeyJoJoJr 1y agoGenerally I find AI autocompletion in cursor pretty bad with Odin, and Claude generally gives me code with incorrect syntax. I think the language is too new to be effectively used with AI assistance.
- Quitschquat 1y agoI like that #soa stuff – can you make your own custom #foo thing that does other things/memory layouts etc?
- alphazard 1y agoOdin is great language. The creator GingerBill is an incredibly talented language designer and I would encourage anyone interested in programming languages to listen to some of the interviews he has done on various podcasts. The way he thinks about tradeoffs and problems when designing a language is exactly what is required to produce something like Odin. He has a level of craftsmanship that is rare. A lot of it just comes down to good taste; he's upfront about the language's influences. When something is good there's no shame in taking it. e.g. The standard library package structure is very similar to Go's. There are plenty of innovations as well. I haven't seen anything quite like the context system before, definitely not done as well as in Odin.
- 90s_dev 1y agoSo far it definitely looks like a better C.
- 90s_dev 1y agoJust looked at implicit contexts, and I'm very much on the fence about whether this is a good feature. I get what it's trying to accomplish, it just seems like perhaps the wrong solution that may cause more problems than it solves.
- tikotus 1y agoRegarding implicit context, it could be nice to use it for time. Games often have different parts running with different speeds, during for example a slowdown effect, or pause, when the game simulation runs slower but the UI should still run at normal speed. They run in different time contexts. You could be passing a time struct around, but slapping it into the context is tempting.
- gethly 1y agoI'm looking for that huge fight next year between Odin, Zig and Jai :) Odin will be hopefully finally specced. Jai will be finally out in public in a stable version. And Zig will be still at 0.x, but usable. Three will enter, but only one will be the victor.
- codr7 1y agoI don't understand why one language has to rule them all. There's room for all of them, each with its strengths and weaknesses. That's the only way they're going to keep evolving.
- gethly 1y agoIt is not about one ruling them all. But people will simply coalesce around one language and communities of the remaining languages will simply dwindle. They will all still exist but there is a reason why only few languages are mainstream. And the three I have mentioned will be essentially competing in the same playfield. Unlike Rust, JS or Go, for example, as they already have their niches. All of the three are here to compete for the place in the low-level language tier list.
- Kinrany 1y agoHaving many languages splits the ecosystem and forces us to reimplement the same things over and over again. The ultimate solution is a common base that allows interoperability of course.
- deafpolygon 1y agoThese days, it's more likely that three will enter- and ten more will emerge victorious.
- masfoobar 1y agoHonestly, I dont think it really matters if there was a fight between Odin, Zig and Jai. I doubt one is going to be a "winner" but one could be the more popular of the 3 and, chances are, it is not because the language is better but how it is advertised. Truth is Rust gets a lot of headlines especially in relation to "memory safety" being thrown around in recent years. Not saying it isn't something to be taken seriously but "Rust" and "Memory Safety" are interchangable when a non-programmer blogger writes an article. - Its Rust that being added into the Linux Kernel. - Its Rust being added to Window Kernel - Its Rust building replacement software (might I add already battle tested projects!) such as coreutil + Expect there to be (if not already) rewrites of git, nginx, sqlite -- in memory-safe, blazingly fast Rust. Rust, rust, rust, rust... RUST! Truth is Rust is taking over. This will either become a HUGE waste of time or mistake.. or it will be the standard for low-level, memory safe software... cancelling out C or C++ originals that have existed for decades (and already stable) The way things are going, you will have Rust... and in the distance (some further than others) is Go, Zig, Jai, Odin, C3, etc. Of course, language like Java, C#, Javascript, etc -- will continue as they are. This is not a dig or hatred. This is just how I see it... and I am really liking Odin. I mean what jobs will I see advertised in the next 10-15 years? I bet I will see more and more Rust in the coming years. The others I mentioned above... I expect to see some Go and some odd Zig... but will I see an Odin or Jai? I hope I am proven wrong. As I wrote, I like Odin!
- jongjong 1y agoThis reminds me of how I wrote a simple query language which can be written inside HTML attribute tags. Its killer feature is that it doesn't need quotation marks to represent strings. It knows if something is a property/variable or a string (e.g. user input) just based on its position in the command. It achieves this by being very strict with spaces. It doesn't collapse/merge multiple spaces down to one because this can wreck edge cases where a user input string might start with a space.