Hacker News new | past | comments | ask | show | jobs | submit login
Coding with Character (realdougwilson.com)
201 points by Eric_WVGG on July 28, 2021 | hide | past | favorite | 151 comments



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.


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


I don't bother trying to convince people to see things my way.

All I can say, is that I almost never get questions about my code.

I write about my approach here: https://littlegreenviper.com/miscellany/leaving-a-legacy/

It's a long screed, so no one reads it.


It was a good screed, not tedious! It made a lot of sense, thank you.


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.


    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.


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


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.


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.


There is an elegant solution:

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


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.


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-...


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.


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


Cousine is one of the ChromeOS core fonts, along with Arimo and Tinos, and I find them both preferable to Arial and Times New Roman respectively.

As for Cousine, it used to be my programming font of choice, but I prefer IBM Plex Mono these days.

https://fonts.google.com/specimen/Arimo

https://fonts.google.com/specimen/Tinos


Discussions like this remind me of the business card scene from American Psycho, where the executives' cards are all nearly identical, and the main character is practically hyperventilating with jealousy at the subtle "improvements" that are shown relative to his card.

I don't mean to begrudge anyone for their preferences. Personally, it just makes very little difference to me. I want a monospace font for coding. If it has the characters I need, which it almost certainly does, then I don't really care about anything else.


Having spent the price of a small car on an Apple laptop, albeit several years ago, I have no qualms in extracting SF Mono from that system and using it on my Linux desktops.

If for some reason Apple take umbrage — I can’t think why they would, it isn’t like they haven’t gotten all they could out of me — I would be happy to give them back their laptop.

Sent from my iPhone.


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


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 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!


I've been spending a lot of time looking at typefaces and usually feeling like I wasted it. Oddly many of the typefaces with roman letters I like the best are from fonts like Adobe's Arabic font for which roman letters aren't the main focus. (e.g. I have yet to see a Chinese font that has great roman letters but I think Arabic and Cherokee writers really appreciate the Roman alphabet.)

This article is no different -- he covers way too many typefaces and most of them are nothing special.

Usually I look at serif faces and think the serifs are just a noisy distraction. Then I was reading a book that was set in Palatino and I was blown away by the way the serif on the right side of "lowercase r" would almost make love to to the curves of the "lowercase e" and the "lowercase s". I was thinking "gee they got the font metrics right".

Then I looked at the "Palatino linotype" that comes with Windows and the lowercase r is not shaped that way at all.

Since "99% of everything is crap" I want to read articles that cut through the crap and present nothing but the best.


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.


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.


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


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.


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?


Yes, an italic font is not merely a slanted version of a regular (Roman) font. The slanted version would be called an oblique font.

Italic fonts traditionally do have more of a handwritten character, but that isn't required. They are distinct fonts of their own, but should be harmonious with the Roman version of the same font.

https://en.wikipedia.org/wiki/Oblique_type

https://en.wikipedia.org/wiki/Italic_type


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.


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)


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.


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.


That would be possible using a proportional font like Input Sans with elastic tabstops[0]

[0] https://nickgravgaard.com/elastic-tabstops/


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.


Hmmm. What if the editor was clever enough to do that, with any font, automatically.


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.


> 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 find you don’t need to. maybe tabs would work w the right editor.


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 was surprised to not find Iosevka font on the list. I discovered it from HN last year and have been using it everywhere i need a mono font since.

https://github.com/be5invis/Iosevka


Quite a few of the usual suspects seem to be absent.

Pragmata Pro, Fantasque Sans Mono, Fira Code, Go Mono, etc.

Definitely expected to see Anonymous or Space Mono on there, though I don't particularly care for either of these myself.


Damn, that is beautiful, but feels too condensed for a terminal/text editor. Maybe I'll give it a try anyway...


Iosevka Aile is my go-to font for note taking!


Mononoki is my recent favorite (unmentioned yet, but surely popular).

https://madmalik.github.io/mononoki/

Monofur is a wild font I'm mildly surprised was omitted. I did use it full-time for a while maybe 10 years ago, but it's maybe not the best daily driver.

https://www.fontspace.com/monofur-font-f39937


I was fresh out of high school and decided to learn computers while I waited for the University entrance exam results. I joined the course about a month late but I was determined to catch up. One day I was alone in the lab trying to run a QBasic code I had written. Everything was Ok except for one line. The interpreter kept pointing to that line and I just didn't get why. I went over my text books several times, and the syntax I had used was correct.

