155 comments

[ 2.6 ms ] story [ 225 ms ] thread
I've spent HOURS playing with fonts for use within VS Code and Windows Terminal. It is a lot of fun, and it really does help readability ... for me at least ;)
Monospaced takes people back to a simpler time, when you would get cheats or walkthroughs printouts. I love how clean the look is with each character having its own distinct spacing
I am a little bit disappointed that my favourite monospace font, Iosevka, wasn't listed.
I also use it but just can't keep up with the pace of development. Like, every two days there's a new update it feels like
all blurry fuzzy fonts... I'm a bit sad to not seeing any sharp, crisp, bitmap font here.
I love Proggy in this regard [1]. It's so hard to go back to an aliased font after using Proggy for a while. Also it's easier to see the structure of your code with smaller fonts, because you can simply see more of it at once.

[1] http://www.proggyfonts.net/index.php?menu=download

What do you mean by "aliased font"? I like the design of Proggy but all the proposed sizes are tiny. I need much larger font sizes, at least three times the size of the largest Proggy.
A free, simple one I like: https://www.marksimonson.com/fonts/view/anonymous-pro (also available from Google and Adobe).

I have long hesitated to pay for fonts for personal, non commercial use. However a well designed font really can make a difference in the usability of a computer. I'm checking these out, I'm at the point where I would be willing to spend some serious cash for a font. Although to me, "serious cash" for a personal use item would be around $25, some of these cost upwards of $100.

Part of my hesitation is a lack of understanding how to analyze fonts and my preference. I've done some reading on typography and design, but any time I install a new font, the depth of my emotion goes as far as "this is nice" or "I liked the previous font more, I guess".

Although some say their trial fonts used for non-commercial works. most foundries doesn’t actually have a seperate license for NC usage. For instance Input have a free (as in free beer) non-commercial license but you have to pay for it if you want to use it in commercial stuff.

(btw, font licensing in general is a mess)

Interesting, but it made me wonder - are there any programming languages that you can use with a proportional font? Python would not be on the list...
Technically, you can use any language, including Python. Python cares about the number of whitespace characters, not the sizing of them. Any other languages will have the same issue of your columns / pretty formatting not lining up exactly, but won't cause any issues.

If I had to pick one to use with a proportional font, I guess it would be Perl. The aesthetics would at least fit it well.

Smalltalk is traditionally done in a proportional font. Short methods, and an editor that only does one method at a time, help that work out.
I’ve used Input Sans[1] with Python in the past and it works pretty well except if you use white space for formatting or ascii art as opposed to just indenting.

It works because the spaces are nice and wide unlike in a typical proportional font.

I don’t use it anymore mostly because I wanted something with a little more character but it’s worth a try.

[1]: https://djr.com/input/

I'd love for all IDEs to support notebook style computing where comment blocks just turn into proportional font prose, perhaps with optional markdown rich text. Tables, lists, etc. look way better as proper HTML instead of ASCII art intermingled with code.
> comment blocks just turn into proportional font

that would be horrific! Don't you ever use comments to pin-point to specific parts of a source line?

I read and write all my Python code (and all my code in every language) in a proportional font.

You may be thinking of Python's "significant whitespace". But all that does is indicate nested blocks.

This works exactly the same in a proportional or monospaced font. The only thing Python cares about is how many spaces or tabs you have at the beginning of a line, and that you don't mix the two.

There are coding styles that don't look as good in a proportional font, such as this kind of "column alignment" or "hanging indent":

  def function_with_a_long_name(first_param_with_a_long_name,
                                second_param_with_a_long_name,
                                third_param_with_a_long_name):
      pass
But you don't have to code like that!

The most popular Python code formatter, Black, only uses indentation and no column alignment. Here is how it formats that code:

  def function_with_a_long_name(
      first_param_with_a_long_name,
      second_param_with_a_long_name,
      third_param_with_a_long_name,
  ):
      pass
This indentation-based coding style is just as easy to read and write in a proportional font as it is in monospaced.

https://black.readthedocs.io/en/stable/

