• Hello from Eric's Blog Generator

    As of my previous post, I'm now generating this site using my very own static site generator that I've creatively named Eric's Blog Generator or EBG for short. Depending on how you count, this is the about the fifth time I've changed blogging platforms.

    Some History

    It's not totally clear what counts as "this blog" but in my mind the first version of it started when I was an intern at Mozilla back in 2011. Mozilla encouraged us to blog and my manager recommended Tumblr, which was the style at the time. So I made four whole posts about my contributions to a new systems programming language called Rust that was designed to be safe, practical, and fast. This language was going to change the world with cool features like typestate! I worked on Rust's concurrency and parallelism features, and if I remember right, my main contribution that summer was Rust's first green threading system.

    Then in March of 2012 I started blogging at WordPress. The first few posts were about things I was working on in grad school, but that summer I went back to work on Rust at Mozilla so I wrote quite a few posts about Rust. I was pretty proud of the protocols feature that I added, which let you define communication protocols that pairs of tasks could follow and the compiler would make sure you sent and received the right messages at the right time. On aspect I was particularly proud of was that in some cases the compiler could prove there was an upper bound on the number of messages that could be in flight, so it could pre-allocate the necessary space and message passing would be zero allocation. Anyway, like most intern projects, this one was ripped out pretty much immediately after I left. It turns out people only ever used two protocols—one-shot and stream—so Rust just included these two in the library and got rid of the complexity of letting people define arbitrary communication protocols. Given that Rust has proc macros now, I've often thought it would be fun to reimplement protocols as a macro. I did make one contribution that stuck around and has enabled many of the concurrency bugs that occur in real-world Rust programs.

    That November, after going back to school I migrated to Octopress, which was the style at the time. This was also when I moved to my own domain, where the site lives to this day. I still have fond memories of Octopress. It seemed effortless to create, write, and publish new blog posts. I think of this era as kind of my golden age of blogging.

    I used Octopress 2.whatever for a while, but in 2017 it was time to migrate to Octopress 3.0. I'm honestly not sure why I did this. The old way worked fine and I never really got comfortable with the new way. Octopress 3.0 was purely a Jekyll plugin, while 2.0 was more of a wrapper around Jekyll. In theory this should have been simpler, and it should have opened up the wider Jekyll ecosystem. Instead, I basically forgot how to work my blog. Something needed to change.

    Why did I write my own?

    First, as I mentioned, I was never really happy with my blog after upgrading to Octopress 3.0, so I was on the lookout for something different. One challenge for me was that Octopress and Jekyll were Ruby-based, and I've never really gotten comfortable working with the Ruby ecosystem. Every time I wanted to write a new post I had to remember how to deal with bundler and Gemfiles and whatever else you have to worry about with Ruby. Furthermore, I tend to work from a number of different computers, and the Ruby environments never worked quite the same in each spot. I tried dockerizing my blog but I'm also not really good with Docker. Finally, I designated one computer as the one where blogging works and I'd SSH into it any time I wanted to work on my blog. The whole setup was suboptimal.

    These days I work mostly in Rust and I love working with cargo and the rest of the Rust ecosystem. Rather than learn some other language ecosystem, I wanted to be able to be able to stick with one I know well and use regularly. There are already static site generators written in Rust, and I looked at some of these, but I wasn't convinced these would give me everything I was wanting. I wanted something that I could do a mostly in-place upgrade. Even moving from Octopress 2.0 to 3.0 required some pretty gnarly git-fu since I basically had to transplant from Octopress 2.0 where everyone just forked the original Octopress repo to Jekyll where the tooling creates a new standalone site for you. I wanted to be able to leave my existing posts basically in tact, although I was willing to make minor edits if it was easier to edit them to not need a feature rather than support a feature in my own generator. Also, I wanted something that I could install by doing cargo install and expect it to work, but some of them required additional build steps that I didn't want to deal with.

    Finally, writing code is fun and this has been a fun little project to work on. And given that I'm trying to make Rust a better language, it makes sense to spend some time using Rust to stay rooted in how the language feels as a user.

    As a bonus of having written my own, I'm now in a good position to try out some ideas I've wanted in a blogging platform for a while. Sure, Jekyll and similar platforms have lots of plugins and I could probably find or write plugins that work, but writing my own software saved me from having to learn someone else's. (Isn't there some saying like one month of coding can save you one hour of reading documentation?) For example, I'd like to try out different ways of rendering footnotes, add captions for images, and so on. One thing I'd like to try is automatically adding <archive.org> links for any external pages I like to, since I've noticed after blogging for twelve years that sometimes things I link to don't stay up. My new blog generator doesn't do any of these things yet, but now I'm in a good place to add these features if I'm so motivated.

    Can I Use Eric's Blog Generator?

    You can if you want to, but honestly, there are many better options out there. While it's good enough that it now powers this site, it's missing some rather basic features. For example, you have to write your own theme from scratch. That said, the code is out there, it's published on crates.io, and there's even a Docker image.

    And since people like feature lists, here are some reasons why you might want to use Eric's Blog Generator:

    • Easy installation, just cargo install ebg.
    • Somewhat Octopress compatible. Your source posts should work with minimal edits, although EBG doesn't support SCSS or Liquid templates so you'll have to redo your theming.
    • Cross platform. I use it on Windows and Linux and I can't think of why it wouldn't work on Mac or any other platform that Rust supports too.
    • Supports writing posts in Markdown.
    • Supports static pages in addition to blog posts.
    • Flexible templates powered by Tera.
    • Used by some of the greatest writers in the world!

    Conclusion

    Well, I thought this was going to be a short post just to say "I made a blog generator and it's now powering this site!" Instead I got a little nostalgic and took a tour through all the earlier incarnations of this blog and this turned out to be kind of long. With any luck, this should be the last version I ever need, because now I can just change things if my tools aren't working for me anymore. I'm hopeful that this will remove some of the friction I've had with writing and publishing in the past so I'll be able to post a lot more regularly. Of course, the bottleneck is always the actual writing, not the tooling...


  • Who Makes the Boxes?

    As I've written about before, one of the major features we're working on adding to Rust is to allow async functions in traits. Today we have support in nightly for async methods in traits in static contexts. This lets you write code like the following:

    trait AsyncCounter {
        async fn get_value(&self) -> usize;
        async fn increment_by(&mut self, amount: usize);
    }
    
    async fn use_counter(mut counter: impl AsyncCounter) -> usize {
        counter.increment_by(42).await;
        counter.get_value().await;
    }
    

    This empowers a lot of use cases, but we also want to support this feature in dynamic dispatch contexts. In other words, we'd like to be able to write use_counter like this:

    async fn use_counter(mut counter: &mut dyn AsyncCounter) -> usize {
        counter.increment_by(42).await;
        counter.get_value().await;
    }
    

    While this looks like a straightforward extension on what we already have, I've been surprised by the amount of additional functionality needed to support this change.

    It turns out there are also a lot of design questions that in my mind do not have an obviously right answer. There are cases to be made for many different points in the design space, but ultimately the right one will depend on what people use in practice.

    In this post, I'd like to explore the space for one of these questions.

    Read more...
  • Async Functions in Trait Objects Update

    As 2022 draws to a close, I want to take a moment to look at where we are with supporting async functions in dyn traits (AFIDT) and suggest some ideas for how to make progress in 2023.

    The set the stage, we'd like to make the following snippet of code work:

    trait AsyncCounter {
        async fn increment_by(&mut self, amount: usize);
        async fn get_value(&self) -> usize;
    }
    
    async fn use_counter(counter: &mut dyn AsyncCounter) {
        counter.increment_by(42).await;
        counter.get_value().await
    }
    

    Through the rest of this post we'll see how close we are to getting that working and what's left to get it across the finish line.

    Read more...
  • A Look at dyn* Code Generation

    As I've written about before, an important goal for async Rust is to support async functions everywhere, including in trait objects (dyn Trait). To this end, we are adding a new experimental type called dyn* that will give us more flexibility to support dynamic dispatch for async methods. We now have experimental support for dyn* in nightly Rust now, so we can start to kick the tires and use our experience to inform future development.

    One thing we'd like to ensure is that using dyn* does not impose significant costs above what's already incurred by dyn. Ideally we'd be able to generate essentially the same code for dyn* Trait that we do for dyn Trait. With that in mind, in this post, I'd like to look at some of the code we currently generate. We'll start by looking at dyn Trait objects, and then we'll see how things change for dyn* Trait.

    Read more...
  • Something That Confused Me About Rust Specialization

    I recently read through RFC 1210 to understand Rust's proposed specialization features. I found the example given in Going down the rabbit hole confusing, so I started writing a question to post to IRLO. In the course of writing up my question I also figured out the solution, so now I'm posting my solution here instead.

    Read more...
  • More Weekly Links

    Continuing the series I started a few weeks ago, here are links to things I've found interesting recently.

    Read more...
  • Links For This Week

    Sort of in the same vein as my last paper review post, I'd like to start periodically posting a weekly links post. In theory I should publish this every week, but I don't want to make a hard time commitment. Instead, I'm going to make a point of writing up little blurbs about things I find interesting and publishing that when I have enough. These can be things I'm reading, things I'm watching, or anything else, but the key thing is that I found them interesting in some way and perhaps they led to some change in how I'm thinking about or doing things.

    Read more...
  • Paper Review: Safe, Flexible Aliasing with Deferred Borrows

    I'm trying something new today. I try to periodically read papers and such to stay on top of the latest research on things I'm interested in. Unfortunately, it's easy to read a paper and have it not really stick. To combat that, today I'm trying a paper review. We did this in some of my classes in grad school, where we'd have an assigned reading for each class period and before that we were supposed to write a couple paragraphs summarizing the paper, evaluating it, and asking a few questions. So, in what will hopefully become a regular feature of my blog, today I'm kicking off my first paper review.

    Today I'm reviewing Safe, Flexible Aliasing with Deferred Borrows by Chris Fallin. This was published in ECOOP 2020. I found out about this paper from Yosh Wuyts who mentioned that it might be a good theoretical foundation for adding defer expressions to Rust.

    Read more...
  • How Async Functions in Traits could Work in Rustc

    One of the major goals for the Rust Async Working Group is to allow async fn everywhere fn is allowed, especially in traits. In this post, I'd like to distill some of the proposed designs and show how async functions in traits could be implemented. We'll look at one possible way this could work, although I'd like to emphasize that this is not the only way, and many details of the design that we'll ultimately adopt are still being worked out.

    Read more...
  • Perspectives on Async Cancellation

    Lately there has been a lot of discussion about async cancellation in Rust. One thing I've noticed in these discussions is that cancellation often means different things to people. As a result, what is a concern for one person may not be a concern for another and it may not even be possible for one person to articulate the other's concern. I think perhaps the reason for this is that async cancellation has to be discussed from a certain perspective, and this perspective is often implied but not explicitly stated or shared. When looking from different perspectives, async cancellation can have different meanings, capabilities, and implications.

    In this post, I'd like to make an attempt at cataloging and categorizing the various perspectives we might use when discussing async cancellation. I don't expect this to be the last word, but I hope it will be useful in clarifying the issues surrounding cancellation and serve as a starting point for more precise classifications.

    Read more...