Searching We Love Privacy Club

Twts matching #programming
Sort by: Newest, Oldest, Most Relevant

PEP 800: Disjoint bases in the type system
To analyze Python programs precisely, type checkers need to know when two classes can and cannot have a common child class. However, the information necessary to determine this is not currently part of the type system. This PEP adds a new decorator, @typing.disjoint_base, that indicates that a class is a “disjoint base”. Two classes that have distinct, unrelated disjoint bases cannot have a common child class. ⌘ Read more

⤋ Read More
In-reply-to » PSA: setpriv on Linux supports Landlock.

Another example:

$ setpriv \
    --landlock-access fs \
    --landlock-rule path-beneath:execute,read-file:/bin/ls-static \
    --landlock-rule path-beneath:read-dir:/tmp \
    /bin/ls-static /tmp/tmp/xorg.atom

The first argument --landlock-access fs says that nothing is allowed.

--landlock-rule path-beneath:execute,read-file:/bin/ls-static says that reading and executing that file is allowed. It’s a statically linked ls program (not GNU ls).

--landlock-rule path-beneath:read-dir:/tmp says that reading the /tmp directory and everything below it is allowed.

The output of the ls-static program is this line:

─rw─r──r────x 3000 200 07-12 09:19 22'491 │ /tmp/tmp/xorg.atom

It was able to read the directory, see the file, do stat() on it and everything, the little x indicates that getting xattrs also worked.

3000 and 200 are user name and group name – they are shown as numeric, because the program does not have access to /etc/passwd and /etc/group.

Adding --landlock-rule path-beneath:read-file:/etc/passwd, for example, allows resolving users and yields this:

─rw─r──r────x cathy 200 07-12 09:19 22'491 │ /tmp/tmp/xorg.atom

⤋ Read More

The WM_CLASS Property is used on X11 to assign rules to certain windows, e.g. “this is a GIMP window, it should appear on workspace number 16.” It consists of two fields, name and class.

Wayland (or rather, the XDG shell protocol – core Wayland knows nothing about this) only has a single field called app_id.

When you run X11 programs under Wayland, you use XWayland, which is baked into most compositors. Then you have to deal with all three fields.

Some compositors map name to app_id, others map class to app_id, and even others directly expose the original name and class.

Apparently, there is no consensus.

⤋ Read More
In-reply-to » The lack of suckless-like simple, hackable software these days is appalling.

@prologic@twtxt.net Yeah, this really could use a proper definition or a “manifest”. 😅 Many of these ideas are not very wide spread. And I haven’t come across similar projects in all these years.

Let’s take the farbfeld image format as an example again. I think this captures the “spirit” quite well, because this isn’t even about code.

This is the entire farbfeld spec:

farbfeld is a lossless image format which is easy to parse, pipe and compress. It has the following format:

╔════════╤═════════════════════════════════════════════════════════╗
║ Bytes  │ Description                                             ║
╠════════╪═════════════════════════════════════════════════════════╣
║ 8      │ "farbfeld" magic value                                  ║
╟────────┼─────────────────────────────────────────────────────────╢
║ 4      │ 32-Bit BE unsigned integer (width)                      ║
╟────────┼─────────────────────────────────────────────────────────╢
║ 4      │ 32-Bit BE unsigned integer (height)                     ║
╟────────┼─────────────────────────────────────────────────────────╢
║ [2222] │ 4x16-Bit BE unsigned integers [RGBA] / pixel, row-major ║
╚════════╧═════════════════════════════════════════════════════════╝

The RGB-data should be sRGB for best interoperability and not alpha-premultiplied.

(Now, I don’t know if your screen reader can work with this. Let me know if it doesn’t.)

I think these are some of the properties worth mentioning:

  • The spec is extremely short. You can read this in under a minute and fully understand it. That alone is gold.
  • There are no “knobs”: It’s just a single version, it’s not like there’s also an 8-bit color depth version and one for 16-bit and one for extra large images and one that supports layers and so on. This makes it much easier to implement a fully compliant program.
  • Despite being so simple, it’s useful. I’ve used it in various programs, like my window manager, my status bars, some toy programs like “tuxeyes” (an Xeyes variant), or Advent of Code.
  • The format does not include compression because it doesn’t need to. Just use something like bzip2 to get file sizes similar to PNG.
  • It doesn’t cover every use case under the sun, but it does cover the most important ones (imho). They have discussed using something other than RGBA and decided it’s not worth the trouble.
  • They refrained from adding extra baggage like metadata. It would have needlessly complicated things.

⤋ Read More

** Om nom nom LLMs, in which I respond to Simon Willison’s analogy **
I am hesitant to wade into the tumultuous waters that are the discourse around generative AI and LLMs, but this morning I came across a thing that so thoroughly melted my brain I feel uncontrollably compelled to respond.

This morning, at evidently 4:10 AM (no mention of timezone), Simon Willison shared the following blog post, quoted here in full:

Quitting programming as … ⌘ Read more

⤋ Read More

Just realized: One of the reasons why I don’t like “flat UIs” is that they look broken to me. Like the program has a bug, missing pixmaps or whatever.

Take this for example:

I’m talking about this area specifically:

One UI element ends and the other one begins – no “transition” between them.

The style of old UIs like these two is deeply ingrained into my brain:


When all these little elements (borders, handles, even just simple lines, …) are no longer present, then the program looks buggy and broken to me. And I’m not sure if I’ll ever be able to un-learn that.

⤋ Read More

I did a “lecture”/“workshop” about this at work today. 16-bit DOS, real mode. 💾 Pretty cool and the audience (devs and sysadmins) seemed quite interested. 🥳

  • People used the Intel docs to figure out the instruction encodings.
  • Then they wrote a little DOS program that exits with a return code and they used uhex in DOSBox to do that. Yes, we wrote a COM file manually, no Assembler involved. (Many of them had never used DOS before.)
  • DEBUG from FreeDOS was used to single-step through the program, showing what it does.
  • This gets tedious rather quickly, so we switched to SVED from SvarDOS for writing the rest of the program in Assembly language. nasm worked great for us.
  • At the end, we switched to BIOS calls instead of DOS syscalls to demonstrate that the same binary COM file works on another OS. Also a good opportunity to talk about bootloaders a little bit.
  • (I think they even understood the basics of segmentation in the end.)

The 8086 / 16-bit real-mode DOS is a great platform to explain a lot of the fundamentals without having to deal with OS semantics or executable file formats.

Now that was a lot of fun. 🥳 It’s very rare that we do something like this, sadly. I love doing this kind of low-level stuff.

⤋ Read More

** Of fairies, compost, and computers **
Lately I’ve buried myself in reading fiction. Stand outs from among the crowd are, of course, Middlemarch but also a lot of sort of scholarly fairy fiction; works that follow the scholastic adventures of studious professorial types in vaugely magical settings. Namely Emily Wilde’s Encyclopedia of Faeries’, Heather Fawcett and The Ten Thousand Doors of January, Alix E. Harrow.

I’ve also been working on a handful of personal utility programs. I … ⌘ Read more

⤋ Read More

Saw this on Mastodon:

https://racingbunny.com/@mookie/114718466149264471

18 rules of Software Engineering

  1. You will regret complexity when on-call
  2. Stop falling in love with your own code
  3. Everything is a trade-off. There’s no “best” 3. Every line of code you write is a liability 4. Document your decisions and designs
  4. Everyone hates code they didn’t write
  5. Don’t use unnecessary dependencies
  6. Coding standards prevent arguments
  7. Write meaningful commit messages
  8. Don’t ever stop learning new things
  9. Code reviews spread knowledge
  10. Always build for maintainability
  11. Ask for help when you’re stuck
  12. Fix root causes, not symptoms
  13. Software is never completed
  14. Estimates are not promises
  15. Ship early, iterate often
  16. Keep. It. Simple.

Solid list, even though 14 is up for debate in my opinion: Software can be completed. You have a use case / problem, you solve that problem, done. Your software is completed now. There might still be bugs and they should be fixed – but this doesn’t “add” to the program. Don’t use “software is never done” as an excuse to keep adding and adding stuff to your code.

⤋ Read More

Okay, here’s a thing I like about Rust: Returning things as Option and error handling. (Or the more complex Result, but it’s easier to explain with Option.)

fn mydiv(num: f64, denom: f64) -> Option<f64> {
    // (Let’s ignore precision issues for a second.)
    if denom == 0.0 {
        return None;
    } else {
        return Some(num / denom);
    }
}

fn main() {
    // Explicit, verbose version:
    let num: f64 = 123.0;
    let denom: f64 = 456.0;
    let wrapped_res = mydiv(num, denom);
    if wrapped_res.is_some() {
        println!("Unwrapped result: {}", wrapped_res.unwrap());
    }

    // Shorter version using "if let":
    if let Some(res) = mydiv(123.0, 456.0) {
        println!("Here’s a result: {}", res);
    }

    if let Some(res) = mydiv(123.0, 0.0) {
        println!("Huh, we divided by zero? This never happens. {}", res);
    }
}