The latter is a better style anyway. It takes more lines, but it doesn't require realignment when renaming. Not to mention that getting the variable indent alignment can require fighting the editor. One common feature is to delete spaces back to the previous tab stop. When not aligning things, that feature is handy and exactly what I want the editor to do. But for realignment, it's a big pain. Removing a single leading space might require hitting delete and then pressing space 3 times. You might even need to do that when adding spaces because it's easy too overshoot by a single character and have to move backwards to correct it.
have been enjoying using Cascadia Code
Same, absolutely love it.
I kept recoiling from how bad "windowWidthResize" looked in the first few fonts.
After trying a lot of fonts for hours and hours, I ended up with Fantasque Sans Mono: https://github.com/belluzj/fantasque-sans

It's somewhat similar to Comic Sans, like the Comic Code from the article, but less playful. It's the most readable programming font I have ever had, with many other typefaces I often see text a little blurry.

FSM surprised me too, especially how readable it ended up being even at smaller sizes. I've stuck with it for quite a while over lots of other good choices.
Oh wow, they really cleaned that one up since I last tried it ages ago! (some of the characters used to be so wonky I just couldn't get over it) Looks really nice now

Looks like "comic sans-inspired" is a genre. We also have Comic Shans, for example:

https://github.com/shannpersand/comic-shanns

I just can't get used to the playful fonts like that. My most recent attempt was with Cascadia Code, but that wobbly Comic Sans feel looks off to me and prevents the font from falling away into the background when reading. I also don't like how different many of those fonts make the italics look. It makes them almost feel like a completely different font and turns them into a distraction.
I've been told that these fonts are actually doing italics "right", as in that originally meant having a "handwritten" look, not just being slanted.

But a quick internet search doesn't produce any obvious result proving or disproving that statement. Maybe someone here knows?

Italic script is one of the basic calligraphic hands; the fact that it's cursive (joined) and oblique (slanted) are key to its identity. But I would imagine it evolved into type the same way that other script styles did, so to say that italic type "should" look like handwriting seems questionable.
No love for Droid Sans Mono? It is the perfect programming font for me (well, the slashed zero variant).
My favorite coding font is actually a proportional coding font: Input Sans.

I love the legibility and the nod to the fact that I am not a computer. I dream of a world where computer code is formatted for humans, not punch card readers.

https://input.djr.com

Input Sans is a great proportional coding font. My personal favorite at the moment is Trebuchet++, my customized version of Trebuchet MS. (I wish I could distribute it; now I will have to find a way to do that.)

The Input Manifesto (that's what I'll call it) has a nice explanation of how proportional fonts are beneficial for code:

https://input.djr.com/info/

How do you line up your equal signs? e.g.

    def mouseMoved(self, info):
        point = info["point"]
        text  = u"%.0f %.0f" % (point.x, point.y)
        self.set(text)
You don't have to.
> You don't have to.

I do. I like being able to visually spot oddness in statements, and having a sequence of assignments, comparisons, etc lined up makes it easy to spot the lines that do something different.

I find you don’t need to. maybe tabs would work w the right editor.
Is this the best case that can be made for using a monospace font for coding? I can do without lining up the equal signs. I may look into switching to a proportional font.
Sibling comments have pointed out that you just don't need to line things up that way. Here is how your code looks without the alignment:

    def mouseMoved(self, info):
        point = info["point"]
        text = u"%.0f %.0f" % (point.x, point.y)
        self.set(text)
Is that any less readable?

Urgent request! We need two new variables for some debugging: distance and relative_velocity. Going back to the vertically aligned format, we will add them like this:

    def mouseMoved(self, info):
        point             = info["point"]
        text              = u"%.0f %.0f" % (point.x, point.y)
        distance          = self.calculate_distance(info)
        relative_velocity = self.calculate_velocity(distance, info)
        log_move(point, text, distance, relative_velocity)
        self.set(text)
We had to add whitespace to the previous assignments to match the new ones. Now, with all that horizontal whitespace, my eyes have trouble tracking what is assigned to what. And the version control history will have unnecessary formatting diffs.

If you forgo the column alignment, those problems go away:

    def mouseMoved(self, info):
        point = info["point"]
        text = u"%.0f %.0f" % (point.x, point.y)
        distance = self.calculate_distance(info)
        relative_velocity = self.calculate_velocity(distance, info)
        log_move(point, text, distance, relative_velocity)
        self.set(text)
> Now, with all that horizontal whitespace, my eyes have trouble tracking what is assigned to what

If it's not aligned I have trouble identifying exactly what I need because it's so chaotic. When everything's aligned it's a bit like a table and my brain immediately knows where the right-hand side is no matter which line I want to read.

Now I don't do that everywhere, often it just doesn't bring any benefit. But generally I often find it helpful and it's one of the quickest ways I can make some code blocks more readable, as it takes just a few keypresses.

It looks chaotic because everything is packed together. If you let that code breathe a bit it looks like this:

    def mouseMoved(self, info):
        point = info["point"]
        text = u"%.0f %.0f" % (point.x, point.y)
    
        distance = self.calculate_distance(info)
        relative_velocity = self.calculate_velocity(distance, info)
    
        log_move(point, text, distance, relative_velocity)
    
        # Update overlay label
        self.set(text)
I find that a much more readable style. Instead of stuff on the left - assigned to stuff on the right, its now a story made up of steps: First we're figuring getting some variables for text labels, and distances. Then logging that out. Then after that we're updating the label on the overlay. Each step in the story has a little breath (the newline). And if needed, a comment.

Here's a random work-in-progress example from some real code I'm working on this week. Its not beautiful or overly fancy. Just steady, confident and readable (assuming you know the context):

https://github.com/josephg/diamond-types/blob/2e807298a70382...

When the equal signs aren't aligned I first have to search where the symbol is on a given line to identify the left and right side. When the assignments are aligned it's obvious at a glance.

I guess it's different between people, I personally find it noticeably slower and more difficult to read like that. Blank lines inbetween don't help because it's about horizontal alignment.

I hear what you’re saying, but the horizontal alignment implies each line is doing a similar thing. That’s not the case here. Eg, the first line creates the ‘info’ variable and later lines use that to calculate derived variables. So order matters.

Both approaches emphasise different narratives about the code. The aligned block style emphasises the similarity between the assignments. My space-between-lines style emphasises the difference between each block of code, as if each block is a paragraph it’s own separate intent.

If the assignments were actually similar, I would find the other approach more compelling. Some sibling comments have given better examples where this makes sense. But for this code in particular, the assignments are more different than similar (in both goal and subject). I’d use spacing to make that difference obvious.

Hmmm. What if the editor was clever enough to do that, with any font, automatically.
I always line up columns like the example above. I think it is a distortion from my background in typesetting and graphic design, but the readability improves greatly… for me at least!

  const style = {
      x               : 3,
      y               : 2,
      width           : 0,
      height          : 0,
      backgroundColor : 'white',
      color           : 'black',
      fontWeight      : 'normal',
      shadowStyle     : 'none',
      borderStyle     : 'round'
      paddingX        : 2,
      paddingY        : 1,
  }
Thanks for posting that example. It helped clarify why I dislike that style so much.

Please don't take offense! What works for me doesn't have to be what works for you, OK? :-)

