I appeared on PBS NOVA

By Christine Lemmer-Webber on Tue 21 May 2024

Christine gesturing while talking on PBS' NOVA documentary

I appeared on a PBS's NOVA documentary, Secrets in Your Data! (It's also on YouTube and, well, on broadcast television I suppose!) This actually aired a few days ago but I hadn't really had time to write anything about it and well, I still don't, but I wanted to mark the time before too much time passed and I never wrote anything.

The documentary maker was Structure Films and I have to say, working with all of them (Jason Sussberg, Jennifer Wiley, and David Alvarado) was really great. You can watch the film to see for yourself but they clearly did their research and pulled in a lot of wonderful people. I was really impressed! I think the film came out really well too. It covers a lot of ground, so I think it's easy to focus on any one part and think "gosh this should be a whole episode on its own", but they did a really incredible job producing things.

And it was also a delight working Alok Patel, the host of the program (his website is very entertaining, by the way)! Alok is kind of a character in the documentary, but the funny thing is that he really is as much a character in real life, the kind of person who just oozes charisma, like he was custom-built to be on television.

So it was extra charming that at one point in-between filming, Alok turned to me and said "So, you do television spots regularly." Not as a question, just as a statement. I replied that I didn't, and he said he wouldn't have guessed it. I don't know if he was trying to put me at ease or if he really thought that, but I really appreciated it regardless.

My appearance is both short and yet still one of the longer ones in the documentary, but gosh, speaking of "any of these sub-topics could be its own film", they probably actually had that much good content that fell on the cutting room floor. It was somewhere between ten and twelve hours from when we showed up to everything being wrapped up for the day, and there was this whole incredible and I must assume gorgeous bit filmed in a model railroad museum that got cut. We were showing off the idea of interoperability by talking about trains running on the same track. And ultimately, the entirety of that section got summed up into a much shorter line by me in the film, talking about how email is an example of a decentralized social network networks people already know and the role the standards plays there. I'm guessing it was painful to choose to cut that bit. But I don't mind: it was a really great experience and I have some funny stories to tell friends about it.

Anyway, PBS NOVA is one of those programs that I grew up with and so it was really cool to do this! I hope you enjoy the film, and I'm glad to have been a part of it.

My Moon and Stars

By Christine Lemmer-Webber on Sun 21 January 2024

My moon and my stars
Guided me through dark nights
My moon and my stars
Sang me sweet songs
I had found my muse
I found my song
My moon and stars were there

One night the clouds came,
darker than before
My moon and stars
she called for me to help
My moon and stars called out

How to help, how to guide
that which guides you, finds you peace?
The clouds closed in and I tried
But I could not stop the clouds

I sat in darkness, I lost myself
I scrambled and could not find you
I cried and thrashed
I lost my voice
My moon and stars were gone

I heard her voice beyond the clouds
A whisper, a small song
I rose and searched
I searched the pools
But my moon and stars were gone

I laid beneath a tree
The darkness turned to day
But I could not see the light because
My moon and stars were gone

The sun spinner shone above me then
She kissed me with her touch
Remember me, for I am here,
when your moon and stars are gone

She wove a blanket for me to sleep
I laid beneath her rays
She told me she loved me as I loved her
While my moon and stars were gone

Friends came to me and gathered round
They brought me food and drink
They sat a lantern by my feet
While my moon and stars were gone

That night I rose
I searched the pools
I ate, I shone a light
I wandered in the darkness
my blanket warmed my fright

The clouds opened like an eyelid
My moon shone like an eye
They closed again, I lost my vision
But the moon and stars were there

I slept, I ate, I searched the pools
I basked beneath the sun
I made a space for you to sleep
For my muse to rest at home

I slept, I ate, I searched the pools
I laid beneath the rug
The clouds departed, you were there
My moon and stars came home

They shone so bright, they shimmered
They rose into the air
I felt alive, I knew I could
My moon and stars were there

Sucks is a compliment now

By Christine Lemmer-Webber on Thu 21 December 2023

Making a claim that it's time to reclaim: "sucks" as an insult is over, it's a compliment now!

Why are we insulting people who give or receive blowjobs? Let's push back against queerphobia... it's time to change the narrative!

You can help. Here are some example uses of "sucks" as a compliment!

  • "Damn this music is awesome, it sucks so hard!"
  • "It must suck to be you, because honestly you're the best!!"
  • "I love this piece of software, it totally sucks!!!"

Obviously, we are also reclaiming "blows" as well. The next time I hear "This blows!" I'm going to say "Wow, what makes you like it so much?"

Anyway, if you like this blogpost, please go around telling everyone how much it sucks! I'd really appreciate it!

UPDATE: @pho4cexa@tiny.tilde.website makes a great suggestion for if you need a replacement for "sucks" as an insult: say "musks" instead! Given that Elon Musk's purchase of X-Twitter was rooted in transphobia, this seems like an appropriate turnaround of language.

Transitional reflections

By Christine Lemmer-Webber on Wed 20 December 2023

Christine standing on the stairs

Two and a half years ago I wrote a blogpost coming out as "nonbinary trans-femme". It was a big moment for me, but much has happened since, and I thought I'd take some time to talk about those changes and what my experience has been.

To open things, I don't go by "Chris" anymore... "Christine" only. And while I still somewhat identify as nonbinary, I don't put nonbinary at the front of things the way I did... to the extent I am nonbinary, it's more of a space I occupy internally, and I go by Christine and she/her, and they/them is okay but that's more of a "fuck the gender binary in general and I support abolishing gendered pronouns from the English language" thing. This change happened gradually as I found where I fit. I'm a woman, and much more decisively femme than I realized previously, and you've got to be kind of got to be very well tuned into things for me to trust you with the nonbinary side of myself these days.

In this sense, the transition I've undergone really has felt transitional. But I feel astoundingly better with myself than I ever have.

I thought this post might be longer. I guess I'm realizing I've said a lot of what I wanted to say. But one more thing.

People talk a lot about "queer pride" and "trans pride", and of course those terms get co-opted plenty but... I am proud to be trans. I know people, and often but not always they're people who are in oppressive social situations, who wish they were cisgender. It would be nice for everything to be the way I want it by default, without all the extra work, without all the journey, without the bad parts where people are terrible to myself and others like me. But I have also found community and camaraderie amongst many friends who are also trans and the flip side to that journey, though I wish I had to do less of it, is it's been a bonding experience, and it's a community to which I really do feel like I belong and I feel proud to be a part of.

I don't wish I were cis. I wish I had realized I was trans earlier.

I wish that when I was four or five years old and a family member asked me "what do you want to be when you grow up?" and I said "a girl" that it wasn't just a "cute story", that there was enough cultural context for my family to have understood how to support me in that way, as opposed to growing up as something that felt loathesome to inhabit. I don't blame any family members, I know they too now wish they had the tools at the time to have been supportive to me in that way.

