Latest Posts (20 found)
maxdeviant.com 2 weeks ago

Head in the Zed Cloud

For the past five months I've been leading the efforts to rebuild Zed 's cloud infrastructure. Our current backend—known as Collab—has been chugging along since basically the beginning of the company. We use Collab every day to work together on Zed in Zed. However, as Zed continues to grow and attracts more users, we knew that we needed a full reboot of our backend infrastructure to set us up for success for our future endeavors. Enter Zed Cloud. Like Zed itself, Zed Cloud is built in Rust 1 . This time around there is a slight twist: all of this is running on Cloudflare Workers , with our Rust code being compiled down to WebAssembly (Wasm). One of our goals with this rebuild was to reduce the amount of operational effort it takes to maintain our hosted services, so that we can focus more of our time and energy on building Zed itself. Cloudflare Workers allow us to easily scale up to meet demand without having to fuss over it too much. Additionally, Cloudflare offers an ever-growing amount of managed services that cover anything you might need for a production web service. Here are some of the Cloudflare services we're using today: Another one of our goals with this rebuild was to build a platform that was easy to test. To achieve this, we built our own platform framework on top of the Cloudflare Workers runtime APIs. At the heart of this framework is the trait: This trait allows us to write our code in a platform-agnostic way while still leveraging all of the functionality that Cloudflare Workers has to offer. Each one of these associated types corresponds to some aspect of the platform that we'll want to have control over in a test environment. For instance, if we have a service that needs to interact with the system clock and a Workers KV store, we would define it like this: There are two implementors of the trait: and . —as the name might suggest—is an implementation of the platform on top of the Cloudflare Workers runtime. This implementation targets Wasm and is what we run when developing locally (using Wrangler ) and in production. We have a crate 2 that contains bindings to the Cloudflare Workers JS runtime. You can think of as the glue between those bindings and the idiomatic Rust APIs exposed by the trait. The is used when running tests, and allows for simulating almost every part of the system in order to effectively test our code. Here's an example of a test for ingesting a webhook from Orb : In this test we're able to test the full end-to-end flow of: The call to advances the test simulator, in this case running the pending queue consumers. At the center of the is the , a crate that powers our in-house async runtime. The scheduler is shared between GPUI —Zed's UI framework—and the used in tests. This shared scheduler enables us to write tests that span the client and the server. So we can have a test that starts in a piece of Zed code, flows through Zed Cloud, and then asserts on the state of something in Zed after it receives the response from the backend. The work being done on Zed Cloud now is laying the foundation to support our future work around collaborative coding with DeltaDB . If you want to work with me on building out Zed Cloud, we are currently hiring for this role. We're looking for engineers with experience building and maintaining web APIs and platforms, solid web fundamentals, and who are excited about Rust. If you end up applying, you can mention this blog post in your application. I look forward to hearing from you! The codebase is currently 70k lines of Rust code and 5.7k lines of TypeScript. This is essentially our own version of . I'd like to switch to using directly, at some point. Hyperdrive for talking to Postgres Workers KV for ephemeral storage Cloudflare Queues for asynchronous job processing Receiving and validating an incoming webhook event to our webhook ingestion endpoint Putting the webhook event into a queue Consuming the webhook event in a background worker and processing it

1 views
maxdeviant.com 3 months ago

31

I turned 31 today. Last night Heather and I went to our favorite Thai restarurant for dinner to celebrate. We shared some chicken satay to start, and I ordered the khao soi and a Thai iced coffee. The khao soi already comes spicy, but I wanted to take it up a notch. Our waitress told me that it comes at a 3 on a 1-5 spice scale. I opted to go for a 4 this time around, which was a decent bit of heat. I think I could probably go for the full 5. We rounded out the meal with some mango sticky rice for dessert. Afterwards, we went home and watched KPop Demon Hunters. The movie—and the soundtrack, in particular—is great. I highly recommend you give it a watch, if you haven't yet. While figuring out what I wanted to write about on this day of my birth, I find myself in a similar situation to what Justin Duke observed on his 27th birthday : it seems weird to do one of these annual posts both for my birthday and for the ending of the year, but also i want to indulge a little There is a lot of overlap between what one might want to write about in a birthday post and an end-of-year review post. Both occur on a yearly cadence, and—in my case—are separated by just 4 months. However, I think that they can ultimately serve different purposes. In previous posts that I've written on my birthday ( 28 , 30 ), they are very much about me and how I am feeling on this day that marks the passage of one year of life into another. Today, I don't really know how to feel. I had a good time celebrating with my family, but after we left I've been feeling hollow. This month I've been revisiting some hard memories with my therapist, and unfortunately it's not a trivial exercise to put those feelings back into the box when the session is over. I've been listening to the new Three Days Grace album, Alienation , over the past few days. I've listened to the album a few times through already, but this morning I was really paying attention to the lyrics of the track "Never Ordinary": We were never ordinary All the weight we carry will help us write our story In the darkest night, you were born to shine This reminded me of something my therapist and I were talking about on Thursday: that my gifts and experiences can be a powerful tool, if I can learn to navigate the downsides. So my goal for 31 is to learn how to navigate.

0 views
maxdeviant.com 4 months ago

Dog Days