But the insight - if I dare call it that - is that one style leads me to read across each line, where the other style leads me to read down the columns.

In your example, my eyes see an x, a y, a width, a height, a backgroundColor, a color, and so on. And then I see a 3, a 2, a 0, another 0, a 'white', a 'black', etc.

As you can tell, I am reading down the first column, and then reading down the second column. And by then I'm losing track of which thing goes with which.

It's not that I mean to do that, it's just how my eyes are drawn when I see something arranged in columns.

If we reformat this without the column alignment, it looks like this:

  const style = {
      x: 3,
      y: 2,
      width: 0,
      height: 0,
      backgroundColor: 'white',
      color: 'black',
      fontWeight: 'normal',
      shadowStyle: 'none',
      borderStyle: 'round'
      paddingX: 2,
      paddingY: 1,
  }
It's definitely not as nice looking this way! But now I read it completely differently:

We have an x of 3, a y of 2, a width of 0, a height of 0, a backgroundColor of 'white', a color of 'black', etc.

This style leads me to read across each line instead of down each column. I think that may be why it is easier for me to understand.

And to repeat myself, I am truly grateful to you for posting this example. It helped me get some understanding of what goes on in my eyes and brain.

You are very cautious with me in not taking any offense; thank you (I won’t)! For me the aligning and the subsequent empty space which is created between the two columns allows very fast skimming in the values of -both- columns. I don’t have any isse in tracking horizontally. Any spreadsheet uses the same technique (aided by the cell lines).

