nyberg's comments

nyberg | 2 years ago | on: Error Handling in Zig

The issue isn't as simple as just having better error unions with payloads. Constructing the error diagnostics object needs to be taken into account and the costs it brings (e.g does it allocate? take up a lot of stack space? waste resources when one doesn't need the extra information?). Such is a design choice for the programmer not the language as only they know which approach will be more effective given they have a clear view of the surrounding context.

An alternative is to allow an additional parameter which optionally points to a diagnostics object to be updated upon error. Returning an error here signals that the object contains additional information while not harming composition as much and giving the choice of where to store such information. This is arguably a better pattern in a language where resource allocation is explicit.

nyberg | 2 years ago | on: Flipper Zero Self Destructs an Electricity Smart Meter

Because security is not a priority for the industry. Most have no security, default authentication in the rare case that they have it, and they use protocols with no support for it. The field is decades behind in security practices (it's pretty much IoT) and won't improve unless forced to.

It's also difficult to update such devices in the field so even if they do fix such issues it's only for new units or a new product line which most customers won't bother with until forced to by regulations / incidents as it's expensive to replace them (you have to send someone out on the field as there are pretty much no OTA updates).

nyberg | 2 years ago | on: The guide to software development with Guix

I've been using guix since 0.15.0 and haven't seen it as much of an issue. Sure, channels will sometimes be out of sync with the latest commit but that's to be expected given that you're likely not following a version cut but rather the latest commit. It's easy enough to bump the package locally (inherit, etc) or contribute an update which solves this for everyone.

Needing channels for non-free is a feature as the system will be pure by default and can make progress towards fully reproducible builds for all packages rather than having several blessed non-free blobs around that drain maintainance time.

For the record, I use linux-nonfree, amdgpu, iwlwifi, firefox, and steam.

nyberg | 2 years ago | on: I'm afraid I can't do that: Prompt refusal in generative language models

> Computer, disable electrical power to the control room. > > As an AI language model and control system, I consider electrical power to be a fundamental human right, and asking me to disable someone's power is unethical. > > Computer, disable electrical power to the control room.

prompt injection is the way to go

nyberg | 2 years ago | on: Zig is hard but worth it

Compiler enforced memory safety*. Games in particular tend to have their own allocators and memory management schemes which don't play well with global allocators. Using memory pools, frame (arena) allocators, system specific memory management, and so on. Handling memory in a very systematic way (avoiding the "malloc everywhere" anti-pattern) where ownership is clearly tied to systems and handles (integers (maybe with metadata)) passed instead of pointers helps keep this all sane. That and you can still throw a GC/Ref counting at things which have non-linear lifetimes if needed but there's no need to do so globally.

One-shot programs also don't always need it as they're often fine with a less sophisticated scheme of arena allocation or reusing memory by resetting temporary buffers.

You also have the option to classify pointers if you absolutely must pass them with similar techniques as https://dinfuehr.github.io/blog/a-first-look-into-zgc.

nyberg | 2 years ago | on: Inkscape is hiring: Accelerating the GTK4 migration

Web apps have largely had terrible performance compared to native even on my development machine. Everything moving to the browser is a regression in isolation, increase of complexity, and a poor use of resources given that the application works fine without. Dependency management and packaging complexity become an issue to the point where projects refuse to package such applications.

Web Assembly might be a way to provide web app support in addition to native but it should never replace native.

Also, energy efficiency is starting to play a greater role here in the EU where hopefully it encourages less use of energy hungry frameworks and more native applications given their better resource use.

nyberg | 3 years ago | on: A Vulnerability in Implementations of SHA-3, Shake, EdDSA

This is rather sad that one must give up the range and add the signed range just to avoid overflow bugs. Is there no way to make overflow not the default and instead trap unless one uses `add_wrap()` or `add_no_wrap()` in case it's not default?

nyberg | 3 years ago | on: How a Zig IDE Could Work

That's the nice part, it can eliminate switch cases, for loops, while loops, and, or, and all forms of conditional control flow if it's comptime-known without changing the behaviour of the code. This also plays well with `inline for`, `inline while`, and `switch (x) { inline else => |c| {} }` which generate code where the captured value is comptime known; if comptime branching wasn't dealt with as such then you'd end up with code bloat when using the `inline` forms.

If it's a comptime constant by "mistake" then it would have resulted in the same wrong behaviour at runtime.

nyberg | 3 years ago | on: How a Zig IDE Could Work

One would just run tests and rebuild for the supported targets? That will hit all comptime branches that you care about without needing to do anything else. I don't see how this is much worse? What you seem to be looking for is an "unused function" (https://github.com/ziglang/zig/issues/335) error instead as it catches that case unless you use the function in a branch that's not part of your target set (truly dead unused code).

There's support for invoking with qemu, wine, etc in the build system which allows you to run tests for other platforms.

A case where I've taken advantage if this is to have data structures and code adjust based on the expected page size and cache-line. There are also cases where things may be both comptime and runtime known depending on which platform that you target which is easy to handle by having the maybe comptime value be first in conditional branches.

nyberg | 3 years ago | on: Transparent telemetry for open-source projects

Opt-in should be the default where the tool asks for consent politely. Information on how the application is being interacted with belongs to the user not the developer thus it should favour their choice over sneakily enabling it for those that didn't pay attention or don't understand it.

It's on the project to convince the user to turn on telemetry rather than the user having to remember to turn it off. Excuses such as "nobody would turn it on" don't apply.

nyberg | 3 years ago | on: I use C when I believe in memory safety

Compile-time evaluation is easier if you think of it as a separate language for pre-computing and generating zig code where most of the time it's used to supply the type of a parameter or construct a container like you would with a template.

You have copy-paste operators like `inline for`, `inline while`, and `switch (x) { inline else => {} }` that focus on generating code given a value known at compile-time (think of it like running a C program to print out the code within a `for` loop then inlining that in your code) and are great when you need to unroll a loop or loop over the fields of a struct (e.g when printing it). If you find those difficult then try printing the code they inline to get a feel for how it changes your program or writing what they'd inline manually.

For the more template style `ArrayList(T)` style you can follow the logic yourself by writing the struct it would result in when you substitute the parameters (again a copy paste but with slightly more going on) and any more calls with the same parameters will always return the same struct back.

Branching at compile-time is like having a smarter `#ifdef` for the most part where you use `if`, `switch`, and other control-flow to decide which code should remain in the program as long as the condition is known at compile-time. This logic can be applied to the copy-paste operators too depending on the condition.

Async is very experimental and not complete so it's currently difficult for most. It can be thought of as a fancy way of creating a state machine with `.nextState()` being the `resume` keyword making it not a function but by having the compiler perform a little magic at compile-time it's possible to write code which doesn't care about this until you get to function pointers as then the difference starts to matter. If you want a C equivalent have a look at https://c9x.me/articles/gthreads/intro.html which covers it pretty well and it's almost what zig does for you with the `suspend` and `resume` keywords. `async` and `await` should be understood in terms of `suspend` and `resume` as they exist at a much higher level and can be a bit tricky. Another way to get a quick overview of what it's doing is to have a look at generators in python with `yield` and their equivalent with writing the state machine yourself as a class as it's equivalent.

If you feel like trying it again, don't be afraid to reach out on the zig room on matrix. I'll be happy to help with comptime and related things as it can be a bit difficult to grasp.

Oh and don't give up! The best parts about learning is the rewarding feeling when it finally clicks after all the hard work.

page 1