A little over a week ago I saw a tweet 1 from Bryan Cantrill announcing that Oxide and Friends would be on a "dog days' hiatus" until August 4th. Since seeing that tweet, my echolalia has had me muttering the phrase "dog days" to myself. Now, I've heard of "dog days" before—most often as the "dog days of summer"—but I was not familiar with the origin of the term. I decided to look it up on Wikipedia: The dog days or dog days of summer are the hot, sultry days of summer. They were historically the period following the heliacal rising of the star system Sirius (known colloquially as the "Dog Star"), which Hellenistic astrology connected with heat, drought, sudden thunderstorms, lethargy, fever, mad dogs, and bad luck. They are now taken to be the hottest, most uncomfortable part of summer in the Northern Hemisphere. — Wikipedia , "Dog days" Over the past week I've found myself in a creative rut. It was especially bad this past weekend, with me wanting to work on something, but not being able to find the creative energy to do anything. So instead, I just sat there and tried to force it out, to no avail. I ended the weekend feeling drained, and like I had wasted it. This was Sunday, July 20th. Yesterday, I saw the latest episode of Noah Kalina's The Hotline Show in my YouTube sub box. It's titled "The Dog Days And Your Creative Juices" . I decided to give it a watch. During the episode's intro, Noah kicks things off with: Today is July 20th, 2025. It's been a while. I've been away doing stuff. It's summer. It's the dog days of summer. Have you heard that expression? The dog days. I've always heard it: "It's the dog days of summer". But I never really looked up what it meant. So, I did. He then goes on to read out the opening paragraph of the "Dog days" Wikipedia article I cited above. Noah then calls his dad on the phone for some advice about creative energy, low periods, and the associated guilt. Before reading any further, I would encourage you to go and watch the video for yourself. It's only eleven minutes, and I think it is well worth your time. Noah's dad offers up a wealth of wisdom, and I'm going to be repeating a lot of it here. It will be a bit redundant if you took my advice and watched the video, but I want to have these things written down so I can come back to them. He talks about what people tend to do when their creative juices aren't flowing: They're trying to make stuff happen. They're trying to get into projects and it usually doesn't work. So what I think has to happen is people have to learn that at some point if they're trying too hard, they have to know the signs of trying too hard, take a breath, and do something to chill. The trying too hard comes about when nothing's going on. You're in a lull, but instead of allowing for the lull, for the down period, you're pushing at it. You're working really hard, you're trying to think of ideas and you're racking your brains and it's not working. Noah later mentions to his dad how he feels guilty for not working on his art. His dad replies with: Being guilty about your work, being guilty about your art is very destructive. So, what I would say is try to learn where the guilt is coming from. Try to hear the message in your head that says you're wrong or bad or something negative about being in a down phase and notice that it's a story you're telling in your mind. And when you notice that, come back into the present. Breathe and let go of that thought and be focused just in the now. That could be on your natural breathing or it could be the surrounding around you. Like I said before, you're in nature. Enjoy the trees. Listen to the birds. Be involved with what's here rather than what's in your head. And continues with what will happen if this guilt is left unchecked: But being guilty about stuff that's creative does nothing but destroy the stuff that you're creative about. During his outro, Noah says: We're not alone out there. We all go through these phases. I'm in it. The dog days. I'm in the dog days too, Noah. But it's good to know I'm not alone. This whole experience feels a bit surreal to me. I've been thinking about dog days while dealing with a period of low creative energy, and then I find a video talking about the exact same things? Uploaded on the exact same day where I was feeling at my lowest? Surely this is no coincidence. When Noah started reading those words from Wikipedia—the very same ones I had read on my own seven days prior—I felt something deep down inside of me. As the words echoed through my brain, I felt as if I was intended to see this video. Yes, they're still tweets on Bluesky.

0 views
maxdeviant.com 4 months ago

The ComputerCraft Iceberg

My friend Steffen recently turned me on to the ComputerCraft mod for Minecraft. For the uninitiated—a group I myself was a member of until a mere 24 hours ago—ComputerCraft is a mod that adds programmable computers and turtles to the game. "Turtles, you say? What, like these fellas ?" Cute as they may be, the sea variety of turtles are not the ones I'm excited to talk about today. Let me introduce you to a new kind of turtle: These turtles—which get their name from turtle graphics —are little robots that you can control programatically. Inside of each one is a ComputerCraft computer. Players are able to write programs in Lua and execute those programs on the turtle. Programs have access to a number of different APIs, including the module that provides functions for controlling the turtle. For instance, calling the function will move the turtle forward. Calling will have the turtle dig the block in front of it. It all started with a video Steffen sent me of a turtle-driven tree farm he had built in his world. The turtle would walk a loop around a patch of trees, checking each spot to see if a tree was grown yet. If it detected a grown tree, it would chop down the tree, replace it with a sapling, and continue on to the next spot. I decided to start up a new Minecraft world to give it a go. For my initial foray into working with turtles, I copied the tree farm program using the code that was visible in the video. I transcribed it, making a few tweaks as I went, and soon ended up with an automated tree farm of my own: During the course of building it and trying it out, I even managed to find a bug in the original program that needed fixing: With my wood situation sorted, I turned my attention to mining. Initially I wanted to write a branch mining program to assist me in quickly finding more diamonds, but this proved to be somewhat complex. I scoped down the implementation to a simple tunnel miner that would mine a tunnel and place torches on the wall every so often: It was at this point that my software engineer brain started screaming at me. I had these two working programs, but was already noticing common functions that were duplicated between the two. I factored out a new module to house the helper functions I had written for dealing with the turtle's inventory: Keeping with the mining theme, the next program I wrote was for digging out vertical mine shafts. I could imagine wanting to have different-sized mine shafts based on the need, so for this program I explored taking user input as arguments to the program: While working on that program, I noticed that could be generalized into a general-purpose function. While in this case we care about mining out a layer of blocks, the core algorithm of moving a turtle around a plane could have lots of different uses. I pulled this out into its own function: This refactoring then enabled me to quickly whip up a new program for having a turtle farm wheat for me: At this point it was bedtime, and I had wrapped up my first day of working with ComputerCraft. I had gotten to grips with basics of Lua (as this was my first time using it in any real capacity), written a handful of different programs, pulled some common functionality into modules, and was feeling pretty happy with it all. As I got ready for bed, I found myself pondering how I would maintain all of this code as I continued to expand my ComputerCraft usage. Something I had observed during my first day was that I spent a lot of time testing my programs "in production", as it were. The general flow of creating a new program looked something like: I spent a lot of time watching the turtle churn through its instructions waiting for it to reach the point in the program that needed testing and observation. I even created a separate Minecraft world that I would use to test my programs in before letting the turtles run them in my actual world. The process was slow and time-consuming. The answer to this, of course, was testing. I needed a way to write tests that I could run over and over as I made changes to the programs, and test that they were all still working in a variety of different scenarios. Bringing forth this vision of automated testing required one crucial component: a way to simulate ComputerCraft in a controlled environment. I'd spent the previous day steeped in Lua, but I set it aside for a moment and broke ground on a new Rust project. My initial idea for the simulator was quite simple: create a simplified representation of a Minecraft world, a simulated turtle that exists in that world, and an embedded Lua VM to run the programs. A few hours of hacking later, and I could write tests like this: There's still more surface area that the simulator will need to cover, but I'm excited that I was able to prove out the concept quickly. That's all for now, but I'll likely be writing more about my ComputerCraft adventures in the future. Write the first version of a program Run it on the turtle See something not work as expected Refine the program Rinse and repeat.

0 views
maxdeviant.com 9 months ago

Beautiful Death

