@minoru@functional.cafe avatar

minoru

@minoru@functional.cafe

Programmer, reader; dreaming of getting back into cycling.

My avatar is from the poster for https://myanimelist.net/anime/5682/Phantom__Requiem_for_the_Phantom anime. I don't associate myself with the protagonist though, don't read too deep into that please.

This profile is from a federated server and may be incomplete. Browse more on the original instance.

minoru, to random
@minoru@functional.cafe avatar

With Junethack 2024 (hopefully) right around the corner, it's a good time to watch this little dive into NetHack source code and discover the techniques, the humour, the philosophy of this great game:

Alexei Pepers - Nethack: Tech Tourist Mode
https://youtube.com/watch?v=5y_IAdOwaYs

minoru, to random
@minoru@functional.cafe avatar
minoru, to random
@minoru@functional.cafe avatar

I was gobsmacked to learn that wristwatches don't need to be wound anymore, at least not for the last hundred years. And I don't mean the quartz ones that run off a battery; I'm talking about the old-fashioned, mechanical kind.

This is called an "automatic watch". It has a little weight (rotor) at the back, which spins when you move your wrist. That movement wounds the mainspring, so you don't need to.

Designs like this first appeared at the end of XVIII century, and became common after World War I.

These days, there are also "automatic quartz" watches where a rotor spins a tiny electrical generator to charge the battery that drives the quartz. Somehow this isn't as impressive as a fully mechanic counterpart, though.

The back of a wristwatch with a transparent backplate. Inside, a semi-circular rotor obscures half the mechanism. When the watch is moved about, the rotor spins to keep facing the ground.

minoru,
@minoru@functional.cafe avatar

Unsurprisingly, this led me to learn more about mechanical watches. Perhaps there's more I don't know?

There sure is! I always thought there are only two practical wristwatch designs: mechanical and quartz.

In a mechanical watch, a spring drives the mechanism. Left alone, the mainspring would unwind instantly, but there's a clever design called an "escapement" that only lets the spring to unwind a tiny bit a few times a second (6 to 10 times for most watches). Each little unwinding advances the mechanism forward by a fraction of a second.

In a quartz watch, a battery drives a generator which "ticks" 32 768 times a second. When it made this many ticks, a little impulse is sent to the mechanism, and it advances by one second.

So one interesting conclusion here is that in a mechanical watch, the seconds hand moves much smoother than in a quartz watch.

Now I have to pull a very lame Steve Jobs impression. It's mechanical and quartz. Mechanical. And. Quartz. Mechanical and quartz. Are you getting it?

In 1999, Seiko released a watch with a Spring Drive mechanism that combines a mainspring and a quartz. The mechanism is pretty much the same as in a mechanical watch, but there is no escapement. Instead, the mainspring is connected directly to the hands of the watch. The mainspring also drives an electric generator, which in turn powers a quartz crystal. This crystal counts time like in a quartz watch, but its measurements are used instead to measure the speed of mainspring's unwinding. That speed in then brought to the desired rate using a little electric brake. How wild is that?

The coolest thing is, with Spring Drive the seconds hand doesn't tick at all. It never stops, not even for an instant. It just glides, its speed controlled by the quartz. It flows like time itself.

Here's how it looks in slow motion: https://www.youtube.com/watch?v=XFo_U7UwROw&t=876s The first five watches are mechanical ones that tick 5 to 10 times a second, and the last one is the Spring Drive.

minoru, to privacy
@minoru@functional.cafe avatar

The European Court of Human Rights has ruled that breaking end-to-end encryption by adding backdoors violates human rights

https://www.schneier.com/blog/archives/2024/02/eu-court-of-human-rights-rejects-encryption-backdoors.html

🎉

icon_of_computational_sin, to random
@icon_of_computational_sin@mstdn.starnix.network avatar

Security dude (he/him) being so wrong about security, it's comical.

https://infosec.exchange/@kurtseifried/111687811980508556

minoru,
@minoru@functional.cafe avatar

@amiloradovsky Inability to paste in a password makes people choose passwords which are easy to type in, which almost always means the passwords will have less entropy. I know because I had to type some of my "32-char mixed-case alphanumeric + ASCII special characters", and that wasn't fun at all; typing passphrases that have corresponding amount of entropy wasn't fun either.

Overriding paste makes the system more amenable to dictionary attacks and/or bruteforce.
@icon_of_computational_sin

