cgtjsiwy

joined 2 years ago
[–] cgtjsiwy@programming.dev 12 points 1 month ago

This is missing the biggest difference: ISO 8601 costs 190-450€, whereas RFC 3339 is free.

[–] cgtjsiwy@programming.dev 1 points 2 months ago* (last edited 2 months ago)

Very few languages (or programmers!) are able to check that a function doesn't have side effects. In particular, checking that a function doesn't diverge generally requires a proof assistant, like in F* and Lean.

Your definition of functional programming is as valid as any, but it's so strict that even Haskell would be mid-tier in the functional ranking.

[–] cgtjsiwy@programming.dev 1 points 4 months ago

I didn't really understand the details of what you're making, but if you want to generate a random variable with entropy x, the straightforward approach would be to use Σ = { n | 1≤n≤⌈2^x⌉ } as the alphabet and start with a uniform distribution (which overshoots the entropy target) and slightly skew the distribution to reduce entropy to hit the target x. Then you can map Σ to your desired set (f64 or Vec in your case?) using an injection, since that preserves entropy.

[–] cgtjsiwy@programming.dev 6 points 8 months ago* (last edited 8 months ago) (1 children)

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.
[–] cgtjsiwy@programming.dev 2 points 9 months ago (1 children)

Another European example is Finnish which has yes but not no.

No in Finnish is ei, similar to Estonian ei or Swedish nej.

[–] cgtjsiwy@programming.dev 10 points 2 years ago (4 children)

I wonder when Firefox is going to add a configuration menu for keybinds.

[–] cgtjsiwy@programming.dev 2 points 2 years ago* (last edited 2 years ago)

In applied CS, it's common to talk about pure and impure functions instead of Turing machines.

Pure functions are, broadly speaking, equivalent to Turing machines. A pure function may only depend on its inputs (like a Turing machine) and has no outputs besides the return value (like the end state of a Turing machine's tape).

Impure functions cover algorithms that aren't Turing machines. For example, you might have a random number generator rand: 1 → N that outputs different natural numbers on every invocation rand() and is hence impure. Output functions are also impure, e.g., a function write: N → 1 that writes a number into a file can't be a Turing machine, because Turing machines have no concept of files.

Computer programs that consist entirely of pure functions aren't very useful, because they can't interact with the user or reality. The typical approach to solving this is to put the core program logic inside pure functions that interact with impure parts through a limited interface. That way, you can apply CS concepts to the important parts of the program and neatly separate out the impure parts.

Edit: Changed ∅ to 1 (singleton set) in function definitions. A function can't return ∅ and a function taking ∅ can't be called.

[–] cgtjsiwy@programming.dev 11 points 2 years ago

all of these are different ways to say “firefox account”?

Basically yes. The idea is that each suffix represents something that's typically a separate word in English, and you can mix and match suffixes just as you'd mix words.

  • my account -> tilini
  • to an account -> tilille
  • to my account -> tililleni
  • to my account too -> tilillenikin
[–] cgtjsiwy@programming.dev 10 points 2 years ago (2 children)

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.

[–] cgtjsiwy@programming.dev 14 points 2 years ago

Teams does actually have a sound cue when people join calls: high-pitched repeated beeps that most people can't hear due to presbycusis, and the few who do hear it think they're going crazy.

Related reddit thread.

[–] cgtjsiwy@programming.dev 2 points 2 years ago

The author should look into Koka. As I see it, Koka is at the bleeding edge of effect handling, which is why the async Rust team has taken some nibbles of inspiration from it. Alas, Rust as a whole is far too cemented to overhaul everything for generic effect support, but at least it's been beneficial for async.

[–] cgtjsiwy@programming.dev 2 points 2 years ago

Love it. Great lesson on why applicative exists, how it would/should look in C++ and discussion on prior/ongoing proposals.

 

P2881 proposes a new way to build iterators, similar to generators but with less performance overhead and better nesting (and hence composability):

struct generator123
{
    auto operator()(auto&& sink) const
    {
        std::control_flow flow;

        // With P2561: sink(1)??;
        flow = sink(1);
        if (!flow) return flow;

        // With P2561: sink(2)??;
        flow = sink(2);
        if (!flow) return flow;

        return sink(3);
    }
};

int main() {
    for (int x : generator123()) // x iterates 1, 2, 3
    {
        std::print("{}\n", x);
        if (x == 2)
            break;
    }
}

While the benefits are undisputable, it's quite verbose without P2561 and I feel C++ is starting to have too many different iterator models.

What do you think?

One of the authors has a nice presentation about pitfalls of ye olde for loops, which was probably a big motivator too: https://www.youtube.com/watch?v=95uT0RhMGwA

view more: next ›