Last Friday the Spotify algorithm suggested that I listen to the new Beautiful Death album, No Grave Can Hold Me . My listening records indicate that I've listened to Beautiful Death a few times back in 2022 and 2023, but they're not an artist that is in my regular listening rotation. I decided to give the album a listen, unaware of the journey I was about to embark upon. After listening through No Grave Can Hold Me a few times through, I started working my way through more of the Beautiful Death catalog. These are the albums I've listened to so far, in order: It's now almost a week later, and I have listened to essentially nothing but Beautiful Death. Beautiful Death's music feels like the embodiment of contrast. The simplicity of a solo acoustic guitar that the guitarist brings forth complex and layered sounds from. The black metal-esque album covers that house tracks less harsh than they'd have you believe. It's soothing and haunting, sorrowful and joyful, despairing and hopeful with each plucked note. I find it's easy to put on an album while I'm working and let it repeat over and over, fading to an almost subconscious level. Lately I've been feeling like nothing that I do matters. The activities I usually enjoying doing all feel hollow and unfulfilling. This has found me spending many evenings sitting in my living room, headphones on, doing nothing but sitting and listening to Beautiful Death. Sitting there I let the music wash over me, focusing on each note as it hangs in the air. I think about how this lone guitarist from Melbourne has crafted these songs that reverberate deep into my soul and bring me to the verge of tears. I think about what it might be like to touch someone in that way with my own work. A Dream Within a Dream Beautiful Death III Beauty & Pain: The Live Collection By Still Waters The Wanderer In the Forest

0 views
maxdeviant.com 11 months ago

2024 in Review

In a rare turn of events, I'm writing this year-in-review in advance of the last few hours of the year. Normally I end up spending New Year's Eve writing it as I rush to publish by midnight. As I look back on this year and try to remember what all transpired—a process that is hampered by a frustrating lack of notekeeping on my part—I'm left feeling like there wasn't all that much. Of course, I know this not to be true. Plenty of things happened , but not many that make for tidy bullet points in an itemized record of the year. In many ways this year has felt like stasis, with not much to show in terms of outwardly-visible signs of progress. Internally, I've been constantly embroiled in battle with my inner thoughts and demons. This unending fight has taxed me both emotionally and physically, and has often left me with little left to give to my family, friends, and my work. Working on myself has taken up the vast majority of my time and energy this year. During one particularly rough bout I wrote: I can't think of a time I've been more exhausted than I have been this past week. Sure, there have been other times where I've felt downtrodden by my emotions and heavy thoughts, but there is something so tangibly exhausting about having to face them head-on. I suppose like pretty much everything else in life, forward progress takes work. It's easier to stay in one place—even if that place is miserable—than it is to take action and move forward. In the face of all this, I've tried to enjoy the little things when I can find them: I turned 30 this year and am still trying to determine how I feel about it. One recurring theme so far has been reflecting on what I want to do today so that I don't look back and wish I had started it today. I've found maintaining this future-oriented outlook to be quite difficult when dealing with a multitude of things in the moment. It reminds me of when I first started learning to drive and I was always looking just a car or two ahead of me (on account of being deathly afraid of hitting them). It wasn't until I took the Pennsylvania Motorcycle Safety Program 3 and was taught to look ahead towards your destination that I realized how much of a difference it makes in the awareness of your surroundings. For motorcycles, in particular, looking right in front of you is actually more detrimental than in a car. For instance, looking directly ahead of you when going into a curve instead of looking through the curve can actually negatively impact your ability to maintain your balance on the bike. Point being, when all your attention is focused on the here and now, it can be easy to forget to look ahead and see what adjustments need to be made for a better outcome down the road. This year marked ten years of this website being online in some shape or form. I had originally intended to write a "10 Years of maxdeviant.com" post, or something of that nature, but the aforementioned struggles of this year got the best of me. I did, however, ship a rebuild of my site this year. This site is now built by a bespoke static site generator, leveraging Razorbill , and I am excited by the possibilities this affords for the future. This was my first year using Rust in a professional capacity, and I could not be happier about it. It's been everything that I had hoped for, and more. I've observed that, for the first time in my career, the language I'm using largely fades away. I find that I can focus on the problem at hand without being abruptly pulled out of my flow state by reaching for a language feature that doesn't exist. This is something that has routinely frustrated me when working with other languages, and it's a welcome change to have the set of language features that I want at my disposal. A note on compile times: the rumors are true. Rust can be quite slow to compile once a codebase reaches a certain size. The Zed codebase, for instance, can be a real bear at times. For smaller projects, like my personal ones, I find that compile times are a non-issue. I do hope that further inroads can be made towards improving this, but I find that sacrificing a bit of compilation speed for all the other benefits Rust provides to be a no-brainer. Lastly, in September I attended RustConf 2024 along with the rest of the Zed team. I had a great time and I enjoyed getting to talk to so many fellow Rustaceans. It's hard to believe that we only open-sourced Zed in January of this year! That moment feels like forever ago, and so much has happened since then. Extension support —a feature I helped build and am deeply proud of—didn't even exist until February. Zed has come a long way this year. It's been a labor of love and tenacity by the entire team, all of whom I feel incredibly lucky to work with day-to-day. The level of talent and commitment to the craft embodied by my teammates is a sight to behold. There's still a lot to be done to make it possible for everyone to feel at home in Zed, but I'm confident that we're up to the task. For a look back at everything that happened in the Zediverse this year, check out the Zed 2024 Recap . As always, here's an assortment of stats from this year. I had an unbroken streak on GitHub of 193 days, from April 1st to October 11th. It would be even longer if I hadn't skipped that one day, but alas. I'm still quite pleased with my contribution chart: It's been a good year for me in the Zed repository as well: Sadly, GitHub no longer shows lines added/deleted once the commit count exceeds 10,000. This year I wrote 6,804 words across my various writings (not including this post). I'd like to bring this number up next year. My music listening was, once again, down from the previous year. I think this can be partly attributed to the change in work environment: we have a very pairing-heavy culture at Zed, and I can't listen to music while I'm pairing with someone. Here are the albums that I listened to the most this year: If there is one thing I am leaving 2024 with, it's a renewed desire for finding balance in my life. The pendulum continues to swing too far in either direction, dragging me with it from one extreme to another. I came into the year with a goal of "devising a system for sustaining my ideal lifestyle", and I have yet to achieve it. To all of you who have been there for me this year: thank you. I know I've been distant for much of it, so I deeply appreciate your steadfast camaraderie in spite of that. I look forward to what the new year will bring. The extended editions, naturally. It was 3 times in Fellowship, 4 times in Two Towers, and 3 more times in Return of the King. As much as I would love to claim the title of "motorcycle rider" in the hopes of sounding cool, I never did end up finishing the course. Having my siblings over for a Lord of the Rings 1 marathon and keeping notes on how many times I tear up or cry 2 Exchanging Strands and Connections results with Heather, and commiserating when the NYT makes them extra difficult Taking walks around my neighborhood where I've lived for 7 years and have yet to fully explore Hiking in the Great Smoky Mountains in Tennessee with nary a bar of cell phone service Sitting in my darkened sunroom during a thunderstorm-induced power outage sipping a Fat Tire while the lightning strikes periodically illuminate the room Hanging out in a Montreal coffee shop talking about Rust with some other engineers Spending a Sunday afternoon setting up a bird feeder next to my deck Watching from the kitchen window as the birds flit around said bird feeder BRAT - Charli xcx cold is the void - and all i can say is Still as the Night, Cold as the Wind - Vital Spirit Dance Fever (Complete Edition) - Florence + The Machine Autumn Eternal - Panopticon Wound - Despite Exile ERRA - ERRA Minecraft - Volume Beta - C418 THE TORTURED POETS DEPARTMENT : THE ANTHOLOGY - Taylor Swift Cutting the Throat of God - Ulcerate End of the World - Searows Nature Morte - Penitence Onirique Fiction - Syncatto Illuminate - Harvs Space Diver - Boris Brejcha Every Sound Has A Color In The Valley Of Night - Night Verses Of Mice & Men - Of Mice & Men ONI//KIJO - Memorist Love Exchange Failure - White Ward Triade III : Nyx - Aara