I use this style also in expressions: often when coding graphics you have similar operations or variables and ordering it in “column fashion” allows quick skimming and error spotting.

Another (real) example:

  const neighbors =
      get(x - 1, y - 1, w, h, prev) +
      get(x,     y - 1, w, h, prev) +
      get(x + 1, y - 1, w, h, prev) +
      get(x - 1, y,     w, h, prev) +
      get(x + 1, y,     w, h, prev) +
      get(x - 1, y + 1, w, h, prev) +
      get(x,     y + 1, w, h, prev) +
      get(x + 1, y + 1, w, h, prev)
Yes, that is a great example of something that falls flat in a proportional font or without using column alignment.

My only suggestion is to be more generous with whitespace inside the parentheses:

  const neighbors =
      get( x - 1, y - 1, w, h, prev ) +
      get( x,     y - 1, w, h, prev ) +
      get( x + 1, y - 1, w, h, prev ) +
      get( x - 1, y,     w, h, prev ) +
      get( x + 1, y,     w, h, prev ) +
      get( x - 1, y + 1, w, h, prev ) +
      get( x,     y + 1, w, h, prev ) +
      get( x + 1, y + 1, w, h, prev )
I don't quite understand why, but most modern coding styles prohibit ever putting a space inside the parens. I think the common philosophy is to follow the same conventions you would when writing English prose. But we're not writing prose, we're writing code! To me it is more readable if we allow a little breathing room inside the parens.
I adopted this style for a while (I mostly code individual and personal projects so I’m not obliged to follow style-guides) but reverted back…

This looks better in monochrome text but usually the editor colors allow a fast distinction of the parentheses, variables and literals so the extra space is not needed for me.

As a digression, this is exactly the same issue that I have with autoformatters. For example, clang-format under default settings turns your example into:

    const neighbors = get(x - 1, y - 1, w, h, prev) + get(x, y - 1, w, h, prev) +
                      get(x + 1, y - 1, w, h, prev) + get(x - 1, y, w, h, prev) +
                      get(x + 1, y, w, h, prev) + get(x - 1, y + 1, w, h, prev) +
                      get(x, y + 1, w, h, prev) + get(x + 1, y + 1, w, h, prev)
In the past, I've resorted to things like adding no-op `+ 0` for alignment and empty comments to force it to preserve line breaks while still allowing it to autoformat the rest:

    const neighbors = get(x - 1, y - 1, w, h, prev) + //
                      get(x + 0, y - 1, w, h, prev) + //
                      get(x + 1, y - 1, w, h, prev) + //
                      get(x - 1, y + 0, w, h, prev) + //
                      get(x + 1, y + 0, w, h, prev) + //
                      get(x - 1, y + 1, w, h, prev) + //
                      get(x + 0, y + 1, w, h, prev) + //
                      get(x + 1, y + 1, w, h, prev)
I really wish that autoformatters had the smarts to understand that if more than X% of the non-whitespace columns within a block repeat the same character from top to bottom, then the lines are probably intentionally aligned that way and that it should try very hard to preserve that alignment. That would eliminate my one real objection to autoformatters. (Bonus points for detecting parallel structure in the code and exposing it through alignment in the first place, but that's a much harder generalization of the problem. I'd settle for just leaving that to me and then not destroying it.)
Wow, that was actually an insightful and respectful comment, that made me appreciate both sides of the argument.

Bonus internet points for you today sir.

> How do you line up your equal signs?

I don't, and if I tried to, the code formatter would get rid of it anyway.

I've been using Input Sans Condensed for years. I thought I'd hate proportional fonts for coding until I tried it.

Given that code formatting is enforced by automated tool, I'm not allowed to use whitespace to align things because the tool decides how stuff should be indented, etc.

The only time I've needed to do any alignment is in comments trying to do some ASCII diagram or something, then I just use the column number to line it up for everyone else.

Monospace fonts now feel... Huge. So much wasted space.