minoru, to Fashion
@minoru@functional.cafe avatar

I'm learning to better combine clothes to create tasteful "looks" from what I already own. This is very overwhelming because I can't just lay it all down on the floor and visually try all valid permutations. Can you recommend Android apps to help with that? Apparently it's called "a virtual closet" or "an outfit planner".

I don't need recommendations, social features, or built-on marketplaces. I also don't want to log in anywhere; let the data be stored just on my phone. It could be a Linux desktop app too, but that'd be slightly more awkward.

There's only Petronius in F-Droid, and that one hasn't been updated for 11 years (and source went proprietary). DDG didn't find any forks or replacements or whatever. Google Play has like 5 apps, all of which run contrary to my wiahes above. But if something like this exists, I bet you know about it!

#AskFedi #fashion #clothes #wardrobe #Android #Linux

rttf, to cpp
@rttf@techhub.social avatar

After watching C++20 Modules: The Packaging and Binary Redistribution Story by Luis Caro Campo, I'm even more convinced that are a mistake. IMHO they just add more complexity that c++, SREs and build tool developers need to deal with, plus solve no real problem, but preprocessor definition conflicts for some legacy headers 🤷‍♂️

I know these are early days for this feature, and I really wish to be wrong here, but I doubt if this feature gets a wide adoption from the community (at least in it's current form)

What are your thoughts on this?

https://www.youtube.com/watch?v=-p9lvvV8F-w

minoru,
@minoru@functional.cafe avatar

@rttf Haven't seen this talk, but my impression of "modules" is the same as yours. They do solve some problems (dependency on the preprocessor, lack of standardized format for "precompiled headers"), but they don't really act like modules. My biggest gripe is that these "modules" are orthogonal to namespaces. Why on earth would I need that? I'm trying to write production software, but the Committee is giving me a construction kit for a programming language =\

minoru, to random
@minoru@functional.cafe avatar

Tried to clean my Lamy for the first time (after one month of use). Left it in a cut to soak for 3 hours, then rinsed and let it dry for half an hour. After reassembly it barely worked; apparently there's still water inside.

Rinsed it again, will let it dry overnight. A bit nervous that I might have ruined it. 🤞

minoru, to random
@minoru@functional.cafe avatar

As if there wasn't enough of things that are wrong with the world, coin flips are found to — 51% of the time it lands on the same side it started.

(I'm yet to read the paper, but Schneier can be trusted not to post total nonsense.)

minoru, to random
@minoru@functional.cafe avatar

The Internet, or rather the people on the Internet, never cease to amaze.

I just watched 10 Things I Hate About You, a teen romcom from 1999. At one point, a male speaks to one sister about the other and says, "No offense, I know everyone “digs” your sister, but she’s without". Not being a native speaker, I look up what "to be without" means, but my searches come up dry. Eventually I look up the exact phrase, and find the same question asked on Reddit three months ago: https://www.reddit.com/r/EnglishLearning/comments/1561dvp/shes_without/ What were the odds?!

BTW Reddit doesn't have a satisfactory answer, so if someone has a better one, please share! The phrase might be Australian slang (the hero lived there for 10 years before moving to USA) or be related to Shakespeare.

jgoerzen, to random
@jgoerzen@floss.social avatar

In a weak moment, it occurred to me that might be a database. I think it upholds most, if not all, properties (especially if one assumes the content of a file won't be modified after creation). I need to look at it in more detail yet, but I'm enjoying this concept.

minoru,
@minoru@functional.cafe avatar

@jgoerzen Funny timing; I just read about Syncthing's protocol yesterday: https://docs.syncthing.net/specs/bep-v1.html

If we treat the file tree as an associative array where keys are filenames and values are either associative arrays (subdirectories) or immutable values (files), then I guess Syncthing is a CRDT.

Of course, we can emulate a set by using empty files for values.

I guess one could implement some of the text CRDTs using file trees as, well, trees, storing data in directory names, but those names are limited by filesystems (e.g. 255 bytes on ext4).

Syncthing is still a CRDT if files are modified, as long as the modifications touch different blocks (which are 16 MiB at most). If one thinks of files as arrays whose elements are 16MiB values, then one can implement grow-only and positive-negative counters; although I think it's more space-efficient to implement them with sets (directories full of empty files, the number of files is the count).

I always thought that trees are a universal data structure that can emulate the interface of any other, so I also guess that Syncthing can implement other data structures too (but inefficiently).

This is all very impractical, but is a fun theoretical exercise to work through :)

minoru, to haskell
@minoru@functional.cafe avatar

folk: how do I verify that my package can be built with bytestring 0.12? There is no GHC releases that bundle that version yet. Is there some flag that could tell it to use a version from Hackage rather than the one included into the GHC distribution?

minoru,
@minoru@functional.cafe avatar

@jaror @romes Thank you both! The mystery is already solved, please see earlier comments. Turns out I was specifying a non-existent version to --constrain, but didn't notice it because the error message for "version doesn't exist" looks the same as for "version couldn't be used because it doesn't satisfy constraints". The Universe seem to be pushing me to contribute to Cabal as of late :)

minoru,
@minoru@functional.cafe avatar
minoru, to random
@minoru@functional.cafe avatar

Now this is simultaneously embarrassing and hilarious.

I decided to unsubscribe from one of the old-fashioned mailing lists. By "old-fashioned", I mean the "forum over the email" kind of list, not the modern "newsletter" which fills your inbox with updates. (Do you even know what I'm blabbing about?..)

Anyway, to unsubscribe one sends an email to a special address with a command in the subject, and voila — no more emails from that list. One could probably do it via a web form as well, but I'd have to find a URL for that. Email is plain easier.

So I send the command and close my email client, fully expecting to read the confirmation email tomorrow.

It doesn't arrive. (No, it isn't in the Spam folder either.) Oh well, too busy for that, will check later.

Another day passes, I get new emails from the mailing list, so clearly the unsubscription didn't work.

I send the command again, with a password this time because according to the help it spares me a confirmation email.

This time, I wait for a few minutes for a response. It does not arrive.

At this point I'm starting to doubt myself, because clearly I'm doing something wrong. But what?

I re-read the help email. The address I'm sending to is correct. The command is indeed in the subject line. The format is "unsubscribe []" — let's double-check what I sent... Yup, looks correct.

Now wait a minute.

It's unsubscribe, not ubsubscribe.

I managed to mistype that two times in a row, on different days.

Learning to touch-type was a mistake :)

juliobiason, to random
@juliobiason@functional.cafe avatar

How the heck Fostodon going invite only is hacker news worth?

minoru,
@minoru@functional.cafe avatar

@juliobiason I've been neglecting the same plan for more than a year now. And I'd bet we're thinking of the same language to implement it, too :) But alas, I'm also not up to scratch at the moment either, even if I had help.

But if two people are thinking of the same idea, perhaps somewhere a third person is already working on it?

minoru, to random
@minoru@functional.cafe avatar

Leadership is the management of people, essentially trying to get the best out of people while also fulfilling their personal needs.

https://facedragons.com/personal-development/books-every-man-should-read/

juliobiason, to random
@juliobiason@functional.cafe avatar

I'm thinking really hard about sync stuff in Rust, and "Rust Atomics and Locks" keeps popping in my head, and I really want to buy it...

but OOF, exchange rate.

minoru,
@minoru@functional.cafe avatar

@juliobiason You know it's available for free, right? https://marabos.nl/atomics/foreword.html

I mean, it's cool to support the author, but it doesn't have to block any of your other work.

minoru, to random
@minoru@functional.cafe avatar

matklad posted an interesting set of rules for writing comparisons:

  1. strongly prefer < and <= over > and >=;
  2. state invariants positively.

Rationale is that it resembles how the numbers are placed on the number line, and thus more intuitive.

The second rule has me conflicted though.

On one hand, I do agree that invariants are easier to read when they’re stated positively. In my code, I follow every invariant-checking if statement with a comment that says something along the lines of // Invariant: the array is large enough for this algorithm to make sense.

On the other hand, my code usually checks that the invariant is not held, and exits early. So my comments state the invariant positively, but the code states it negatively.

I think I could get used to negating a positively stated invariant:

if (!(array.size() > MIN_DATAPOINTS_COUNT)) {<br></br>    return;<br></br>}<br></br>

But that looks quite ugly to me and I immediately itch to rewrite it to <=.

minoru, to random
@minoru@functional.cafe avatar

I made a PR to my project the other day and CI failed with "error 137". What's that?

Quick lookup on DDG => all results say it's OOM killer => I brush it off as an intermittent CI oddity, restart the jobs, they pass and I'm happy.

Another day, someone else submits a few more PRs, and all of them have some jobs failing with the same error. Well, my PR did add a test that creates a one-megabyte string, so perhaps that's it? I dive in to investigate.

So I learn about systemd-run --scope -p MemoryMax=123M. Find that the tests do fail, but only occasionally. Try to figure out if it has anything to do with running them in a random order. strace them. Just plain stare at the code.

Go through the CI provider's issue tracker looking for mentions of same. Find my own issue from a couple years ago, but no new ones.

DDG some more, finally bump into a closed issue on some other CI provider's tracker (!) with a link to TLDP (!) where Advanced Bash Scripting-Guide claims that exit code 137 is caused by SIGKILL: https://tldp.org/LDP/abs/html/exitcodes.html

It finally clicks. My test does spawn a thread which it later kills with SIGKILL. Well, it tries :) Apparently in some cases it kills the entire process, which kinda makes sense (signal handlers are global to the process), but simultaneously doesn't (why doesn't it do this every time?)

