Cosmic Blink of an Eye

Sometimes in science articles, and in arguments about abiogenesis or evolution on the Internet, a writer will refer to a length of time as a cosmic, geologic, or evolutionary “blink of an eye”. The length of time varies, but typically the writer means something on the order of a thousand years, the subtly ironic point being that, although a thousand years seems like a long time to us, or in the time frame of human civilization, it’s a very short in the time frame of the Universe.

But some writers are a bit loose with the term. I have seen legitimate, intelligent science writers refer to millions of years as a cosmic blink of an eye, which seems a tad long to me. The universe is 13.8 billion years old. A million years is not a huge fraction of that, but it’s long enough that “blink of an eye” is not an apt comparison.

One time, while arguing on the Internet with someone who claimed that life appeared on Earth “almost instantly” after Earth’s formation (only two hundred million years, I pointed out), they claimed that two hundred million years is a “blink of an eye” (only about 1/70th the age of the Universe, I pointed out).

It got me to wondering, what actually is a cosmic blink of an eye?

I figure that if you want to scale human time scales up to cosmic, a good simple way to do that is to equate one year of human time to one billion years of cosmic. That would make the Universe a healthy young teenager approaching their 14th birthday, and the Earth a rambunctious four-year-old. In order to find out how much time a cosmic blink of an eye is, we simply multiply the duration of a human blink by a billion.

A blink takes about 0.2 seconds, which makes a cosmic blink 200 million seconds. There are 31,557,600 seconds in a year.1

A cosmic blink of an eye is 6.3 years.

Yeah, that’s a little shorter than 200 million years.

In fairness, the phrase is not supposed to me mathematically foolproof. Nobody is doing calculations when the use, or hear, this phrase. It’s supposed to be an ironic way to point out the vast difference between human and cosmic time scales. I’d say as long as you keep it to the order of a thousand years (a cosmic commercial) or ten thousand years (a cosmic smoke break), the phrase “cosmic blink of an eye” is acceptable. When you start using it to refer to a hundred thousand years or more, “blink of an eye” is no longer a reasonable comparison.

  1. A Julian year, 365.25 days. When scientists recon prehistoric times, they use the Julian year, which differs slightly from our familiar tropical year, which is a Gregorian year (97 leap days every 400 years) plus occasional inconsistent leap seconds. ↩︎

Grand list of every superhero movie I have seen

I am not a fan of today’s superhero movies, but even I’m surprised how few I’ve seen. Here’s a literal complete list.

All four of the Superman movies with Christopher Reeve4 wasn’t as bad as everyone says, 3 was worse than people say, and I don’t remember a single thing about 2, other than that the villains were the criminals who were banished at the beginning of the first movie, though I am sure I saw it in whole once.
The Batman Movie based on the show from the 60’sAKA the only true Batman, according to Boomers. (“Some days you just can’t get rid of a bomb.”)
The two Tim Burton Batman movies with Michael KeatonAKA not fun like the 60’s Batman was, again according to Boomers. It was okay in a ten year old boy fandom kind of way.
The first Spiderman with Toby MacguireIt sufficed as entertainment on a flight.
First two Christopher Nolan Batman movies with Christian BaleBatman Begins and the Dark Knight, these were pretty entertaining actually, but I can’t say I really thought about them a lot after.
Mystery MenUnderrated parody of superhero movies. (“We’ve got a blind date with destiny, and it looks like she ordered the lobster.”)
The Powerpuff Girls MovieWhich was not unlike a longer episode of the show, so it was pretty good.
Guardians of the Galaxy Part 2My brothers dragged me to see it. It did not convince me to give any other Marvel movies a chance.

An that’s it. There are a few more dubious superhero movies I’ve seen, such as The Rocketeer and Robocop.

What amazes me is how pervasive the concept of a superhero has become. I don’t read comics, and have watched little TV and fewer movies about superheroes. Most of my exposure comes from watching cartoons as a kid. Yet, almost nothing about a superhero is unfamiliar to me, the whole story cycle of a superhero and every note it hits is as well known to me any story archetype.

WordPress kicked my ass

So, my hosting provider, Dreamhost, recently announced that they’d be discontinuing support for WSGI. My blog had heretofore been a simple one that I wrote myself, in Python, that used WSGI as the server interface. It was fun and educating to write, and it ran reliably for years, but once they dropped support, I had to find another option. FastCGI was still supported, I believe, but no.

