Almost monospaced: the perfect fonts for writing
blakewatson.com
blakewatson.com
Then again, I don't see values lined up much these days:
{
"someKey": "someValue",
"someOtherKey:" "someOtherValue,
and if you only care about leading whitespace (that is, the whitespace before a character appears on the line), maybe it doesn't matter how your font is spaced.I suspect numbers in these almost-mono fonts are monospaced, so numerical values should still have nice rhythm too.
> Sometimes programmers rely on the monospaced grid to create a second column of values or comments on the right side of the page. It’s true, these secondary columns won’t align in a proportionally spaced font. But why are we making these columns in the first place? Even in a monospaced font they can be finnicky and hard to maintain.
> In virtually every other form of typography, the responsibility of alignment is given to the typesetting application, not the font. If source code editors can highlight syntax, they could also interpret tabs and syntax to create true, adjustable columns of text.
You want 8-space tabs and braces on their own lines? Cool. We'll save the file with all the formatting defaults, but run a formatter tuned to your preferences before displaying.
Same reason I don't like using those things where <= turns into ≤ in your editor but it's written to disk as <=.
If the code doesn't parse, save it as-is. If it does, run the formatter with the defaults before saving. When opening, run the formatter with the user's preferences before displaying.
Gets you the benefits of a formatter, with the freedom to control your environment to your tastes. You can already pick your editor, font, and color theme. You ought to be able to pick your formatter settings too.
Only rarely is the vertical alignment useful because mostly code isn't read vertically. Used in moderation, the reverse Christmas tree style used in the Linux kernel can be as good for readability (sorted longest to shortest). For some constant structures a reordering of fields to put the variable length element at the end of the line removes the need for padding space (like in the output of `ls -l` where filenames come last).
A common indentation style for continuation lines is to align with the start of arguments to the function. I've never seen the sense of this variable amount where indentation after a while is much more than after an if. Double the normal indentation for continuation works well in languages where line continuation isn't otherwise distinct from normal blocks.
I recall reading something about "tab stops" that solved this problem, but I don't think there are any mainstream implementations of it.
But a major flaw is that it only works when your cell has less than 8 characters. Or it will go to the wrong stop. Which isn't that common today.
Because why insist in short names and 80 width character limit? Almost everyone have a screen that can fit hundreds of characters per line today.
Yet, books don't work that way, even though we have the technology. Long lines aren't readable. There's a reason newspapers have columns.
See eg https://baymard.com/blog/line-length-readability and https://en.wikipedia.org/wiki/Line_length
You can keep to mostly text, but give the editor more leeway in how to lay it out and make the code's structure more visible.
Some really simple options, that you might not even recognise as going beyond text: folding of block and go-to-definition.
> Never attempt to line up text by using spaces. The only exception is if you are using a monospaced font. But in word processing applications, there are appropriate tools available for lining up text, like tables[1] and tab stops[2].
[1]: https://practicaltypography.com/tables.html [2]: https://practicaltypography.com/tabs-and-tab-stops.html
Seeing the same shape repeatedly tells me a lot about what is happening. It also helps highlight changes between two lines that are very similar.
I agree and I think that is the same thing as code-readability. Code-readability means you can easily understand the code.
I personally try to abide by what I call "hedge" formatting convention, the punctuation forms a vertical hedge which then shows the structure of your code clearly:
[ a
, b
, c
]
Moving my eyes down to look for the closing bracket is easier (to me) than moving my eyes from left to right to spot it somewhere on the right side of the page.
Note how above ALL the punctuation is in the same (first) column, Having read that it then becomes easier to read what is on the rest of the columns.
In general it helps when things that are the same, or have the same purpose, on each line are in the same horizontal position. It is is then easier to see what is different about each line, since it is easy to see what is the same.
But as long as everything is written under the same guidelines, I will accept it.
Your explanation makes good sense. I guess I just wasn't seeing the forest for the trees. ;)
[
, a
, b
, c
]
Depending on the rest of the language syntax, it could also be nice to have a markdown-style list syntax: [
- a
- b
- c
] [
a,
b,
c,
][ a
, b
, c
]
because, I think this is as 'uniform" as it gets. All syntactic separators are in the first column. Thus they are all uniformly in the same column. Line 1 has the syntactic separator '[' which means start-of-array. Lines 2 and 3 have ',' as the syntactic separator which means element-separator. And line 4 has the final syntactic marker which means "end of Array".
All elements of the array start at the same column, uniformly. And all syntactic separators are in the same column also uniformly.
abc = 1
d = 2
which add very little readability value IMHO.Things like
func(arg1,
arg2,
arg3)
usually don't align well because func( has a different width than the five spaces in the lines below. However1) my text editor (emacs) aligns those lines for me (probably any programmer's editor does) so at least I don't have to do precision work
2) I ended up writing code like
func(
arg1,
arg2,
arg3
)
especially with named arguments (arg=value). That aligns even with proportional fonts and all arguments immediately stand out.If the arguments are few (two or three) and there are no named arguments I don't break them on multiple lines.
The result is that no coworker ever complained about my code.
Languages with a formatter (Elixir) solve the problem once and for all and align well with both kinds of fonts.
At the same time I get your point and also the argument about Git diffs (which also should be readable). So maybe the ideal situation would be a separation of code and its formatting, so that we have more options than tabs and also no need for crutches like tabs. Like a better, more flexible code formatter that lets you display and edit code in the editor using one style but then saves the file in a standard format that's consistent across the whole project.
func(arg1, arg2, arg3)
the first example splits it across multiple lines in a way which maximally preserves the other aspects of the notation.The argument is already being muddled with the function in the same way.
These conventions are seen in the wild:
func (arg1, arg2, arg3)
and func( arg1, arg2, arg3 )
The real fix for that muddling is to drop the commas, and move the parenthesis to include the function: (func arg1 arg2 arg3)
Now func and arg1 are no more or less muddled than are arg1 and arg2. :)Once you’re splitting it across lines I don’t think that is a desirable attribute. Better to use a format that suits multiple lines than attempt to match as closely as possible to a format intended for one line. Like those “flying cars” that try to look like the “canonical” car.
From my perspective this is a UI problem (though not a serious one).
if (condition...
&& condition...
&& condition...
) { if ((
condition1
) && (
condition2
) && (
...
)) {Seems wrongheaded to me; that's the same reason Elm wanted you to write arrays like this:
[item1
,item2
,item3
,item4
]
instead of a sane way. It means adding or removing an element only changes one line in the diff!Who cares? It's not hard to understand what's happening in a diff that makes this kind of change. You want the code to be easy to read, not easy to diff.
You could also easily base your diff algorithm on a lexer for the language rather than a lexer for ascii, in which case changing the amount of whitespace would register as "not a change".
[
item1,
item2,
item3,
item4,
] [ item1
, item2
, item3
, item4
] (item1
item2
item3
item4)
;p [ a [ a [ a
, b , b / , b
, c --> , c / , c
, d , d / , dd
] , e ]
]
Your usual 3 way merge algorithm will correctly deduce: [ a
, b
, c
, dd
, e
]
Contrast this with trailing comma: [ a, [ a, [ a,
b, b, / b,
c, --> c, / c,
d d, / dd
] e ]
]
You now have a merge conflict between "d," and "dd".However, if you were to require a trailing comma after the final element you wouldn't have this problem.
Example doesn't have a trailing comma. If it did, it would act the same as the leading comma.
But also the leading comma just moves the problem to the beginning of the list instead of the end. Trailing comma with the opening [ on its own line wouldn't have that problem anywhere.
I've encountered this sentiment more than a few times and I find it hard to accept. It totally makes sense to align repetitive stuff in columns. That's why people use tables in other contexts, and code should be no different. This alignment makes clear any deviations from the norm and lets you "see" the structure of the data easily.
It doesn't matter for minor stuff and, usually, the code linter/formatter is "good enough"-- but sometimes, you REALLY want to have columnar layout!
With monospaced fonts, the columns will be guaranteed to line up with the correct number of spaces, which your IDE will determine anyway.
I might give these fonts a try, although I've been used to Menlo for a long time.
When I attended university in the mid-1990s, and again in mid-2000s, we were required to hand in papers using monospace font, black ink, with a specific point size and margins.
It kept everything looking consistent with typewriters (which some people still used through the 1990s), but also kept people from using distracting or illegible fonts, or trying to work around page or word limits by using different fonts.
The main use of this in practice is using line-char-count limits as a proxy to lint for code readability, but it can also be beneficial in other contexts.
> You might be thinking, “Okay, but now characters won’t line up neatly.”
The typeface is a modification of IBM Plex Mono[0][1]. I'd recognise that 'a' glyph anywhere.
> This is a modification of IBM's Plex font.
https://github.com/iaolo/iA-Fonts/tree/master/iA%20Writer%20...
(Not linking the solutions here to make it harder to spoil the puzzle, but you can find them online with a bit of effort — maybe this will help: https://digitalcommons.butler.edu/cgi/viewcontent.cgi?articl... — and it's also reprinted in Selected Papers on Fun and Games.)
Does it? It feels like the "typewriter aesthetic" is pretty much gone. The comically wide thin characters (i, r, l, etc), and comically small wide chars (m, w) are the clearest difference of such a font; without that it looks like a normal proportional font (which it basically is).
Terminal emulators, however, have a model on which glyphs are always placed onto a visual grid (the PTY render-model grid, emulating text-mode VRAM); so in a terminal emulator that supports rendering Unicode at all, any glyph will have its visual width "snapped" to an integer multiple of the grid spacing, and will be considered to take up that many grid cells. It is up to the particular terminal emulator where it places the glyph within that array of grid-cells; some left-align glyphs, others center-align.
Sun Gallant Demi, Solarize, Libertine/Libertinus Mono, Triplicate, Prestige Elite, CMU Typewriter, Latin Modern Mono, MingLiU, sony-misc, Verily Serif Mono, Century Schoolbook Mono BT, UM Typewriter, American Typewriter, Courier, Pitch, TiredOfCourier, Xanh Mono, DSE Typewriter, LTC Remington Typewriter, Bitstream Pica 10 Pitch, Italian Typewriter, Typist Slab, FF Elementa, EF Techno Script, Drafting* Mono, Bodoni Egyptian Mono.
(I don’t remember which one I ended up using, though.)
Buried the lede on that one. Was looking forward to the recommended typewriter font.
1) Support for vim navigation, where hjkl move you one character in a direction on an evenly spaced grid. Remove that uniform spacing and up ceases to be “up”
2) Legibility for formatted comments and ASCII art (could argue these should be avoided but I’ve seen some magical ASCII art in code)
////////////////
// My Comment //
////////////////
1/ That’s already broken by line wrapping. gj is the command moving up in the grid not j. The fact you are confusing the two should tell you how little of a difference some sideway movement makes.
2/ Don’t use ASCII art in code. It’s annoying for people not using monospaced font and I’m not alone.
But I've always wondered if allowing three or four different widths would help. We could still align text if (narrow) spaces were the smallest unit, and other widths were repeated multiples of that.
This makes me think it's doable.
My point is that if handled correctly, e.g. in terminals, there is no problem with that, as long as the application is double-width aware. For example I use Mutt as a mail reader in a terminal, with Vim as an editor, and mixed latin and east-asian characters work fine with them and line up on the terminal grid.
The article doesn’t use the font it is extolling the virtues of, except for illustration. I found that interesting.
Also, there is something that gets under my skin about using anything other than monospaced to write code, as was one of the demo’s. I would genuinely be fine with writing code in a monospaced Arial or Times, but even courier-semispaced makes me shiver inexplicably.
I do use them for writing and coding.
I’m bummed out to see an article about “a perfect font”, especially being a monospaced one (or nearly), but that does not use said font throughout. I was sort of hoping to be immersed in this font for awhile, but wasn’t.
I use fira+ligatures. I am a monospacer too.
https://ericfortis.com/portfolio/design#-verdana-camel
---
For aligning content, I think IDEs should be able to represent some parts of the code as tables. For example, similar to the Decision Tables of Jetbrains Projectional Editor:
IMHO of course.
Hm. If Verdana is the render font for you here on HN, I believe that's that's all about your browser config, and nothing about HN.
I do override it, for more than ten years. That's what I get for posting without sanity checking myself.
I stopped because the spaces are too small for my liking. It worked when I was using 4 spaces for indentation but now the more or less agreed-upon standard is 2 (for JS/TS which I mostly write). I wish I could create a custom version with a larger space.
Well, not sure what is the basis for that assertion, but I find it easier to read text rendered in a monospaced font (Courier is my favorite). In fact, when I need to read something longer than a minute on the browser, I switch to monospace (with help of a browser plugin). It's not about text alignment -- it does not matter when reading prose, but perhaps about the familiarity of a font.
As an aside, I also try to get rid of formatting when reading long text. It allows me to focus on the essence of the written word. Perhaps, this is why the old school mailing lists and message forums are more appealing than the modern crop of social media apps. Also plain text email (what a rarity in the corporate world today!).
If you're willing to pay for typefaces, though, there's a really good "almost typewriter" font called Triplicate, which comes in four versions -- the original, a slight variation with the same metrics as Courier, a "code" version that has a few characters changed to be better for coding (this is a great alternative to the more expensive Operator Mono, in my experience), and a proportional one which fits the "almost monospaced" idea. (It's not designed for coding, but I don't think proportional fonts work for coding in most editors.)
A demo of my own of Triplicate with use of both Poly and Code: https://chrismorgan.info/blog/rust-fizzbuzz/, code is all Poly + Code, compiler errors are just Code (it uses columnar alignment, so not Poly). The lowercase l can be seen in all the figures in one form or another (e.g. “else” in bold, “result” in regular, but not “println!” because italics always uses a curly-tailed l).
$ brew tap homebrew/cask-fonts # You only need to do this once!
$ brew install font-andale-mono
Of course, most other recommendations in this thread are available as well:https://github.com/Homebrew/homebrew-cask-fonts/tree/master/...
These land in the same folder as user installs through Font Book. Using homebrew makes moving to a new system as easy as bundling the Brewfile.
I really hope some font foundry out there focuses on designing something specifically for readability of large bodies of monospace/duospace text.
It’d also be nice to have a provable metric for readability, rather than the anecdotal evidence I tend to see, but I suspect this is hard in and of itself.
In the screenshot, if you were to see a properly fitted proportional version of iA Quattro, you'd ditch iA Quattro. But that comparison is not presented, I don't think they've tried making a proportional version of it.
You can't use Nitti Grotesk, a cookie batter, to make an argument here either for a fair comparison. It's an entirely different thing.
In order to do a proper comparison, they should finish the kerning job and present their arguments fairly and squarly.
The image I am talking about is: https://i0.wp.com/blakewatson.com/wp/wp-content/uploads/2022...
It needs a 3rd line "iA Writer Proportional". Looking at the word "next" in iA Quattro, the fitting looks really bad which is a known trade-off in monospaced typefaces, but not an excuse to leave it like that in a proportional typeface.
The word "chain" looks more like "cha in" which just makes the font seem unfinished to me.
/Almost monospace/ is probably great _for writing_, but I find it a bit frustrating that the author doesn't address lining up things with /almost monospace/...
- https://github.com/preservim/vim-pencil
- https://github.com/junegunn/goyo.vim.git
- https://github.com/junegunn/limelight.vim.git
- https://github.com/vimwiki/vimwiki
It was fun, and the setup is almost identical to iA Writer which I appreciate. I even had it all on my phone with Termux!
Last year I just did it in Markdown in VSCode in "zen mode" which also worked pretty well. It was definitely easier to setup than Vim and had better highlighting of bold/italics/etc.
However, when Jetbrains Mono came out, I switched my code editors to it (IntelliJ was trivial) - https://www.jetbrains.com/lp/mono/ (and no, I don't like ligatures). The slightly larger lowercase high at the same font size makes it a bit easier to read without boosting the entire editor's font size up, the 'g' debate I lean to the single story, open tail form ( https://www.typeroom.eu/the-elusive-mystery-of-letter-g-expl... ).
Umm... no?
"The difference is subtle but notice that the sample on the right gives letters like lowercase “m” a little leg room, improving the readability of the code."
Uhh... If you say so...
I honestly don't see any of the upsides he's talking about. But the downside of things not lining up is definitely real.
If I don't need characters lined up I can use just about any font there is.
So this font is not competing with monospace fonts, it's competing with all non-monospaced fonts, so there's really no advantage in using it.
I noticed the difference immediately — but not in a good way. I just felt a much stronger preference for the version on the left, the true monospace. I initially put it down to the indent — that "n" beginning "num" just looks horribly placed wrt to line above it — but, on reflection, I think it's the 'sans' properties that make it less pleasant for me — like the "i" and "l" in "while" that are much rounder and, of course, without even slab serifs.
For me the lower L and the number 1 have to be different. Most mono fonts make them almost identical.
Typing “lst” looks like 1st (First). They either need to curve the bottom of the lowercase “L” or remove the bottom bar of the one.
https://support.microsoft.com/en-us/topic/microsoft-supplied....
Yes, I read the article to the end. No, I don’t get it. Either they line up or they don’t. Either it’s monospace or it’s not.
If all you're saying is that you personally don't care to make a finer distinction than monospace/proportional, that's fine, but it's probably not worth commenting on either.
Monospace has one and only one redeeming quality that makes it worth using over proportional fonts: it lines up.
There could also be an element of tradition; prestigious institutions and individuals, like Bell Labs, Donald Knuth and Apple, have devoted significant resources to typesetting and publishing, so an appreciation for typography could be seen as a marker of sophistication from that.
And lastly we must often have some working knowledge of the design of user interfaces at some point in our careers, and you need to have some notions of typography to be effective at that.