I love IBM Plex Mono and try to use it on all of my machines
Seconded, I even use the Sans version for my system font and the Serif version for letters
Surprised that there was no mention of Fantasque Sans Mono, one of my favourites and full of character especially on Windows.

For MacOS I've yet to find anything that comes close to Andale Mono.

Having spent hours looking for the 'perfect' coding font, I've noticed a lot of them only look good under Windows on a HiDPI screen. My main monitor is 'only' a large QHD screen, that I run at 100% scaling, and most of the really nice coding fonts render really badly at typical sizes (12px-16px).

It feels overkill to get a 4K monitor and scale at 200% just to get nice looking fonts :/

Try IBM Plex, it looks great on my HiDPI screen
Back to Consolas.
I really like Consolas. It looks nice and it has neat italics, which I usually use for comments.
I currently use Mac (200% scale) and Linux (FHD, 13", 100%) at home, and 24" FHD (100%) at work, and tbh I don't notice any problem with my font (Iosevka). Idk about other though.
I originally built Luculent [1] on a non-HiDPI screen, optimized it for that size range, and fully hand-hinted it to get it to look super crisp on Windows and Linux. This sort of thing is always a matter of taste, but it might be worth a try.

[1] http://eastfarthing.com/luculent/

I continue to use Lucida Console for that reason.
A pet peeve, thinking of web fonts, is that every license I’ve ever read makes you commit to not distribute the font at all in a way that an end user could get access to the font file. Which is impossible for a web font. It’s just litigious and ignorant

Other requirements are sort of nasty too. MyFonts requires you to embed tracking code into your website to prove you don’t go over your view count

I never understand why so many font studios do this. I don't mind paying a fair price for a good font that a professional has designed, for the same reason I don't mind paying for a good book. But the terms for using it have to be sensible. They are now competing with some high quality fonts that are also comprehensive and professionally designed but free to use with few restrictions, so the licence needs to be simple with no sense of danger or I will walk away immediately. Some of these font developers seem to think they are the reincarnation of Elvis or something with the level of hassle they think people will go through to pay them money!
MyFonts is owned by Monotype, the big gargantuan soulless mega corp that is still profiting off typefaces designed by people that have been dead for over a century.

But if you look at independent font developers (who are just folks like you and me), most are perfectly reasonable in pricing and license constraints, and are happy to answer questions or even change the terms and conditions if this makes it easier for you to spend the $30 - $100. I don't think any of these are trying to be litigious, and they're certainly not ignorant.

(Though I understand that your misunderstanding of the web font licensing might make it look so!)

I'm still waiting for the day something trumps Source Code Pro for me...
(comment deleted)
Yep any time I install a new editor the first thing I do is switch it to Source Code Pro. Maybe a bit boring compared to those on Doug's list but I love it nonetheless.
I'm missing the ancient IBM 3270*, which has strangely achieved a permanent status as my go-to font for (personal) monospaced.

* the modern, open source revival → https://github.com/rbanffy/3270font

Personally, i really enjoy using the Liberation fonts for both regular writing and software development:

  - Liberation Sans - metrically compatible with Arial
  - Liberation Serif - metrically compatible with Times New Roman
  - Liberation Mono - metrically compatible with Courier New
You can read more about them here: https://en.wikipedia.org/wiki/Liberation_fonts

In my experience, Liberation Mono has really good information density while being easy on the eyes and also really readable. In addition, it seems to have pretty good unicode symbol support as well. Also, it remains readable at smaller font sizes as well, which comes in handy if you're working on an enterprise Java code and don't have a really big monitor.

Overall, i'm glad that the font family exists, because it provides a good alternative to having to install MS fonts on *nix systems, which can be annoying at times, plus the fonts are actually included with LibreOffice, which i use nowadays.

The Wikipedia page has a bit more information about the related fonts, but if you'd like to preview something that's a lot like Liberation Mono in the form of a webfont, have a look at Google Cousine: https://fonts.google.com/specimen/Cousine

Someone in my team writes all his C and Lua code in Comic Sans Mono. That's all I'm going to say.
My favourite set of fonts is definitely IBM Plex. The mono font is super clean, very pretty, easy on the eyes, and no characters look alike (Il1, for example, is actually readable). All other types, like sans and serif are amazing, too. The IBM Plex website sucks, but damn is it a pretty font.
I've tried various other fonts to spice things up a bit from JetBrains Mono (https://www.jetbrains.com/lp/mono/), but everything else just pales in comparison for both terminal and text editor usage. Highly recommended!
I switched to JetBrains Mono a year or so ago. It's so nice sometimes I even zoom in on my terminal just so I can appreciate it.

I'm totally sold on ligatures too.

Since everyone is posting their suggestions, a couple of years ago I settled on the open-source Monoid font with ligatures. https://larsenwork.com/monoid/

I find it that it's very easy to get used to ligatures, and I find them strangely satisfying to look at. They're code-specific replacement characters that combine your == into a single long double bar, or -> and => into a neat little arrow character, and so on (link above for more examples). Monoid also has some useful readability tweaks, like bringing together the // or .. character pairs, which are common in many languages. If you're looking to add some quirk and (arguably) readability to your coding, this could be your thing!

I've created a page to test monospace fonts in browser: https://alexey-milovidov.github.io/font-selector/

This is intended mostly for my own use case: desktop workstation, light theme, C++ development environment. Though dark theme is also included.

Many caveats exist, there is "About" with disclaimers.

Slight rant about a mistake I see every times this is mentioned:

> a user needs to easily differentiate between 1, I, |, and l along with 0 and O.

Most of the times, a font present those characters side by side, to show their differences and to illustrate the fact that they can be easily differentiated.

But what we need is not differentiate between them, but identify precisely every single one of them when presented without the other as a comparison point.

Almost every font presented in the article makes that mistake: for example, 0 is almost always the exact same shape and size compared to O, except for a dot or a slash across the 0. This allows you to recognize a 0 at first glance, but not a O. The same issue is also present in a lot of the presented fonts with l that can be mistaken for a 1.

This is one of the things I appreciate about using a proportional font for coding. Nothing stops you from having a big fat O and a little skinny 0, just like you see right here in your comment and mine with HN's Verdana font. You don't have to have every character stuffed into the same fixed size box.
I can't imagine trying to code without being able to align characters on different rows...
Show me an example where you need to do that, and maybe I can suggest an alternative.

Or I will say "yup, you got me there!" ;-)