0 views
maxdeviant.com 1 years ago

RIP Cohost (2022–2024)

Cohost recently announced that the service will be shutting down at the end of this year. In 2022 I wrote about Cohost back when they first launched. At the time I had not yet received a posting invite link, so my thoughts about it were mostly speculative. It did give me Tumblr vibes and I thought that maybe, just maybe, it could recapture some of the magic I remember from those days. Once I was able to post I reposted a few things and made a single post of my own: Looks like I can post here now? Not quite sure what I'll post on cohost yet, but I'm sure I'll figure it out. I didn't use it much after that. I suspect this can partly be attributed to network effects: it was still early days for Cohost and there weren't that many people I knew actively posting there. Without a group of people to follow and interact with, there wasn't all that much motivating me to log in and check on a regular basis. Again, thinking back to my Tumblr days, I didn't really get into Tumblr until college when I had a group of friends who were all on it together. Cohost also came onto the scene at a time where I was feeling very disillusioned with having my data locked up inside walled gardens. At the time I wrote: As always, my primary focus will be building out my own platform, on this site and beyond. Despite not having used it much, I am sad to see Cohost go. They really seemed like they were trying to build something unique and do right by their users. Unfortunately, it would seem that alone isn't enough to sustain a business. I want to live in a world where more people are able to build fun little communities like Cohost that aren't trying to milk their users for everything they're worth. RIP Cohost, you were gone too soon.

0 views
maxdeviant.com 1 years ago

On Being Ready

On Being Ready This piece from Isabel really speaks to my present state. In it, she approaches the question that both she and I ask ourselves: "am I ready?" By interrogating this question each time it comes up, I've realized that this elusive, rather mysterious notion of "being ready" might just be the most well-disguised psychological block of all time. It's this idea that one day, you will receive a magical stamp of approval, delivered directly to you by some mysterious external force, telling you that you are now Ready For The Thing. I turned 30 two weeks ago, and since then I have been spending a lot of my time thinking about what I want to accomplish in the next ten years. There are a lot of things I want to do, but I can feel myself blocked by this exact sensation of not feeling "ready" to embark on any of them. Even coming up with a list of long-term goals has proved somewhat difficult, as I find it hard to nail down the specifics of which things I want to start focusing on right now . While I doubt that this solely originates from a feeling of unreadiness, I do think that evaluating ideas through the lens of "am I ready to commit to this?" when deciding whether they belong on my list of "Goals for the Next 10 Years" is not doing me any favors. This invisible, poorly defined prerequisite began to block me from doing things I felt deeply called to but had never done before, because I felt like I couldn't do them until I achieved some unidentifiable hurdle indicating I would succeed. The problem was: this ready-ness prerequisite didn't actually exist. The "unidentifiable" qualifier here is quite load-bearing. When I feel like I'm not "ready" to do something, it's generally not attached to some quantifiable criterion of what "ready" would look like. It's more hand-wavy and vibes-based; an "I'll know it when I see it" kind of feeling that allows putting off a task into the indeterminate future. I have tried to write about many things these last few weeks, but I have discarded all of them, because—I told myself—the pieces weren't "ready" or I wasn't "ready" to write them. There are many half-written pieces sitting in my drafts that have fallen into this exact trap. I'll have an idea for an article, start writing it, only to get stuck partway through. Typically this stems from discovering that the article in my head requires more something to achieve—more research, more examples, more eloquence—that I don't feel ready to give it in that moment. If you keep waiting for permission from some external source long after anyone is responsible for giving it to you, your ideas and ambitions will [wither] while you become bitter that no one is letting you do what you wanted to do. But in the end: it's your responsibility to give yourself permission. This waiting for permission is an interesting one for me. In my day job, I have no problem taking initiative and doing what needs to get done without waiting for specific permission or directive from anyone to do it. But when it comes to doing things for myself, I find it much harder. I think part of this is that, within the context of work, there is already some level of blanket permission that has been granted in order for me to do my job. To give a concrete example, I've been mulling over buying a walking pad for my desk so that I can be a bit less stationary while working. I've been considering this for probably over six months at this point, and yet have still not managed to pull the trigger on it. Why is that? Is it because I don't feel I'm "ready"? To do the research before selecting a particular model? To spend the money? To incorporate a change into my work environment? Recognizing that the permission has to come from inside myself really puts a different spin on it. Viewed in that way, it becomes painfully obvious that I'm the only thing standing between me and something that would arguably be a big boon to my physical health. So, the next time you find yourself wondering if you're ready: don't. Instead: start. We become ready by trying, not by thinking.

0 views
maxdeviant.com 1 years ago

Bad Fruit