You can’t divide by zero, so the function returns an “error” in that case. (Option isn’t really used for errors, IIUC, but the basic idea is the same for Result.)

Option is an enum. It can have the value Some or None. In the case of Some, you can attach additional data to the enum. In this case, we are attaching a floating point value.

The caller then has to decide: Is the value None or Some? Did the function succeed or not? If it is Some, the caller can do .unwrap() on this enum to get the inner value (the floating point value). If you do .unwrap() on a None value, the program will panic and die.

The if let version using destructuring is much shorter and, once you got used to it, actually quite nice.

Now the trick is that you must somehow handle these two cases. You must either call something like .unwrap() or do destructuring or something, otherwise you can’t access the attached value at all. As I understand it, it is impossible to just completely ignore error cases. And the compiler enforces it.

(In case of Result, the compiler would warn you if you ignore the return value entirely. So something like doing write() and then ignoring the return value would be caught as well.)

⤋ Read More

We really are bouncing back and forth between flat UIs and beveled UIs. I mean, this is what old X11 programs looked like:

Image

Good luck figuring out which of these UI elements are click-able – unless you examine every pixel on the screen.

⤋ Read More
In-reply-to » Fuck me sideways, Rust is so hard. Will we ever be friends?

@prologic@twtxt.net I’m trying to call some libc functions (because the Rust stdlib does not have an equivalent for getpeername(), for example, so I don’t have a choice), so I have to do some FFI stuff and deal with raw pointers and all that, which is very gnarly in Rust – because you’re not supposed to do this. Things like that are trivial in C or even Assembler, but I have not yet understood what Rust does under the hood. How and when does it allocate or free memory … is the pointer that I get even still valid by the time I do the libc call? Stuff like that.

I hope that I eventually learn this over time … but I get slapped in the face at every step. It’s very frustrating and I’m always this 🤏 close to giving up (only to try again a year later).

Oh, yeah, yeah, I guess I could “just” use some 3rd party library for this. socket2 gets mentioned a lot in this context. But I don’t want to. I literally need one getpeername() call during the lifetime of my program, I don’t even do the socket(), bind(), listen(), accept() dance, I already have a fully functional file descriptor. Using a library for that is total overkill and I’d rather do it myself. (And look at the version number: 0.5.10. The library is 6 years old but they’re still saying: “Nah, we’re not 1.0 yet, we reserve the right to make breaking changes with every new release.” So many Rust libs are still unstable …)

… and I could go on and on and on … 🤣

⤋ Read More

OpenBSD has the wonderful pledge() and unveil() syscalls:

https://www.youtube.com/watch?v=bXO6nelFt-E

Not only are they super useful (the program itself can drop privileges – like, it can initialize itself, read some files, whatever, and then tell the kernel that it will never do anything like that again; if it does, e.g. by being exploited through a bug, it gets killed by the kernel), but they are also extremely easy to use.

Imagine a server program with a connected socket in file descriptor 0. Before reading any data from the client, the program can do this:

unveil("/var/www/whatever", "r");
unveil(NULL, NULL);
pledge("stdio rpath", NULL);

Done. It’s now limited to reading files from that directory, communicating with the existing socket, stuff like that. But it cannot ever read any other files or exec() into something else.

I can’t wait for the day when we have something like this on Linux. There have been some attempts, but it’s not that easy. And it’s certainly not mainstream, yet.

I need to have a closer look at Linux’s Landlock soon (“soon”), but this is considerably more complicated than pledge()/unveil():

https://landlock.io/

⤋ Read More

So I was using this function in Rust:

https://doc.rust-lang.org/std/path/struct.Path.html#method.display

Note the little 1.0.0 in the top right corner, which means that this function has been “stable since Rust version 1.0.0”. We’re at 1.87 now, so we’re good.

Then I compiled my program on OpenBSD with Rust 1.86, i.e. just one version behind, but well ahead of 1.0.0.

The compiler said that I was using an unstable library feature.

Turns out, that function internally uses this:

https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.display

And that is only available since Rust 1.87.

How was I supposed to know this? 🤨🫩

⤋ Read More

