HN user

gingerBill

894 karma
Posts26
Comments232
View on HN
www.gingerbill.org 2mo ago

Blessed syntax and ergonomics

gingerBill
1pts0
www.gingerbill.org 5mo ago

Choosing a Language Based on Its Syntax?

gingerBill
1pts0
www.gingerbill.org 6mo ago

The Only Two Markup Languages

gingerBill
7pts1
www.gingerbill.org 6mo ago

Was It a Billion Dollar Mistake?

gingerBill
10pts9
www.gingerbill.org 10mo ago

A critique of package managers

gingerBill
118pts217
www.youtube.com 11mo ago

Assuming as Much as Possible [video]

gingerBill
3pts0
www.youtube.com 12mo ago

Most of your projects are stupid. Please make some actual games. [video]

gingerBill
2pts0
www.youtube.com 1y ago

Vjekoslav KrajačIć – File Pilot: Inside the Engine – BSC 2025 [video]

gingerBill
5pts0
www.youtube.com 1y ago

GingerBill – Tools of the Trade – BSC 2025 [video]

gingerBill
7pts2
zylinski.se 1y ago

Odin: A programming language made for me

gingerBill
213pts210
www.gingerbill.org 1y ago

Unstructured Thoughts on the Problems of OSS/FOSS

gingerBill
5pts4
www.youtube.com 1y ago

ThePrimeagen Top Shelf #2 Ginger Bill – Creator of Odin [video]

gingerBill
1pts0
jangafx.com 1y ago

OpenVDB Format: A Deep Dive

gingerBill
3pts0
www.gingerbill.org 2y ago

Why People Are Angry over Go 1.23 Iterators

gingerBill
4pts1
www.youtube.com 2y ago

"Boundaries of Language Design" with Andrew Kelley (Zig) & Ginger Bill (Odin) [video]

gingerBill
10pts2
www.gingerbill.org 2y ago

The Video That Inspired Me to Create Odin

gingerBill
6pts0
graphitemaster.github.io 3y ago

A Review of the Odin Programming Language

gingerBill
145pts140
www.gingerbill.org 3y ago

Reverse Engineering Alembic

gingerBill
2pts0
www.youtube.com 4y ago

Carbon Language – Who is it even for?

gingerBill
1pts0
odin-lang.org 4y ago

Odin is taking documentation seriously–Brand New Docs for the Official Libraries

gingerBill
3pts0
www.youtube.com 4y ago

Interview with Odin programming language creator Ginger Bill

gingerBill
3pts0
www.youtube.com 5y ago

An Interview of Ginger Bill for the Odin Programming Language 2021-06-09

gingerBill
2pts0
www.gingerbill.org 5y ago

The Essence of Programming – The Novice's Pitfall

gingerBill
1pts0
www.youtube.com 5y ago

Odin Programming Language: An Introduction

gingerBill
3pts0
odin-lang.org 6y ago

The Odin Programming Language

gingerBill
194pts141
odin-lang.org 7y ago

The Odin Programming Language

gingerBill
18pts3

STM32 microcontroller

The answer is "yes" depending on what you mean by STM32 :D

But if it's one we don't currently support officially, it should be pretty easy to support too, with probably a little extra assembly.

Vim does not have multiple cursors which can be placed ANYWHERE even multiple on the same line and at any offset. You are clearly not aware of what Vim actually offers.

People don't use vim because they enjoy puzzle solving.

I didn't say that either nor even imply it, and you know that when you quote me afterwards. So huh?!?!

People don't use Linux because they enjoy tweaking config files and everybody else has too busy a life to do that.

A lot of people, including younger myself, got into Linux and Android BECAUSE it was configurable and customizable. And even played around with all of the customizations because it was fun to do. But it didn't really make my general experience better because I was forever trying to correct something I should have to correct in the first place.

I am not sure how much clearer I can be in the article or in my replies to comments.

You just edit as normal while recording, and replay those edits later.

And there is the problem. The first time you do the edit, it might be fine, but when you make a mistake in the edit, you then have to go back and correct all of the cases. With multiple cursors, I am seeing instant visual feedback on all instances of the cursor at once. I am getting literally 2D spatial information, compared to the 1D spatial information per each replay. The multiple cursors approach is better not because it's a different mindset or whatever, but rather it produces a different feedback loop to correct mistakes.

If you still prefer the macro approach over the multiple cursors approach, then you do you. But as an example in the article, I have seen people think they are being productive by their own standards, and they really aren't.

Which is kind of what I was arguing. Understand that having "fun" is not necessarily equivalent to being "productive". And even by an individuals own standards, the two can be completely different.