This article from Ian comes at an apt time for me. For as long as I can remember I've had an expansive backlog of pretty much everything just sitting there, waiting. I think everyone, but especially artists, tend to collect a lot of stuff. There's so much art in the world, it's easy to see something you like, draw some connecting threads to similar things, and add them to you "to watch / read / play / etc." pile. Congratulations: you now have a backlog. Crucially, unfairly: just like in making art, it's on you and only you to work through even this. This rings true, for me. It's so easy to bookmark a webpage, jot down a movie or show name into a note on my phone, save a YouTube video to "Watch later"; and then simply never get around to actually consuming it. Still, a saved video or article isn't any good if you don't make time to watch / read it. In the past few months I've started entering backlog items—predominantly articles I want to read—into a "To Read" project in Todoist to help give some more structure in keeping track of the things I see and want to take the time to read. The problem, however, is that I'm too unwilling to check them off. Even if I open an article, read it, and then check it off, I want some more lasting record of having done so. That has lead to the creation of this "Library" section of my website that you now find yourself on. As I work through my backlog, I will record items here, ideally with some thoughts or commentary of my own to accompany them. Perhaps this is overstating it, but to me, making a backlog is an act of love: it's the recognition there are things in this life you want to give careful attention to. Working through a backlog is a recognition of mortality: there's only so much time in this life. One of my old bosses once told me something that's stuck with me: "Life's too short for bad fruit."

0 views
maxdeviant.com 1 years ago

Crouching Tiger, Hidden Dragon

I've seen bits and pieces of this movie over my life, but had yet to sit down and watch the entire thing. I remember when I was a kid my parents had some Chinese friends over to watch it. I was watching along with them, captivated by the action sequences. But I had done something to one of my siblings earlier that day that resulted in my being banished to the 阳台 and was unable to finish the rest of the movie. Then in high school I also got to watch the first bit of the movie in Chinese class, but once again never got to finish it. When I saw it listed on Max, I was worried that it might be an English dub, but thankfully it had the original Mandarin audio with English subtitles. Amusingly, I had to turn off the second set of subtitles in the app so that they wouldn't double up with the in-movie subtitles. Watching it as an adult, I was able to actually follow and get invested in the plot. The action sequences—especially those towards the beginning of the movie—were just as I remember them: tight martial arts combat and fanciful acrobatics. The camera work during these fight scenes is phenomenal and really lends to the action. In the downtime between fights I found myself getting immersed in the world, aided by the elaborate set pieces and shots of beautiful landscapes. You really feel transported back to ancient China. I think the movie has held up very well for being 24 years old, at this point. The wire fu might seem a bit cheesy to someone unfamilar with 武俠 media, but it took me right back to the glimpses of 武俠 TV shows that I've seen over the years.

0 views
maxdeviant.com 1 years ago

30

On my 25th birthday my dad told me "you're now closer to 30 than you are to 20." While said in jest, those words have hung heavy around my head for the past five years. During this later half of my twenties, I've felt like my thirtieth birthday has been approaching at an ever-accelerating pace. And much like an object approaching the event horizon of a black hole, try as I might to glimpse something from the other side of what the future may hold, there is no light that can make its way back to me. My twenties as a whole have passed before me much faster than I could have imagined when coming into them. So much has happened in a span of time that feels woefully compressed. I ask myself "will my thirties fly by even faster?" And yet, as I sit here on my 30th birthday I feel oddly at peace. This morning I woke up, took the dog for a walk, and then brewed myself a pot of jasmine tea. As I write this, I am sitting in my sunroom, enjoying my tea, and being still. A few weeks from now will mark one year of being in therapy. The experience of learning about myself as I've opened up to my therapist has been as rewarding as it has been brutally taxing. You don't reach twenty-nine years split between two opposing hemispheres without accruing a whole mountain of baggage. Baggage which, up until this point, I'd buried deep down and never come to grips with. Over the course of that year, I've learned so much more about myself. I wish I had started sooner, but I find it rather fitting that it lines up so well with this final stretch before turning 30. I know I have a long ways to go, but I am thankful for having taken the time and energy to work on myself and deal with some of these things—at least in part—before entering this next decade of my life. It's hard to know what I want to say at what feels like a seminal moment. I just know I want to write something down that I can look back on in ten years to remind myself of how I was feeling in this moment. Recently I've had this image from Tim Urban fixed in my mind's eye: We think a lot about those black lines, forgetting that it's all still in our hands. — Tim Urban, @waitbutwhy I've spent a lot of time over these last few years obsessing over the black lines of the past. What could I have done differently? What would I have done differently? What should I have done differently? I think it important that I remind myself that the past is the past and there's no use wringing my hands over it. The important thing is that today, in this moment, I consider what I will do that I can look back on fondly tomorrow. So if there is one thing that I want to say to my now 30-year-old self, it is this: You still have a lot of time to make yourself be what you want. — S. E. Hinton

0 views
maxdeviant.com 1 years ago

A 1:1 Site Rebuild

