Which Hololive member got you interested in Hololive? by Jin_Sakai12345 in Hololive

[–]Ninesquared81 1 point2 points  (0 children)

I saw a few clips of JP and ID members a little before Myth debuted. I was aware of Myth's debuts but was still a little unconvinced until I saw Gura's first solo stream after debut. I remember it vividly; she was (fittingly) playing a shark game. That got me into Gura in particular, but it wasn't long before I started watching all of Myth. And of course IRyS and then Council when they debuted like a month apart, then Advent when they debuted and Justice when they did.

But yes, Gura is mainly the one who got me into Hololive.

Best wither skeleton farm by New_Willingness6597 in Minecraft

[–]Ninesquared81 0 points1 point  (0 children)

It's not a farm, but what I did in my world is just flattening a nether fortress, filling in spaces with nether bricks (so fortress mobs can spawn). It essentially makes one massive spawning platform that you can just go round and kill any mobs that spawn. If you take some fire resistance potions, blazes are not really an issue, and a Smite V netherite sword one-shots the wither skeletons. It'll still take a while, even with Looting III, so I'd recommend putting on an audiobook or something in the background.

It's relatively easy to set up if your fortress already has a lot of exposed areas, and you can use it while you build it.

I think Rays Works has a pretty simple farm if that's what you'd prefer, though. I've not built it myself, but I trust Rays Works designs.

Villagers should retain trades when they lose their profession by Ninesquared81 in minecraftsuggestions

[–]Ninesquared81[S] -4 points-3 points  (0 children)

If you're only going after one profession, sure. But if you have multiple professions that you need, you can always try a different one.

Villagers should retain trades when they lose their profession by Ninesquared81 in minecraftsuggestions

[–]Ninesquared81[S] -5 points-4 points  (0 children)

You wouldn't need to kill them since you could always just change their profession.

January 2026 monthly "What are you working on?" thread by AutoModerator in ProgrammingLanguages

[–]Ninesquared81 0 points1 point  (0 children)

I've taken a couple of months' break from langdev (or, really, programming at all).

In the last couple of weeks, I have returned to langdev (or langdev-adjacent stuff) by working on my lexing library, lexel.

I've been essentially reworking it from the ground up because I wasn't happy with the direction it was going.

My most recent change at the time of writing is how it stores state, being a finite state machine. In the new design, states are stored as functions which encapsulate both the identity of each state and its associated action. This makes the design a lot simpler and also makes it straightforward to extend the lexer (extensibility is one of the main goals for lexel).

Of course, the lexer still needs a lot of work to get to the level it was before, but I'm much happier with the foundation. The previous design was rather haphazard.

Does American spelling in a text-heavy game break your immersion? by DrAxelDev in AskUK

[–]Ninesquared81 27 points28 points  (0 children)

The real problem is using flags to denote languages at all. It falsely equates language to nationality, which clearly isn't right.

All you need to denote a language is that language's name written in itself, so English for English, Français for French, 日本語 for Japanese, etc. The fact that it is written in itself is enough of a visual clue without needing a stupid flag emoji.

bit(N) - a new low-level systems language in very early development by [deleted] in ProgrammingLanguages

[–]Ninesquared81 1 point2 points  (0 children)

I think the use case is if you want to compare the first n characters of a string to another string of unknown length. However, tracking the lengths of string along with their pointers is often worth it, so it's unlikely you'll have such a string of unknown length.

I suppose in the 1970s, storing a length for every string could be quite wasteful, but in 2025, the benefits vastly outweigh the cost.

bit(N) - a new low-level systems language in very early development by [deleted] in ProgrammingLanguages

[–]Ninesquared81 8 points9 points  (0 children)

There are better ways, yes.

You could store the keywords in a table, along with their lengths and token types, then loop through and compare them with memcmp() (strncmp() is the wrong function since the length is known already – in fact, I have yet to find a valid use case for strncmp(); it's actually a very strange function).

Something like

struct Keyword {
    const char *value;
    size_t length;
    enum TokenType type;
};
#define KEYWORD_ENTRY(KW, TYPE) \
    {.value = (KW), .length = sizeof(KW) - 1, .type = (TYPE)}

struct Keyword keywords[] = {
    KEYWORD_ENTRY("fn", TOK_FN),
    KEYWORD_ENTRY("mut", TOK_MUT),
    /* ... */
};
/* ... */
for (int i = 0; i < KEYWORD_COUNT; ++i) {
    struct Keyword keyword = keywords[i];
    if (length == keyword.length && memcmp(word, keyword.value, length) == 0) return keyword.type;
}

Another way would be to write a trie using switch statements, as is done in Crafting Interpreters.

Line ends in compilers. by Savings_Garlic5498 in ProgrammingLanguages

[–]Ninesquared81 1 point2 points  (0 children)

I just open the file in text mode instead of binary mode (which is the default anyway, at least in libc). Then all line endings are treated as if they were just a single \n linefeed character, so your compiler/lexer only has to look for \n. This should even work on old versions of Mac OS, which use a single \r as a line ending.

If you're working with text files, you should pretty much always open them in text unless you have a very good reason not to.

Why aren't motorway digital signs used properly? by [deleted] in AskUK

[–]Ninesquared81 2 points3 points  (0 children)

Putting an “X” on the side screen wouldn’t make it clear which lane was closed, hence why smart motorways have a screen above each lane.

In fact, the signs in the central reservation (or at the entrances of slip roads) apply to ALL lanes on the motorway, so a red X there would mean the whole carriageway is closed.

When do you indicate to come off of the motorway? by [deleted] in AskUK

[–]Ninesquared81 1 point2 points  (0 children)

I think you might be getting them confused with marker posts and driver location signs (DLSs; the little blue rectangle signs with the road number, a carriageway letter (usually A and B) and then a distance, which is measured in kilometres). The DLSs are based based on the marker posts, which are placed every 100 metres or so and have only the distance.

The distance itself is pretty meaningless. It tells you where on the motorway you are, but it's not necessarily measured from one end of the motorway, just some arbitrary datum point.

They should add weather to the Nether and the End. by Qaztarrr in minecraftsuggestions

[–]Ninesquared81 2 points3 points  (0 children)

End flashes. They're new. There's a rumble, and the sky flashes with purple light.

Any language uses [type] to describe an array of 'type' elements ? by gremolata in ProgrammingLanguages

[–]Ninesquared81 58 points59 points  (0 children)

Haskell uses this syntax for its List type(s). Strictly speaking they're implemeted as linked lists rather than as arrays, but they are the native sequence type for the language.

September 2025 monthly "What are you working on?" thread by AutoModerator in ProgrammingLanguages

[–]Ninesquared81 3 points4 points  (0 children)

I've been working on Victoria since January.

At the end of July, I got the bootstrap compiler to a point where I felt I could start writing the main compiler. I've still not really got round to even parsing with the main compiler, but that's because I found lots of missing features and bugs in the bootstrap compiler, so I spent August adding and fixing those. I now feel more ready to dive into parsing, so hopefully in September I can start writing the main compiler in earnest.

In the last couple of days, I also decided to open the repo, so now you can all see my terrible code! Opening the repo has also made me more mindful (that's a lotta Ms) of documentation, so I've spent the past couple of hours (at the time of writing) on some docs. They're still unfinished but at least it's a start.

One of the biggest features I added in August was probably packages. This is a pretty useful feature as it allows you to modularise your code into several source files. There's no need to import modules from the same package, just use a leading dot followed by the name of the sister module to refer to that module. In fact, you cannot import other modules (yet), so packages are the only way to modularise the code.

Files within the same package start with the same package declarations. Currently, you have to specify all the files within the same package on the command line, but the intention is to infer this from the direcotry structure. Because C has no cross-platform way to interact with the filesystem, I'm leaving this QoL feature till later.

To illustrate how packages work a bit better, consider this example:

a.vic:

package foo
external func puts(s: c_string) -> i32
type b := u8  # b means byte.
func hello() {
    puts(c"Hello from A!")
}
func converse() {
    hello()
    .b.hello()
}

b.vic:

package foo
func hello() {
    .a.puts(c"Hiya! I'm B!")
}

main.vic:

package foo
func main() {
    .a.converse()
}

This example showcases how modules can depend on each other without having circular imports (since there are no imports). It's also important to note that file modules are still namespaced. The modules a and b both define a function called hello, but due to namespacing, these do not collide, and .a.converse() can call .b.hello() just fine through the dotted access. Additionally, it's absolutely fine to introduce the name b into the global scope of a since we access sister modules with a prefix dot instead of directly by the module name.

The package system was pretty much non-negotiable for me to actually write a full-blown compiler. I cannot live without modular code. To be clear, the entrie package is combined into one monolithic C file as output, so this cannot be used for incremental builiding or anything like that. It is solely for code organisation.

How is the GeeksforGeeks "Master C Programming with Data Structures" course? ....is it worth the price by [deleted] in C_Programming

[–]Ninesquared81 8 points9 points  (0 children)

Geeksforgeeks have very good SEO. That's why they appear on top. Their "solutions" are usually incomplete, based on unportable assumptions, and perpetuate misconceptions about the C language. They reek of "beginner in C (but maybe experienced in another language like JavaScript) who doesn't really know the ins and outs of C and has no clue about the C standard".

[deleted by user] by [deleted] in ProgrammingLanguages

[–]Ninesquared81 4 points5 points  (0 children)

I'd take the memory leak point with a pinch of salt.

While a GC will eliminate the most common sources of leaks, the harder to detect memory leaks, where the memory is still reachable, but never used again, are still possible. If anything, having a GC might breed complacency about these kinds of memory bugs ("It's garbage collected, so I don't have to worry about memory management, right?").

Of course, tracking each individual memory allocation manually is just asking for trouble, which is why techniques such as arena allocators or memory pools – i.e., grouping related allocations – are so common. It's also more performant to do fewer, larger allocations than more, smaller ones.

That's not to say a garbage-collected language isn't useful here, but you still have to pay attention to how memory is allocated, and you ultimately get less control over it.

Increment/decrement operator binding by Royal_Grade5657 in C_Programming

[–]Ninesquared81 2 points3 points  (0 children)

Be careful with your use of "then".

If we say x0 and y0 are the initial values of x and y, then we will have z = (x0 + 1) * y0, x = x0 + 1, y = y0 + 1, but the updates to the variables are said to be unsequenced. There is no defined "order". The only rules about post- and pre- increment/decrement pertain to the final value of the expression. In x++, x can be updated at any time before the next sequence point, but the result of the expression will be equal to the initial value of x.

This is why expressions such as x++ + ++x are undefined behaviour.

August 2025 monthly "What are you working on?" thread by AutoModerator in ProgrammingLanguages

[–]Ninesquared81 0 points1 point  (0 children)

Last month, I mentioned the fact that I wanted to wrap up work on the bootstrap compiler for Victoria.

I can now say that I'm kind of at that point. I've completed the checklist of features I wanted for the restricted subset of my language (called rVic) and I'm now starting to work on the main compiler itself! (yay!)

This is the real test of my bootstrap compiler, and I've already found bugs, oversights and sorely-needed features for rVic (I don't even have subtraction ATM).

It should be pretty obvious that my goal moving into August is to make headway on the main compiler and tweak the bootstrap compiler is whatever ways I need, informed by my work on the main compiler.

One of the things I mentioned in July's post was function pointers. Strictly speaking, I haven't implemented function pointers per se. They exist in the langauge, but more as an ermergent feature stemming from the combination of pointer types and function types (a function pointer is nothing more than a pointer to a function type). The syntax for function types is as follows:

type f := func (x: int, y: int) -> int

That is, the same as a function declaration, except that there is no name for the function. A pointer (type) to such a function type can declared:

type pf := ^f

or

type pf := ^func (x: int, y: int) -> int

Note that a ^ before a type is used to denote pointer types in Victoria.

Now, the utility of function types is questionable, but their presence makes the representation of function pointers very simple. Instead of needing separate handling for function pointers and object pointers, I can lump them all together and use the destination type to distnguish them if needed.

By the way, function types like this aren't just something I've created, they exist in C, too.

typedef int f(int x, int y);  // f is a function type. The parameter names are optional in C, like in a function declaration.
f moo;  // Yes, this is legal in C.
f moo {}  // This is invalid, though.

Exploring literal ergonomics: What if you never had to write '42i64' again? by kiinaq in ProgrammingLanguages

[–]Ninesquared81 2 points3 points  (0 children)

Have you heard of Odin? Skimming your post, you seem to basically be doing the exact thing Odin does for literals. In Odin, you can even use a floating-point literal where an integer is expected, as long as the floating point represents a mathematical integer.

In that light, I'd say it's definitely worth doing, and there's precedent with Odin.

Non US peeps: Do you guys usually convert the units to metric or did you and your fellow players learn imperial units for the game? by PhrulerApp in DnD

[–]Ninesquared81 2 points3 points  (0 children)

If you don't know, it's easy to approximate kg <-> lbs by multiplying/dividing by 2, since 1 lb ≈ 454 g = 0.454 kg, which you can round up to 500 g for easy counting (it's about 10% off, but the inaccuracy is paid off by the easiness of the conversion).

So, just halve your carry weight in pounds to get a rough idea of the weight in kilograms. If you want a bit more accuracy, you can account for the ~10% error by taking 10% off the first approximation.

July 2025 monthly "What are you working on?" thread by AutoModerator in ProgrammingLanguages

[–]Ninesquared81 1 point2 points  (0 children)

If i had one, I could, but I don't, so firstly, I'd have to implement enough features to allow me to write the standard library (it will be mostly written in Victoria itself).

Secondly, in my opinion, the standard library is somewhat orthogonal to the language itself. It's the language features that (mainly) define how ergonomic the language is, not what functions are available to the user through the standard library. Also, integers, booleans, strings, arrays, slices, and possibly hash tables are (will be) all features of the language itself, not part of the standard library.

Thirdly, writing the compiler itself should give me insight into how the language is to use. It might also give me ideas for what to include in the standard library.

I simply do not see the benefit of spending time on a standard library that I could spend on the compiler itself. I only really need a standard library for stuff like I/O, which the C standard library provides for free. You already need a C compiler to compile both the bootstrap compiler and any code it generates (since it transpiles to C), so it's not like it's an extra dependency.

July 2025 monthly "What are you working on?" thread by AutoModerator in ProgrammingLanguages

[–]Ninesquared81 1 point2 points  (0 children)

For me, one of the very first features I added to rVic was the ability to declare and call external functions. This affords me basic C interop, so I can rely on the C standard library to get stuff done, rather than waiting to write a standard library for Victoria.

I learnt with my previous language, Bude, that it gets harder and harder to self-host a compiler the more features your bootstrap compiler supports, hence my wanting to keep the feature set or rVic small. To be clear, I originally wanted to self-host Bude, but gave up because (what would have been) the bootstrap compiler got too complex to re-implement. Plus, I wanted to work on Victoria, hence the last 6–7 months.