In a way, I don’t blame them. Python, as great as the language is in terms of utility, readability, and straightforwardness, isn’t exactly fast, and is relatively resource hungry. And deploying it is a hellish nightmare.

I decided to throw in the towel and just use WordPress. It’ll probably be the right decision in the long run, but holy cow was it a nightmare to transfer data. Basically ate up a whole weekend.

First, to get it out of the way, PHP is a rotting carcass heap of a language. It’s abysmally bad. I know about a dozen programming languages, and usually when I see code in any language I can follow what’s going on with mild effort. PHP is like reading code through a CAPTCHA challenge, you know there’s something discernible there, but it’s a mental challenge just to make it out. Thus, I had no desire to dive in and code my way out of problems, which in retrospect was my first mistake.

My second mistake was trying to use the XMLRPC interface to transfer data. Where shall I begin with this mess? The XMLPRC interface itself wasn’t a huge problem. The problem was that, because XMLRPC is not your normal accessing pages from a web browser, the whole error handling mechanism just isn’t really there. A good chunk of my time was spent trying to guess why errors were happening with little or no explanation other than a server 500 error. To make matters worse, I had no control of many things on the host machine, and eventually I realized that the XMLRPC requests were being intercepted by anti-malware and rate limiting filters.

(Then there was this weird issue that Googling for anything about WordPress XMLRPC yielded hundreds of pages about how to disable it. I assume the articles were computer generated as part of a smear campaign, probably by someone owning a competing technology. The articles had that uncanny “every article is the same” feeling, even though they were worded differently.)

In the end, I ended up hacking together the following solution. I set up an older version of WordPress on a side computer (getting that to run was its own nightmare), and used a Python script to import data from my old blog using XMLRPC. Because it was on my own machine, I was able to disable the filtering, which solved most of my XMLRPC issues. Then I migrated that older WordPress to the most recent version of WordPress. (The migration turned out to be unnecessary. I had thought that the script I wrote was conking out on the post formatting used by the most recent version, but it turns out that was due to a technicality.) Once I had my local WordPress running and posts showing correctly, (which took two hours longer than it needed to thanks to a dumb cut-and-paste error in an Apache config file), I did a database export, which I then imported to the database on my web host, with a little surgery to adapt it to the new location.

The database import went remarkably smoothly after the trial-and-error disaster of using XMLRPC , and makes me think I should have just written the original script to update the database directly.

Anyway, it’s now done, posts are transferred and look good, and the theme suffices for now.

Altoona-Style PIzza

I was bored and decided to try my hand at Altoona-style pizza.

It intrigues me that, on the short list of locales that can claim their own style of pizza, Altoona has become one of them. Altoona style pizza is simple: Sicilian crust, sauce, salami, sliced green bell pepper, topped by (brace for impact) American cheese.

Altoona-style pizza became famous thanks to a social media frenzy of people calling it an abomination. You might think it’s nothing but the Internet deciding to pile on a random thing, but I don’t think it’s a random. (Indeed, I think that’s rarely the case.) Altoona-style pizza became Internet famous, I suspect, because it is right on the periphery of appealing, it looks just oddball enough that it might actually work, yet the appeal is shameful, and people pile on it to cover their shame.

My opinion? It looks like something I’d appreciate in a bachelor throw-a-bunch-of-stuff-together way. But I don’t know because I’ve never tried it, and I’m not expecting to be in Altoona any time soon. So.


First step, dough. It uses a Sicilian pizza base. Sicilian pizza is not like the trendy thin crusts of Neapolitan or New York pizza: it’s basically full-on bread, almost like foccacia. A bit of olive oil is mixed into the dough as well. I whipped up a dough, let it rise about three hours in a bowl with one punch down, then about another hour in the pan. Here it is.

One thing that amazes me is how easy making bread has become. I remember when making bread meant my fingers would be muddled with sticky dough. For this dough, I mixed, kneaded it, and rose it with hardly anything sticking.

Next is the sauce. I am not a fan of tomato sauce at all, I very often get white pizza, or at most ask for light sauce. To be authentic, I did do the tomato sauce, but stayed on the light side.