Since early 2019 I've been using Zola to power my website. As detailed in "New Year, New Site" , the primary impetus for picking Zola was to allow me to focus less on fiddling with my site and more on writing. In that regard, the choice was quite successful. Once I got it set up the way I wanted, it has largely faded into the background and given me room to focus on writing and publishing content to the site. Zola has served me well for five years at this point, but recently I have found myself feeling that Zola isn't quite what I want. Back in January I sent a Discord DM to my friend Steffen: I had the very dangerous urge to overhaul my website tech the other day. My north star in all of this was the idea of using a general-purpose programming language for the templating. The thing that felt the most restrictive about Zola is having limited programmability inside of the templating engine, Tera . While Tera does allow you to define your own functions and filters when using it directly, since I was consuming Zola as a pre-built binary I could not make any adjustments. This meant that for simple things like formatting numbers I had to upstream my changes to Zola or Tera in order to make use of them. While this approach is fine for general-purpose features—I have no problem contributing to the ecosystem as a whole—for features more specific to my site this becomes an untenable solution. Additionally, the mere exercise of writing anything more complex than a loop and a few conditionals inside of a Tera template was feeling painful. Early in my career I was working on an app using AngularJS, which required the use of Angular-specific attributes in order to express things like conditionals: This adds a lot of additional API surface area to learn, as you need to know how different concepts like conditionals or iteration are represented in Angular. Pardon the lack of syntax highlighting, this was one of the things that didn't make the cut in the rebuild (more on that later). In 2016 when I first started learning React, a common aphorism used within the community was that "React is just JavaScript". In contrast to AngularJS, React relied heavily on existing JavaScript syntax instead of having React-specific APIs to learn. For instance, conditionals in React components can just be ternary expressions 1 : In fact, you can even use React without using JSX at all, making it really just plain JavaScript: I've long-since fallen off the JavaScript bandwagon, but the React mindset has stuck with me since then. A thought embedded itself in my brain: What if I could just use Rust as my templating language? Inspired by working with GPUI at Zed, I decided to experiment with building an eDSL for writing HTML inside of Rust. I call it Auk : My initial explorations were enough to convince me that this was a path I wanted to pursue, and I settled on Auk as my replacement for Tera. When I first begin thinking about doing a site rebuild I had the idea of building a "static site generator in a box". It would come with a bunch of existing components that you might want in a static site generator, but allow customizing or swapping out components to suit your needs. To this end, I created Razorbill and began using it to rebuild my site. In the interest of keeping the scope of the rebuild as small as possible, I decided to limit it to just swapping out Zola for Razorbill while leaving everything else as untouched as I could. This meant making Razorbill understand Zola's content structure, frontmatter, and shortcode syntax. This decision meant I could still continue to write and publish content on my site during the rebuild process. Replacing the templating system was in-scope, so I duplicated the Tera templates and ported them to Auk. Having to fork the templates like this did mean that any changes to the templates needed to be done twice, so I tried to refrain from making any major changes to them while the rebuild was in-flight. After a week or so of work, I had a version of my site running on Razorbill that very closely resembled my Zola site: An early version of my about page running on Razorbill. You may, as I did, look at that and think "so you're done, right?" In reality, there was still a long ways to go. After working on the site rebuild for two weeks, progress ground to a halt under the weight of functionality that Razorbill needed to support in order to achieve parity with Zola. Shaving the yak of static site generator features seemed daunting, and I ended up setting the project aside. I would not revisit it for almost seven months. In late July, weary of having this unfinished project hanging over me, I picked it up again. I had to finish it. The main impediments thus far were not knowing how close I was to being done, and what things I still needed to implement or fix. To help improve my understanding of the status of the migration, I created a small tool called to build both versions of my site and then compare the differences between them. The way it worked was rather simple: The generated report would give me a high-level overview of which files had differences: A list of changed files between the two site versions, with changed line counts shown. It would also show diffs for each of the changed files: A diff between the HTML output of the old and new site. Building ended up being the catalyst I needed to push the rebuild over the finish line. I quickly settled into a fast-feedback cycle of: After two weekends of this, I finally reached my goal: a near 1:1 rebuild of my entire website. Here is the final comparison report: The comparison report showing 98% similarities between the two sites. The only differences between the old and new sites remaining were a handful HTML-encoding discrepancies. I ended up cutting syntax highlighting from the scope of this rebuild. It seemed like a complex enough feature that could make the already-dragging project take even longer. Additionally, I wanted to explore alternative approaches to syntax highlighting to how Zola does it, which felt like a good standalone project for my future self. Once I decided to cut it, it was easy to set to in my Zola config to remove any differences stemming from syntax highlighting from the diffs. Satisfied with the state of the new site, the last thing remaining was to deploy it. I set up a GitHub Action for building the new site and deploying to Cloudflare Pages. This did require a bit of shuffling things around in Cloudflare, as it turns out there's no way—at least, not that I could find—to disconnect a Cloudflare Pages project from a GitHub repo once connected. After inspecting a preview deployment and confirming that all was in order, I merged my PR and the new site went live. The GitHub stats for the new maxdeviant.com. After dragging this rebuild out for more than half the year, I am glad to finally have it done. While this rebuild has been almost entirely unnoticeable to any lay visitors to my website, it serves as a foundation for all of the things I want to do in the coming months and years. Even though I built it specifically for my own needs, I decided to open-source in its current state in case someone else might benefit from it. You can find it on GitHub . I used to extract it from my website repository: With the following contents in the file: When I have some time I'd like to clean it up a bit and make it a bit more usable outside of its original use-case. Since is a statement in JavaScript and cannot be used as an expression. Build both sites Format the output files with Prettier Diff the content with Generate an HTML report Make a change in Razorbill See what changed in the comparison report

0 views
maxdeviant.com 1 years ago

Take a Walk

For the past few days I've been taking daily walks around my neighborhood. I already take my dog, Arya, out for a walk twice a day. However, these walks are more utilitarian in nature. Having to wrangle a rambunctious terrier mix does not lend itself to a peaceful stroll. When I am walking by myself it's different. I can go at my own pace, stopping to smell the roses, both figuratively and (sometimes) literally. The beautiful, sunny weather beckons to me even more than usual on account of my currently overburdened mental state. The thoughts pounding away inside my brain seem to double their efforts when I'm sat at my desk, wishing for nothing more than for them to subside. So I lace up my sneakers and cross the threshold out into the glorious sunlight. The streets are empty as I walk them, with nary a soul in sight. Every so often a car will pass by, breaking my solitude but for a moment before the sight and sound of it disappear. Other than that, it is almost totally silent, save for the sounds of birds. The birds. Ah, the birds. A host of them surround me as I amble along my route. Starlings and robins and sparrows are in abundance. Crows are a common sight as well, along with a cardinal or dove every so often. These are just the ones I've yet identified, with many more—some tucked away from view within the leaves of nearby trees—singing their song. Sometimes I'll hear the drumming of a woodpecker off in the distance. I was graced with a glimpse of one the other day, flitting between mailbox posts in search of a meal. Every so often over the course of my walk I'll stop for a moment, close my eyes, and just feel the sun on my face and the wind in my hair. If I stay there long enough—eyes tightly shut—I can almost picture myself somewhere else. I am transported to Chiang Mai, walking down a residential street. There are concrete walls and gates on either side, separating the compounds from the road. It's nearly noon, and the sun is shining brightly overhead. Just as I begin to wonder why I left my air-conditioned refuge, a cool breeze starts to blow. Despite being brief, it provides welcome relief from the heat of the sun. I open my eyes and the vision fades, and I continue walking. So far these walks have proved to be an anchoring experience for me. In recent years I have found it increasingly hard to be present in my daily life. I seem to be always longing for the past or anxious about the future, to the point of not being able to enjoy the present. Yet, on these walks I've felt present and at ease for the first time in a very long time.

0 views
maxdeviant.com 1 years ago

Zed Docs: Powered by Cloudflare Workers