Almost all my code is heavily aligned, and I rely on monospace.

I’m pretty anal about that kind of thing. My cloc score is generally about 50% comment-to-code.

But I’m an outlier. Most folks have almost no comments at all in their code.

I guess I could use tabs, instead of spaces, but I’m not interested in doing that.

(comment deleted)
I find it interesting how controversial the code comments situation has become.

When I started in this industry, comments were extremely rare and people were consistently pushing to add comments everywhere. Some time later, the pushback came and people started saying that code shouldn't need comments, and if you feel the need to add one... You should rewrite it instead so the code is self explanatory.

Neither side seems to have stopped repeating their points though and there is always a chance to trigger opinionated people into endless discussions just by mentioning comments

One big thing that has changed in regard to comments is that variables and functions can have longer names now. In most modern languages it is considered bad practice to have single letter variables, or even abbreviated ones, except in very well known cases.

So the rule of thumb for languages like python or ruby is that if you need comments to understand what your code is doing, then you messed up somewhere. Make it easier to read, keep your functions small, and add docstrings. Save your comments for why you're doing something.

But if you're using a less readable language like c, then by all means, comment everything along the way.

I just read a comment I wrote a few years ago that said "I don't know why I have to do it the long way, but it's the only thing that works consistently" over a bit of seemingly verbose code that I would have tried to simplify if I didn't remind myself of that previous struggle.

In the previous century I worked at a company that offered a SQL database, and the mandatory coding standard included:

- Maximum of six characters for any function name. Three characters for the category and three for the actual function. Imagine a code base where every function has a name like strcmp, strlen, etc. So you might have a name like sqlijn for an inner join.

- 80 column line limit, with the first 40 columns reserved for code, and the second 40 columns for a comment. A comment was required on every line of code. So yes indeed, you might see this classic:

         ++i;                             /* increment i */
I was hired to build a Windows GUI for the database, and I explained that Windows API functions had much longer names and I was going to run out of room to do much in 40 columns. Thankfully, they gave me special dispensation to follow Windows conventions in the Windows code.
My function/method/property/variable names can be quite long.