(Back when I was a teenager I had some super-tasting reaction to tomatoes; if I ate something with tomato and not enough other flavors to cover it, it could trigger a reaction and I felt like there was chalk all over the inside of my mouth. Pizza with a lot of sauce, spaghetti and marinara, and raw tomatoes were major triggers. I don’t get that reaction today, but still don’t like tomatoes or tomato sauce. But I find that in modest amounts tomatoes and tomato sauce can add dimension so I these days I tend to just go light on them rather than avoid entirely.)

I used one of those humble canned tomato sauces and some of my own seasonings, not the ritzy jarred stuff. I have a few tricks to take the edge off the tomato. Heat helps a lot, so I put a bit of cayenne in it, and another secret is I’ll put in a pinch of baking soda to cut down on the acidity. Here’s what it looks like:

Then the salami. Ralph’s did not have sandwich size salami so I used these smaller slices, which probably works better honestly. They are still larger than an average pepperoni.

Green pepper slices next. Amazingly, I think this was the first time I ever cored a green pepper rather than just cut into it. (I’ve cored jalapenos though.)

And finally, the cheese. I decided to use Kraft slicese for this, as I thought it was the closest in spirit to the original recipe. (I think the original used Velveeta.) More on that decision below.

Put it into a 450 oven bake for 15 minutes. Given that this is a Sicilian pizza dough, it’s pretty good for home oven baking. Thin crust depends on getting a nice char or something, but that’s not really the right thing with a thick doughy crust, and even if you have no firm crust at all (and I didn’t) it’s still good because it’s bread.

Here’s how that looked:

It was way, way gooier than it looks here. The top of the cheese firmed up, but underneath, it was melt city. Here’s a couple slices ready to eat.


The verdict: I thought it was good, in a bachelor throw-a-bunch-of-stuff-together way.

Good: Sicilian pizza dough (we should do more of it, seriously I know it’s a lot of calories, but come on, bread is good), the salami and pepper worked for me, and the gooey consistency of the cheese.

Bad: The strong flavor or the American cheese was too much. Actually, I feel like American cheese in general is too much these days. I don’t know if I’m getting older an my taste has changed, or if the Kraft singles are getting stronger (and, I want to say, tangier) in flavor, or if its a weird change in flavor that has stuck around from when I got covid).

If I were to do this again, I’d use mild cheddar or mild provolone. Provolone probably, it goes so good with salami, and melts great. This experience has made me realize that pizza is not somethign you want strong cheese on, so the mild versions.

Wheel of Time

So, thanks to this nice little pandemic, I have a little more free than usual, and I thought it would be a good time to take in a long series. So I chose Robert Jordan’s Wheel of Time. Big mistake.

It actually wasn’t bad as far as quarantine fodder goes. Quarantine books don’t really need to be good so much as they need to pass time well. Wheel of Time was absorbing, read easily, and wasn’t mind-bending or too disturbing. But the characters, my God the characters.

I hated just about every character in the book. My favorite characters are the ones I only disliked.

Everyone, and I mean everyone, is abjectly stupid. Almost always when someone did something smart is when some kind of magic overwhelmed their intentions and they ended up doing the right thing reluctantly and often now knowing how they did it. Furthermore, few of the characters were credible; their personalities were malleable to the needs of the story. The one thing you could trust about the characters is that if their personality changed it was only to make them stupider. It’s like Jordan had no idea how to create drama other than for people to fall into ridiculous traps or refuse to believe people who were trying to help.

I pushed through to about a fifth of the way into the fourth book, giving it a chance to get better, but finally I read a chapter so awful I had to stop. Though in truth it had been coming for awhile.

Since I didn’t finish, I do wonder about the future books in the series. I lost all interested in finishing (especially given the reputation of the books to drag on as the series progresses) but it’s possible, especially once Sanderson took over.

  • Do any of the main characters make a single good decision on their own in the entire series?
  • Does any character ever, even one time in the whole series, give a straight answer to a question? (I’ve heard that this is the main difference with the Sanderson books.)
  • Does it ever happen, even one time in the whole series, that a main character staying at an inn just checks out the next morning and moves on? (On screen, I mean; I know it happened a few times off screen.)

I’m exaggerating a little, but not much. The problem with these books isn’t that characters make stupid decisions, it’s that they make nothing but stupid decisions. It’s the sheer relentlessness of these simpleminded drama devices used over and over again.