If you are having fun, and it's a hobby: who cares? If it's in the professional setting, make sure what you are doing is not actually wasting time and/or money, i.e. be productive.

The things about multiple cursors is that you think about the processing while doing it

That visual feedback is EXTREMELY useful because I learn of the edge cases to what I am editing in bulk (usually formatting code or tables or whatever) as I am editing it. When you do a macro, you have to try and get it right, and then try again from the start each time to get it right. `dot` et al are not enough in that regard. So the multiple cursors approach is better not because it's a different mindset, but it produces a different feedback loop to correct mistakes.

If you still prefer the macro approach over the multiple cursors approach, then you do you. But as an example in the article, I have seen people think they are being productive by their own standards, and they really aren't.

Sublime is invisible to him because he's been at it for fifteen years.

It's not perfect and the bugs that have been there for years (and won't be fixed) have annoyed me for years too. The reason I still stick to Sublime is just because the alternatives that are similar are much much slower. I wish Sublime was actually invisible to me, but it isn't. It's just the most invisible I've found out of the alternatives.

But the escape hatch is the whole problem with his thesis

I understand what you are saying, but the point of an escape hatch is that for the general everyday cases, the defaults should be good and invisible. But there will always be edge cases which you cannot handle nicely, either there hasn't been a way discovered yet which is better or there are other external accidental things which prevent it from being "nice" (not I am talking about tools in general and not just text editors, maybe even programming languages hint).

The escape hatch and the learning curve that leads to it are the same object. He even admits it. He even admits it. In the learning-curve section he concedes a steep curve "could absolutely be a cost worth paying" if the payoff is real productivity. That's the entire counter-thesis.

I don't agree with your interpretation of my article. I am talking about certain people in particular that are saying the bad aspect of tool is actually good. If there is a high learning curve for a tool, it needs to eb compared to the current alternatives. But sometimes the curve is "essential" and cannot be improved upon, for better or for worse. I have yet to see many "essentially" high learning curves in the domain of programming.

I am not sure how to summarize the entire article other than what I already wrote in the conclusion.

That's not what I was saying. I used vim macros specifically as an example, not Vim as a whole.

I’ve had people tell me how “fun” it was to build a macro to handle some one-off text-refactoring problem. But when I looked at what they were doing and how long it took, my honest reaction was: I could have done that in Sublime in a minute with multiple cursors, or just written a quick script.

and

What baffles me is that so many people treat that friction—the effort of working around a tool’s limitations—as the “fun” part, and then advertise it as evidence that the tool is great.

If you can affectively use vim macros, then GREAT! But if you cannot, even with using vim for decades, then please don't advertise them as the "fun" part.

I am afraid the author confuses familiarity with proof that his tools are better.

Literally NOT what I was implying or even said anywhere. Quote me where I said anything like that.

To quote myself:

What baffles me is that so many people treat that friction—the effort of working around a tool’s limitations—as the “fun” part, and then advertise it as evidence that the tool is great.

This has nothing to do with why I or another person one tool over another, but rather treating the flaws as if they are things to have a puzzle game to work around.

Regarding the implementation of Odin's `context` not being thread-local, source from here: https://www.gingerbill.org/article/2025/12/15/odins-most-mis...

Another common question I’ve gotten a few times is why the `context` is passed as an implicit pointer argument to a procedure, and not something like a thread local variable stack? The rationale being that there would not need to be a calling convention difference for `context`. Unfortunately through a lot of experimentation and thought, there are a few reasons why it is implemented the way it is:

* Easier to manage across LIB/DLL boundaries than trying to use a single thread-local stack

* Easier management of recovery from crashes where the context might be hard to figure out.

* Using the existing stack makes stack management easier already, you don’t need to have a separate allocator for that stack

* Some platforms do not thread-local variables (e.g. freestanding targets)

* Works better with async/fiber based things, which would then require a fiber-local stack instead of a thread-local one

* Prevent back-propagation, which would be trivial with a global/thread-local stack

Odin’s context also has copy-on-write semantics. This is done for two reasons: to keep things local, and prevent back-propagation of “bad” data from an third-party library (be it malicious or just buggy). So not having an easily accessible stack of context values makes it harder for this back-propagation to happen.

If you're referring to me, I don't use Reddit much at all any more. I used to comment sometimes on that specific subreddit, but I didn't find the community that great nor the conversations that useful for me. There seemed to be more of a focus on Lambda-Calculus-related type theories, and less in other type theories, and less on practical design and implementation of programming languages and compilers. It varied from beginner level topics to very niche technical topics. I usually talk to other language/compiler developers (outside of Reddit) for discussions on programming languages, meaning most of it is not done in the public.