Most of my documentation is headerdoc-style stuff, at the opening of methods, or above properties.

I generally don't have much inside methods, unless I think the code is a bit obtuse, and needs a hand.

Then, it's more important for me to document "why," as opposed to "what."

The trouble with comments is that good taste as well as intelligence is required of the comment author. If you cast your mind over your colleagues you see the problem.
When you hardcode a lookup table to be able to align data is very useful (and also esthetically pleasant), at least from my point of view. I would not leave my monospace font
Printing a table to the console or log file. A very simple example from just this weekend for me is that I wanted to see how C++ was laying out an object in memory. I assigned the pointers to one and two character variables. When I printed out the variable name followed by the address, I actually had to go back and add an extra space before the single character variable names so the addresses would align. That made it much easier to see the differences between the various pointers into the object.
Funny you mention log files with extra spaces. At my current job, I deal with an API called the RTO, and I wanted to log the requests to that API and the matching responses.

Of course the words "request" and "response" are not the same length. But I thought it would look nice to line things up for a request and its matching response, so I just added an extra space after "request:", like this:

  RTO request:  {...}
  RTO response: {...}
When testing locally in a terminal, this looked great. Everything lined up and was pretty.

What I didn't realize was that most people view these logs in New Relic, which does use a monospaced font but does not prevent collapsing of adjacent spaces. So the logs look like this:

  RTO request: {...}
  RTO response: {...}
Obviously not the end of the world! But it did happen that the first part of the {...} stuff should match between the request and the response, so it made it easier to understand (if it worked) to line them up.

I am tempted to change the messages to this, which I think will work around this problem:

  RTO request : {...}
  RTO response: {...}
Sometimes you can't win for losing!
> does use a monospaced font but does not prevent collapsing of adjacent spaces.

Whoever implemented this in "New Relic" did not think at all about preserving information, which seems critical in a log file.

It may be lost at display time. The default behavior of a browser is to collapse adjacent white space so something like

    <p>
        Hello
        <span>World</span>
doesn't render with a huge number of spaces.
You could also align the text with a leading space. But either that workaround or yours only works because the lengths are 1 apart.

I wonder why the creators of New Relic decided to let spaces collapse like that. I can't imagine ever wanting that feature in a monospace font.

    SELECT
        CAST(CASE WHEN DENY_ADMIN_FILTERS > 0       THEN 0 WHEN ALLOW_ADMIN_FILTERS > 0         THEN 1 END AS bit) CAN_ADMIN_FILTERS,
        CAST(CASE WHEN DENY_ADMIN_ACL > 0           THEN 0 WHEN ALLOW_ADMIN_ACL > 0             THEN 1 END AS bit) CAN_ADMIN_ACL,
        CAST(CASE WHEN DENY_ADMIN_RML > 0           THEN 0 WHEN ALLOW_ADMIN_RML > 0             THEN 1 END AS bit) CAN_ADMIN_RML,
        CAST(CASE WHEN DENY_ADMIN_WORKFLOW > 0      THEN 0 WHEN ALLOW_ADMIN_WORKFLOW > 0        THEN 1 END AS bit) CAN_ADMIN_WORKFLOW,
        CAST(CASE WHEN DENY_SET_STATE > 0           THEN 0 WHEN ALLOW_SET_STATE > 0             THEN 1 END AS bit) CAN_SET_STATE,
        CAST(CASE WHEN DENY_SHARE > 0               THEN 0 WHEN ALLOW_SHARE > 0                 THEN 1 END AS bit) CAN_SHARE,
        CAST(CASE WHEN DENY_LINK_PARENTS > 0        THEN 0 WHEN ALLOW_LINK_PARENTS > 0          THEN 1 END AS bit) CAN_LINK_PARENTS,
        CAST(CASE WHEN DENY_UNLINK_PARENTS > 0      THEN 0 WHEN ALLOW_UNLINK_PARENTS > 0        THEN 1 END AS bit) CAN_UNLINK_PARENTS,
        CAST(CASE WHEN DENY_LINK_CHILDREN > 0       THEN 0 WHEN ALLOW_LINK_CHILDREN > 0         THEN 1 END AS bit) CAN_LINK_CHILDREN,
        CAST(CASE WHEN DENY_UNLINK_CHILDREN > 0     THEN 0 WHEN ALLOW_UNLINK_CHILDREN > 0       THEN 1 END AS bit) CAN_UNLINK_CHILDREN,
        CAST(CASE WHEN DENY_WRITE > 0               THEN 0 WHEN ALLOW_WRITE > 0                 THEN 1 END AS bit) CAN_WRITE,
        CAST(CASE WHEN DENY_SEE > 0                 THEN 0 WHEN ALLOW_SEE > 0                   THEN 1 END AS bit) CAN_SEE,
        CAST(CASE WHEN DENY_READ > 0                THEN 0 WHEN ALLOW_READ > 0                  THEN 1 END AS bit) CAN_READ,
        CAST(CASE WHEN DENY_READ_END > 0            THEN 0 WHEN ALLOW_READ_END > 0              THEN 1 END AS bit) CAN_READ_END
    FROM
        private_data_iviews.SECURITY_PRECACHE_ACL_INCLUSIVE WITH (NOEXPAND)
    WHERE
        @acl_id IS NOT NULL
        AND @acl_id = ACL_ID
        AND @user_id = USER_ID
