217 results for "":

Having fun with ooc

Unfortunately, the ooc language could have better documentation. In the meantime, I’d like to blog about about some features that might not be very well-known.

Nested functions

Here’s a program that prints 1, 3, 5, 7, 9:

import structs/ArrayList main: func { list := ArrayList<Int> new() addIfOdd := func (i: Int) { if (i % 2 != 0) list add(i) } for (i in 0..10) { addIfOdd(i) } list map(|i| i toString()) join(", ") println() }

Day 11 (Advent of Code 2020)

Another day, another problem.

This time the problem looks suspiciously like Conway’s Game of Life, or, I guess, any old Cellular automaton.

We have a map like so:

L.LL.LL.LL LLLLLLL.LL L.L.L..L.. LLLL.LL.LL L.LL.LL.LL L.LLLLL.LL ..L.L..... LLLLLLLLLL L.LLLLLL.L L.LLLLL.LL

And for each iteration:

  • L symbols turn into # if there’s no # in any of the 8 adjacent cells

Improving error handling - panics vs. proper errors

Before we move on to parsing more of our raw packets, I want to take some time to improve our error handling strategy.

Currently, the ersatz codebase contains a mix of Result<T, E>, and some methods that panic, like unwrap() and expect().

We also have a custom Error enum that lets us return rawsock errors, IO errors, or Win32 errors:

pub enum Error { Rawsock(rawsock::Error), IO(std::io::Error), Win32(u32), }

Implementing "Log in with GitHub"

Because I started accepting donations via GitHub Sponsors, and because donating at the “Silver” tier or above gives you advance access to articles and your name in the credits, I need to interface with the GitHub API the same way I do the Patreon API.

Because I’d rather rely on third-party identity providers than provide my own sign up / log in / password forgotten / 2FA flow, user identifiers on my website are simply {provider}:{provider_specific_user_id}:

color npm package compromised

On September 8 2025, around 13:00 UTC, someone compromised Josh Junon’s npm account (qix) and started publishing backdoored versions of his package.

Someone noticed and let Josh know:

Hey. Your npm account seems to have been compromised. 1 hour ago it started posting packages with backdoors to all your popular packages.
Charlie Eriksen on BlueSky

Josh confirmed he’d gotten pwned by a fake 2FA (two-factor authentication) reset e-mail:

Yep, I've been pwned. 2FA reset email, looked very legitimate.  Only NPM affected. I've sent an email off to @npmjs.bsky.social  to see if I can get access again.  Sorry everyone, I should have paid more attention. Not like me; have had a stressful week. Will work to get this cleaned up.
Josh Junon on BlueSky

The phishing e-mail came from npmsj.help (registered 3 days prior) and claimed users had to reset their 2FA:

Day 10 (Advent of Code 2022)

Onwards! To the day 10 puzzle.

I don’t see a way to make part 1 especially fun — so let’s just get to it.

Parsing

As usual, let’s reach for the nom crate

$ cargo add nom@7 (cut)

…to parse the input into nicely-organized Rust data structures:

// in `src/main.rs` use nom::{ branch::alt, bytes::complete::tag, combinator::{map, value}, sequence::preceded, IResult, }; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] enum Instruction { Noop, Addx(i32), } impl Instruction { fn parse(i: &str) -> IResult<&str, Self> { let noop = tag("noop"); let addx = preceded(tag("addx "), nom::character::complete::i32); alt((value(Self::Noop, noop), map(addx, Self::Addx)))(i) } fn cycles(self) -> u32 { match self { Self::Noop => 1, Self::Addx(_) => 2, } } }

rock 0.9.8 is out

A little less than two months after the previous release, I’m happy to announce that the ooc compiler rock 0.9.8, codename columbia is now out.

The impatients can readily skip to the release notes, but for those who prefer a narrative, let me tell you why I’m excited about this release.

String interpolation

We’ve thrown around this idea a lot since the early versions of rock since we have a few rubyists in our ranks, but only recently Alexandros Naskos took matters into his own hands and just implemented the fuck out of it.

Things I struggle with

Putting thoughts in bits

I think about lots of things but when it comes down to writing them, drawing them, implementing them, it’s not that easy. Even with years of practice in each of these trades, it’s still an uphill battle.

Which is why I am not going to read that article after I wrote it and will go straight to publication.

Not assuming nobody cares

Day 7 (Advent of Code 2022)

The day 7 challenge talks about trees! File trees that is.

The temptation to solve it before starting to write this article so I don’t look silly is high, but I’m explicitly not doing so, so that we can bang our collective heads against any walls at the same time, and see how we can get out of it! Trees are serious business!

Part 1

The sample input looks like this:

Serving ASCII cats over HTTP

Our catscii program does everything we want it to do, except that it’s a command-line application rather than a web server. Let’s fix that.

Enter axum

The documentation for the axum crate tells us how to make a basic web server, and we honestly don’t need much more than that.

So let’s add axum:

amos@miles:~/catscii$ cargo add axum@0.6 Updating crates.io index Adding axum =0.6 to dependencies. Features: + form + http1 + json + matched-path + original-uri + query + tokio + tower-log - __private_docs - headers - http2 - macros - multipart - w