Sign in

Patrik Svensson

@patriksvensson.se
1.4K followers 494 following 2.3K posts

Father. Husband. Programmer. Likes OSS, compilers, programming. Spectre.Console, Cake. Ally ✊🏾🏳️‍🌈🏳️‍⚧️♀️(He/Him) @patriksvensson@mstdn.social Stockholm, Sweden

PostsRepliesMedia
Patrik Svensson @patriksvensson.se · 04/10/2026
And it of course supports debugging.
A code editor paused in the debugger on a Mew build script. Execution is stopped at a breakpoint inside a "compile" task, and the side panel shows the task's local variables, such as the release configuration, the matched source files, and the path to the compiler output. The debug console below shows the previous restore step has finished and compile is starting.
011
Patrik Svensson @patriksvensson.se · 03/10/2026
Mew's build system "Purr" is coming along nicely. It's still an early prototype, but everything finally works the way I envisioned! Naturally, it's written in Mew and included in the stdlib.
Terminal output from the Mew build system. The first run executes three steps (setup, restore, compile) and finishes in 2.4 seconds. Running the same "mew run build.mew compile" command again skips restore and compile because they're already up to date, and the build finishes in 0.0 seconds.A Mew build script:

```
task restore 
    in sources = glob(
        "src/compiler/**/*.{csproj,props}",
        "global.json") 
    out assets = glob("src/compiler/**/obj/project.assets.json") {
    dotnet("restore", "src/compiler/Mew.slnx")?;
}

task compile(ctx: Mew) : restore 
    in sources = glob(
        "src/compiler/**/*.{cs,csproj,props,targets}",
        "src/stdlib/lib/**/*.mew",
        "global.json",
        "!**/{obj,bin}/**")
    out compiler = file($"src/compiler/Mew/bin/{ctx.configuration()}/net10.0/Mew.dll")
{
    dotnet("build", "src/compiler/Mew.slnx", "--no-restore", "-c", ctx.configuration())?;
}
```
181
Patrik Svensson @patriksvensson.se · 25/09/2026
Looks like Claude can do other things than code...
120
Patrik Svensson @patriksvensson.se · 24/09/2026
Viewing the result in the explorer is a single command with 1130 options..
Documentation page for ffmpeg 8.1.2 (LGPL-2.1-or-later, OpenCLI 0.1), "Universal media converter." A sidebar with a "Filter commands…" box lists a single command, ffmpeg. The main area shows option tables for Smooth Streaming, SPDIF, and Tee muxers, with the WAV muxer section starting below.
000
Patrik Svensson @patriksvensson.se · 24/09/2026
I generated a OpenCLI (opencli.org) description for ffmpeg via "ffmpeg -h full", and the file is 2Mb big...
Finder listing: dotnet.json (52 KB) and the selected ffmpeg.json (2 MB).
220
Patrik Svensson @patriksvensson.se · 21/09/2026
020
Patrik Svensson @patriksvensson.se · 20/09/2026
I got error propagation working in Mew yesterday! One thing I love about how the compiler works is that this change didn't require any new concepts, just new lowering mechanisms, which made it pretty quick to implement.
Mew code:

```
pub fn evaluate(text: string) -> Result<i64, string> {
    if text.is_empty() {
        return .ok(0);
    }

    let tokens = tokenize(text)?;
    let expr = parse(tokens)?;

    let eval = new Evaluator { };
    return .ok(expr.accept(eval));
}
```
010
Patrik Svensson @patriksvensson.se · 18/09/2026
Spent most of my evening on this, but finally got "if let" statements working tonight! github.com/patriksvenss...
Mew code:

```
pub fn parse(tokens: Enumerable<Token>) -> Result<Expression, string> {
    let mut stack = Stack<Expression>::new();
    for token in tokens {
        match token {   
            .LParen => { /* Ignore */ },
            .RParen => { /* Ignore */ }
            .Integer(value) => stack.push(new IntegerExpression { value: value }),
            .Operator(op) => { 
                if let .some(right) = stack.pop() {
                    if let .some(left) = stack.pop() {
                        stack.push(new ArithmeticExpression {
                            operator: op.kind,
                            left: left,
                            right: right,
                        });
                        continue;
                    }
                }

                return .err("Expected operand on stack");
            },
        }
    }

    if stack.is_empty() {
        return .err("Expected expression on stack but found none");
    }

    return .ok(stack.pop().unwrap());
}
```
140
Patrik Svensson @patriksvensson.se · 17/09/2026
So this happened yesterday. For some unknown reason (I attribute it to some kind of clerical error), I was awarded "Developer of the Year" at the Developers Day gala here in Stockholm. It was a super fun evening.
A picture of me getting an award for some unknown reason.Me and some other people who also won awards. Probably for a good reason.
6231
Patrik Svensson @patriksvensson.se · 17/09/2026
😅
Screenshot of a Bluesky feed. A post from Patricia Aas jokes that all programmers will create their own programming language unless reined in by "adults", and wonders what happens if LLMs start doing the same. Directly below it, posted moments earlier, is Patrik Svensson's post announcing the first real program written in Mew, his own programming language.
140
Patrik Svensson @patriksvensson.se · 17/09/2026
The first real Mew program was written tonight: a simple arithmetic calculator that takes input either from command-line arguments or from stdin. It demonstrates most of the language's current features, as well as interop with .NET. github.com/patriksvenss...
#load "parsing/mod.mew"

use std;

let expression = read_expression();
let result = parsing.evaluate(expression);
match result {    
    .ok(value) => println($"The result is: {value}"),
    .err(message) => panic(message),
}

fn read_expression() -> string {
    let args = System.Environment::GetCommandLineArgs();
    if args.count > 1 {
        // Get the first provided value
        return args[1];
    } else {
        // Get expression from stdin
        print("> ");
        return System.Console::ReadLine();
    }
}Terminal screenshot showing two runs of a Mew program in a directory named mew-demo. In the first, the command mew main.mew "1+2+3+4*7+(32/2)" prints "The result is: 50". In the second, mew main.mew is run with no arguments, the expression 1+1+2*3 is typed at a ">" prompt, and the program prints "The result is: 8".
140
Patrik Svensson @patriksvensson.se · 12/09/2026
The Mew compiler now emits correct MSIL via System.Reflection.Metadata, so I can produce proper PDB files, which means DEBUGGING NOW WORKS!
Screenshot of VS Code debugging a Mew-language file, paused at a breakpoint inside a match expression, with the Variables, Call Stack, and Debug Console panels visible.
1344
Patrik Svensson @patriksvensson.se · 05/09/2026
Mew (my toy language) now supports interfaces, generics, discriminated unions, and lambdas. For the first time since I started building it three years ago, I think I might be ready to use it in Advent of Code this year.
Some Mew source code. Not really important for the post.
2202
Patrik Svensson @patriksvensson.se · 03/09/2026
I'm kind of proud of this.
```
// Then
result.ShouldHaveDiagnostics(
    """
    Error [MEW2071]: Duplicate case
      ┌─[]
      │
    1 │ pub union U { a, b(i32), a }
      ·               ┬          ┬
      ·               │          ╰── 'U' already declares a case named 'a'
      ·               │
      ·               ╰───────────── First declared here
      │
      └─
    """);
```
070
Patrik Svensson @patriksvensson.se · 01/09/2026
After a lot of work, Mew now supports interfaces! I'm so incredibly happy with the implementation of this.
Mew source code:

```
pub interface Shape {
    /// Gets the shape area
    fn area() -> i32;
}

pub type Square {
    pub field side: i32;
}

impl Shape for Square {
    pub fn area() -> i32 {
        return self.side * self.side;
    }
}

pub type Box {
    pub field width: i32;
    pub field height: i32;
}

impl Shape for Box {
    pub fn area() -> i32 {
        return self.width * self.height;
    }
}

fn test_interfaces() {
    let shapes = new Shape[] {
        new Square { side: 2, },
        new Box { width: 3, height: 4, }
    };

    let mut total = 0;
    let mut index = 0;
    while index < shapes.count {
        total += shapes[index].area();
        index += 1;
    }

    println(itoa(total));
}
```
040
Patrik Svensson @patriksvensson.se · 16/08/2026
This is the most ridiculous thing I've seen in a long time. I was just about to catch up on all the blog posts I missed, but now I need a new RSS reader.
An screenshot of Feedlys landing page, which seems to have "pivoted" to some AI analysis crap.
690
Patrik Svensson @patriksvensson.se · 17/07/2026
I hope we'll get Apple Intelligence in the EU soon...
010
Patrik Svensson @patriksvensson.se · 17/06/2026
Did I mention that I really hope we will get the new Siri improvements in the EU?
iPhone Reminders notification reading "Sorry not a reminder an alarm," timestamped "Today, 9:15 PM," shown below the Dynamic Island.
021
Patrik Svensson @patriksvensson.se · 14/06/2026
I dug a hole today (oh boy).
Excavated dirt pit bordered by gray gravel, framed by wood beams on both sides, with a gloved hand and bucket at right. An interior foundation or crawlspace dig in progress.
350
Patrik Svensson @patriksvensson.se · 14/06/2026
I made an animated overview of my new OSS project (Drift, proper announcement coming soon). It's a simplified setup with only one agent, but hopefully the animation will make it a bit more approachable.
2102
Patrik Svensson @patriksvensson.se · 12/06/2026
Pretty neat thing in C# I wouldn't have known about if Rider hadn't told me...
var parts = passwordHash.Split('.');
if (parts is not [Version, _, _, _])
{
    return false;
}
2100
Patrik Svensson @patriksvensson.se · 12/06/2026
@james-jackson-south.me Do you know what this means?
110
Patrik Svensson @patriksvensson.se · 08/06/2026
If anyone is interested, this is what I'm building 😅
Architecture diagram for "Drift", a container deployment system. Shows a control plane with REST API, deploy engine (blue/green), and gRPC AgentLink server coordinating agents on multiple servers. Each agent manages Docker containers via Caddy reverse proxy. CI/CD pushes images via webhook; operators use a CLI.
010
Patrik Svensson @patriksvensson.se · 02/06/2026
I wrote an app for the GitHub Universe badge that will come in handy these days.
A small handheld device with a clear plastic case sits propped against a GitHub-branded card (featuring the Mona Lisa octocat mascot) on a laptop keyboard. The device’s screen displays the text “Is GitHub down?” with the answer “No” in a retro monospace font on a dark blue background.
51038
Patrik Svensson @patriksvensson.se · 31/05/2026
It's not breaking a sweat. I need to migrate some other things off the Synology...
CPU: 0% of 8 CPUs
Memory: 2.5 / 15 GiB
010
Patrik Svensson @patriksvensson.se · 31/05/2026
Spending the afternoon converting an old Mac Mini M1 to a Fedora Asahi Remix home server. Hopefully this will take some pressure off my Synology NAS.
Mac Mini on a shelf below a wall-mounted TV showing a Terminal with the Asahi Linux installer running.
290
Patrik Svensson @patriksvensson.se · 22/05/2026
Beautiful.
000
Patrik Svensson @patriksvensson.se · 22/05/2026
It's time to see Rufus Wainwright for the 1000th time!
Audience and an orchestra.
190
Patrik Svensson @patriksvensson.se · 11/05/2026
*record scratch* *freeze frame* You're probably wondering how I ended up here?
Picture of a man in fetal position.
020
Patrik Svensson @patriksvensson.se · 10/05/2026
Breakfast is the most important meal of the day.
Banana bread and a beer.
2140
Patrik Svensson @patriksvensson.se · 08/05/2026
I've had worse days.
First-person view from a deck chair: a hand holds a ribbed glass tumbler of beer in the foreground, with bare feet propped up beyond it. Behind a glass railing, sunlit pine trees and a glimpse of blue water stretch under a clear sky.​​​​​​​​​​​​​​​​
2170
Patrik Svensson @patriksvensson.se · 07/05/2026
I'm sure this won't confuse me when I revisit it in a week.
Terminal output of git log showing three commits: "tests", "more", and "initial work".
240
Patrik Svensson @patriksvensson.se · 05/05/2026
Meme. A cartoon illustration showing the inside of a bus with two passengers sitting on opposite sides. The man on the left looks sad and gloomy, staring out his window at a dark, dreary cliff face of jagged grey rock. The man on the right looks happy and amazed, gazing out his window at a beautiful sunset over rolling mountains and a winding river. Same bus, same journey, but their experience depends entirely on which way they’re looking. A visual metaphor for how perspective and mindset shape the way we see life.​​​​​​​​​​​​​​​​
060
Patrik Svensson @patriksvensson.se · 04/05/2026
No TUI framework is complete without a sparkline widget. I guess I'll have to write an htop alternative now...
070
Patrik Svensson @patriksvensson.se · 03/05/2026
I put the text boxes in a pop-up (since most keys were already bound to other actions), and I personally think it looks great!
130
Patrik Svensson @patriksvensson.se · 03/05/2026
This has been cooking for a while, but I'm finally (kind of) happy with the text input widget.
140
Patrik Svensson @patriksvensson.se · 30/04/2026
I wrote a small application framework on top of Spectre.Tui, in addition to my Elm experiment. This one is more like a game engine, with a screen stack and an update/render loop, and it also handles focus. Fits TUI applications very well to my surprise!
0181
Patrik Svensson @patriksvensson.se · 29/04/2026
I added a simple backdrop widget that mutes all underlying cells, and together with the other components, I have a nice pop-up dialog. It should be easy to create a dedicated pop-up widget to remove some boilerplate, but that's something for tomorrow.
A terminal UI application with a retro dark theme showing a "Largest Cities" table with city rankings and population data, overlaid by an orange-bordered popup demonstrating word wrapping, colored text, and italic styles.
260
Patrik Svensson @patriksvensson.se · 28/04/2026
And fancy progress bars too!
160
Patrik Svensson @patriksvensson.se · 28/04/2026
Progressbar added!
110
Patrik Svensson @patriksvensson.se · 28/04/2026
Tabs added!
240
Patrik Svensson @patriksvensson.se · 27/04/2026
Tables added!
An application running in the terminal, displaying a table containing data over the largest cities in the world.
180
Patrik Svensson @patriksvensson.se · 26/04/2026
Turns out using tables looks even cleaner.
A terminal UI application called "Tuiget" displaying a NuGet package browser. The interface has a search box at the top with "Spectre" entered, a scrollable results panel on the left listing matching packages with version numbers, and an info panel on the right showing details for the selected Spectre.Tui package, including author, license, and description. Keyboard shortcuts are shown along the bottom.
030
Patrik Svensson @patriksvensson.se · 26/04/2026
I love it when a plan comes together!
Screenshot of a terminal UI titled "NuGet TUI" with a search bar at the top containing the query "Spectre". Below are two side-by-side panels: a "Results" panel on the left showing a scrollable list of NuGet packages with version numbers, and an "Info" panel on the right displaying details for the highlighted package (Spectre.Tui), including authors, license, and description fields.
4161
Patrik Svensson @patriksvensson.se · 26/04/2026
Added box titles today. Being funemployed is probably the best thing that has happened to my open-source projects.
Screenshot of a terminal UI showing a To-Do list inside a panel with pink rounded borders. The panel has labeled corner and edge positions: "To-Do" as the top-left title, plus "Top center", "Top right", "Bottom left", "Bottom center", and "Bottom right". An FPS counter is displayed above the panel. The list contains several items in various states: dimmed unselected items, one completed item marked with a checkmark reading "An initially completed list item" (with "initially" in italics), and a highlighted item indicated by an arrow (→). A scrollbar is visible on the right side.
5811
Patrik Svensson @patriksvensson.se · 26/04/2026
I added spinners and scrollbars tonight. Productive evening!
290
Patrik Svensson @patriksvensson.se · 25/04/2026
I wrote a bridge/adapter between Spectre.Console and Spectre.Tui which should make it easier than ever to create interactive terminal applications!
Screenshot of a Spectre.Tui demo. A dark terminal with a pink outer border frames a green-bordered panel titled "Spectre.Console Features", showing off what the library can do.
0103
Patrik Svensson @patriksvensson.se · 18/04/2026
Let's do this!
A TV screen in a dimly lit living room showing the title screen of Pragmata, a sci-fi action-adventure game by Capcom. The screen displays Earth rising over a cratered lunar surface against a starry sky, with the game’s logo and “PRESS ANY BUTTON” prompt. In the foreground, a wine glass, a can, and some books are visible on a shelf.​​​​​​​​​​​​​​​​
020
Patrik Svensson @patriksvensson.se · 16/04/2026
My new coffee mug arrived! #smbc (ping @zachweinersmith.bsky.social)
A white ceramic mug featuring a bell curve chart. The peak is labeled “Good Dad” and a dashed arrow points to a spot left of center labeled “You,” implying the owner falls below average as a dad. The other side of the mug says "Not significantly different from a good dad"A white ceramic mug featuring a bell curve chart. The peak is labeled “Good Dad” and a dashed arrow points to a spot left of center labeled “You,” implying the owner falls below average as a dad. The other side of the mug says "Not significantly different from a good dad"
3883
Patrik Svensson @patriksvensson.se · 10/04/2026
I added my little Elm architecture + Spectre.Tui love story to GitHub for anyone who wants to take it for a spin or build something themselves. A lot of rough edges, but I'm planning on smoothing them out a bit in the coming week. github.com/patriksvenss...
A screenshot of my NuGet TUI explorer application.
1131