Anyway, swapping pthread_cancel for pthread_kill resolved the issue. I thought I'd blog about it, but now that I DDG it once more it turns out someone already did: https://specificlanguages.com/posts/2022-07/14-exit-code-137/

(Hmm, maybe I just did, too :)

minoru, to random
@minoru@functional.cafe avatar

> be me
> C++ all day every day at $dayjob
> decide to touch on a small web app I made a year ago
> npm audit fix
> huh, it seems stuck, what's up?
> open htop
> it's node-gyp compiling C++ code

(╯°□°)╯︵ ┻━┻

minoru, to random
@minoru@functional.cafe avatar

Hey netizens, do me a favour: if you have a site and it has a newsfeed ( or ), please check it with https://validator.w3.org/feed/ If it fails the validation, please tell the author of your software about it. If you're the author and you don't understand what the validator is telling you, comment here and I'll try to help (others are welcome to help too!)

The world is full of slightly broken feeds. Let's make it a better place.

minoru, to books
@minoru@functional.cafe avatar

Finally got around to Robert Martin's Clean Code (). I'm halfway through the first chapter and it's already brutal: they turn a messy, yet manageable function into an atomized cloud of two-line methods. Sure, there is an hierarchy to them, but to see it you have to read the entire thing, which is four times longer than the original. Was that really an improvement?