CNCF Kubestronaut Program Momentum Highlights Asia’s Role in Growing Cloud Native Talent
Upcoming Kubestronaut celebrations in China and Japan to honor global program growth Hong Kong, China– 10 June, 2025 – The Cloud Native Computing Foundation® (CNCF®), which builds sustainable ecosystems for cloud native software, today announced continued… ⌘ Read more

⤋ Read More

How can one write blazing fast yet useful compilers (for lazy pure functional languages)?
I’ve decided enough is enough and I want to write my own compiler (seems I caught a bug and lobste.rs is definitely not discouraging it). The language I have in mind is a basic (lazy?) statically-typed pure functional programming language with do notation and records (i.e. mostly Haskell-lite).

I have other ideas I’d like to explore as well, but mainly, I want the compiler to be so fast (w/ optimisations) that … ⌘ Read more

⤋ Read More

plwm: X11 window manager written in Prolog
plwm is a highly customizable X11 dynamic tiling window manager written in Prolog. Main goals of the project are: high code & documentation quality; powerful yet easy customization; covering most common needs of tiling WM users; and to stay small, easy to use and hack on. ↫ plwm GitHub page Tiling window managers are a dime-a-dozen, but the ones using a unique or uncommon programming language do tend to stand out. ⌘ Read more

⤋ Read More

Jubilejných 280 rokov príchodu Slovákov do Petrovca
Báčsky Petrovec sa v dňoch 22. až 25. mája 2025 niesol v slávnostnej atmosfére pri príležitosti Dní Petrovca a významného jubilea – 280. výročia príchodu Slovákov do tejto vojvodinskej slovenskej osady. Program bol tradične bohatý a počas troch dní rušno bolo nielen v Miestnom spoločenstve, ale aj v Turistickej organizácii Obce Báčsky Petrovec, v Múzeu vojvodinských Slovákov, v Spolku Petrovských žien, na Námestí … ⌘ Read more

⤋ Read More
In-reply-to » @kat I don’t like Golang much either, but I am not a programmer. This little site, Go by example might explain a thing or two.

One of the nicest things about Go is the language itself, comparing Go to other popular languages in terms of the complexity to learn to be proficient in:

⤋ Read More

Google’s “AI” is convinced Solaris uses systemd
Who doesn’t love a bug bounty program? Fix some bugs, get some money – you scratch my back, I pay you for it. The CycloneDX Rust (Cargo) Plugin decided to run one, funded by the Bug Resilience Program run by the Sovereign Tech Fund. That is, until “AI” killed it. We received almost entirely AI slop reports that are irrelevant to our tool. It’s a library and most reporters didn’t even bother to read the rules or even look at what the intend … ⌘ Read more

⤋ Read More

10 Most Devastating Computer Viruses
Long before computers made their way into workplaces and homes everywhere, people theorized about a destructive kind of program that could replicate itself and spread between networked machines. In the 1980s and early 1990s, those programs became popularly known as “computer viruses.” You’ve probably had one at some point. All it takes is one wrong […]

The post [10 Most Devastating Computer Viruses](https://listverse.com/2025/05/19/10-most-devastating-comput … ⌘ Read more

⤋ Read More

What were the MS-DOS programs that the moricons.dll icons were intended for?
Last time, we looked at the legacy icons in progman.exe. But what about moricons.dll? Here’s a table of the icons that were present in the original Windows 3.1 moricons.dll file (in file order) and the programs that Windows used the icons for. As with the icons in progman.exe, these icons are mapped from executables according to the information in the APPS.INF file. ↫ Raymond Chen … ⌘ Read more

⤋ Read More

What Problems are Truly Technical, not Social?
Most “tech” problems (and solutions) seem social, with e.g. most newer startups relying on internal connections to gain real world adoption, otherwise blocked due to institutional apathy and bad regulations (sms 2fa, hospital faxes…)

A recent (unlocated) poll asked a similar question: “what percent of workers in the software industry are employed writing programs that should not exist?” While we do have NP-hard problems, politically hard problems like avoi … ⌘ Read more

⤋ Read More

Rust celebrates ten year anniversary with Rust 1.87.0 release
I generally don’t pay attention to the releases of programming languages unless they’re notable for some reason or another, and I think this one qualifies. Rust is celebrating its ten year anniversary with a brand new release, Rust 1.87.0. This release adds anonymous pipes to the standard library, inline assembly can now jump to labeled blocks in Rust code, and support for the i586 Windows target has been rem … ⌘ Read more

⤋ Read More