It’s regrettable, too, because apart from the characters there was a lot of good stuff in these novels. The worldbuilding was fantastic. The different countries and their cultures were interesting. The backstory was very interesting, and the way details of history were revealed, and how it affected the present-day plot, was great. The mythology was terrific; if they hadn’t been terrible characters for the most part, the Forsaken would have been great villains just due to their circumstances. I didn’t even mind when Jordan went off on long descriptions (they weren’t that long).

Even the characters had their moments. I was amused how often Nynaeve (who I disliked and therefore was one of my favorite characters) resolved problems just by punching people, for instance. But all in all, the characters were just so awful I couldn’t read on.

Parlay: A Paragraph Layout Library

Parlay is a C library for laying out out paragraphs to an in-memory buffer.

This current version is 0.1.

Summary

Parlay does one thing. It take some text (it could be plain text or a simple markup language), lays that text out in a paragraph, and creates an RGBA image of that paragraph in memory.

That’s it. That’s all it does. You give it paragraph text, you get back an image buffer.

It’s not something that exists only as part of some weird rendering pipeline. It is not built upon a massive foundational library. It doesn’t have multiple backends. It doesn’t have plugins. It’s not scriptable. It’s not part of a framework. It stands alone.

The only input to Parlay is the text you want to render, some style information, including the font to use, and a few layout options. The only output is an RGBA image buffer.

Its only dependencies are FreeType and, optionally, MiniXML.

Features

  • Lays out and renders text to an in-memory buffer
  • Supports any True Type or Type 1 font that FreeType library supports
  • Allows user to register font files (it doesn’t rely on system fonts)
  • Renders text in different styles like italic and bold, different font sizes, and different colors
  • Supports outlines on characters
  • Supports highlighting characters (i.e., as with a highlighting pen)
  • Has basic layout control like maximum width and paragraph alignment
  • Supports Unicode and the UTF-8 encoding
  • Implements a simple XML-based markup language for specifying styles
  • Does not have a lot of dependencies: just FreeType and optionally MiniXML

Limitations

  • Currently only supports left-to-right text
  • Probably does not support combining characters, though I’ve never actually tried it
  • Requires user to register font files (it doesn’t use system fonts at all)
  • Supports ONLY the UTF-8 encoding
  • Does not yet support some basic styles like underline
  • Does not yet support grayscale buffers, though of course you can render gray characters to an RGB buffer
  • Does not currently support kerning

License

Parlay is free to use and distribute, subject to a BSD-Style license. See the file LICENSE.txt for details.

For binary distributions (i.e., if you distribute software that uses Parlay) I consider a note saying that the software uses Parlay, with a clickable link back to the official home page of Parlay, to satisfy the second bullet point of license.

http://blog.aerojockey.com/post/parlay

Source distributions should include the license file and not rely on a link.

Downloading

You can download Parlay from GitHub.

https://github.com/aerojockey/parlay

Building

Parlay is highly portable C. I think the only compatibility drama might come from a pair of inline functions. I don’t expect you’ll have trouble building it on any system that FreeType supports.

Unless you’re building libparlay.so for some kind of Linux distro, I recommend you just add the source files to your project and compile it in. You need to build it with the FreeType library, version 2. If you want the simple markup language, you’ll also need to build with MiniXML.

There is only one configuration option, PARLAY_USE_MINIXML, which specifies whether to build the function parlay_markup_text, which requires MiniXML. You can modify this option at the top of parlay.h, or define it on your compiler’s command line.

I make no guarantees about thread safety at this point. The functions parlay_register_font and parlay_init are certainly not thread safe, but you should probably be calling those during initialization anyway. I suspect that if you linked Parlay with a thread-safe version of Freetype, then the functions parlay_plain_text and parlay_markup_text would be thread-safe. But it wasn’t a design goal of mine to make them thread-safe, so no guarantees.

Usage

The API is very simple at this point: after initializating and registering fonts, you call one function to get one rendered buffer.

(The underlying implementation allows for more exciting possibilities like streaming text into a ParlayParagraphBuilder object, but the public API currently doesn’t offer this.)

Start by calling parlay_init. This simply initializes some FreeType objects.

Then, register some fonts with parlay_register_font. Each font is given a name and up to four font files (for regular, italic, bold, and bold-italic). The fonts can be TrueType or Type 1.

Once initialized, to lay out some text, you have to initialize two structures and pass them to parlay_plain_text along with the text you want to render. The first structure is PaylayStyle, which contains style information. The second is ParlayControl, which has some options for layout control. You’ll also create a structure, ParlayRGBARawImage, to receive the image buffer output.

If you build it with MiniXML, you could call parlay_markup_text instead.

Example


#include "parlay.h"

int parlay_hello(char* font_filename) {
    ParlayRGBARawImage image;
    ParlayStyle style;
    ParlayControl ctl;

    /* "Hello, world" isn't really long enough to show paragraph layout so we
    use a slightly longer message */

    const char* message = "Hello, my name is Inigo Montoya. You killed my father. Prepare to die.";

    /* Initialize Parlay */

    if (parlay_init() != 0) {
        /* error if parlay_init() returns nonzero */
        return -1;
    }

    /* Register the given font with the name "hello" */
    /* Arguments 3, 4, and 5 to parlay_register_font allow one to
    specify filenames for the italic, bold, and bold-italic
    styles, but to keep the example simple we'll not bother. */

    if (parlay_register_font("hello",font_filename,NULL,NULL,NULL) != 0) {
        /* error if parlay_register_font() returns nonzero */
        return -1;
    }

    /* Set up the style structure */

    style.font_name = "hello";  /* same name we registered the font as */
    style.font_size = 20;       /* size is roughly the number of pixels wide for lower-case m */
    style.font_scaler = 1.0;    /* a convenience to allow common scaling of fonts; just set to 1 */
    style.font_style = PARLAY_STYLE_NORMAL;  /* don't use bold or italic */
    style.text_color[0] = 0.0;  /* red component of text color, in range from 0 to 1 */
    style.text_color[1] = 0.0;  /* green component of text color */
    style.text_color[2] = 0.0;  /* blue component of text color */
    style.text_color[3] = 1.0;  /* alpha component of text color, 1 = fully opaque */
    style.border_thickness = 0; /* no border around the glyphs */
    style.highlight = 0;        /* no highlighting */

    /* Set up the control structure */

    ctl.width = 300;            /* number of pixels wide to wrap the paragraph--use 0 for no wrapping */
    ctl.text_alignment = PARLAY_ALIGN_CENTER; /* paragraph alignment */
    ctl.collapse_whitespace = 0; /* don't collapse whitespace--this option is mainly for markup */
    ctl.cropping_strategy = PARLAY_CROP_FAILSAFE; /* retain all rendered pixels */

    /* It's unnecessary but good practice to clear the image structure when not in use */

    image.data = NULL;    /* will be set to point at the malloc'ed image buffer */
    image.width = 0;      /* will be set to the width of the image buffer */
    image.height = 0;     /* will be set to the height of the image buffer */
    image.x0 = 0;         /* will be set to the recommended x-location to draw the buffer */
    image.y0 = 0;         /* will be set to the recommended y-location to draw the buffer */

    /* Now call parlay_plain_text */

    if (parlay_plain_text(message,&style,&ctl,&image) != 0) {
        /* error if parlay_register_font() returns nonzero */
        /* notice a pattern? */
        return -1;
    }

    /* The ParlayRGBARawImage structure has been filled with the image data */
    /* For this example just print out the width and height of it */
    /* A better example would show how the image buffer is used somehow */

    printf("parlay_plain_text produced an image of size %d x %d\n",image.width,image.height);

    /* We're done with image, free the image data. */

    parlay_free_image_data(&image);

    return 0;
}

What To Do With Your Shiny New Image Buffer

I mean, it’s kind of out of the scope of this README, but for those skimming this file wondering, “Can Parlay do this?”, here are some examples of fun and cool things you can do with the image buffer output of Parlay.

  • You can use it to create OpenGL textures by passing it to glTexImage2D. (I assume you can do something similar with Direct X but I’ve never used it.)
  • You can use an image format library, such as libpng or libjpeg, to save the buffer in a standard image format.
  • You can use the image buffer to initialize a Pixmap object of some sort from a GUI Framework such as Qt or GTK, though if we’re being fair, in most cases you’d just want to use the text capabilities built into the GUI Framework for that.
  • You can do image operations (like compose, overlay, convolve, etc.) with other in-memory image buffers.
  • You can load a cute picture of a kitten or a blobfish from the Internet into memory, and then use Parlay to add a funny or sarcastic caption to it, save that combined image to a file, and upload it to a social media website such as Twitter or Linkedin.

Some of these might need a little manipulation of the image data. The data format of the buffer is the obvious one. Each pixel is four unsigned chars, in order RGBA. Each row is an array of pixels from left to right. The whole image is a an array of rows from top to bottom. Width and height are returned in the image structure.

History

I wrote Parlay for a game I was working on, The Ditty of Carmeana.

Early on in development, I realized my crude way of rendering individual letters from an alphabet texture didn’t scale up well, and looked terrible. (Even by Ditty of Carmeana standards, which, if you decide to look into the game, you will see are very very, low.) I decided my next step was to use real font rendering, and because I’m a modern, savvy programmer who mindlessly heeds the woke advice to reuse code and not reinvent the wheel, I went looking for a freeware library that could do this for me.

Perhaps I didn’t search the Internet well enough, but I could not find a library that could simply lay out a paragraph of text into a memory buffer. The only applicable library I found was Pango. Pango could do what I wanted, it just could not do what I wanted simply.

The less I say about Pango the better. (Put it this way: the two things in the world I hate most are Pango and Adolf Hitler… in that order.) I will only mention that the last straw was when it turned out to have a complete inability to specify a application font. All font selection had to go through Font-Config, which manages system fonts, and this was so baked into Pango it was like altering a law of nature to get it to use an app font.

So I reinvented the wheel.

That’s what this is. When The Ditty of Carmeana was Greenlit on Steam (so this is a while back), I decided it was worth my while to write my own paragraph layout engine, that could do what I needed it to do, lay out paragraphs to an in-memory image… simply.

I am a mental powerhouse when I’m dreaming

Last night I had a dream, and I don’t remember why but at some point in the dream I uttered the word “mathish”.

In the dream, it occurred to me that the English suffix “-ish” might be descended from the same root as the Greek suffix “-ικος” (aka, “-ic”, a suffix which we borrowed into English and use extensively). In the dream I recalled a linguistic rule that causes k sounds to turn into sh (softening: a k or g sound followed by a vowel where the tounge is forward in the mouth often ends up turning into an s, z, sh, or th). I recalled that in our word mathematician, the “ic” is pronounced “ish”, so this process still happens today. And, still in the dream, I wondered if Latin had a similar suffix, and recalled the word amicus (“friend”).

When I woke up I looked up the origins of those suffixes and sure enough I was right.

My only mistake was, there was a minor wrinkle I didn’t anticipate: “-ish” actually descends from a composition of two suffixes, but one of them was indeed the same one that became “-ic” in Greek.

Python 3

Yeah, I spent an entire Saturday upgrading this blog to use Python 3. What a great use of my time…. This includes about 5 hours I spent switching the site to use FastCGI as the entry point instead of Passenger, only to switch it right back to Passenger. (Kind of glad I did, actually, as the FastCGI required a delicately tuned set of mod_rewrite rules. However, it can cause an annoying delay when first loading my page because Passenger has to spawn a new interpreter to use Python 3, and to make matters worse my hosting provider kills the interpreter after only a few minutes.)

Anyway, there’s (kind of) a reason for it. I have a separate need to host a different web application, which would have required me to set up a new Python environment, so I figured I might as well take care of the blog while I was at it. (I’ll cover the new app in a later post for my Faithful Readers.)

Another good thing: I diagnosed an issue where every page load was sending upwards of 50 queries to the MySQL database. Now it sends only a few. That usually makes it faster even if it has to spawn a new Python 3.

Diet Rules

Some people who know me may realize that I have an odd diet concerning sugary foods. Basically, for 2/3 of the year I don’t eat most sugary foods; for the other third I do. The point of this diet is not to give up sugar, but to eat less of it.

This has worked well for me. I generally stick to it, and as a result I think I’ve at least halved my sugar consumption. I regard it a permanent part of my life, and have no plans to ever go off it. In this blog post I will shares the intricate details of this diet.


The main rule of the diet is that, for the most part, I can only eat sugary foods in the following months. (These are called the Allowed Months):

  • March
  • June
  • September
  • December

I don’t officially limit my sugar consumption in any way during Allowed Months. Unofficially I don’t really drink sugary beverages any more. (Maybe the odd milkshake, or a craft soda once in awhile. I almost never drink juice.)


All other months (which I call the Limited Months), my consumption of sugary foods is limited. In general, I think of these as sugar-free months, but they’re really not. As I said, this is not to prohibit sugary foods but to reduce. In practice, I allow myself certain exceptions.

Here are the exceptions I allow myself during all Limited Months:

  • I can eat fruit that isn’t too sweet. For me that means mostly apples and bananas, but canteloupe and watermelon I sometimes eat too. Maybe even grapes. This applies to fresh fruit only. Not juice, dried fruit, or anything like that.
  • I can add honey or jelly to a peanut butter sandwich.
  • If someone offers me something sweet, I can take one piece. So, for instance, if someone sticks a plastic bowl full of cookies in my face, I’m allowed to take one. But it has to be a deliberate, active offer from someone. If there’s just a bowl of cookies or candy sitting there, I can’t take one. If someone just mentions, “Hey there’s cake”, I can’t take a slice of cake. But if they said, “Hey Carl, I made a cake, why don’t you have a piece”, then I can.
  • I can eat Girl Scout Cookies with impunity, but only if I bought them myself from an actual Girl Scout. (So no second hand cookies, and no buying them from her mother, or from a box at work.)
  • I can take a single breath mint from a bowl after eating dinner at a restaurant.
  • Cough drops with sugar are ok. (Though I prefer sugar-free in any case; the sugary ones make my teeth sticky, moreso than candy. Sometimes sugar-free cough drops are not easy to find, though.)
  • I have a rule that I can add about a tablespoon of honey or syrup to yogurt, which I did a lot when I first started this diet, but I don’t eat as much yogurt as I used to.

In addition to these permanent rules, I usually also give myself a monthly exception. The monthly exception is usually a broad category: “ice cream”, “maple syrup” (unlocking pancakes), “12 ounce bottles of craft soda”, or something like that. Sometimes, if I feel like I didn’t do well during the previous month I won’t give myself this exception, but most months I do.

Here’s the thing about the monthly exceptions: I won’t simply shift all the sugar consumption to that one item. What I try to do is consume the exception at the same rate as I would during an Allowed month, and drop all other sugary foods. (At least that’s the theory; I’m sure I end up at the upper range most months.)

And finally, I waive the limits for sugary foods on major holidays.


In spite of the numerous exceptions, I have not stuck to this diet perfectly. I have eaten sugary foods for comfort here and there. I’ve waived the diet in certain situations (like when travelling). I used to not bother at all when I visited the family, since they always used to leave all kinds of chocolate and candy laying around the house, and at that point it’s hopeless. (Though they don’t leave chocolate out so much any more, no idea why.)

However, by and large this has been successful. At least for me, the exceptions give me a bit of an outlet and allow me to be strong in the face of temptation most of the time. It’s a lot easier to give up something when you know you’ll be able to take it up again soon.


I’ve been doing this in some form since 2011, about eight years now.

When I first started, I was like a statue of stone. I gave up the sweet foods absolutely during Limited Months, did not cheat at all, and gave myself fewer and narrower exceptions. Then, when Allowed Months came, I went crazy. I’d eat as much sugary food as I could, knowing that soon it would be a Limited Month again. I ended up eating more sugary foods than I otherwise would have during Allowed months (although it was certainly still less overall when you averaged it woth the Limited Months).

But as time went on, a very interesting thing has happened. I started adding new exceptions, and also ended up cheating more. But during Allowed Months, I got less and less crazy. Temptation had a smaller and smaller effect on me over time.

Now, I hardly eat more sugar during the Allowed months than I eat during Limited Months, and I eat a lot less sugar in any month. About the only difference now is that I might buy a candy bar while visiting a convenience store during a Allowed month, but won’t during a Limited month.

Basically, by sticking to this diet, I gradually learned to moderate.


I have a few tradtions associated with this diet. The first sweet I eat on an Allowed Month is always a King Size Kit-Kat. The last sweet I like to eat before I go back to Limited Months is an ice cream sandwich from Diddy Riese, but I don’t do that all the time (especially since I moved away from the Westside). And on holidays I usually limit myself to thematically appropriate sweets, so for Halloween I’ll only eat candy, for Thanksgiving, only pie.

Frontier Theme