Posted by yakkomajuri 11/3/2025
Or if feeling fancy, Erlang, Elixir.
"Migrated from Python to Rust? That makes sense, I guess. Next".
"Migrated from Python to Javascript? What? That's crazy! I'd better read this."
I started ripping them out of a java system even before that.
import { Skald } from '@skald-labs/skald-node';
const skald = new Skald('your-api-key-here');
// Create a memo const result = await skald.createMemo({ title: 'Meeting Notes', content: 'Full content of the memo...' });
// Chat with the memo const result = await skald.chat({ query: 'What were the main points discussed in the Q1 meeting?' });
Normally I do this either through multiprocessing or concurrent.futures, but I figured this was a pretty simple use case for async - a few simple functions, nothing complex, just an inner loop that I wanted to async and then wait for.
Turns out Python has a built in solution for this called a TaskGroup. You create a TaskGroup object, use it as a context manager, and pass it a bunch of async tasks. The TaskGroup context manager exits when all the tasks are complete, so it becomes a great way to spawn a bunch of arbitrary work and then wait for it all to complete.
It was a huge time saver right up until I realized that - surprise! - it wasn't waiting for them to complete in any way shape or form. It was starting the tasks and then immediately exiting the context manager. Despite (as far as I could tell) copying the example code exactly and the context manager doing exactly what I wanted to have happen, I then had to take the list of tasks I'd created and manually await them one by one anyway, then validate their results existed. Otherwise Python was spawning 40 external processes, processing the "results" (which was about three incomplete image downloads), and calling it a day.
I hate writing code in golang and I have to google every single thing I ever do in it, but with golang, goroutines, and a single WaitGroup, I could have had the same thing written in twenty minutes instead of the three hours it took me to write and debug the Python version.
So yeah, technically I got it working eventually but realistically it made concurrency ten times worse and more complicated than any other possible approach in Python or golang could have been. I cannot imagine recommending async Python to anyone after this just on the basis of this one gotcha that I still haven't figured out.