programming
- Read a binary file and embed it in the final executable as an array of bytes.
- Create a
HashSet
(Python folks: aset()
of items of a specific type) where each element is an array of bytes. - Skip the first 7 bytes of the binary file using Python-like slice notation.
- Create an iterator that emits 10-byte portions of the rest of the file, one at a time.
- Collect all the values from that iterator into… oh!, a
HashSet<&[u8]>
because Rust can tell what the type of the target variable is, so why make me repeat myself?
Python 3.13 launched today. I’ve done it. I’ve lived long enough to see a less-GIL’ed Python released to the public. Until now there’s been an unvirtuous cycle:
Python isn’t good at running CPU-intensive threaded code. → No one writes code like that. → There was no pressure to remove the GIL because no one writes code that would benefit from it. → Repeat.
I hope this is the first giant step toward good Python multithreading.
Google writes safer code with Rust
From “Google hails move to Rust for huge drop in memory vulnerabilities”:
In Google’s own shift towards using memory safe programming languages there has been a significant drop in the number of memory-related vulnerabilities, with memory safe vulnerabilities down to 24% in 2024 - a stark contrast from 2019 [76%] and well below the industry norm of 70%.
Memory safety is not the same as safety. You can still write bad logic in any language. It “just” gets rid of the majority of bugs so that programmers can concentrate on the more interesting parts.
Also, yes, of course you can write safe C code. No one with a large codebase ever has in practice, but it’s at least hypothetically possible. Wouldn’t rather not have to, though?
Sometimes Rust makes me so happy. I wrote this over the weekend:
let embedded_data = include_bytes!("../static/data.bin");
let my_set: HashSet<&[u8]> = embedded_data[7..].chunks(10).collect();
It does this:
Rust isn’t magic. Other languages can do similar things if you poke at them enough. It’s more that 2 lines of builtin Rust can readably implement a reasonably sophisticated set of operations that get compiled into a static executable. That’s a very pleasant combination of features.
If you’re writing an SDK, don’t include a section on how to fetch all the pages of chunked results. That’s your job, not theirs. Make that the default interface and provide advanced methods to fetch a page at a time if your user specifically needs to for whatever reason.
Don’t make users write this:
all_results = []
results = sdk.get_items()
all_results.extend(results.items)
while results.has_more:
results = sdk.get_more_items(results.next)
all_results.extend(results.items)
Let them write this:
all_results = sdk.get_all_items()
Looking at you, AWS and Dropbox.
Language Server Protocol Launched a Golden Age of Editors
Microsoft developed Language Server Protocol (“LSP”) a few years ago to make it easier to add support for new languages to VS Code. Lots of smart people have written interesting things about LSP and I don’t want to rehash all that, but in summary: it gives people who like using a computer language a standard way to tell VS Code how to work with it.
Thing is, I don’t like VS Code at all. It’s a brilliant program, but under the covers it’s a web browser running a very clever JavaScript program. It doesn’t, and can’t, and won’t, ever feel like a native application, and that bothers me more than it should. I much prefer using what others call Mac-assed Mac apps. This is where LSP shows its real value.
Other apps can support LSP, too. Emacs users wrote a couple of different ways to connect those nifty new language servers to their favorite editor. Voila! Now Emacs has delightful support for every language that VS Code knows how to edit. So does Vim. And now, so do Nova and even the venerable BBEdit.
That last one blew me away. I’d seen it from a distance over the years. It’s impossible to use a Mac as a professional developer without at least being aware that it exists. BBEdit always struck me as a very neat, but very dated, niche editor that people kept using because they were too stubborn to switch. Oh, how wrong I was. I downloaded a copy a couple of weeks ago to kick the tires and found that since it can speak LSP, it might be the best programming environment I’ve ever used on my Mac. (“How’s its Python? Whoa! Is it that good with Rust? Whoa! How about… Terraform files? WHOA!”) 30 years of development as a text editor, plus all the effort that programming language users put into giving LSP broad and deep language support, yielded something that has incredible text mangling abilities and cutting-edge programming features. I love it. I’ve been trialing it as my main editor since then, and every day I appreciate it more.
I think we’re in a new golden age of programming editors. Now that any editor which can use LSP competes on a level playing field, the real competition is in subjective areas like the user interface, responsiveness, ergonomics, and extra functionality. Thanks to VS Code, those Mac-assed Mac apps redefine what developing software on a Mac can be like, and I couldn’t be more pleased with my options.
Google v. Oracle - victory!
This morning the US Supreme Court ruled for Google in Oracle’s case against them. This is wonderful news for American software engineering as the opposite ruling would have been disastrous for the entire industry.
Consider a comprehensive, albeit farfetched, analogy that illustrates how the API is actually used by a programmer. Imagine that you can, via certain keystrokes, instruct a robot to move to a particular file cabinet, to open a certain drawer, and to pick out a specific recipe. With the recipe in hand, the robot then moves to your kitchen and gives it to a cook to prepare the dish. This example mirrors the API’s task-related organizational system. Through your simple command, the robot locates the right recipe and hands it off to the cook. In the same way, typing in a method call prompts the API to locate the correct implementing code and hand it off to your computer. And importantly, to select the dish that you want for your meal, you do not need to know the recipe’s contents, just as a programmer using an API does not need to learn the implementing code. In both situations, learning the simple command is enough.
I think that’s a great analogy, if I do say so myself.
Use local Git repos for personal work
I’ve heard a lot of online arguments about whether you should host your Git-based projects in GitHub or GitLab, but a lot of them miss an obvious option. Is this repo for your own personal work that you don’t intend to share with others? Great! You can host unlimited, free, completely private repositories on your own system. Here’s the complete process:
$ mkdir -p ~/src/myproject
$ cd ~/src/myproject
$ git init --bare
$ cd ~
$ git clone ~/src/myproject
$ cd myproject
There, you’re done. Now you have a 100% fully functional Git repo that doesn’t require a network connection and supports every single Git feature. Pull it, push it, branch it, revert it, whatever: it’s your own repo and you can do whatever you want with it. And you don’t have to sign up for anything, or agree to a Terms of Service, or share your work, or trust a company you don’t know very well.
If you want to move your repo to another server later, you can copy ~/src/myproject
to its new home via whatever means you find most convenient, use git remote set-url origin [...]
to point your existing work toward the new location, and then go on about your business as usual without changing any of your workflow.
GitHub and GitLab have a lot of nice features that may be totally irrelevant if you’re not collaborating with a team. Never forget that you can host Git projects yourself, easily and for free.
Oh, and if you do find yourself needing to work with a handful of people and don’t need all of the integration features of the commercial options, I highly recommend Gitea. It’s a tiny little service you can host yourself and it takes very few resources. I use it whenever I need my Git repo to be accessible across the Internet.
Google v. Oracle, by analogy
Suppose Joe opens a restaurant. He hires a waiter who is really great at following directions, but speaks no English. Over time, Joe comes up with a way of working with this waiter that’s very precise and detailed. You can ask the waiter for things like “order burger plus cheese plus ketchup no tomato no onion” or “bring check” or “bring water”. However, you have to say things exactly the right way each time. You can’t just say “order cheeseburger” instead of “order burger plus cheese”, or “bring me some water” instead of “bring water”. If you do, the waiter will only say “I don’t understand” and wait for you to say it the right way.
All of this is explained on the menu, and the waiter is otherwise good enough at his job that people are willing to learn the Joe’s Cafe way of ordering their food and asking for the check afterward.
A while later, Gina decides to open a different restaurant across town from Joe’s place. Her food is nothing like Joe’s, she uses different suppliers, her kitchen has a brand new setup she invented herself, and she uses little robot dogs instead of waiters. However, she does a little market research and finds out that a lot of people in her city are use to ordering food the Joe way. To make it easier for her customers, she programs her robot dogs to respond to requests the same way that Joe’s waiter would. Then they’ll be able to order food and enjoy her restaurant without having to learn a whole new system!
Now, at Joe’s, if you say “order burger plus cheese”, the waiter writes this down, carries the order to the kitchen, and hands it to the cook. The cook follows the instructions, hands the food to the waiter, and the waiter takes it back to the table. Gina’s restaurant doesn’t have burgers, but if you tell her robot dog to “order steak plus potato”, it transmits the order via radio to the kitchen where a 3D printer makes it and then sends it to your table via a flying drone.
In other words, you place your order at Gina’s restaurant the same way you would at Joe’s, but almost everything else about the process is completely different because Gina came up with her system from scratch. As it turns out, a few orders do happen to work the same because there are only so many ways to react to “bring water”. That’s natural, though. Gina didn’t copy Joe’s “leave the table, fill a pitcher with water, bring it back to the table, and fill the empty glasses” process; that’s just the way you do it.
This is same as the relationship between Oracle and Google. Oracle bought a company who made a programming language called Java that became popular. When Google was making their Android phones, they wanted to make it easy for developers to write apps and games for it. Since so many people were already familiar with Java, they decided to let developers use it. However, they made their own Java from scratch that looks like Oracle’s Java from a programmer’s point of view but is completely different behind the scenes. As with Joe and Gina, the way you place your order is the same, but that’s where the similarity ends.
Oracle is suing Google because they say it’s unfair that Google allowed their developers to write programs in something that looks like Java, except without it actually being Java, and that Google should pay them for the privilege.
If it’s not reasonable that Gina should have to pay Joe just because her robot dog knows how to respond to “order steak plus potato”, then it’s not reasonable that Google should have to pay Oracle since they didn’t use any of Oracle’s underlying work.
Google is asking the US Supreme Court to declare that they didn’t copy Oracle’s programming code when they created their own work-alike system. For the sake of the US software industry, I hope Google wins.
As a personal note, I don’t like eating at either Joe’s or Gina’s restaurant. The food’s awful in both places. I still don’t think that Gina (or Google) owe Joe (or Oracle) anything.