The categorizes are useful for understand how people perceive a language. It's a human psychology category, and just because you think it is "irrelevant" misunderstands why I made the categorical distinctions in the first place.

People actually talk this way about languages, and they already have this conception.

And I've just realized what your psychological hang-up is now too, the word "focused". I originally didn't use this term when I wrote the article in 2018, but a friend suggested the term instead because it was probably a little more "neutral". I honestly cannot remember what I used before now since I have just absorbed this arbitrary term "focused", even if the distinctions are useful.

You might not think this way about languages. I know I don't when I program. But I know this is how others things, and that's the entire aspect of design. Design is just so much about understanding humans. How they function, mentally and physically. Perception, psychology, sociology, physiology, ergonomics, needs, desires, etc. It's all about being able to put yourself in other people's shoes, more than making _the thing_.

And that's what I've been trying to understand and that categorization has been helpful for understand other people. I don't care if you think the categorizes are "irrelevant" but you are not "everyone".

This might might sound weird but I think that's a distinction without a difference.

Those "newline tokens" are effectively the equivalent to a semicolon in the parser. They are statement terminators. The way that Odin or Python handles them is effectively the same except when I tokenize the newlines, they are treated as semicolons but with the "text" being "\n". Thus the distinction here is a matter of what you call it, not how it is treated.

That is the same as a form of "automatic statement-terminator insertion" where that statement-terminator is whatever you want it to be. And to me, that is as form of "semicolon" (which is being used as a generalization for statement-terminator) insertion.

First, tell me languages which have named value declarations which don't fit into that category. I'd love for my hypothesis to be proven wrong.

Second, how are they wrong? You haven't proved any point as you were extremely vague.

In the follow up article, I wrote something like this in the conclusion:

Designing a language is more than just getting the syntax right, and denotation semantics are a lot more important in most ways, but that does not mean syntax does not matter. When you get syntax right, people won’t even know you’ve done anything at all. But when you’ve got it wrong (and have actually tried using the language), they will complain instantly.

Follow-up Article: https://www.gingerbill.org/article/2026/02/21/does-syntax-ma...

I was trying to be EXTREMELY clear I am talking specifically about DECLARATION syntax only and how for the most part, the concrete syntax for the DECLARTAION syntax is not that important in many languages.

However concrete syntax matters a heck of a lot and cannot be trivially interchangeable.

I had to write a follow-up article to clarify this because of people like yourself wrongly interpreting the article: https://www.gingerbill.org/article/2026/02/21/does-syntax-ma...

I tried my best to be very clear within this article that I am talking about two specific things: DECLARATION SYNTAX and SEMICOLONS. This does not extend to anything else. In fact I got so frustrated with people like yourself who are wrongly interpreting the article that way and extrapolating too much that I had to write a new article: https://www.gingerbill.org/article/2026/02/21/does-syntax-ma...

"Does Syntax Matter?" And the first one is "Yes."

And all languages can have their declaration syntaxes categorized into one of the three I mention. This is not limited to ALGOLs. And I have come across "really interesting language syntax". I am not talking about that in this article.

----

Ergonomics does matter and it's not just about optimizing for typing either. It's actually all about coherency and consistency, something I go into depth into the following article on syntax.

----

I am not "conflating" a semicolon with statement terminators, I am using that as shorthand as most languages that most people encounter (not all languages, obviously) will use semicolons. Python's approach to parsing is a form of automatic semicolon insertion, even if most people don't think of it that way.

----

And I do not like Python's approach requiring significant whitespace of "blocks" through indentation. I much prefer using something like braces, or an `end` keyword, etc, literally because it prevents the problems that significant whitespace introduces. I am not getting into that argument here; please don't start it.

Hello again. That's not my position in the slightest. The point of the article is to express how people will shallowly and naïvely judge something. It might be naïve conception of "aesthetics" but it's not even a good one.

It has nothing to do with people disagreeing with me, I have seen people dismiss numerous languages (not just my own) based on that declaration syntax. Things like "why does Rust not use `type name = value`? why did they have to change things so much from C++?".

Do you think these people are actually serious programmers or just having shallow and dumb opinions on things they know little to nothing about?

I never got why compilers don't have pluggable syntaxes.

Because then you've created dialects and produced the Curse of Common Lisp all over again.

Syntax matters a heck of a lot, and you want consistency and coherency across codebases of the same language, otherwise you don't have a language at all. So wanting it "pluggable" is in fact the worse possible choice you want.

It's also a naïve view to think that concrete syntax can be trivially swapped out with the abstract syntax remaining. For certain things it can usually work (like declaration syntax in the article) but for most things it cannot.