I think the author's advice itself is solid, but it sure feels like their examples take it to an extreme. I guess that's why this book has such a mixed reputation.

minoru,
@minoru@functional.cafe avatar

Page 72, first bit of nonsensical advice: put the bodies of try and catch into functions. Why? Because mixing error handling with normal processing is "bad", and it makes the code convoluted. Both of these statements are mostly true, but the suggested solution is, simply speaking, bullshit.

What do you prefer, mothballs or spider webs? You can't make a mothball beautiful by spreading it out into a web. The way to make it beautiful is to take it apart, sort useful stuff into piles and discard the junk. Code-wise, it means splitting the original try-catch into multiple ones and then moving each into a separate function. Then maybe unifying some of the error handling by pushing it from the functions up to their callsite.

minoru,
@minoru@functional.cafe avatar

Chapter 5 of Clean Code is on formatting. Martin argues that functions should be ordered in a top-down order: high-level stuff first, then their callees, then callees' callees and so on.

This makes sense to me on a conceptual level, because code is read more often than it's written and I find it easier to learn classes/modules in a top-down way.

Still, I never do it in my own practice. Even if I tried, I dread to think of the amount of work I'd need to perform when changing any of the code (as that requires re-ordering to maintain the "callers before callees" invariant). And even if I was up for that work, I realize it'd make my Git diffs noisy and less helpful.

But both problems seem like something that tools could handle. Are there any IDEs that re-order functions within a module? Are there any VCS that are able to hide movements of code?

  • All
  • Subscribed
  • Moderated
  • Favorites
  • provamag3
  • thenastyranch
  • magazineikmin
  • ethstaker
  • InstantRegret
  • tacticalgear
  • rosin
  • love
  • Youngstown
  • slotface
  • ngwrru68w68
  • kavyap
  • cubers
  • DreamBathrooms
  • megavids
  • mdbf
  • modclub
  • GTA5RPClips
  • normalnudes
  • khanakhh
  • everett
  • cisconetworking
  • osvaldo12
  • anitta
  • Leos
  • Durango
  • tester
  • JUstTest
  • All magazines