The Zed docs have been in need of some infrastructural love for a while. The existing setup for the docs entailed manually replicating changes from the source files—stored in the Zed repo—to a separate repo for . As you might imagine, this setup came with a number of issues: To solve this, we simplified our docs pipeline using mdBook to render the docs. This provided us with an easy way to build and deploy a static site for the docs, as well as a local development server that could be used by anyone to preview docs changes. However, one question remained: how would we get these docs to live at ? I've used Cloudflare Workers in the past to stitch multiple sites together with great success, so I suggested we leverage it here again. The first order of business was to get the docs deployed somewhere. Since we're already using Cloudflare for everything else in this setup, Cloudflare Pages seemed like an obvious choice. The one trick here is that we needed to deploy the docs at the path instead of at the root path. We can set the in the for mdBook: And then when deploying use the flag to place the built artifacts into a subdirectory: Now when we deploy the docs they'll be hosted at 1 . With the docs deployed to Cloudflare Pages, we needed a Cloudflare Worker to route requests there from . The Worker doing the heavy lifting here is incredibly simple: This Worker will take the incoming request, change the hostname to the Pages deployment ( ), and then proxy the request to its new destination. If we get a 404 response back from the docs, we then forward the request to so that we get back our regular 404 page instead of a the mdBook one. Otherwise, we just return the response as-is. We then setup a Workers route to forward traffic under to the Worker. This means that any requests beneath will go through the Worker, while the rest of our traffic is left untouched. The end result of this is that, for all intents and purposes, it appears that the is a part of the entire site while being able to be deployed independently to a separate location. And that's pretty much all there is to it. Cloudflare Workers has once again proved itself as an invaluable tool to have in my web toolbox. Every time I use a Cloudflare product it really does feel like magic. But there's no magic here; just some excellent engineering by the folks over at Cloudflare. Right now the new docs live at , but they'll be promoted to early next week. I'm looking forward to writing more docs in this streamlined setup. is an example domain for illustrative purposes. The real URL is slightly different. Having to manually replicate the docs was annoying, error-prone, and resulted in docs being frequently outdated Contributors couldn't see the repo on account of it being private, meaning that docs changes were essentially being made blind

0 views
maxdeviant.com 1 years ago

Transactional Appointment Scheduling

I woke up early this morning to go to my semi-annual dentist appointment. Midway through my shower, I realized that I didn't recall receiving any form of automated confirmation about my appointment. Sure enough, when I checked my phone the only confirmation email I had in my inbox was for my previous appointment. I started to wonder if maybe I was mistaken about my appointment date. Had I entered it into my calendar incorrectly? Not wanting to make the drive over there for nothing, I called the office right before it was time for me to head over. There was a change in office staff since my last visit, so the receptionist who answered did not know me by name. After checking my records, she told me that I did not have an appointment scheduled for today. In fact, there was no future appointment scheduled for me at all! Throughout this exchange, I was staring at the reminder card on the front of my fridge telling me I had an appointment in thirty minutes. I'm sure this can be chalked up to a clerical error. The person who scheduled my appointment during my last visit probably wrote out the appointment date on the card, handed it to me, but then never finalized the record in the patient scheduling system. This whole experience got me thinking about ways this process could be improved. In software systems it's generally desirable for operations to be atomic . That is, a group of related operations should either all pass or none should pass. If one operation fails, then the rest should fail as well. This property is often enforced at the database layer through the use of database transactions. In fact, it's quite likely that my dentist's scheduling software makes use of transactions in some form to keep the system in a consistent state. Unfortunately, these transactional guarantees don't extend to the physical artifacts: the appointment reminder card I receive after each visit. As I described above, on my last visit I received a reminder card that seemingly never had a backing appointment record. One way to prevent situations like this would be to have the appointment reminder card be derived from the digital record. For instance, the reminder card could be printed out once the appointment itself has been created. This is actually—as far as I can tell—true of how the digital reminders work. Looking back through my inbox, I can see for my past appointments I received a scheduling confirmation email shortly after the appointment was scheduled. That email is notably absent after my most recent visit. While it would be nice if the card I can stick on my fridge had stronger guarantees that it corresponded to an actual appointment, I suspect that is unlikely to happen. More likely is that the physical cards get phased out in favor of solely digital reminders. Until then, I suppose I'll have to keep a more watchful eye out for scheduling confirmations (or lack thereof).

0 views
maxdeviant.com 1 years ago

redux-persist-transform-encrypt (2016–2024)