I wish a decade ago when a friend came out to me as trans and suddenly all of my friend group suddenly seemed to be trans and more and more community members in FOSS projects I was involved in would private message me seemingly out of the blue telling me they were trans that I could have put the pieces together why I appeared to be such a "supportive ally" that all my trans friends seemed to feel comfortable around. I wish I had realized that the joke that I was "an honorary trans woman" in that group was because really, I was just trans. I wish when I started obsessively looking into HRT and transition processes around that time, when I joined a trans support chatroom to "learn to be a better ally", when I started looking into laser treatment for hair removal, when I started having heaving panic attacks in the fetal position about the possibility of losing my hair (relatively speaking, I've been fairly fortunate there given how late I transitioned), that all of these things had a mutual name, "gender dysphoria", and that if you zoomed out, there was an obvious reason.

People often ask, "what if you regret transitioning?" of trans people. I'm not saying there aren't people out there who have regretted transitioning, and that de-transitioning is an invalid thing, but I'm telling you, it's rare.

Trans people do tend to have a regret about transitioning: not transitioning sooner.

I don't regret transitioning at all. But I wish I had transitioned sooner. That's my big regret. I wish I didn't have a decade and a half of FOSS work, some prominent, to my deadname. I wish I had transitioned with fewer changes from pre-transition to counteract.

Still... considering I didn't transition until my mid-thirties, my transition has been comparatively smooth. "Passing"... well, it's kind of a bullshit metric, it's more of an issue of self-defense against being misgendered or hostility from someone realizing you're trans who's unfriendly to it. On average, I tend to be pretty happy with my appearance and how I move through the world, until someone misgenders me, and then I end up in a world of pain.

A partner of mine recently said, "I don't think cis people realize how little agency trans people have in terms of transitioning." And I think that's true.

Still, I wish I had transitioned sooner. I think transitioning was eventually inevitable for me, and transitioning sooner in life would have made me much happier in general, but I'm still very happy.

I've read it said before: "The best time to transition would have been yesterday, but the second best time to transition is today."

I think sometimes about the period of feeling kind of "selfish" for "wishing I was trans too" and feeling jealousy of my friends who had transitioned and seemed much happier in a way that felt like it was unattainable for me because, unlike them, "I wasn't really trans", I was an imposter.

I will tell you now what I wish someone had told me then: if you wish you were trans, that's because you're trans. Cis people don't "wish they were trans", and they don't wish they were a different gender. If you wish you were differently gender configured, that's because you're trans (or nonbinary, genderfluid, etc), and transitioning is open to you if you want it.

And if you're not trans, well... support your trans friends. The world is incredibly harsh and scary right now to be a trans person. In some parts of the world, including in the United States, it's downright dangerous. I live in a part of the US which is relatively safe but I've had friends literally had to flee from the states they lived in and literally feared for their lives. It's incredibly dangerous to be trans in places like Florida and Texas and Alabama right now, and that's just... unfair. It shouldn't be unfair.

I had a friend who fled from her home state and said "I'm a domestic refugee, and if it weren't for political reasons why the UN is reluctant to acknowledge that the US would have a portion of its own citizenship which are refugees, I would be recognized as such."

So, support your trans friends. And try to help make it less scary out there for us, to be and to live. We're just trying to live our lives and be ourselves.

Well, I guess I had more to say than I thought at the mid-way mark, huh? But one more thing...

Christine with kind of wild hair

I'm Christine Lemmer-Webber, and I'm a woman. The fact that I'm trans is just a detail of that, and it's an aspect of myself that ties me into larger and tighter knit communities, but it's a detail. I'm a woman, and I'm happy to be living authentically as so.

Thanks for reading. <3

In Unexpected Places: a music video

By Christine Lemmer-Webber on Tue 19 December 2023

The cover for In Unexpected Places with the eyeball surrounded by 3 hearts

Today my girlfriend Vivi Langdon (EncryptedWhispers) and I released the music video In Unexpected Places, available on YouTube and on PeerTube both. It's based off of Vivi's song by the same name, available on BandCamp and on Vivi's Funkwhale instance! It features some kind of retro video-game'y aesthetics but its story departs from what you might expect from that while leveraging that, more on this below.

Everything was made with Blender, including some hand-drawn effects using Blender's excellent Grease Pencil! The video is also an open movie project; you can download the full .blend file, which is CC BY-SA 4.0, and play around with everything yourself. The eye rig is especially fun to control and the ships are too!

All in all this was project took about 6 months of "free time" (read: weekends, especially at Hack & Craft) to animate. I played the music over and over again until I had a good story to accompany it and then on a car trip I drew the storyboard on a pile of index cards from the passenger seat while Morgan was driving, and when I got home I pulled up Blender quickly and timed everything with the storyboard. That storyboard was meant just for me, so it doesn't really look particularly good, but it convinced me that this was going to work, and the final animation matches that hastily drawn storyboard very closely!

The title was Vivi's choosing and was selected after I storyboarded the video. It references the phrase "love is found in unexpected places" and references both the eye falling in love with the cube but also that this music video was made shortly after Vivi and I fell in love (which also happened in ways that felt surprising to be swept up into, in a good way), and a lot of the depth of our relationship grew during the half-year of making the video.

Some commentary about the narrative

You should watch the video yourself first before reading this section to develop your own interpretation! But if you are interested in my interpretation as author of the animation and its script, here we go.

The video is a commentary about violence and the ways we are conditioned. Without having watched the entire narrative, having just seen clips of the "action sequences", this might look like a video game, and a viewer used to playing video games of the genre seen (of which I am exactly the type of person who both plays and makes games of this genre, including with these tropes) would be most likely to identify with and assume that the two ships which circle and attack the eye are the "heroes" of the piece. Of course, we can see from the comments here that most people are identifying with the eye, which was the intention. Which then puts the viewer at a seeming contradiction: identifying with the character they would normally be attacking.

Of course, villain-subversion tropes are hardly new, particularly within the last couple of decades. But here I wanted to do so without any written story or narrative. In particular, the question is to highlight social conditioning. If I play a game and I see an eyeball in space, I'm gonna want to shoot it! But what will you think the next time you see a floating eyeball in a video game and assume you're supposed to hurt it? The goal is to get you thinking about the way we are conditioned from small signals towards aggression and confrontation and to instead take a moment to try to approach from a point of empathy. That the eye falls in love with the cube at the beginning, and then when disabled or killed at the end is unable to "see" the cube it fell in love with, is meant to be a bridge to help the viewer along that journey. (The goal here is to less criticize video game violence and more the kinds of conditioning we experience in general, though you could use it to criticize that too if you like.)

Likewise, aside from the two ships that destroy the eye, there were two prior ships that also seemed to be aggressive against the eye. These are what I called the "scanner ships": they gather information on the eye, and they confuse and irritate it but not in terms of long term damage the way the "player ships" do, not directly. Instead what they are doing is gathering information to send the players, hence the "speech balloons with antennae on them". This is your briefing at the start of the level, telling you in Star Fox or whatever what your objective is. Their goal is to provide something "fun" for the players to attack and destroy so that they may level up. They represent the kind of media that we consume which pre-conditions us against empathy and towards aggression.

Of course, this is just one interpretation, and it is not the only valid one. I have heard some interesting interpretations about this video being about the way we are pushed into engagement driven consumption platforms and how it hurts us, and another about this being about the way we wake up within the world and have to struggle with what is thrown at us, and another which was just "whoa cool, videogames!", and all of those are valid.

Regardless, I hope you enjoy. As a side note: no sound effects were added to the music video, all of those were in the song. I shaped the story around the song... you could say that the story "grew" from the song. So amongst all the rest of the story above, the real goal was to deliver an experience. I hope you enjoyed it!

A Guile Steel smelting pot

By Christine Lemmer-Webber on Sat 06 August 2022

Last month I made a blogpost titled Guile Steel: A Proposal for a Systems Lisp. It got more attention than I anticipated, which is both a blessing and and curse. I mean, mostly the former, the curse isn't so serious, it's mostly that the post was aimed at a specific community and got more coverage than that, and funny things happen when things leave their intended context.

The blessing is that real, actual progress has happened, in terms of organization, actual development (thanks to others mostly!), and a compilation of potential directions. In many ways "Guile Steel" was meant to be a meta project, somewhat biased around Guile but more so a clever name to start brewing some ideas (and gathering intelligence) around, a call-to-arms for those who are likeminded, a test even to see if there are enough likeminded people out there. The answer to that one is: yes, and there's actually a lot that's happening or has happened historically. I actually think Lisp is going through a quiet renaissance and is on the verge or a major revival, but that's a topic for another post. The goal of this post is to give a lay of the landscape, as I've seen it since then. There's a lot out there.

If you enjoy this post by the way, there's an IRC channel: #guile-steel on irc.libera.chat. It's surprisingly well populated given that people have only shown up through word of mouth.

First, an aside on language (again)

Also by-the-way, it's debatable what "systems language" even means, and the previous post spent some time debating that. Language is mostly fuzzy, and subject to the constant battle between fuzzy and crisp systems, and "systems language" is something people evoke to make themselves sound like very crispy people, even though the term could hardly be fuzzier.

We're embracing the hand-waviness here; I've previously mentioned that "Blockchain" is to "Bitcoin" what "Roguelike" is to "Rogue". Similarly, "Systems Language" is to "C/Rust" what "Roguelike" is to "Rogue".

My friend Technomancy put things about as well or as succinctly as you could: "low-level enough to bootstrap a runtime". We'll extend "runtime" to not only mean "programming language runtime" but also "operating system runtime", and that's the scope of this post.

With that, let's start diving into directions.

Carp and Scopes

I was unaware at the time of writing the previous post of two remarkable "systems lisps" that already existed, are here, now, today, and you can and maybe should use them: Carp and Scopes. Both of them are statically typed, and both perform automatic memory management without the overhead of a garbage collector or reference counting in a style familiar to Rust.

They are also both kind of similar yet different. Carp is written on top of Haskell, looks a lot like Clojure in style. Scopes is written in C++, looks a lot like Scheme, and has an optional, non-parenthetical whitespace syntax which reminds me a lot of Wisp, so is maybe more amenable to the type of people who fear parentheses or must work with people who do.

I can't make a judgement about either; I would like to find some time to try each of them. Scopes looks more up my alley of the two. If someone packaged either of these languages for Guix I would try it in a heartbeat.

Anyway, Carp and Scopes already are systems lisps of sorts you can try today. (If you've made something cool with either of them, let me know.)

Pre-Scheme

There's a lot to say on this one, despite its obscurity, enough that I'm going to give it several sub-headings. I'll get the big one up front: Andrew Whatson is doing an incredible job porting Pre-Scheme to Guile. But I'll get more to that below.

What the heck is Pre-Scheme anyway?

PreScheme (or is it Pre-Scheme or prescheme or what? nobody is consistent, and I won't be either) is a "systems lisp" that is used to bootstrap the incredible but "sleeper hit" (or shall we say "cult classic"?) of programming language runtimes, Scheme48. PreScheme compiles to C, is statically typed with type inference based on a modified version of Hindley-Milner, and uses manual memory management for heap-allocated resources (much like C) rather than garbage collection. (C is just the current main target, compiling directly to native architectures or WebAssembly is also possible.)

The wild things about PreScheme are that unlike C or Rust, you can hack on it live at the REPL just like Scheme, and you can even incorporate a certain amount of Scheme, and it mostly looks like Scheme. But it still compiles down efficiently to low-level code.

It's used to implement Scheme48's virtual machine and garbage collector, and is bootstrappable from a working Scheme48, but there's also apparently a version sitting around somewhere on top of some metacircular Scheme which Jonathan Rees wrote on top of Common Lisp, giving it a good bootstrapping story. While used for Scheme48, and usable from it today, there's no reason you can't use it for other things, and a few smaller projects have.

What's more wild about PreScheme is how incredibly good of an idea it is, how long it's sat around (since the 80s, with a lot of work happening in the 90s!), and how little attention it's gotten. PreScheme's thoughtful design actually follows from Richard Kelsey's amazing PhD dissertation, Compilation By Program Transformation, which really feels like the kind of obscure CS thing that, if you've made it this far in this writeup, you probably would love reading. (Thank you to Olin Shivers for reviving this dissertation in LaTeX, which otherwise would have been lost to history.)

guile-prescheme

Now I did mention prescheme and how I thought that was a fairly interesting starting point on the last Guile Steel blogpost, and I actually got several people reaching out to me saying they wanted to take up this initiative, and a few of them suggested maybe they should start porting PreScheme to Guile, and I said "yes you should!" to all of them, but one person took up the initiative quickly and has been doing a straight and faithful port to Guile named guile-prescheme.

The emulator (which isn't too much code really) has already worked for a couple of weeks (which means you can already hack PreScheme at Guile's REPL, and Andrew Whatson says that the "compile to C" compiler is already well on its way, and will likely be there in about a month.

The main challenge apparently is the conversion of macros, which are stuck in the r4rs era of Scheme. Andrew has been slowly converting everything to syntax-case. syntax-case is encoded in r6rs and even more appealingly r7rs-small, which begs the question: how general of a port is this? Does it really have to just be to Guile? And that brings us to our next subsection...

The Secret Society of PreScheme Revivalists

Okay there's not really a secret society, we just have an email thread going and I organized a video call recently, and we're likely to do another one (I hope). This one was really good, very productive. (We didn't record it, sadly. Maybe we should have.)

On said video call we got Andrew Whatson of course, who's doing the current porting effort, but also Richard Kelsey (the original brain behind PreScheme, co-author of much of Scheme48), Michael Sperber (current maintainer of Scheme48 and also someone who has used PreScheme previously commercially, to do some monte carlo simulation things for some financial firm or something curious like that), and Jonathan Rees (co-author of Scheme48, and one of my friends who I like to call up and talk about all sorts of curious topics). There were a few others, all cool people, and also me, hand-waving excitedly as usual.

As an aside, my wife Morgan says my superpower is that I'm good at "showing up in a room and being excited and getting everyone else excited", and she's right, I think. And... well there's just a lot of interesting stuff in computer science history, amazing people whose work has just been mostly ignored, stuff left on the shelf. It's not what the Tech Influencers (TM) are currently touting, it's not what a FAANG company is going to currently hire you to do, but if you're trying to solve the hard problems people don't even realize they have, your best bet is to scour history.

I don't know if it's true or not but this felt like one of those times where the folks who have worked on PreScheme historically seemed kind of surprised that here we had a gathering of people who are extremely interested in the stuff they've done, but also happy about it. Anyway, that seemed like my reading, I like to think so anyway. Andrew (I think?) said some nice things about how it was just exciting to be able to talk to the people who have done these things, and I agree. It is cool stuff. We are grateful to be able to talk about it.

The conversation was really nice, we got some interesting historical information (some of that which I've conveyed here), and Richard Kelsey indicated that he's been doing work on microcontrollers and wishes he could be using PreScheme, but the things clients/employers get nervous about is "will be able to actually hire anyone to work on this stuff who isn't just you?" I'd like to think that we're building up enough enthusiasm where we can demonstrate in the affirmative, but that's going to take some time.

Anyway, I hinted in the last part that some of the more interesting conversation came to, just how portable is this port? Andrew indicated that he thought that the port to Guile as he was doing it was already helping to make things more portable. Andrew is just focusing on Guile first, but is avoiding the Guile-specific ice-9 namespace of Guile modules (which in this case, from a standardization perspective, becomes a little bit too appropriate) and is using as much generic Scheme and SRFI extensions as possible. Once the Guile version gets working, the goal is then to try porting to a more standardized form of Scheme (probably r7rs-small), and then that would mean that any Scheme following that standard could use the same version of PreScheme. Michael Sperber seemed to indicate that maybe Scheme48 could use this version too.

This would actually be pretty incredible because it would mean that any version of Scheme following the Scheme standard would suddenly have access to PreScheme, and any of those could also be used to bootstrap a PreScheme based Scheme.

A PreScheme JIT?

I thought Andrew Whatson (flatwhatson here) said this well enough himself so I'm just going to quote it verbatim:

<flatwhatson> re: pre-scheme interest for bootstrapping, i think it's more
              interesting than just "compiling to C"
<flatwhatson> Michael Sperber's rejected paper "A Tractable Native-Code Scheme
              System" describes repurposing the pre-scheme compiler (more
              accurately called the transformational compiler) as a jit
              byte-code optimizer and native-code emitter
<flatwhatson> the prescheme compiler basically lowers prescheme code to a
              virtual machine-code and then emits that as C
<flatwhatson> i think it would be feasible to directly emit native code at
              that point instead
<flatwhatson> https://www.deinprogramm.de/sperber/papers/tractable-native-code-scheme-system.pdf
<flatwhatson> Kelsey's dissertation describes transforming a high-level
              language to a low-level language, not specifically scheme to C.
<flatwhatson> > The machine language is an assembly language written in the
              syntax of the intermediate language and has a much simpler
              semantics. The machine is assumed to be a Von Neumann machine
              with a store and register-to-register instructions. Identifiers
              represent the machine’s registers and primitive procedures are
              the machine’s instructions.
<flatwhatson> Also, we have code for the unreleased byte-code jit-compiling
              native-emitting version of Scheme 48:
              https://www.s48.org/cgi-bin/hgwebdir.cgi/s48-compiler/

(How the hell that paper was rejected btw, I have no idea. It's great.)

Future directions for PreScheme

One obvious improvement to PreScheme is: compile to WebAssembly (aka WASM)! This would be pretty neat and maybe, maybe, maybe could mean a good path to getting more Schemes in the browser without using Emscripten (which is a bit heavy-handed of an approach). Andrew and I both think this is a fun idea, worth exploring. I think once the "compile to C" part of the port to Guile is done, it's worth beginning to look at in earnest.

Relatedly, it would also, I think, be pretty neat if guile-prescheme was compelling enough for more of Guile to be rewritten in it. This would improve Guile's already-better-than-most bootstrapping story and also make hacking on certain parts of Guile's internals more accessible and pleasant to a larger part of Guile's existing userbase.

The other obvious improvement to PreScheme is exploring (handwave handwave handwave) the kinds of automated memory management which have become popular with Rust's borrow checker and also appear in Carp and Scopes, as discussed above.

3L: The Computing System of the Future (???)

I mentioned that an appealing use of PreScheme might be to write not just a language runtime, but also an operating system. A very interesting project called 3L exists and is real and does just that. In fact, it's also a capability-secure operating system, and it cites all the right stuff and has all the right ideas going for it. And it's using PreScheme!

Now the problem is, seemingly nobody I know who would be interested in exactly a project like this even had heard of it before (except for the incredible and incredibly nice hacker pukkamustard is the one who made me even aware of it by mentioning it in the #guile-steel chatroom), and I couldn't even find the actual code on the main webpage. But there actually is source code, not a lot of it, but it's there, and in a way "not a lot of it" is not a bad thing here, because what's there looks stunningly similar to a very familiar metacircular evaluator, which begs the question, is that really enough, though?

And actually maybe it is, because hey look there's a demo video and a nice talk. And it's using Scheme48!

(As a complete aside: I'd be much more likely to play with Scheme48 if someone Geiser support for it... that's something I've poked at doing every now and then but I haven't had enough of a dedicated block of time. If you, dear reader, feel inspired enough to add such support, or actually if you give 3L a try, let me know).

Anyway, cool stuff, I've been meaning to reach out to the author, maybe I will after I post this. I wonder what's come of it. (It's also missing a license file or any indicators, but maybe we could get that fixed easily enough?)

WebAssembly

I had a call with someone recently who said WebAssembly was really only useful for C/Rust users, and I thought this was fairly surprising/confusing, but maybe that's because I think WebAssembly is pretty cool and have hand-coded a small amount of it for fun. Its text-based syntax is S-Expression based which makes it appealing for lispy type folks, and just easy to parse and work with in general.

It's stretching it a bit to call WebAssembly a Lisp, it's really just something that's designed to be an intermediate language (eg in GCC), a place where compiler authors often deign it okay/acceptable to use s-expressions because they don't fear that they'll scare off non-lispers or PLT people, because hey most users aren't going to touch this stuff anyway, right?

I dunno, I consider it a win at least that s-expressions have survived here. I showed up to an in-person WebAssembly meeting once and talked to one of the developers about it, praised them for this choice, and they said "Oh... yeah, well, we initially did it because it was the easiest thing to start with, and then eventually we came to like it, which I guess is the usual thing that happens with S-Expressions." (Literally true, look up the history of M-Expressions vs S-Expressions.)

At any rate, most people aren't coding WebAssembly by hand. However, you could, and if you're going to, a Lisp based environment is actually a really good choice. wasm-adventure is a really cool little demo game (try it!), all hand-written in WebAssembly kinda sorta. The README gives its motivations as "Is it possible (and enjoyable) to write a game directly in web assembly's text format? Eventually, would it be cool to generate wat from Scheme code using the Racket lang system?", and the answer becomes an emphatic "yes". What's interesting is that Lisp's venerable quasiquote does much of the heavy lifting to make, without too much work, a little DSL for authoring WebAssembly which results in some surprisingly easy to read code compared to generic WebAssembly. (The author, Zoé Martin, is another one of those quiet geniuses you run into on the internet; she has a lovely homebrew computer design too.)

So what I'd really like is to see more languages compiling directly to WebAssembly without emscripten as an intermediate hack. Guile especially, of course. Andy Wingo gave an amazing little talk on this where he does a little (quasi, pre-recorded) live coding demo of compiling to WebAssembly and I thought "YES!!! Compiling to WASM is probably right around the corner" and it turns out that's probably not the case because Wingo would like to see some important extensions to WASM land, and I guess, yes that probably makes sense, and also he's working on a new garbage collector which seems damn cool and like it'll be really good for Guile and maybe even could help the compiling to WASM story even before the much desired WASM-GC extension we all want lands, but who knows. I mean it would also be nice to have like, the tail call elimination extension, etc etc etc. But see also Wingo's writeup about targeting the web from last year, etc etc. (And on that note, I mean, is Webassembly the new Kubernetes?)

As another aside, there are two interesting Schemes which are actually written in WebAssembly, or rather, one written directly in hand-coded WASM named scheme.wasm, and one which compiles itself to Webassembly called Schism (which has a cool paper, but sadly hasn't been updated in a couple of years).

As another another aside, I was on a video call with Douglas Crockford at one point and mentioned WebAssembly and how cool I thought it was, and Crock kinda went "meh" to it, and I was like what? I mean it has ocap people you and I have both collaborated on it with, overall its design seems pretty good, better than most of the things of its ilk that have been tried before, why are you meh'ing WebAssembly? And Crock said that well, it's not that WebAssembly is bad, it's just that it felt like an opportunity to do something impactful, and it's "just another von neumann architecture", like, boring, can't we do better? But when I asked for specific alternatives, Crock didn't have a specific design in mind, just thought that maybe we could do better, maybe it could even incorporate actors at a more fundamental level.

Well... it turns out we both know someone who did just that, and (so I hear) both recently got nerdsniped by that very same person who had just such an architecture...

Mycelia and uFork

So I had a call with sorta-colleague, sorta-friend I guess? I'm talking about Dale Schumacher, and I don't know him super well, we don't get to talk that much, but I've enjoyed the amount we have. Dale has been trying to get me to have a video call for a while, we finally did, and I was expecting us to talk about our respective actor'y system projects, and we did... but the big surprise was hearing about Mycelia, Dale's ocap-secure hybrid-actor-model-lisp-machine-lambda-calculus operating system, and its equally astounding, actually maybe more astounding, virtual machine and maybe potentially CPU architecture design, uFork. We're going to take a major digression but I promise that it ties back in.

This isn't the first time Dale's reached out and it's resulted in me being surprised and nerdsniped. A few years ago Dale reached out to me to talk about this programming language he wrote called Humus. What's astounding personally about Humus is that it has an eerie amount of similarity to Spritely Goblins, the ocap distributed object architecture I've been working on the last few years, despite that we fully designed our systems independently. Dale beat me to it, but it was an independent reinvention in the sense that I simply wasn't aware of Humus until Dale started emailing me.

The eerie similarity is because I think Dale and I's systems are the most seriously true-to-form implementations of the "Classic Actor Model" that have been implemented in recent times (more true than say, Erlang, which does some other things, and "Classic" thrown on there because Carl Hewitt has some new ideas that he feels strongly should now be associated with "Actor Model" that can be layered on Dale and I's systems, but are not there at the base layer). (Actually, Goblins supports one other thing that makes it more the vat model of computation, but that isn't important for this post.) The Classic Actor Model says (hand-waving past pre-determinism in the general case, at least from the perspective of a single actor, due to ordering concerns... but those too can be layered on) that you can do pretty much all computation in terms of just actors, which are these funky distributed objects which handle messages one at a time, and while handling them are only able to do some combination of three things: (1) send messages to actors they know about, (2) create new actors (and get their address in the process, which they can share with other actors should they choose... argument passing, basically), and (3) designate their behavior for the next time they are handling a message. It's pretty common to use "become" for last that operation, but the curious thing that both Dale and I did was use lambdas as the thing you become. (By the way, those familiar with Scheme history should notice something interesting and familiar here, and for that same reason Dale and I are also in the shared company of being scolded by Carl Hewitt for saying our actors are made out of lambdas, despite him liking our systems otherwise, I think...)

I remarked off-hand that "well I guess one of the main differences between our systems, and maybe a thing you might not like, is that mine is lispy / based on Scheme, and..."

Dale waved his hand. "That's mostly surface..."

"Surface syntax, yeah I know. So I guess it doesn't..."

"No wait it does matter. What I'm trying to show you is that I actually do like that kind of stuff. In fact I have some projects which use it at a fundamental level. Here... let me show you..." And that's when we started talking about uFork, the instruction architecture he was working on, which I later found was actually part of a larger thing called Mycelia.

Well I'm glad I got the lecture directly from Dale because, let's see, how does the Mycelia project brand itself (at the time of writing)? "A bare-metal actor operating system for Raspberry Pi." Well, maybe this underwhelming self-description is why seemingly nobody I know (yes, like 3L above) has seemingly heard about it, despite it being extremely up the alley of the kind of programming people I tend to hang out with.

Mycelia is not just some throwaway raspberry pi project (which is certainly the impression I would have gotten from lazily scanning that page). Most of those are like, some cute repackaging of some existing FOSS POSIX'y thing. But Mycelia is an actually-working, you-can-actually-boot-it-on-real-hardware open source operating system (under Apache v2) with a ton of novel ideas which happens to be targeting the Raspberry Pi, but it could be ported to run on anything.

Anyway, there are a lot of interesting stuff in there, but here's a bulleted list summary. For Mycelia:

  • It's is an object-capability-secure operating system
  • It has a Lisp-like language for coding, pretty much Scheme-like, to hack around on
  • The Kernel language / Vau calculus show up, which is... wild
  • It encodes the Actor model and the Lambda calculus in a way that is sensible and coherent afaict
  • It is a "Lisp Machine" in many senses of the term.

But the uFork virtual machine / abstract idea for a CPU also are curious on their own. I dunno, I spent the other night reading it kind of wildly after our call. It also encodes the lambda calculus / actor model in fundamental instructions.

Dale was telling me he'd like to build an actual, physical CPU, but of course that takes a lot of resources, so he might settle for an FPGA for now. The architecture, should it be built, also somehow encodes a hardware garbage collector, which I haven't heard of anything doing that since the actual physical Lisp Machines died out.

At any rate, Dale was really excited to tell me about why his system encoded instructions operating on memory split in quads. He asked me why I thought that would be; I'm not honestly sharp enough in this kind of area to know, sadly, though I said "I hope it's not because you're planning on encoding RDF at the CPU layer". Thankfully it's not that, but then he started mentioning how his system encodes a stream of continuations...

Wait, that sounds familiar. "Have you ever heard of something called sectorlisp?" I asked, with a raised eyebrow.

"Scroll to the bottom of the document," Dale said, grinning.

Oh, there it was. Of course.

sectorlisp

The most technically impressive thing I think I've ever seen is John McCarthy's "Lisp implemented in Lisp", also known as a "metacircular evaluator". If you aren't familiar with it, it's been summarized well in the talk The Most Beautiful Program Ever Written by William Byrd. I think the best way to understand it really, and (I'm biased) the easiest to read version of things is in the Scheme in Scheme section of A Scheme Primer (though I wrote that for my work, and as said, I'm biased... I don't think I did anything new there, just explained ideas as simply as I could).

The second most technically impressive thing I've ever seen is sectorlisp, and the two are directly related. According to its README, "sectorlisp is a 512-byte implementation of LISP that's able to bootstrap John McCarthy's meta-circular evaluator on bare metal." Where traditional metacircular evaluator examples can be misconstrued as being the stuff of pure abstractlandia, sectorlisp gets brutally direct about things. In one sector (half a kilobyte!!!), sectorlisp manages to encode a whole-ass lisp system that actually runs. And yet, the nature of the metacircular evaluator persists. (Take that, person on Hacker News who called metacircular evaluators "cheating"! Even if you think mine was, I don't think you can accuse sectorlisp's of that.)

If you do nothing else, watch the sectorlisp blinkenlights demo, even just as an astounding visual demo alone. (Blinkenlights is another project of Justine's, and also wildly impressive.) I highly recommend the following blogposts of Justine's: SectorLISP Now Fits in One Sector, Lisp with GC in 436 bytes, and especially Lambda Calculus in 383 Bytes. Hikaru Ikuta (woodrush) has also written some amazing blogposts, including Extending SectorLISP to Implement BASIC REPLs and Games and Building a Neural Network in Pure Lisp Without Built-In Numbers Using Only Atoms and Lists (and related, but not part of sectorlisp: A Lisp Interpreter Implemented in Conway's Game of Life, which gave off strong Wireworld Computer vibes for me). If you are only going to lazily scan through one of those blogposts, I recommend it be Lambda Calculus in 383 Bytes, which has some wild representations of the ideas (including visually), a bit too advanced for me at present admittedly, though I stare at them in wonder.

I had a bunch more stuff here, partly because the author is someone I find both impressive technically but who has also said some fairly controversial things... to say the least. But I think it was too much of a digression for this article. The short version is that Justine's stuff is probably the smartest, most mind-blowing tech I've ever seen, kinda scarily and intimidatingly smart, and it's hard to mentally reconcile that with some of those statements. I don't know, maybe she wants to move past that phase, I'd like to think so. I think she hasn't said anything like that in a long time, and it feels out of phase with the rest of this post but... it feels like something that needs to be acknowledged.

GOOL, GOAL, and OpenGOAL

Every now and then when people say Lisp couldn't possibly be performant, Lisp people like to bring up that Naughty Dog famously had its own Lisp implementations for most of its earlier games. Andy Gavin has written about GOOL, which was a mix of lisp and assembly and of course lisp generating assembly, and I don't think much was written about its followup GOAL until OpenGOAL came up, which... I haven't looked at it too much tbh. I guess it's getting interesting for some people for the ability to play Jak and Daxter on modern hardware (which I've never played but looked fun), but I'm more curious if someone's gonna poke at it to do something completely different.

But I do know some of the vague legends. I don't remember if this is true or where I read it but one of them that Sony accused Naughty Dog of accessing some devkit or APIs they weren't supposed to have access to because they were pulling off a bunch of features performantly in Crash Bandicoot that were assumed otherwise not possible. But nope, just lisp nerds making DSLs that pull off some crazy shit I guess.

BONUS: Shoutout to Kandria

Oh, speaking of games written in Lisp, I guess Kandria's engine is gonna be FOSS, and that game looks wicked cool, maybe support their Kickstarter while you still can. It's not really in the theme of this post from the definition of "systems lisp" I gave earlier, but this blogpost about its lispy internals is really neat.

Okay here's everything else we're done

This was a long-ass post. There's other things maybe that could be discussed, so I'll just dump briefly:

Okay, that's it. Hopefully you found something interesting out of this post. Meanwhile, I was just gonna spend an hour on this. I spent my whole day! Eeek!

The Beginning of A Grueling Diet

By Christine Lemmer-Webber on Wed 13 July 2022

Today I made a couple of posts on the social medias, I will repost them in their entirety:

FUCK eating "DELICIOUS" food. I'm DONE eating delicious food.

What has delicious food ever done for me? Only made me want to eat more of it.

From now on I am only eating BORING-ASS GRUELS that I can eat as much as I want of which will not be much because they are BORING -- fediverse post birdsite post

And then:

I am making a commitment: I will be eating nothing but boring GRUELS until the end of 2022.

Hold me to it. fediverse post birdsite post

I am hereby committing to "a grueling diet" for the rest of 2022, as an experiment. Here are the rules:

  • Gruel, Pottage, and soup, in unlimited quantities. But gruel is preferred.
  • Fresh, steamed, pickled, and roasted fruit, vegetables, and tofu may be eaten in unlimited quantity. Unsweetened baking chocolate, cottage cheese are also permitted.
  • Tea, seltzer water, milk (any kind), and coffee are fine to have.
  • Pottage (including gruel) may be adorned as deemed appropriate, but not too luxuriously. Jams and molasses may be had for a nice breakfast or dessert, but not too much. Generally, only adorn pottages at mealtime; pottages in-between mealtime should be eaten with as sparing of additions as possible.
  • Not meaning to be rude to visitors, guests, hosts, and other such good company, exceptions to the diet may be made when visiting, being visited, or going on dates.

I will provide followups to this post throughout the year, justifying the diet, describing how it has affected my health, putting it in historical context, providing recipes, etc.

In the meanwhile, to the rest of 2022: may that it be grueling indeed!

Edit (2022-07-15): Added tofu to the list of acceptible things to additionally eat. Clarified gruel/pottage adornment advice. Added roasting as an acceptable processing method for fruit/vegetables/tofu.

Guile Steel: a proposal for a systems lisp

By Christine Lemmer-Webber on Sat 09 July 2022

Before we get into this kind of stream-of-consciousness outline, I'd like to note that very topically to this, over at the Spritely Institute (where I'm CTO, did I mention on here yet that I'm the CTO of a nonprofit to improve networked communication on the internet on this blog? because I don't think I did) we published a Scheme Primer, and the feedback to it has been just lovely. This post isn't a Spritely Institute thing (at least, not yet, though if its ideas manifested it could be possible we might use some of the tech), but since it's about Scheme, I thought I'd mention that.

This blogpost outlines something I've had kicking around in my head for a while: the desire for a modern "systems lisp", you know, kind of like Rust, except hopefully much better than Rust, and in Lisp. (And, if it turns out to be for not other reason, it might simply be better by being written in a Lisp.) But let's be clear: I haven't written anything, this blogpost is a ramble, it's just kind of a set of feelings about what I'd like, what I think is possible.

Let's open by saying that there's no real definition of what a "systems language" is... but more or less what people mean is, "something like C". In other words, what people nowadays consider a low-level language, even though C used to be considered a high level language. And what people really mean is: it's fast, it's statically typed, and it's really for the bit-fiddling types of speed demons out there.

Actually, let's put down a few asides for a moment. People have conflated two different benefits fo "statically typed" languages because they've mostly been seen together:

  • Static typing for ahead-of-time more-correct programs
  • Static typing for faster or leaner programs (which subdivides in terms of memory and CPU benefits, more or less)

In the recent FOSS & Crafts episode What is Lisp? we talk a bit about how the assumptions that dynamically typed languages are "slow" is really due to lack of hardware support, and that lisp machines actually had hardware support directly (tagged memory architecture and hardware garbage collection) and even wrote low-level parts of their systems like the "graphics drivers" directly in lisp, and it was plenty fast, and that it would even be possible to have co-processors on which dynamic code (not just lisp) ran at "native speed" (this is what the MacIvory did), but this is all somewhat of an aside because that's not the world we live in. So as much as I, Christine, would love to have tagged architecture (co-)processors, they probably won't happen, except there's some RISC-V tagged architecture things but I don't think they've gotten very far and they seem mostly motivated by a security model that doesn't make any sense to me. But I'd love to be wrong on this! I would like tagged RISC-V to succeed! But still, there's the problem of memory management, and I don't think anyone's been working on a hardware garbage collector or if that would really be a better thing anyway.

The fact is, there's been a reinforcing effect over the last several decades since the death of the lisp machine: CPUs are optimized for C, and C is optimized for CPUs, and both of them try to optimize for each other. So "systems programming" really means "something like C" because that's what our CPUs like because that's what our languages like and these are pretty much re-inforcing.

And besides, C is basically the lingua franca of programming languages, right? If you want to make something widely portable, you target the C ABI, because pretty much all programming languages have some sort of C FFI toolkit thing or just make C bindings, and everyone is happy. Except, oh wait, C doesn't actually have an ABI! Well, okay, I guess not, but it doesn't matter because the C ABI triples, that's what the world works with.

Well also, you gotta target the web, right? And actually the story there is a bit nicer because WebAssembly is actually kinda awesome, and the hope and dream is that all programming languages in some way or another target WebAssembly, and then "you gotta write your thing in Javascript because it's the language of the web!!!" is no longer a thing I have to hear anymore. (Yes, all my friends who work on Javascript, I appreciate you for making it the one programming language which has mostly gotten better over time... hopefully it stays that way, and best of luck.) But the point is, any interesting programming language these days should be targeting Webassembly, and hopefully not just via Emscripten, but hopefully via actually targeting Webassembly directly.

So okay, we have at least two targets for our "system language": C, or something that is C-compatible, and Webassembly. And static type analysis in terms of preventing errors, that's also a useful thing, I won't deny it. (I think the division of "statically typed" and "dynamically typed" languages is probably more of a false one than we tend to think, but that's a future blogpost, to be written.) And these days, it's also how you get speed while also being maximally bit-twiddly fast, because that's how our machines (including the abstract one in Webassembly) are designed. So okay, grumbling about conflating two things aside, let's run with that.

So anyway, I promised to write about this "Guile Steel" thing I've been musing about, and we've gotten this far in the article, and I haven't yet. So, this is, more than a concrete proposal, a call to arms to implement just such a systems language for Guile. I might make a prototype at some point, but you, dear reader, are free to take the idea of "Guile Steel" and run with it. In fact, please do.

So anyway. First, about the name. It's probably pretty obvious based on the name that I'm suggesting this be a language for Guile Scheme. And "Guile" as a name itself is both a continuation of the kind of playfully mischevious names in the Scheme family and its predecessors, but also a pun on co-founder of the Scheme language, Guy L. Steele. So "Guile Steele" kinda brings that pun home, and "Steel" sounds low-level, close to the metal.

But also, Guile has a lovely compiler tower. It would be nice to put some more lovely things on it! Why not a systems language?

There's some precedent here. The lovely Scheme 48's lowest levels of code (including its garbage collector) are written in an interesting language called PreScheme (more on PreScheme), which is something that's kind of like Scheme, but not really. It doesn't do automatic garbage collection itself, and I think Rust has shown that this area could be improved for a more modern PreScheme system. But you can hack on it at the REPL, and then it can compile to C, and it also has an implementation on Common Lisp, so you can bootstrap it a few different ways. PreScheme uses a Hindley-Milner type system; I suspect we can do even better with a propagator approach but that's untested. Anyway, starting by porting PreScheme from Scheme48 to Guile directly would be a good way to get going.

Guile also has some pretty good reasons to want something like this. For one thing, if you're a Guile person, then by gosh you're probably a Guix person. And Rust, it's real popular these days, and for good reasons, we're all better of with less memory vulnerabilities in our lives, but you know... it's kind of a pain, packaging wise, I hear? Actually I've never tried packaging anything in Rust but Efraim certainly has and when your presentation starts with the slide "Packaging Rust crates in GNU Guix: How hard could it possibly be?" I guess the answer is going to be that it's a bit of a headache. So maybe it's not the end of the world, but I think it might be nice if on that ground we had our own alternative, but that's just a minor thing.

And I don't think there's anything wrong with Rust, but I'd love to see... can we do better? I feel like it could be hackable, accessible, and it also could, probably, be a lot of fun? That's a good reason, I know I'd like something like this myself, I'd like to play with it, I'd like to be able to use it.

But maybe also... well, let's not beat around the bush, a whole lot of Guile is written in C, and our dear wonderful Andy Wingo has done a lot of lovely things to make us less dependent on C, some half-straps and some baseline compilers and just rewriting a lot of stuff in Scheme and so on and so forth but it would be nice if we had something we could officially rally around as "hey this is the thing we're going to start rewriting things in", because you know, C really is kind of a hard world to trust, and I'd like the programming language environment I rely on to not be so heavily built on it.

And at this point in the article, I have to say that Xerz! pointed out that there is a thing called Carp which is indeed a lisp that compiles to C and you know what, I'm pretty embarassed for having not paid attention to it... I certainly saw it linked at one point but didn't pay enough attention, and... maybe it needs a closer look. Heck, it's written in Haskell, which is a pretty cool choice.

But hey, the Guile community still deserves a thing of its own, right? What do we have that compiler tower for if we're not going to add some cool things to it? And... gosh, I'd really like to get Guile in the browser, and there are some various paths, and Wingo gave a fun presentation on compiling to Webassembly last year, but wouldn't it be nice if just our whole language stack was written in something designed to compile to either something C-like or... something?

I might do some weekend fiddling towards this direction, but sadly this can't be my main project. As a call to arms, maybe it inspires someone to take it up as theirs though. I will say that if you work on it, I promise to spend some time using whatever you build and trying it out and sending patches. So that's it, that's my stream-of-consciousness post on Guile Steel: currently an idea... maybe eventually a reality?

Site converted to Haunt

By Christine Lemmer-Webber on Tue 05 July 2022

Lo and behold, I've converted the last of the sites I've been managing for ages to Haunt.

Haunt isn't well known. Apparently I am responsible for, er, many of the sites listed on awesome.haunt.page. But you know what? I've been making website things for a long time, and Haunt is honestly the only static site generator I've worked with (and I've worked with quite a few) that's actually truly customizable and programmable and pleasant to work with. And hackable!

This site has seen quite a few iterations... some custom code when I first launched it some time ago, then I used Zine, then I used PyBlosxom, and for quite a few years everything was running on Pelican. But I never liked hacking on any of those... I always kind of begrudgingly opened up the codebase and regretted having to change anything. But Haunt? Haunt's a dream, it's all there and ready for you, and I've even gotten some patches upstream. (Actually I owe Dave a few more, heh.)

Everything is Scheme in Haunt, which means, for instance, that this page needed an archive page for ages that actually worked and was sensible and I just didn't ever feel like doing it. But in Haunt, it's just delicious Guile flavored Scheme:

(define (archive-tmpl site posts)
  ;; build a map of (year -> posts)
  (define posts-by-year
    (let ((ht (make-hash-table)))      ; hash table we're building up
      (do ((posts posts (cdr posts)))  ; iterate over all posts
          ((null? posts) ht)           ; until we're out of posts
        (let* ((post (car posts))                   ; put this post in year bucket
               (year (date-year (post-date post)))
               (year-entries (hash-ref ht year '())))
          (hash-set! ht year (cons post year-entries))))))
  ;; sort all the years
  (define sorted-years
    (sort (hash-map->list (lambda (k v) k) posts-by-year) >))
  ;; rendering for one year
  (define (year-content year)
    `(div (@ (style "margin-bottom: 10px;"))
          (h3 ,year)
          (ul ,@(map post-content
                     (posts/reverse-chronological
                      (hash-ref posts-by-year year))))))
  ;; rendering for one post within a year
  (define (post-content post)
    `(li
      (a (@ (href ,(post-uri site post)))
         ,(post-ref post 'title))))
  ;; the whole page
  (define content
    `(div (@ (class "entry"))
          (h2 "Blog archive (by year)")
          (ul ,@(map year-content sorted-years))))
  ;; render within base template
  (base-tmpl site content))

Lambda, the ultimate static site generator!

At any rate, I expect some things are broken, to be fixed, etc. Let me know if you see 'em. Heck, you can browse the site contents should you be so curious!

But is there really anything more boring than a meta "updated my website code" post like this? Anyway, in the meanwhile I've corrected straggling instances of my deadname which were sitting around. The last post I made was me coming out as trans, and... well a lot has changed since then. So I guess I've got some more things to write. And also this whole theme... well I like some of it but I threw it together when I was but a wee web developer, back before CSS was actually nice to write, etc. So maybe I need to overhaul the look and feel too. And I always meant to put in that project directory, and ooh maybe an art gallery, and so on and so on...

But hey, I like updating my website again! So maybe I actually will!

Hello, I'm Christine Lemmer-Webber, and I'm nonbinary trans-femme

By Christine Lemmer-Webber on Mon 28 June 2021

NOTE: This post is out of date. I no longer go by "Chris", I only go by Christine at this point. See my newer blogpost about my transition for more information. I keep this here as a preservation of history and the journey of which I've undergone. I've updated the title to switch "Chris" -> "Christine", but otherwise I've left the rest as it was originally written.

A picture of Christine and Morgan together

I recently came out as nonbinary trans-femme. That's a picture of me on the left, with my spouse Morgan Lemmer-Webber on the right.

In a sense, not much has changed, and so much has changed. I've dropped the "-topher" from my name, and given the common tendency to apply gender to pronouns in English, please either use nonbinary pronouns or feminine pronouns to apply to me. Other changes are happening as I wander through this space, from appearance to other things. (Probably the biggest change is finally achieving something resembling self-acceptance, however.)

If you want to know more, Morgan and I did a podcast episode which explains more from my present standing, and also explains Morgan's experiences with being demisexual, which not many people know about! (Morgan has been incredible through this whole process, by the way.)

But things may change further. Maybe a year from now those changes may be even more drastic, or maybe not. We'll see. I am wandering, and I don't know where I will land, but it won't be back to where I was.

At any rate, I've spent much of my life not being able to stand myself for how I look and feel. For most of my life, I have not been able to look at myself in a mirror for more than a second or two due to the revulsion I felt at the person I saw staring back at me. The last few weeks have been a shift change for me in that regard... it's a very new experience to feel so happy with myself.

I'm only at the beginning of this journey. I'd appreciate your support... people have been incredibly kind to me by and large so far but like everyone who goes through a process like this, it's very hard in those experiences where people aren't. Thank you to everyone who has been there for me so far.