Did you even read the article, even the heading of that section? You know there is a huge majority that do not want semicolons whatsoever, so saying people should just suck it up is actually a determent to the adoption of the language because of people's general tastes.

That sidestepping only introduces significant whitespace, which may not be what people want in the first place. It can be quite common to align call expressions by the parentheses if they span multiple lines for clarity, and you preventing might not be desireable.

The article does no such thing and just focused on declaration syntaxes and semicolons. I can class literally any language into the three categories for declaring variables.

* Haskells are name-focused languages. * Smalltalk is a name-focused language. * LISPs are qualifier-focused languages.

I think you might have a blinkered viewpoint in how you have interpreted the article.

Those syntax examples are literally just general examples, not the only way you have to write them. But to categorize the ones you wrote:

* Clojure is qualifier-focused * Prolog is name-focused * Forth is qualifier-focused (`:` is the qualifier in this case)

I literally had to write an extra article because of the number of people who thought I was saying syntax doesn't matter. It matters a hell of a lot:

https://www.gingerbill.org/article/2026/02/21/does-syntax-ma...

I was trying to be as clear as I possibly could within that article to state I was only focusing on those two specific topics, rather syntax as a whole. How people judge a language based purely on its declaration syntax and nothing else. Where the declaration syntax makes the least difference compared to the rest of the syntax in the language. And still people wrongly interpreted the article.

In the first case in a language with type inference, I'd argue it would probably be written a bit different. And probably something like the following two cases:

    x := &bar
    if is_foo { x = &foo }
    // or
    x := &foo if is_foo else &bar
I know this is a simple example, but it's kind just a different way to think about the problem. Sometimes the default C way of having to specify the type first is a good enough of a nudge away to not do when you can just infer the type from the expression. Especially when this variable is being used not as a variable in itself but as an alias for another. The place where it is more likely to have a `nil` pointer due to no explicit initialization in Odin would be within a struct, rather than on its own on the stack.

In the second case, Odin's approach would probably just not even do that, but rather `f, b := grab_data()`. The use of `&` is when it needs to be an in-out parameter (i.e. read and write to), which means it has different functionality.

The thing that is at odds with Rust is the second part of the article: the difference in mindsets.

Rust by default doesn't really encourage the group-element mindset and people have to work against the language in order to do it. And what usually happens is people work around the borrow-check as a result, through the use of a handle system. And they do this in order to get the lifetime benefits, performance benefits, and also get around the problems of the ownership semantics.

Of course you can do this in Rust, but the point is that the default approach in Rust does not encourage it at all. The default Rust mindset is the individual-element mindset.

To make `Maybe(T)` feel like a multiple return, you just need to do `.?` so `maybe_foo.? or_return` would just the same.

But as you say, it is more common to do the multiple return value thing in Odin and not need `Maybe` for a return values at all. Maybe is more common for input parameters or annotating foreign code, as you have probably noticed.

The first paragraph from the article:

*TL;DR* null pointer dereferences are empirically the easiest class of invalid memory addresses to catch at runtime, and are the least common kind of invalid memory addresses that happen in memory unsafe languages. The trivial solutions to remove the “problem” null pointers have numerous trade-offs which are not obvious, and the cause of why people think it is a “problem” comes from a specific kind of individual-element mindset.

Unfortunately I don't think you've understand what I was I trying to say.

Rust was designed from day-0 around explicit individual-value based initialization. Odin from day-0 was not designed around this (explicitly).

This ever so minor choice might not seem like a big thing to you, as you have stated in your comment, but it leads to MASSIVE architectural decisions later on when the user programs.

Odin could not "just add" non-nil pointers and it be "fine". It would actually not be Odin any more, and the entire language would not even be a C alternative any more, and feel much more like C++ or Rust. Rust and OCaml (which Rust is based off) are different kinds of languages to Odin and their approach does not translate well to what Odin (or C) is trying to do.

Unfortunately I will not be able to explain this to you in a comment or article, and it is something that takes a while to understand since it is a subtle effect of locality affecting globality. The best video on this might be from Casey Muratori: https://www.youtube.com/watch?v=xt1KNDmOYqA

Yes, initialization can be less efficient in Rust but then most of the time spent is spend in algorithms when they run, not during initialization of the data structure.

Sadly this isn't as true as you think it is. I've written a lot of C++ code before and doing its boilerplate for ctors/dtors actually leads to much slower code in general, and I'd argue this does apply to Rust too. Most of the time isn't necessarily spent in "algorithms", especially when "algorithms" also include initialization of values. You've turned something which could be O(1) into at best O(N), which does not help when things scale, especially with "algorithms".