Programming Leftovers
-
Yoshua Wuyts ☛ Why `Pin` is a part of trait signatures (and why that's a problem)
I've been wondering for a little while why the Future::poll methods takes self: Pin<&mut Self> in its signature. I assumed there must have been a good reason, but when I asked my fellow WG Async members nobody seemed to know off hand why that was exactly. Or maybe they did, and I just had some trouble following. Either way, I think I've figured it out, and I want to spell it out for posterity so that others can follow too.
-
Sean Conner ☛ Unit testing from inside an assembler, part IV
I'm not terribly happy with how running unit tests inside my assembler work. I mean, it works, as in, it tests the code and show problems during the assembly phase, but I don't like how you write the tests in the first place. Here's one of the tests I added to my maze generation program (and the routine it tests): [...]
-
Rlang ☛ How to Add Suffix to Column Names in Base R: A Beginner’s Guide
When working with data frames in R, you might find yourself needing to modify column names to include additional information, such as a suffix. This can be particularly useful when merging datasets or when you want to ensure that column names are unique and descriptive.
-
Rlang ☛ Shiny for Python: How to Create and Style a Custom Module
Think of Shiny for Python custom modules as reusable components. You write the logic once, make it as tweakable as possible, and then reuse it throughout your application. As it turns out, creating custom modules in Shiny for Python is simple enough, but there are some new concepts you need to be aware of.
After reading this article, you’ll have a clear picture of how to create a custom Shiny for Python module. We’ll show you two examples of different complexities, and these should be enough for you to utilize custom modules in your projects.
-
Karl Seguin ☛ TCP Server in Zig - Part 5a - Poll
One of the reasons we introduced multithreading was to get around that fact that our read and, to a lesser extent, accept and write, block. In our initial single-threaded implementation, rather than pushing our server to its limits, we spent a lot of time idle, waiting for data to come in. Multithreading helped to unblock the main thread so that new connections could be accepted - as long as we had enough workers to handle them - while processing existing connections. But threads are relatively heavyweight constructs and it isn't particularly efficient to spawn them and then have them blocked waiting for data.
There are two complimentary parts to improving our design: non-blocking I/O and event-notification.
-
Muxup ☛ Accessing a cross-compiled build tree from qemu-system
I'm cross-compiling a large codebase (LLVM and sub-projects such as Clang) and want to access the full tree - the source and the build artifacts from under qemu. This post documents the results of my experiments in various ways to do this. Note that I'm explicitly choosing to run timings using something that approximates the work I want to do rather than any microbenchmark targeting just file access time.
-
Chris Hannah ☛ Early Praise Kills Projects
When you're sharing news of an idea you've just had, or telling the world how much closer you are towards your goal, itcan feel pretty good to receive encouragement and praise. Maybe someone tells you your idea is great, or that after waking up at 4 am twice a row, you're clearly on the way to becoming the most productive person ever. Either way, in that moment, it can feel like you've already made it.
And that is the key part of the problem.
-
Jim Nielsen ☛ Prototyping Magic Tricks and Software
You have to start working on problems to fully understand them — and prototyping is a beautiful way to do that.
-
Michael Tsai ☛ Swift Foundation Unification
Apple has rewritten Foundation in Swift, and the Objective-C Foundation and Core Foundation now call into the Swift implementation. This improves performance from Swift, as there are fewer conversions, and also generally, as the Swift code has in some cases been optimized to reduce allocations.
-
Nicholas Tietz-Sokolsky ☛ Making Rust builds fail from YAML config mistakes
I was talking to a friend recently, and zie1 lamented that a Rust web framework uses YAML for its configuration. I'm far from one to defend YAML2, but dug in a little to understand zir issues with it: is it the trauma here, or is it something else? Ultimately, zie wanted something that I also seek in Rust: compile time errors over runtime errors.
-
Mapotofu ☛ Cyanide - Improve an algorithm performance step by step
Recently, I've been working on a new approximate nearest neighbor search algorithm called RaBitQ. The author has already provided a C++ implementation that runs quite fast. I tried to rewrite it in Rust (yet another RiiR). But I found that my implementation is much slower than the original one. Here is how I improve the performance step by step.
-
Rust
-
Niko Matsakis: The `Overwrite` trait and `Pin`
In July, boats presented a compelling vision in their post pinned places. With the
Overwrite
trait that I introduced in my previous post, however, I think we can get somewhere even more compelling, albeit at the cost of a tricky transition. As I will argue in this post, theOverwrite
trait effectively becomes a better version of the existingUnpin
trait, one that effects not only pinned references but also regular&mut
references. Through this it’s able to makePin
fit much more seamlessly with the rest of Rust.Just show me the dang code
Before I dive into the details, let’s start by reviewing a few examples to show you what we are aiming at (you can also skip to the TL;DR, in the FAQ).
I’m assuming a few changes here:
- Adding an
Overwrite
trait and changing most types to be!Overwrite
by default. - The
Option<T>
(and maybe others) would opt-in toOverwrite
, permittingx.take()
. - Integrating pin into the borrow checker, extending auto-ref to also “auto-pin” and produce a
Pin<&mut T>
. The borrow checker only permits you to pin values that you own. Once a place has been pinned, you are not permitted to move out from it anymore (unless the value is overwritten).
The first change is “mildly” backwards incompatible. I’m not going to worry about that in this post, but I’ll cover the ways I think we can make the transition in a follow up post.
Example 1: Converting a generator into an iterator
- Adding an
-