After about an hour, I got depressed and my thoughts went all over the place. "It's karma! You see that 'little' lie you told a couple of years ago about not being responsible for knocking moms pot of soup over? Well, the spirits are paying you back now. Your code is fine boy. But your sins cause it not to work. Maybe you should confess when you get home". Luckily for me, a friend walked into the lab and saw me slouched and with a long face. "What are you coding?" I pointed to the offending line. He looked at it for a few seconds and said "it seems fine... Ah! line 1O should be 10." He corrected it, pressed Shift + F5 and like magic it worked. Now whenever I write code I always put a slash across the zero to indicate it's 0 and not O.


The pricing model of programming fonts makes no sense. Most seem to be sold at standard desktop font licensing rates, i.e. the $30 to $100 range. 99.999% of developers are not going to spend this much on a nice-to-have.

On the other hand, if these fonts were priced at around $5, they drop into the range of an easy, impulse purchase. Even if the creators made substantially less money on each license, I'm sure they'd make more overall from much higher sales.


I don't think a font author would see a 20x uptick in sales if they priced a $100 programming font at $5. We are arguing a counterfactual though so it's hard to say.


> Most seem to be sold at standard desktop font licensing rates, i.e. the $30 to $100 range. 99.999% of developers are not going to spend this much on a nice-to-have.

Sure, but 99.9989% aren't going to spend money on programming fonts, period.


Then I'm in those 0.0011%. That is, if any reasonably priced font actually managed to be better than Bitstream Vera Sans Mono / DejaVu Sans Mono in my view.


Is it less work to design and produce a good programming font? Or is there a larger target market at a lower price? In other words, what market forces would make the price go down for this one category of fonts? Personally I doubt that a programmer who wouldn't spend $100 for a font would spend $5, and you have to sell 20x as many to make up the difference.


Obviously, it's not less work. Given the need to develop complex additional ligatures, it's likely more.

> I doubt that a programmer who wouldn't spend $100 for a font would spend $5

This is where we disagree then. I think there is a big psychological difference for most consumers, including devs, between spending $5 and $100. Even if you can afford both, the former falls into the range of impulse purchases, like getting a sandwich or a cup of coffee, where you spend without really thinking.

On the other hand, I think a $100 price is far more likely to trigger a more analytical and skeptical response. Do I really need it? Is it worth it? Should I research alternatives? Maybe, I should think about it and decide tomorrow... Etc. And the consequence will be a huge drop in sales.

Also, I also do think there are significant differences in the market for programming fonts vs. general desktop fonts. The market for a single font is likely a relatively small pool of designers / content creators who are spending their employers money, need it to complete a specific project, and who value achieving a unique look. The former is a larger market, who are spending their own money on a nice-to-have, and who don't particularly care about uniqueness.


All good points but I think at the $5 level you're also competing with "free". There are a lot of comments here suggesting fonts like Iosevka which are open source/free. In any case my point was that we don't really have to debate what the market "would do": there isn't a market for $5 fonts but there is for $100 fonts. It's possible that nobody has figured out there's a gap and therefore an opportunity. Or font makers have found that they make more money selling fewer licenses.


I would spend $5 on a font, but would not spend $100. I would buy the font the author of this article likes for even $10, but it costs $200 (for just the monospaced variant).

The price point for fonts is set for people who intend to use the font to make money – like graphic designers. One could imagine a lower price point for private use, similar to media.


> In other words, what market forces would make the price go down for this one category of fonts?

The font a programmer uses has absolutely no bearing on the products they produce or the money they make. Unlike graphic design, where a licensed font becomes a direct part of the sold product.


I would pay the going rate for a font that I used every day (or expense it, anyway) but a splash page isn't enough to determine whether I would make a font my daily driver, especially since current fashion is quite different from my own environment.

(I do use a font ‘with character’, Fantasque Sans Mono)


Meh, it took me a while, but I eventually shelled out for PragmataPro after hearing many good things about it. It may not be big, but there is a market.


Speaking of pricing, I personally believe that communication forms and methods should not be copyrightable. This includes fonts.

I mean, what is next, someone copyrighting the way to pronounce words?


I don't understand what you mean. Fonts take time and effort to create, and some creators want to be able to benefit from the financial fruits of their work, with intellectual property and nonfree licenses.

Who created the way we pronounce words? We collectively did, over hundreds of years.


The shape itself is not copyrighted (in the US), only the representation in code is. It's the same concept with pronunciations: the pronunciation itself is not copyrighted, a specific recording of someone saying a word is.


I am a little bit disappointed that my favourite monospace font, Iosevka, wasn't listed.


Same here. It‘s a very narrow font and everything wider than Iosevka feels like a downgrade to me.

https://typeof.net/Iosevka/


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