This seems like a good example of when not to arbitrarily align characters. Large horizontal gaps can very easily result in moving up or down a line and not realizing it.
How is that? Are you talking about word wrapping?

Also, what's the alternative here? Sure, I could indent everything and make it much more vertical, but that would make things even less readable.

Need? No. Prefer? Yes.

  foo(True,  True)
  foo(False, True)
  foo(False, False)
  foo(True,  False)
Add a few more parameters, put some arithmetic in there that isn't clearly an unrolled double for-loop. Maintaining repetitive code of that form is easier when the arguments are well aligned. And if you're using an editor with a block-select feature, then this changes from an aesthetic preference into a game-changer when you, say, add or remove an argument to foo.
There is an elegant solution:

https://nickgravgaard.com/elastic-tabstops/

While I do very much like that article, and I think it's a viable contender for The One True Way™...

They don't solve it. Those spaces to manually-align things are still potentially skewed because it's not fixed-space.

I don't have anything against proportional fonts for coding in, but the font has to actually be designed for coding, regardless of if it's proportional or monospace. That doesn't just mean having distinguishable 1/l/| and 0/O etc, it also means that the more obscure symbols/punctuation can't just be an afterthought and should compose nicely with regular characters and with each other: (foo) and [foo] and {foo} and <foo> should all look pleasant, things like += and <= and -> should not be misaligned, etc.
Do you have examples of where that doesn’t happen?
I found ubuntu mono to be one of the best in term of identifying those characters, with l and 1 being immediately identifiable, but O is only slightly larger than 0 so it can still be mistaken for a 0 if you are not careful (0 has a dot so it can not be mistaken with O).

I don't know of any monospace font where O can easily be identified as such and not mistaken with 0.

edit: see a sample here: https://fonts.google.com/specimen/Ubuntu+Mono?category=Monos...

Every character is easily identifiable by itself, except for O. I'm also curious if anyone has a monospace with better identifiably for O and 0.

I use andale mono it has a dot in the middle of zero. There are plenty of others that have dots and slashes. I wouldn't use a font that didn't.

https://en.wikipedia.org/wiki/Andalé_Mono

edit: I also use monaco which has slashes in zero

https://en.wikipedia.org/wiki/Monaco_(typeface)

The point is not that 0 must be easily identifiable, but also O: If you see a O without 0 as a comparison, can you identify it as such ?

In every monospaced font I know, there is a way to identify 0 (the dot or the slash), but not O which could be easily mistaken for a 0.

Wouldn't it be the one without the dot or the slash? it's honestly never been a problem for me. What has been a problem is the difference between an oval and a circle when zero is not marked.
Identifying 0 and O might be trivial for most of us, But it's a major problem for some.

One of the first problem posted on my problem validation platform was 'Identifying letter O from 0 and vice versa '[1], within couple of days a browser plugin to address the problem was developed by someone else and posted.

It's now my poster for a problem to push down the point that no problem is small.

[1] https://needgap.com/problems/12-identifying-letter-o-from-0-...