On February 2, 2024, I declared bankruptcy on an open-source project of mine: . This is a postmortem of sorts for that project. I'll detail how it came to be, developments that happened over the years, and the events that led to my eventual decision to shut it down. Back in 2016 I was spending my days at work rebuilding our existing AngularJS frontend using React. As part of this rewrite, we had chosen Redux as our state management solution, in part due to the incredible amount of hype it commanded in the React ecosystem at the time. I can still remember watching Dan Abramov's "Live React: Hot Reloading with Time Travel" talk from react-europe 2015 and being wowed by the possibilities that Redux offered. In the interest of making our application more tolerant to network interruptions, I started looking into as a way to persist and rehydrate a Redux store using the browser's . Given that we were dealing with student data and grade information, one of our requirements was that this data had to be secured at rest. On May 14, 2016, I released the first version of ( ). The goal of the library was fairly simple: provide a transform for that could encrypt a Redux store when persisting it to , and then decrypt it during dehydration. The store was encrypted using AES from , secured by a secret key provided by the caller. Given that this was all happening client-side, we would use a user-specific secret key returned from our API when the user signed in to read the encrypted contents of the store. Once the user signed out, the key would be evicted from memory and unavailable until they signed in again. Work on the library progressed with some regularity for the next couple of years, with small improvements being made gradually in response to my needs at work. I released v2.0.0 and v2.0.1 on April 2, 2018 ( ). It was around this time that a shift occurred. We had stopped using Redux at work, having completed a (rather involved) migration to . Redux had a lot of papercuts when trying to write well-typed code in TypeScript, and we were also starting to see some performance issues when dispatching certain actions. After some trialing, MobX did better on both those fronts, and seemed like a clear win for us to adopt. Along with the move to MobX, we also ditched the whole idea of local persistence, instead falling back to a more traditional "always online" approach. The result of this was that I was left with no further use for , and the library sat untouched. Pretty early on in 's lifetime—almost as soon as the first version was out in the wild—I started getting a lot of GitHub issues pertaining to using it with React Native. Not being a React Native user myself, I tried to support the use case as best I could. I set up a React Native example app in the repo ( ) so I could reproduce issues reported on React Native. This will be important later on. On October 16, 2020, I merged a PR titled "Total overhaul", which did exactly what it said on the tin ( ). I had rewritten the codebase in TypeScript, modernized it, and fixed a number of issues from the backlog that had piled up in the interim two years. In the PR description I wrote: This library has been stagnating for a long while. This PR gives some much-needed love and fixes/obviates a number of issues that have cropped up over time. At this point in time the repository had accumulated 277 stars, far more than any of my other repositories, and I felt an obligation to continue maintaining it. After releasing v3.0.0 (and a subsequent patch release) I went on hiatus from my maintainer duties for a while. I returned on July 28, 2022, to do some housekeeping—mainly dependency bumps—and released v4.0.0 ( ). One of the issues prompting the release of v4.0.0 was updating to v4.1.1 to fix a security vulnerability. Unfortunately, this update caused more problems on React Native, due to not playing nice with React Native environments. The PR to fix this, brix/crypto-js#259 , is still open four years later. On March 24, 2023, I returned again to do some more housekeeping. This time a bigger change was made: the switch to ES Modules (ESM) . At this point in time the ESM discourse was all over the place. Package authors were trying to navigate landscape of deciding whether to migrate their packages to ESM, or go down the rabbit hole of dual-hosting CommonJS and ESM. JavaScript package behemoth Sindre Sorhus had been putting out new major versions of his packages that were ESM-only, linking out to a gist titled "Pure ESM package" letting package consumers know what they needed to do to consume a pure ESM package. After evaluating my options, I opted to go the pure ESM route. After all, ESM support was generally less of a problem for frontend projects, as most bundlers had good support for ESM (the same of which could not be said for backend projects). I published v5.0.0 ( ) with the new ESM support, dropping support for CommonJS in the process. Shortly after releasing v5.0.0 I started seeing an influx of GitHub issues stemming from issues using the new version on React Native. This time it was due to the ESM changes. Amongst the issues were also pull requests trying to fix the ESM issues with React Native, but they all seemed like application authors doing whatever worked to fix their specific use case, with seemingly little regard for what other impact their changes might have. At this point I was starting to get frustrated with having to try to troubleshoot this issue in the dark. I put out a call for a reproduction on one of the issues so I could test out any changes and hopefully put this to rest: If someone could provide a repo with a reproduction of the issue that would be immensely helpful for getting it resolved. I don't use React Native, , or anymore, so I don't have anywhere to effectively test any potential fixes. I never received a reproduction. On February 2, 2024, I received a GitHub notification from one of the open ESM-related PRs with the PR author tagging me for a review. That notification ended up being the last straw. I knew I couldn't keep going on maintaining a library that I hadn't used in seven years. So I made the decision to shut it all down, updating the README with the following notice: As of February 2, 2024, I will longer be maintaining . I have been supporting it as best I can these past few years, but the reality of it is I have not used , , or Redux since 2017. Since I no longer use any of the technologies involved and don't have a good way of testing any potential changes, I am no longer in a position where I feel I can maintain this package to my desired standards. Additionally, as a project also seems dead, despite an attempted change in management. Then I archived all the open issues and PRs and, finally, the repo itself. By the end of its run, had accumulated 359 stars, and is still my most-starred repo. The unexpected popularity of the library—combined with my own personal vanity towards silly internet points—was a large part of what kept me going so long. For a while it felt like I could keep things in stasis forever. I suspect I likely could have—at least for a little while longer—had I not gone through with the ESM change. After all, it doesn't take a terrible amount of effort to return every so often, do a bit of housekeeping, ship a new version, and then disappear again. But it was the reality of the ESM change and the subsequent fallout that made me reckon with some things. Back when I started this project, I was still a junior engineer hoping to make a name for himself. So when gained some amount of traction, I felt I had to ride it as long as I could. Now I'm at a much different place in my career, and don't much care to be known for a tiny JavaScript library. Another factor that weighed in on my decision was the state of the ecosystem as a whole. To be blunt, is dead. The last commit to the repository by its original author was on September 1, 2019. There was an attempted change in management in September 2021, but that seems to have petered out as well. As I write this, the last commit to the repository was on November 22, 2021, going on three years ago. There's probably a dozen different things I could have done differently over the lifetime of this project. Could I have put in a bit more work to reproduce and troubleshoot user issues? Sure. Could I have found additional maintainers to help out or take over when I was ready to move on? Perhaps. At the end of the day, I think there's something to be said for knowing when to throw in the towel. So that's what I did. If you were a user, thank you. I hope you found it useful for the time that you did.

0 views
maxdeviant.com 1 years ago

Happy Birthday

Today is your birthday. I sent you a text, wishing you the best on this special day. I hope you're doing well. I can see in our message history that the last time we talked was four years ago, on your 26th birthday. You're turning 30 today. I thought it important to reach out. After all, you only turn 30 once. You never replied. To be honest, I don't blame you. If I was in your position I wouldn't reply either. Four years is a long time to go without talking to someone. You probably think that I've forgotten about you. Truth is, I've just been dealing with a lot. Yea, there's the whole pandemic thing. It was just getting started when last we spoke. That alone is enough for me to give someone a pass for not maintaining contact. But I've been dealing with my own baggage too. Some of it known; even more of it that I didn't know I was carrying. I've thought a lot about how things went down between us. I think it's safe to say I fucked up pretty bad. I hope you can forgive me. Happy birthday.

0 views
maxdeviant.com 1 years ago

AI Continues to Impress

I make no secret of being a bit of an AI skeptic, however, I will give credit where it's due. Today I've had two AI experiences that left me feeling impressed. Both of these involved leveraging the AI assistant built into Zed . Earlier today I was writing some documentation in the Zed codebase. I had two structs with the same fields: an internal settings struct and a separate struct for serialization. One of these structs had its fields documented while the other did not. While I could have copied the doc comments over by hand, I decided to enter this prompt into the inline assistant to see what would happen: Copy the doc comments from the fields in and add them to the fields in . Ignore the note about the default value. Just bring over the doc comments. The AI copied over the doc comments verbatim—sans the note about the default value that I asked it to ignore—and put them on the corresponding fields. Later this evening I was doing some work on my site, translating some of my templates from Tera over to a new templating system I'm building on top of . I needed to port this small component I had written over to Auk's DSL: Once again, I thought it would be interesting to see what the Zed assistant could do with this. I prompted it with: Rewrite this HTML using 's DSL like the function above. The end result that the assistant spit out looked identical to what I would have produced by hand: I still don't buy into the notion that AI will make software developers obsolete. Rather, I think that a judicious integration of AI into our development tools and workflows can make us all more effective at building software.

0 views