Now that you mentioned, upgraded it from 3.x.x to 8.x.x - I wonder I'll notice anything different.


And as if to prove my point: two days after you did that version 9.x.x was released

https://github.com/be5invis/Iosevka/releases


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.


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.


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.


No mention of the open source font Hack (maybe because it doesn’t fall into the category of great personalty, but there are many options to customise it…), so here it is:

https://sourcefoundry.org/hack/


I'm still waiting for the day something trumps Source Code Pro for me...


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.


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 :/


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 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 continue to use Lucida Console for that reason.


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.


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)


Agave[1] and Lekton[2] are among my favorite monospace fonts.

[1]: https://app.programmingfonts.org/#agave

[2]: https://app.programmingfonts.org/#lekton


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!


For non-hidpi screens I always use Dina font and I've used it for many years. https://www.dcmembers.com/jibsen/download/61/


No mention of Terminus?? https://files.ax86.net/terminus-ttf/

Those were the days.

Today I stick with whatever the IDE or distro system font has. Meh.


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


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.


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 not to see Space Mono on the list, it's a solid one I like to use in terminals (gray/white on blue gives a nice 1960's 2001/what if IBM ruled the future of computing kind of aesthetic): https://fonts.google.com/specimen/Space+Mono


I switched to Iosevka Term Regular, which is a condensed font so it gives me more characters in the horizontal direction. It took me a week of getting used to it, but now I'm not looking back. It's free.

https://github.com/be5invis/Iosevka


I switched all my text editors and terminals to Cascadia PL these last few years, after having tried the Windows Terminal. Microsoft really came out with a near perfect coding font for me with this one. I used to be a Source Code Pro guy.

The only caveat with Cascadia is that it needs fairly high DPI to be nice looking with the bold weight.


Love Cascadia Code. It's bizzarely thick the first time you lay eyes on it. But once I got used to it, it was fantastic.


I've tried a bunch of different fonts, but I always find myself going back to PragmataPro. I love that the characters are narrow but still readable and distinguishable. It also comes with the PUA loaded up with Powerline and Nerd Font glyphs. I appreciate not having to patch it myself to get those.


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


Someone in my team writes all his C and Lua code in Comic Sans Mono. That's all I'm going to say.


What about the beautiful M+ 1m font? https://www.fontsquirrel.com/fonts/list/foundry/m-fonts


Never imagined that I'd read about Vulfpeck in a HN link :-)


They had some attention here when they did Sleepify too. I think there was a more popular post than in this link, but perhaps without their name in the title? I just did a quick search.

https://news.ycombinator.com/item?id=7428550


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 ;)


I said it before, and I stand by it: to me, all these re-appearing discussions about "programming fonts" are - to the most part - bike shedding.


As programmers, we spend many hours a day looking at text.

You may not care what font someone gives you, and that's fine.

But we all have different eyes, different tastes, and different priorities.

I care enough about it to have spent some hours customizing my own personal proportional programming font.

Is that bike shedding? I don't think so. I don't even have a bike!


Funny.

But in reality, if you did not even have a choice (like we didn't in the olden days), I honestly don't think your productivity would suffer.

I think there other factors that are way more important for that. Like for instance, having syntax highlighting (which hasn't even been around for that long) is in my opinion way more crucial than the choice of font. A way to visualize matching parentheses is way more useful than the choice of font (think Lisp, especially).

So, yeah, nothing wrong with having different tastes.

I'm just saying that the topic of which font you use for programming is way less than important than some people make it out to be, if you believe the internet.


Oh, trust me, I learned to program when there was no such thing as a "font" other than WHAT YOUR TELETYPE PRINTED OUT IN UPPER CASE BECAUSE THAT WAS ALL WE HAD.

Hey, any other old-timers here? Did that UPPERCASE TEXT make you hear the chunkity-chunk-chunk sound of an Model 33 ASR cranking away at ten characters per second? Cannot be unheard!

I don't know if I am more productive now, but as much as that sound makes me sentimental, I think I am glad to be rid of it.

https://en.wikipedia.org/wiki/Teletype_Model_33


Welcome to the club, then!


Well, time to retire the term "bikeshedding". It used to mean something (the tendency of people to have the biggest arguments over trivia because everyone feels they understand it), but apparently not anymore.


This is exactly the way I mean it, except maybe for the "everyone feels they understand it" part, which I would replace with "everyone has an opinion on it."


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...


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.


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.


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.


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’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/


No love for Droid Sans Mono? It is the perfect programming font for me (well, the slashed zero variant).


have been enjoying using Cascadia Code


Same, absolutely love it.


I kept recoiling from how bad "windowWidthResize" looked in the first few fonts.


1




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: