[HN Gopher] Odin: A programming language made for me
       ___________________________________________________________________
        
       Odin: A programming language made for me
        
       Author : gingerBill
       Score  : 162 points
       Date   : 2025-05-13 08:35 UTC (14 hours ago)
        
 (HTM) web link (zylinski.se)
 (TXT) w3m dump (zylinski.se)
        
       | mrkeen wrote:
       | > 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 wrote:
         | > why not compile-time error for reading memory that hasn't
         | been written?
         | 
         | so... like Rust?
        
           | Timwi wrote:
           | Curiously, 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 wrote:
             | That's likely because p/invoke is quite common.
        
               | neonsunset wrote:
               | No, 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 wrote:
               | The main motivation to use unsafe is p/invoke.
               | 
               | Without unsafe, zero init is not needed.
        
               | neonsunset wrote:
               | > 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 wrote:
               | Explicit 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 wrote:
             | This 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 wrote:
               | You don't need the "default" keyword to run into that. A
               | simple "new Guid()" gives you all-zeroes (try it!). Nice
               | and foot-gunny.
        
               | neonsunset wrote:
               | Only 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.
        
             | munificent wrote:
             | It 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 wrote:
         | I 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 wrote:
           | Then 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 wrote:
             | I'd guess it was because 0 init is desired often enough
             | that this is a convenient implicit default?
        
               | yusina wrote:
               | "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?
        
               | sph wrote:
               | Please, 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
        
               | yusina wrote:
               | I'm actually with you on the ease of use. I don't see
               | this as the opposite to safety. To me, making it harder
               | for me to make mistakes means it's easier to use. That
               | is, easier to use right and harder to use wrong. I'm not
               | a Rust or Ada advocate. I'm just saying that making it
               | harder to make the same mistakes people have been doing
               | for decades would be a good thing. That would contribute
               | to ease-of-use in my book since there are fewer things
               | you need to think about that could possibly go wrong.
               | 
               | Or are you saying that a certain level of bugs is fine
               | and we are at that level? Are you fine with the quality
               | of all the software out there? Then yes, this discussion
               | is probably not for you.
        
               | sph wrote:
               | > Are you fine with the quality of all the software out
               | there?
               | 
               | This is the kind of generalisation I'm ranting against.
               | 
               | It is not constructive to extrapolate any kind of
               | discussion about a single, perhaps niche, programming
               | languages with applicable advice for "all the software
               | out there". But you probably knew that already.
        
               | vacuity wrote:
               | TL;DR: I disagree, and I will say upfront that my views
               | on software are extreme. I think quality is a glaring
               | issue in most software.
               | 
               | There is a lot of subpar software out there, and the rest
               | is largely decent-but-not-great. If it's security I want,
               | that's commonly lacking, and hugely so. If it's
               | performance I want, that's commonly lacking[0]. If it's
               | documentation...you get the idea. We should have rigor by
               | default, and if that means software is produced slower, I
               | frankly don't see the problem with that. (Although
               | commercial viability has gone out the window unless big
               | players comply.) Exceptions will be carved out depending
               | on the scope of the program. It's much harder to add in
               | rigor _post hoc_. The end goal is _quality_.
               | 
               | The other issue is that a program's scope is indeed
               | broader than controlling lives, and yet there are many
               | bad outcomes. If I just get my passwords stolen or my
               | computer crashes daily or my messaging app takes a bit
               | too long to load every time, what is the harm? Of course
               | those are wildly different outcomes, but I think at least
               | the first and second are obviously quality issues, and I
               | think the third is also important. Why is the third
               | important? When software is such an integral part of
               | users' lives, minor issues cause faults that prompt
               | workarounds or inefficiencies. [1] discusses a similar
               | line of thought. I know I personally avoid doing some
               | actions commonly (e.g. check LinkedIn) because they
               | involve pain points around waiting for my browser to load
               | and whatnot, nothing major but something that's always
               | present. Software ("automation") in theory makes all
               | things that the user implicitly desires to be non-pain
               | points for the user. An interesting blend of issues is
               | system dialog password prompts, which users will
               | generally try to either avoid or address on autopilot,
               | which tends to reduce security. Or take system update
               | restarts, which induce not updating frequently. Or take
               | what is perhaps my favorite invectives: blaming Electron
               | apps. One Electron app can be inconvenient. Multiple
               | Electron apps can be absurd. I feel like I shouldn't have
               | to justify calling out Electron on HN, but I do, but I
               | won't here. And take unintended uses: if I need to set
               | down an injured person across two chairs, I sure hope a
               | chair doesn't break or something. Sure, that's not the
               | intended use case of a chair, but I don't think it's
               | unreasonable that a _well-made_ chair would not fail to
               | live up to my expectations. I wouldn 't put an elephant
               | on the chair either way, because intuitively I don't
               | expect that much. Even then, users may expect more out of
               | software than is reasonable, but that should be remedied
               | and not overlooked.
               | 
               | Do not mistake having users for having a quality product.
               | 
               | [0] https://news.ycombinator.com/item?id=43971464 [1]
               | https://blog.regehr.org/archives/861
        
               | 90s_dev wrote:
               | You seem to use eager evaluation of usability whereas in
               | practice most people only need lazy evaluation. We use
               | risk assessment of going from point A to point B, two
               | concrete points. You seem to use risk assessment
               | equivalent to JavaScript's array.flat(Infinity).
        
               | vacuity wrote:
               | We don't need to talk about theoretical risks. Is there
               | not something wrong about a calculator app asking for
               | contacts and location permissions[0]? Are ads fine if
               | they can be used to track every detail of what you do and
               | want? Was it fine when CrowdStrike caused Windows systems
               | in airports BSOD and lead to massive delays? I'm not even
               | talking about threats to life here. There is plenty of
               | evidence that a lot of software has...issues. If you
               | haven't come across one that you consider indicative, try
               | waiting a few years. Time doesn't heal bugs that don't
               | get fixed, and the best case scenario is a headache or
               | some lost money. You can say "in practice most people
               | only need lazy evaluation" because the reality isn't that
               | software quality is overall mediocre, it's that there
               | aren't delightfully convenient alternatives to switch to.
               | In practice, most people only need something that
               | somewhat works, even when it often doesn't, because
               | complaining otherwise is unproductive.
               | 
               | And you seem to have ignored a lot of what I said, as if
               | I was just talking about a few rare, critical problems.
               | 
               | [0] https://old.reddit.com/r/unpopularopinion/comments/d6
               | g6qr/it...
        
               | johnnyjeans wrote:
               | For the same reason you wear a seatbelt and not a 7-point
               | crash harness.
        
             | layer8 wrote:
             | Operating systems usually initialize new memory pages to
             | zero by default, for security reasons, so that a process
             | can't read another process's old data. So this gives you
             | zero-initialization "for free" in many cases. Even when the
             | in-process allocator has to zero out a memory block upon
             | allocation, this is generally more efficient than the
             | corresponding custom data-type-specific default
             | initialization.
             | 
             | If you have a sparse array of values (it might be structs),
             | then you can use a zero value to mark an entry that isn't
             | currently in use, without the overhead of having to
             | (re-)initialize the whole array up-front. In particular if
             | it's only one byte per array element that would need to be
             | initialized as a marker, but the compiler would force you
             | to initialize the complete array elements.
             | 
             | Similarly, there are often cases where a significant part
             | of a struct typically remains set to its default values. If
             | those are zero, which is commonly the case (or commonly can
             | be made the case), then you can save a significant amount
             | of extra write operations.
             | 
             | Furthermore, it also allows flexibility with algorithms
             | that lazy-initialize the memory. An algorithm may be
             | guaranteed to always end up initializing all of its memory,
             | but the compiler would have no chance to determine this
             | statically. So you'd have to perform a dummy initialization
             | up-front just to silence the compiler.
        
           | bobbylarrybobby wrote:
           | If you zero initialize a pointer and then dereference it as
           | if it were properly initialized, isn't that UB?
        
             | jerf wrote:
             | It is undefined behavior in C. In many languages it is
             | defined behavior; for instance in Go, dereferencing a nil
             | pointer explicitly panics, which is a well-defined
             | operation. It may, of course, crash your program, and the
             | whole topic of 'should pointers even be _able_ to be nil? '
             | is a valid separate other question, but given that they
             | exist, the operation of dereferencing a nil pointer is not
             | undefined behavior in Go.
             | 
             | To many people reading this this may be a "duh" but I find
             | it is worth pointing out, because there are still some
             | programmers who believe that C is somehow the "default" or
             | "real" language of a computer and that everything about C
             | is true of other languages, but that is not the case.
             | Undefined behavior in C is undefined _in C, specifically_.
             | Try to avoid taking ideas about UB out of C, and to the
             | extent that they are related (which slowly but surely
             | decreases over time), C++. It 's the language, not the
             | hardware that is defining UB.
        
               | gingerBill wrote:
               | This is a common thing I get annoyed with when explaining
               | to people too about Odin. Odin also defines dereferencing
               | `nil` as panicking (as on all systems with virtual
               | memory, it comes for free).
               | 
               | C is just one language of many and you do not have to
               | define the rules of a new language to it.
        
         | tlb wrote:
         | Being 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 wrote:
           | > 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
           | 
           | [2]: https://issuetracker.google.com/issues/42402087?pli=1
        
             | gingerBill wrote:
             | > 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.
        
               | nlitened wrote:
               | > C programmers, then `int x;` can either have a value
               | which is just not known at compile time
               | 
               | I am pretty sure that in C, when a program reads
               | uninitialized variable, it is an "undefined behavior",
               | and it is pretty much allowed to be expected to crash --
               | for example, if the variable turned out to be on an
               | unallocated page of stack memory.
               | 
               | So literally the variable does not have a value at all,
               | as that part of address space is not mapped to physical
               | memory.
        
               | gingerBill wrote:
               | It is "undefined behaviour" in C (which is an overloaded
               | term which I will not discuss why I hate it in this
               | comment). But my point was that is how many people
               | conceptualize it, and for many things people do expect it
               | to be one of the possible values, just not knowable ahead
               | of time.
               | 
               | However, I was using that "C programmers" bit to explain
               | the conceptualization aspect, and how it also applies to
               | other languages. Not every language, even systems
               | languages, have the same concepts as C, especially the
               | same construction as "UB".
        
               | shwouchk wrote:
               | As someone who recently wondered what kinds of things
               | might happen, im actually very glad for GPs
               | clarification.
        
               | uecker wrote:
               | It is undefined in C for automatic variables whose
               | address was not taken (and in this case a compiler should
               | be able to warn).
        
               | steveklabnik wrote:
               | Interestingly enough, C++26 introduces "erroneous
               | behavior" and uses it for uninitialized variables, rather
               | than undefined behavior.
        
               | maccard wrote:
               | The problem is that "allowed to be expected to crash" is
               | one interpretation. Another is "0 initialized" (which
               | debug runtimes sometimes use), another is "whatever was
               | on the stack last time" and another is "we can reorder
               | program and eliminate what you think is logical code".
               | int main() {           int val;           if (val == 3) {
               | cout << "here" << end;           }           return 0;
               | }
               | 
               | A perfectly legal interpretation of this program is to
               | remove the call to cout, as is just printing "here" on
               | every run.
               | 
               | > So literally the variable does not have a value at all,
               | as that part of address space is not mapped to physical
               | memory.
               | 
               | There are vanishingly few platforms where the stack you
               | have in a C program maps to physical memory (even if you
               | consider pages from the OS)
        
             | chipsrafferty wrote:
             | The unsafe part is supposed to tell you that any
             | assumptions you might make might not hold true.
        
         | gingerBill wrote:
         | You'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 wrote:
           | That'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 wrote:
             | > 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
        
               | iainmerrick wrote:
               | That's what I was trying to get at by talking about
               | making ZII opt-in. If you're using a big chunk of memory
               | -- say a matrix, or an array of matrices -- it's a win if
               | you can zero-initialize it cheaply or for free, sure. In
               | JS, for example, you'd allocate an ArrayBuffer and use it
               | immediately (via a TypedArray or DataView).
               | 
               | But still, in other parts of the program, ZII is bad!
               | That local or global variable pointing at an ArrayBuffer
               | should definitely not be zero-initialized. Who wants a
               | null pointer, or a pointer to random memory of unknown
               | size? Much better to ensure that a) you actually
               | construct a new TypedArray, and b) you don't use it until
               | it's constructed.
               | 
               | I guess if you see the vast majority of your action
               | happening inside big arrays of structs, pervasive ZII
               | might make sense. But I see most of the action happening
               | in local and temporary variables, where ZII is bad and
               | explicit initialization is what you want.
               | 
               | Moving from JavaScript to TypeScript, to some extent you
               | can get the best of both worlds. TS will do a very good
               | (though not perfect) job of forcing you to initialize
               | everything correctly, but you can still use TypedArray
               | and DataView and take advantage of zero-initialization
               | when you want to.
               | 
               | ZII for local variables reminds me of the SmallTalk /
               | Obj-C thing where you could send messages to nil and
               | they're silently ignored. I don't really know SmallTalk,
               | but in Obj-C, to the best of my knowledge most serious
               | programmers think messages to nil are a bad idea and a
               | source of bugs.
               | 
               | Maybe this is another aspect where the games programming
               | mindset is skewing things (besides the emphasis on low-
               | level performance). In games, avoiding crashes is super
               | important and you're probably willing to compromise on
               | correctness in some cases. In most non-games
               | applications, correctness is super important, and
               | crashing early if something goes wrong is actually
               | preferable.
        
               | gingerBill wrote:
               | Making it opt-in, means making the hierarchical approach
               | the default. Whatever you make "opt-in" means you are by
               | default discouraging its use. And what you are suggesting
               | as the default is not what I wanted from Odin (I am the
               | creator by the way).
               | 
               | I normally say "try to make the zero value useful" and
               | not "ZII" (which was a mostly jokey term Casey Muratori
               | came up with to reflect against RAII) because then it is
               | clear that there are cases when it is not possible to do
               | ZII. ZII is NOT a _maxim_ but what you should default to
               | and then do something else where necessary. This is my
               | point, and I can probably tell you even more examples of
               | where "ZII is bad" than you could think of, but this is
               | what is a problem describing the problem to people: they
               | take it as a maxim not a default.
               | 
               | And regarding pointers, I'm in the camp that nil-pointers
               | are the most trivial type of invalid pointer to catch
               | empirically speaking. Yes they cause problems, but
               | because how modern systems are structured with virtual
               | memory, they are empirically trivial to catch and deal
               | with. Yes you could design the type system of a language
               | to make nil-pointers not be a thing unless you explicit
               | opt into them, but then that has another trade-off which
               | may or may not be a good thing depending on the
               | application.
               | 
               | The Objective-C thing is just a poorly implemented system
               | for handling `nil`. It should have been more consistent
               | but wasn't. That's it.
               | 
               | I'd argue "correctness" is important in games too, but
               | the conception of "correctness" is very different there.
               | It's not about provability but testability, which are
               | both valid forms of "correctness" but very different.
               | 
               | And in some non-game applications, crashing early is also
               | a very bad thing, and for some games, crashing early is
               | desired over corrupted saves or other things. It's all
               | about which trade-offs you can afford, and I would not
               | try to generalize too much.
        
               | iainmerrick wrote:
               | Yeah, that's fair, clearly this sort of thing is why we
               | have multiple languages in the first place!
               | 
               | I don't think I'll ever abandon the idea that making code
               | "correct by construction" is a good goal. It might not
               | always be achievable or practical but I strongly feel
               | it's always something to aim for. For me, silent zero
               | initialization compromises that because there isn't
               | always a safe default.
               | 
               | I think nil pointers are like NaNs in arithmetic. When a
               | nil or a NaN crops up, it's too late to do anything
               | useful with it, you generally have to work backwards in
               | the debugger to figure out where the real problem
               | started. I'd much rather be notified of problems
               | _immediately_ , and if that's at compile time, even
               | better.
               | 
               | In the real world, sure, I don't code review every single
               | arithmetic operation to see if it might overflow or
               | divide by zero. But when the compiler can spot potential
               | problem areas and force me to check them, that's really
               | useful.
        
               | Rusky wrote:
               | If you don't want to make it "opt-in" would it at least
               | make sense to make it "opt-out"? Does Odin have a way for
               | specific types to omit a zero value?
        
               | gingerBill wrote:
               | That would require having constructors, which is not
               | something Odin will ever have nor should it. However you
               | can just initialize with a constant or variable or just
               | use a procedure to initialize with. Odin is a C
               | alternative after all, so it's a fully imperative
               | procedural language.
        
               | Rusky wrote:
               | Why would it require constructors? As opposed to simply
               | enforcing that it always be initialized with a
               | constant/variable/procedure/etc rather than zeroed.
        
               | igouy wrote:
               | > the SmallTalk / Obj-C thing where you could send
               | messages to nil and they're silently ignored.
               | 
               | Messages sent to the Smalltalk UndefinedObject instance
               | are not silently ignored -- #doesNotUnderstand.
               | 
               | Sometimes that run time message lookup has been used to
               | extend behavior --
               | 
               | 1986 "Encapsulators: A New Software Paradigm in
               | Smalltalk-80"
               | 
               | https://dl.acm.org/doi/pdf/10.1145/28697.28731
        
               | igouy wrote:
               | For example, send #class to nil                   nil
               | class UndefinedObject
               | 
               | For example, send #iainmerrick to nil
               | nil iainmerrick              Object>>doesNotUnderstand:
               | UndefinedObject>>{unbound}doIt
        
         | slowmovintarget wrote:
         | Here's Casey Muratori on his habit of moving to ZII:
         | 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 wrote:
           | These 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 wrote:
             | > 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 wrote:
               | _But 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 wrote:
               | It'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 wrote:
         | I 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 wrote:
           | I'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 wrote:
             | It 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 wrote:
               | Sure, 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.
        
         | dooglius wrote:
         | > why not compile-time error for reading memory that hasn't
         | been written
         | 
         | https://en.wikipedia.org/wiki/Rice%27s_theorem?useskin=vecto...
        
           | TheCoelacanth wrote:
           | A 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 wrote:
             | Sure, but then not accepting many programs would be the
             | answer to parent's question "why not"
        
               | jerf wrote:
               | Not 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 wrote:
               | I 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.
        
               | reverius42 wrote:
               | It may not be feasible in the general case by changing
               | the compiler, but it's definitely feasible in the general
               | case by changing the language. If you can't specify an
               | uninitialized variable syntactically then you don't have
               | to analyze whether it exists semantically.
        
           | trealira wrote:
           | Somehow Rust is able to do it, though. Is it really that hard
           | for compilers to do flow analysis to detect and forbid uses
           | of uninitialized variables? Not even being sarcastic, I
           | genuinely would like to know why more languages don't do
           | this.
        
             | trealira wrote:
             | This is a self-response, but I've thought of a case where
             | it might be fairly difficult for a compiler to prove a
             | variable is always initialized, because of the use of
             | pointers. Take this function to copy a linked list in C:
             | struct node {           struct node *next;           int
             | data;       };            struct node *copy_list(struct
             | node *list_node) {           struct node *new_list,
             | **indirect;                indirect = &new_list
             | while (list_node != NULL) {               // Pretend malloc
             | can't fail               struct node *np =
             | malloc(sizeof(*np));               np->data =
             | list_node->data;               *indirect = np;
             | indirect = &np->next;               list_node =
             | list_node->next;           }           *indirect = NULL;
             | return new_list;       }
             | 
             | The variable "new_list" is always initialized, no matter
             | what, even though it's never explicitly on the left hand
             | side of an assignment. If the while loop never ran, then
             | indirect is pointing to the address of new_list after the
             | loop, and the "*indirect = NULL;" statement sets it to
             | NULL. If the loop did run, then "new_list" is set to the
             | result of a call to malloc. In all cases, the variable is
             | set.
             | 
             | But it feels like it would be hard for something that isn't
             | a formal proof assistant to prove this. The equivalent Rust
             | code (unidiomatic as it would be to roll your own linked
             | list code) would require you to set "new_list" to be None
             | before the loop starts.
        
             | steveklabnik wrote:
             | The flow analysis isn't particularly hard, but lots of
             | languages simply don't do it because they don't allow
             | uninitialized variables in the first place. Given null is a
             | pretty common concept, you just say they're initialized but
             | null, and you don't even need to do the analysis at all.
        
         | drannex wrote:
         | Not 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 wrote:
           | Yes, this is mentioned explicitly in the article.
        
         | melodyogonna wrote:
         | You're talking about Mojo there. Even memory allocated with
         | UnsafePointer must be explicitly initialised before it can be
         | written to or read from.
        
         | variadix wrote:
         | This 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 wrote:
           | The 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 wrote:
             | If 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 wrote:
         | 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?
         | 
         | see 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...
        
           | Arnavion wrote:
           | >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 wrote:
         | Same. 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 wrote:
       | You 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-
       | all...
       | 
       | [2]: https://nullprogram.com/blog/2023/10/08/
        
         | arp242 wrote:
         | > 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 wrote:
         | The 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 wrote:
           | I 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.
        
             | gingerBill wrote:
             | Because to be _standard_, it would have to come with the
             | compiler toolchain. And if it's scattered around on the
             | internet, people will not use it.
             | 
             | I tried to create my own alternative about a decade ago
             | which eventually influenced my other endeavours.
             | 
             | But another big reason is that people use C and its stdlib
             | because that's what it is. Even if it is bad, its the
             | "standard" and trivially available. Most code relies on it,
             | even code that has its own standard library alternative.
        
             | HexDecOctBin wrote:
             | > Why has nobody come along and created an alternative
             | standard library yet?
             | 
             | Everybody has created their own standard library. Mine has
             | been honed over a decade, why would I use somebody else's?
             | And since it is designed for my use cases and taste, why
             | would anyone use mine?
        
             | yusina wrote:
             | > Why has nobody come along and created an alternative
             | standard library yet?
             | 
             | Because people are so terribly opinionated that the only
             | common denominator is that the existing thing is bad. For
             | every detail that somebody will argue a modern version
             | should have, there will be somebody else arguing the exact
             | opposite. Both will be highly opinionated and for each of
             | them there is probably some scenario in which they are
             | right.
             | 
             | So, the inability of the community to agree on what "good"
             | even means, plus the extreme heterogenity of the use cases
             | for C is probably the answer to your question.
        
             | dspillett wrote:
             | _> Why has nobody come along and created an alternative
             | standard library yet?_
             | 
             | Probably, IMO, because not enough people would agree on any
             | particular secondary standard such that one would gain
             | enough attention and traction1 to be remotely considered
             | standard. Everyone who already has they own alternatives
             | (or just wrappers around the current stdlib) will most
             | likely keep using them unless by happenstance the new
             | secondary standard agrees (by definition, a standard needs
             | to be at least somewhat opinionated) closely with their
             | local work.
             | 
             | Also, maintaining a standard, and a public implementation
             | of it, could be a faffy and thankless task. I certainly
             | wouldn't volunteer for that!
             | 
             | [Though I am also an outsider on the matter, so my
             | thoughts/opinions don't have any particular significance
             | and in insider might come along and tell us that I'm
             | barking up the wrong tree]
             | 
             | --------
             | 
             | [1] This sort of thing _can_ happen, but is rare. jquery
             | became an unofficial standard for DOM manipulation and
             | related matters for quite a long time, to give one example
             | - but the gulf between the standard standard (and its bad
             | common implementations) at the time and what libraries like
             | jquery offered was much larger than the benefits a
             | secondary C stidlib standard might give.
        
           | uecker wrote:
           | I would not agree that the ergonomics are so much better in
           | Odin that switching to another language is worth giving up
           | the advantages of a much larger ecosystem. For a hobby
           | project this may not matter at all, of course.
        
             | gingerBill wrote:
             | Odin has very good FFI with its `foreign import` system, so
             | you can still use libraries written in C, Objective-C, or
             | any other language. And Odin does support tools like asan,
             | tsan, etc already too. So what are the thing that you are
             | giving up if you were using Odin instead of C?--in
             | practice.
        
               | uecker wrote:
               | Use of libraries via FFI also has a cost in terms of
               | ergonomics. But then, what do you give up: For C, many
               | tools exist that support C from very basic stuff such as
               | syntax highlighting to formal verification etc. There are
               | plenty of C programmers, C tutorials, C books etc. There
               | is an industry supporting tooling with many different
               | implementations even for obscure platforms. There is an
               | ISO standard and processes for certification. It is also
               | basically guaranteed that C exists and will be supported
               | in the next 50 years no matter what. Once you start using
               | a niche language you lose a lot of this.
               | 
               | (But I think Odin is great!)
        
               | nickpsecurity wrote:
               | For those use cases, I've always encouraged new languages
               | to support transiting to a verifiable subset of C or
               | another language with such tooling. Errors detected in
               | the other language can be corrected in the source written
               | in the new language. The abstraction gaps must be
               | minimized, though.
        
       | yusina wrote:
       | As 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.
        
         | gingerBill wrote:
         | > 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.
        
           | yusina wrote:
           | Real world example. You go sit in your ICE car. You press the
           | gas pedal and the car starts moving. And that's your mental
           | model. Depressing pedal = car moves. You do _not_ think
           | "depress pedal" = "more gasoline to the engine" = stronger
           | combustion" = "higher rpm" = "higher speed". But that's the
           | level those C and C-like language discussions are always on.
           | The consequence of you using this abstraction in your car is
           | that switching to a hybrid or lately an EV is seemless for
           | most people. Depress pedal, vehicle moves faster. Whether
           | there is a battery involved or some hydrogen magic or an ICE
           | is insubstantial. Most of the time. Exceptions are race track
           | drivers. But even those drop off their kids at school during
           | which they don't really care what's under the hood as long as
           | "depress pedal" = "vehicle moves faster".
        
             | yusina wrote:
             | And you were perhaps asking about programming languages.
             | Python does not model objects as bytes in physical memory.
             | Functional languages normally don't. That all has
             | consequences, some of which the "close to the metal" folks
             | don't like. But throwing the "but performance" argument at
             | anyhing that moves us beyond the 80s is really getting old.
        
               | gingerBill wrote:
               | Thank you for telling me you have no idea why people want
               | or need to use a systems-level programming language.
               | 
               | And yes, I explicitly asked for a language: "Is there a
               | language that already exists that is closer to what you
               | want?", which means you reading comprehension isn't very
               | high.
               | 
               | In your analogy, it's still extremely oversimplified
               | because what about a manual car, of which I have only
               | ever driven. I don't have just acceleration and break,
               | but also a clutch. I also have to many other things too
               | to deal with. It's no where near as simple as you are
               | making out, and thus kind of makes your analogy useless.
        
               | yusina wrote:
               | > Thank you for telling me you have no idea why people
               | want or need to use a systems-level programming language.
               | 
               | > And yes, I explicitly asked for a language: "Is there a
               | language that already exists that is closer to what you
               | want?", which means you reading comprehension isn't very
               | high.
               | 
               | Really? Two insults packaged into two paragraphs? Was
               | that really necessary? It's possible to discuss technical
               | disagreements without insulting others.
               | 
               | I'm doing systems-level programming every day, some of it
               | involves C. It provides me with the perspective from
               | which I'm expressing my views. There are other views,
               | thankfully, and a discussion allows to highlight the
               | differences and perhaps provide everybody with a learning
               | opportunity. That's what I'm here for.
               | 
               | Obviously I saw that you asked for a language and I
               | replied to that. I separated the concrete answer to avoid
               | getting things mixed up with the more general point.
        
               | gingerBill wrote:
               | The insults were warranted.
               | 
               | Your initial comment was effectively describing object
               | relational models for every expression, like where `a.b`
               | is some database query across the world "shouldn't matter
               | to you". So saying we should get away from the model of
               | programming that reflects the underlying hardware and do
               | something more "abstract" but not be clear on what you
               | mean by this, this is all kind of insane.
               | 
               | And then the examples of languages you gave being Python
               | (a high level interpreted language that is several orders
               | of magnitude slower than any systems language) and
               | "functional languages" which is still quite vague. If
               | Python is close to what you want (and by that I mean the
               | object-model, and not the declaration syntax), then it is
               | not applicable to anything systems related.
               | 
               | > But throwing the "but performance" argument at
               | [anything] that moves us beyond the 80s is really getting
               | old.
               | 
               | And your knowledge of computers appears to be stuck in
               | the 80s too. There is a reason people want what they
               | want, and why the author of the article likes what Odin
               | is offering. Systems-level programmers want the control
               | to program effectively for the machine. And yes
               | "performance" is actually important, and sadly most
               | programmers don't seem to care whatsoever. There is a
               | reason everything is a web browser now, even the Windows
               | 11 task bar is a web browser. Everything is many many
               | orders of magnitude slower than it needs to be, nor even
               | would be if naively implemented. Knowing how memory is
               | laid out, how it is allocated, how it will be affected by
               | cache-lines, how to properly utilize SIMD, and so much
               | more, is extremely important. None of which was even a
               | concern in the 80s.
        
               | yusina wrote:
               | > The insults were warranted.
               | 
               | They never are.
               | 
               | https://news.ycombinator.com/newsguidelines.html
        
               | AnimalMuppet wrote:
               | > The insults were warranted.
               | 
               | Perhaps they were. _Don 't give them, even if they are
               | warranted._ See the site guidelines for why.
        
               | gingerBill wrote:
               | Sure. What I originally wrote was not actually intended
               | to be an insult, but I didn't mind calling it that if he
               | took it as insulting.
               | 
               | It's just very weird to see be very vague when
               | questioned, and claim things which cannot be true based
               | on what he's stated already in this comment chain.
        
               | finnh wrote:
               | I'm with you here. The whole diatribe falls firmly under
               | "tell me you've never needed to write performant code
               | without telling me you've never needed to write
               | performant code..."
        
             | pjc50 wrote:
             | The perfect analogy, because sometimes people want to drive
             | a manual car, and sometimes people aren't American and it's
             | the default.
        
               | tough wrote:
               | PRESS PEDAL CAR STOPS
               | 
               |  _DIDNT SHIFT UP_
        
             | Intermernet wrote:
             | This may be true, but it's also false. Many regular drivers
             | have an understanding of how the machine they're driving
             | works. Mechanical sympathy is one of the most important
             | things I've ever learnt. It applies to software as well.
             | Knowing how the data structures are laid out in memory,
             | knowing how the cache works, knowing how the compiler
             | messes with the loops and the variables. These aren't
             | necessarily vital information, and good compilers mean that
             | you can comfortably ignore much of these things, but this
             | knowledge definitely makes you a better developer. Same as
             | knowing how the fuel injection system or the aspiration of
             | your ICE will make you a better driver.
        
               | yusina wrote:
               | I'm totally with you that it's useful knowledge. One of
               | the main differences between a Youtube/bootcamp trained
               | programmer and a university-CS-educated software
               | engineer, though either "side" has outliers too.
               | 
               | But there is a fine line between having general
               | understanding of the details of what's going on inside
               | your system and using that knowledge to do very much
               | premature optimizations and getting stuck in a corner
               | that is hard to get out of. Large parts of our industry
               | are in such a corner.
               | 
               | It's fun to nerd out about memory allocators, but that's
               | not contributing to overall improvements of software
               | engineering as a craft which is still too much ad hoc
               | hacking and hoping for the best.
        
             | hoseja wrote:
             | Uhhhhh that's kind of how I think about the gas pedal
             | though. There's some lag. The engine might stall a bit if
             | you try to accelerate uphill in a wrong way. There's ideal
             | RPM range. Etc.
        
             | johnnyjeans wrote:
             | > You do not think
             | 
             | Actually I do, and I include the inertia and momentum of
             | every piece of the drive-train as well, and the current
             | location of the center of gravity. I'm thinking about all
             | of these things through the next predicted 5 seconds or so
             | at any given time. It comes naturally and subconsciously.
             | To say nothing of how you really aren't going to be driving
             | a standard transmission without that mental model.
             | 
             | Your analogy is appropriate for your standard American
             | whose only experience with driving a car is the 20 minute
             | commute to work in an automatic, and thus more like a
             | hobbyist programmer or a sysadmin than someone whose actual
             | craft is programming. Do you really think truckers don't
             | know in their gut what their fuel burn rate is based on how
             | far they've depressed the pedal?
        
         | StopDisinfo910 wrote:
         | > Instead, data needs to be viewed more abstractly.
         | 
         | There is no instead here. This is not a choice that has to be
         | made once and for all and there is no correct way to view
         | things.
         | 
         | Languages exist if you want to have a very abstract view of the
         | data you are manipulating and they come with toolchains and
         | compilers that will turn that into low level representation.
         | 
         | That doesn't preclude the interest of languages which expose
         | this low level architecture.
        
           | yusina wrote:
           | Sure. But solving problems at the wrong level of abstraction
           | is always doomed to fail.
        
             | StopDisinfo910 wrote:
             | That would be true if it was always the wrong level of
             | abstraction.
             | 
             | It's obviously not for the low level parts of the toolchain
             | which are required to make very abstract languages work.
        
         | Philpax wrote:
         | While 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.
        
         | card_zero wrote:
         | It's always current_year, and I like bytes, thanks.
        
         | lynx97 wrote:
         | Well, the DOD people keep finding that caring about the cache
         | is more helpful regaring performance then the casual programmer
         | might think. Even compiler people are thinking about ditching
         | the classical AST for something DOD-based. I admin HPC systems
         | as a dayjob, and I rarely see programmers aware of modern CPU
         | design and how to structure your data such that it actually
         | performs. I get that you'd like to add more abstractions to
         | make programming easier, but I worry that this only adds to the
         | (already rampant) inefficiency of most programs. The
         | architecture is _NOT_ irrelevant. And with every abstraction
         | you put in, you increase the distance the programmer has from
         | knowing how the architecture works. Maybe thats fine for Python
         | and other high level stuff, but it is not a good idea IMO when
         | dealing with programs with longer runtimes...
        
           | yusina wrote:
           | That's great! Let the compiler figure out the optimal data
           | layout then! Of course the architecture is relevant. But does
           | everybody need to consider L2 and L3 sizes all the time?
           | Optimizing this is for machines, with very rare exceptions.
           | Expecting every programmer to do optimal data placement by
           | hand is similar to expecting every programmer to call malloc
           | and free in the right order and the correct number of times.
           | And we know how reliable that turned out.
        
             | lynx97 wrote:
             | I am reluctant to believe compiler optimisations can do
             | everything. Kind of reminds me of the time when people
             | thought auto parallelisation would be a plausible thing. It
             | never really happened, at least not in a predictably
             | efficient way.
        
             | gingerBill wrote:
             | The compiler cannot know the _purpose_ of your program, and
             | thus cannot "figure out the optimal data layout". It's
             | metaphysically not possible, let alone technically.
             | 
             | Not everybody needs to worry about L2 or L3 most of the
             | time, but if you are using a systems-level programming
             | language where it might be of a concern to you at some
             | point, it's extremely useful to be able to have that
             | control.
             | 
             | > expecting every programmer to call malloc and free in the
             | right order
             | 
             | The point of custom allocators is to not need to do the
             | `malloc`/`free` style of memory allocation, and thus reduce
             | the problems which that causes. And even if you do still
             | need that style, Odin and many other languages offer
             | features such as `defer` or even the memory tracking
             | allocator to help you find the problems. Just like what was
             | said in the article.
        
             | johnnyjeans wrote:
             | > That's great! Let the compiler figure out the optimal
             | data layout then!
             | 
             | GHC, which is without a doubt the smartest compiler you can
             | get your grubby mitts on, is still an extremely stupid git
             | that can't be trusted to do basic optimizations. Which is
             | exactly why it exposes so many special intrinsic functions.
             | The "sufficiently smart compiler" myth was thoroughly
             | discounted over 20 years ago.
        
             | munificent wrote:
             | _> Let the compiler figure out the optimal data layout
             | then!_
             | 
             | Unfortunately, that's not possible. The optimal data layout
             | depends on the order that data is accessed, which isn't
             | knowable without knowing all possible ways the program
             | could execute on all possible inputs.
        
           | whstl wrote:
           | IMO, DOD shows that you don't have to sacrifice developer
           | ergonomics for performance.
           | 
           | ECS is vastly superior as an abstraction that pretty much
           | everything that we had before in games. Tightly coupled
           | inheritance chains of the 90s/2000s were minefields of bugs.
           | 
           | Of course perhaps not every type of app will have the same
           | kind of goldilocks architecture, but I also doubt anyone will
           | stumble into something like that unless they're prioritizing
           | it, like game programmers did.
        
             | gingerBill wrote:
             | I won't get into it too much but virtually no one needs
             | ECS, and if you have to ask how to do it, it's not for you.
             | There are much better ways to organize a game for most
             | people than the highly generic relational-database-like
             | structure that is ECS. ECS does make sense in certain
             | contexts but most people do not need it.
             | 
             | But I agree that DOD in practice is not a compromise
             | between performance and ergonomics, and Odin kind of shows
             | how that is possible.
        
           | bob1029 wrote:
           | > caring about the cache is more helpful regaring performance
           | then the casual programmer might think.
           | 
           | Cache is easily the most important consideration if you
           | intend to go fast. The instructions are meaningless if they
           | or their dependencies cannot physically reach the CPU in
           | time.
           | 
           | The latency difference between L1/L2 and other layers of
           | memory is quite abrupt. Keeping workloads in cache is often
           | as simple as managing your own threads and tightly
           | controlling when they yield to the operating system. Most
           | languages provide some ability to align with this, even the
           | high level ones.
        
           | keybored wrote:
           | > Even compiler people are thinking about ditching the
           | classical AST for something DOD-based.
           | 
           | Andrew Kelley rewrote the Zig compiler in that style and got
           | great speedups.
        
         | rixed wrote:
         | Ideally, the same language would allow programmers to see
         | things at different abstraction levels, no? Because when you
         | are stuck with bytes and allocators and doing everything else
         | manually, it's detious and you develop hand arthritis in your
         | 30s. But when you have only abstractions and the performances
         | are inacceptable because no magic happened, then it's not great
         | either.
        
         | ulbu wrote:
         | and we should probably look at alcoholic liver disease as an
         | expression of capitalism.
         | 
         | data is bytes. period. your suggestion rests on someone else
         | seeing how it is the case and dealing with it to provide you
         | with ways of abstraction you want. but there is an infinity of
         | possible abstractions - while virtual memory model is a single
         | solid ground anyone can rest upon. you're modeling your
         | problems on a machine - have some respect for it.
         | 
         | in other words - most abstractions are a front-end to
         | operations on bytes. it's ok to have various designs, but
         | making lower layers inaccessible is just sad.
         | 
         | i say it's the opoposite - it's 2025, we should stop stroking
         | the imaginaries of the 80s and return to the actual. just
         | invest in making it as ergonomic and nimble as possible.
         | 
         | i find it hard understand why some programmers are _so_ intent
         | on hiding from the space they inhabit.
        
           | codr7 wrote:
           | OCD
           | 
           | Pretending to control the situation feels better than
           | embracing the chaos.
        
         | jandrewrogers wrote:
         | In the kinds of applications that require a systems language
         | you need to know the object layouts, it isn't avoidable.
         | Algorithm selection over those objects is dependent on the
         | physical object layout and hardware architecture based on the
         | use case. The compiler doesn't do any of this and largely can't
         | because it doesn't understand what you are trying to do. It has
         | nothing to do with "hand-optimized assembly code".
         | 
         | You are making a classic "sufficiently smart compiler"
         | argument. These types of problems can't be automagically solved
         | without strong general AI inside the compiler. See also: SIMD,
         | auto-parallelization, etc. We don't have strong general AI,
         | never mind inside the compiler.
         | 
         | Until we have such a compiler, you will be dependent on people
         | caring a lot about physical data layout to make your software
         | scalable and efficient.
        
         | layer8 wrote:
         | GC languages like Java, Haskell, or Lisp give you that, so what
         | you want already exists.
        
       | jkercher wrote:
       | When 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 wrote:
         | Yep. 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 wrote:
         | It'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 wrote:
         | May 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 wrote:
           | Zig 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 wrote:
           | Call 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.
        
             | phalanx104 wrote:
             | `impl Fn/FnOnce/FnMut` don't stand for function pointers,
             | but rather function items in Rust, and as such they are
             | zero sized so Rust can provide optimizations regarding
             | function items specifically at compile time.
             | 
             | They can decay to function pointers (`$(unsafe)? $(extern)?
             | fn($(inp),*) $(-> $(output))?`, example: unsafe extern fn()
             | -> i32), which you can freely cast between function
             | pointers, `*const/mut T` pointers or `usize`s.
             | https://doc.rust-lang.org/reference/types/function-
             | pointer.h...
        
           | jkercher wrote:
           | Rust and Zig are both perfectly fine languages. Odin wins on
           | simplicity and familiarity for me. I'm most productive in C
           | which is what I use at work. So, for me, it's a better C with
           | some quality of life improvements. It's not trying to be too
           | radical, so not much to learn. The result is that I move can
           | fast in Odin, and it is legitimately fun.
        
       | jay_kyburz wrote:
       | I'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 wrote:
         | I 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 wrote:
         | I 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
         | 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
        
           | sph wrote:
           | Looks 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)
        
           | pbohun wrote:
           | That's one of the best intro pages I've seen for a language.
           | I really like how it has tabs for different practical
           | examples (http, generics, coroutine, etc.).
        
       | jmull wrote:
       | The 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 wrote:
         | I'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.
        
           | nasretdinov wrote:
           | I feel like Odin is the closest to "normal C", especially in
           | its simplicity, which is often undervalued. If C was easily
           | fixable it probably would've been done already anyway...
        
           | bondant wrote:
           | Do you know if there are some professional games that have
           | been made with Odin and released on steam or on game
           | consoles?
        
             | karl_zylinski wrote:
             | I (the author of the article) also made a kooky game called
             | CAT & ONION:
             | https://store.steampowered.com/app/2781210/CAT__ONION/
             | 
             | It's a short game made in Odin, but I spent a lot of effort
             | in polishing it so that it would be a pleasant little
             | strange experience.
             | 
             | It was the first commercial game made in Odin.
             | 
             | Some games made by other people:
             | 
             | Solar Storm (turn-based artillery game):
             | https://store.steampowered.com/app/2754920/Solar_Storm/
             | 
             | 2deez (fighting game, not yet released):
             | https://store.steampowered.com/app/3583000/2Deez/
        
           | uecker wrote:
           | I am quite happy with what you can do with C's types already
           | today: https://godbolt.org/z/njzazY4n6
           | 
           | This is (almost *) bounds safety with -fsanitize=bounds
           | 
           | *) with some pending some compiler improvements it will be
           | perfect
           | 
           | (edit: updated godbolt link)
        
         | uecker wrote:
         | I agree, this is absolutely the right approach. And any
         | suggestions to make C better are very welcome.
        
         | jerf wrote:
         | The most powerful objection to the proposition that C can be
         | fixed is the many, many attempts lying by the side of the road.
         | 
         | There seems to be some sort of force in the programming
         | language landscape that prevents a language that is too similar
         | to another language from being able to succeed. And I don't
         | just mean something like "Python versus Ruby", although IMHO
         | even that was a bit of a fluke due to geography, but the
         | general inability to create a variant of C that everybody uses.
         | 
         | The other problem is you still end up pushed in the direction
         | of a new language anyhow. Let's say you create C-New and it
         | "fixes pointers" so now they're safe. I don't care how you do
         | that. But obviously that involves some sort of writing into
         | C-New new guarantees that pointers take. But if you're
         | conceiving of this as "still basically C", such that you can
         | just call into C code, when you pass your C-New pointer into
         | C-Old, you can no longer make those guarantees. You still
         | basically have to treat C-Old as a remote call, just like
         | Python or Go or Lua, and put it at arm's length.
         | 
         | The extent to which you can "fix C" without creating this
         | constraint is fairly limited. It's a very well defined language
         | at this point with extremely strong opinions.
         | 
         | As for "C alternatives", actually, the era of C alternatives
         | has passed. C++, Java, Objective-C, C#, many takes on the
         | problem, none perhaps nailing the totality of the C problem
         | space but the union of them all pretty much does. The era we
         | have finally, at long last, it's about time we entered is the
         | era of programming languages that aren't even reactions to C
         | anymore, but are just their own thing.
         | 
         | The process of bringing up an ecosystem that isn't C is now
         | well-trod. It's risky, certainly, but it's been done a dozen
         | times over. It's often the only practical way forward.
        
       | codr7 wrote:
       | Which parts of the C standard library has any need for
       | allocators?
        
         | gingerBill wrote:
         | Loads 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 wrote:
           | malloc/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 wrote:
             | Many implementations of qsort do allocate using malloc.
             | 
             | And I know malloc/free is the allocator, but you cannot
             | override it either.
        
               | uecker wrote:
               | Can 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_ wrote:
               | Glibc's one does and it caused a security vulnerability:
               | 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.
        
             | codr7 wrote:
             | Yeah that's my hunch as well, and replacing strdup if you
             | absolutely have to isn't really a big problem.
        
       | leecommamichael wrote:
       | Odin 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 wrote:
       | By 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
        
       | macintux wrote:
       | Odin has been hitting HN semi-regularly. A recent thread:
       | https://news.ycombinator.com/item?id=43939520
        
       | knowitnone wrote:
       | You'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 wrote:
         | There 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 wrote:
       | What's the vibe coding landscape look like for Odin?
        
         | spicyusername wrote:
         | What... 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?
        
       | Quitschquat wrote:
       | I like that #soa stuff - can you make your own custom #foo thing
       | that does other things/memory layouts etc?
        
       | alphazard wrote:
       | Odin 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 wrote:
         | So far it definitely looks like a better C.
        
         | 90s_dev wrote:
         | Just 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 wrote:
         | Regarding 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 wrote:
       | I'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 wrote:
         | I 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 wrote:
           | It 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.
        
         | deafpolygon wrote:
         | These days, it's more likely that three will enter- and ten
         | more will emerge victorious.
        
       | jongjong wrote:
       | This 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.
        
       ___________________________________________________________________
       (page generated 2025-05-13 23:01 UTC)