Spyke

Replies

Comment on

The only thing doing tech tests has taught me is that I'm too stupid to do the job I've been doing professionally for the better part of 2 decades.

Reply in thread

My workplace has the opposite problem.

The company has been in dire need of programmers for years, so they hired people (including myself) without tests. However, the work involves lots of custom iterators and the occasional handcrafted parser, which most of the company is incapable of writing. The bright side is that management has their metrics mostly right, so I'm getting lots of raises for solving fun problems.

Comment on

Project Fluent: A localization system for natural-sounding translations

As a Finnish speaker, I just can't see generic localisation systems like Fluent working with agglutinative languages. For instance, consider the Polish example for Firefox Account from Fluent's front page:

-sync-brand-name = {$case ->
   *[nominative] Konto Firefox
    [genitive] Konta Firefox
    [accusative] Kontem Firefox
}

In Finnish, this would be called Firefox-tili. Tili means account and belongs to the Kotus type 5 words, which specifies how the word is inflected with various suffixes. Fluent doesn't support agglutination, so you'd have to specify every form of the word separately:

-sync-brand-name = {$case ->
    [nominative] Firefox-tili
    [partitive] Firefox-tiliä
    ... 10ish more inflections
    [nominative first person] Firefox-tilini
    [partitive first person] Firefox-tiliäni
    ... 10ish more inflections
    ... the above inflections but for 2nd and 3rd persons
    [nominative first person plural] Firefox-tilimme
    [partitive first person plural] Firefox-tiliämme
    ... 10ish more inflections
    ... the above inflections but for 2nd and 3rd persons plural
    [nominative first person questioning] Firefox-tilinikö
    [no idea what this is even called] Firefox-tilittömänäkin
    [no idea what this is even called 2] Firefox-tililleensäkään
    ... lots more
}

Ideally, you'd only specify that Firefox-tili is a type 5 word and the system generates all of that boilerplate.

Comment on

Language Design: Fixing Rust's mistakes – Syntax

Agreed on all points except possibly semicolons. Automatic semicolon inference has a very big language footprint, similar to the range syntax that the author disliked.

That said, I don't think the vararg suggestion belongs in this list of syntax changes. For this feature to be useful, it has to be at least powerful enough to replace format!, but the current type system isn't even remotely expressive enough to do this. I imagine this would require something like C++-style templates or comptime reflection, which goes well beyond syntax changes.

I added the author's other texts to my reading backlog too. Looks interesting.

Comment on

A comprehensive guide to the dangers of Regular Expressions in JavaScript

Regular expressions are great and can always be matched in linear time with respect to the input string length.

The problem is that JS standard library RegExps aren't actually regular expressions, but rather a much broader language, which is impossible to implement efficiently. If RegExp switched to proper regular expressions, they would match much faster but supporting backreferences like /(.*)x\1/ would be impossible.

Comment on

Make my application extendable by "mods"?

For your holy-mod-sword example specifically, the better approach is to specify a structured data format (think Excel sheets) that your game loads from a specific directory at startup and inserts the found items, NPCs etc. into the game's runtime data structures (e.g. loot tables).

For example, Skyrim (and other Bethesda games) do this with .esp-files, which allow you to import a big variety of different game entities. In a small indie game, the format doesn't have to be anything special; e.g. Elin modders use plain .xlsx files, where the columns are item name, item weight, item sell value, item damage, etc.

The above approach works for static data, such as simple items, but you'll need more to allow modders to write Turing complete scripts. There are two different approaches to this:

  • Expose a language runtime in which the game runs mods. You can design your own language and/or runtime (e.g. Warcraft 3 has JASS), or use existing ones (this is basically what eval is, though you'll need to hide builtins, globals and such by passing extra parameters). These approaches are theoretically safe thanks to the runtime sandbox, but there are often unintended ways to escape the sandbox and execute arbitrary code.
  • Inject the mod executable directly into the game with tools like BepInEx (Unity) or DLL injection (used by e.g. Skyrim Script Extender). There are no security guard rails, so you'll need to manually review mods.

Comment on

Algorithm complexity challenge

What is the median amount of times you end up shuffling the array before it is sorted?

The answer is n! where n is length of the array.

I assume you meant mean instead of median. The median of a geometric distribution with parameter p is ceil(-1/log2(1-p)).

Comment on

Spells as Code - a typesafe skill system

Another point in favour of databases is simplicity of client-server communication and data models.

Many objects in WoW (not too sure about spells, but most likely them too) work such that the client asks the server for the related DB rows when it sees an object for the first time. So instead of sending code across the wire, which would be a bad idea for many reasons, you instead send structured data that the client interprets.

Of course, you could just bake the spell code into the client at compile-time, but then dataminers will take it apart on day 0. WoW datamining mostly works such that you play the game normally and see what data the server gives you.

Comment on

Type Inspection in Typescript

Although I’ve used a number of languages including Python, Javascript, and Go to build software, the bulk of my experience is working in Java.

Notably, Python's type annotations are extremely similar to Typescript. I guess the author hadn't used Python's type annotations very much (which is understandable considering they're often missing from libraries and the implementations are buggier than Typescript).

cpp

Comment on

Ranges (C++20)

In C++23, you can zip the two arrays, so there's no need to declare an otherwise useless index variable:

int stdSumOfValidDataPoints(const MyData& data)
{
    using namespace std;
    auto&& r = ranges::views::zip_transform(
        [](int data, bool valid){return data * valid;},
        data.dataPoint,
        data.dataPointIsValid
    );
    return accumulate(begin(r), end(r), 0);
}

Unfortunately, the current implementation of zip_transform in GCC doesn't understand that the output length is constant 8, so it does needless cmps every iteration to check if it should stop iterating. (Godbolt)

Comment on

UserChrome help - new message background color

After some trial and error, I found that adding the following to userContent.css seems to work:

@-moz-document url(about:blank?compose) {
    body {
        background-color: red;
    }
}

Thunderbird's source code also has some function that reads preferences editor.use_custom_colors and editor.background_color and sets the default color based on those, but it seems that the function is never called. Code rot I guess.