top | item 29637876

Ligatures in programming fonts: hell no (2019)

157 points| susam | 4 years ago |practicaltypography.com | reply

195 comments

order
[+] WesolyKubeczek|4 years ago|reply
Ligatures in programming look cute, and maybe if you want to showcase a snippet of some particularly clever and elegant code, print it on some expensive paper with tasteful palette (and none of your CMYK nonsense! Only pure pigments!), frame it, and hang it on the wall, I can see its appeal.

At work, I've tried it. I've tried hard to like it. I had to stop because Fira Code (and ligatured Iosevka) took the principle of the least astonishment, threw it on the concrete floor and kept beating it down till it stopped breathing, and then some.

I found myself spending time wondering "what characters is this made of?", and "how do I type THAT?" when viewing some existing code, and "WTF is this?" when a ligature that would have likely made sense in Ruby or Haskell (or in APL?) made it into my Perl code.

Also, "is this a ligature or some Unicode glyph?" was a question I found myself asking. In a better world, I shouldn't be wondering about it while fixing some integration with one of Intuit's molochs or somesuch. But here I was.

Switching to non-ligatured text shed a lot of cognitive burden off me. At least I can tell which thing is ASCII and how I type it. And my code doesn't look as a Guillome Apollinaire's calligramme.

[+] michaelcampbell|4 years ago|reply
> I found myself spending time wondering "what characters is this made of?", and "how do I type THAT?" when viewing some existing code, and "WTF is this?" when a ligature that would have likely made sense in Ruby or Haskell (or in APL?) made it into my Perl code.

I guess everyone's got their thing, but on that paragraph I have to say my experience with ligature'd fonts in programming has led me to wonder the same thing... never.

I don't say this over some love of them; I'm fickle and change fonts about quarterly; some with ligatures some not, but I can't think of a single instance of WTF or actual confusion.

[+] skhm|4 years ago|reply
I can't agree. I type up something in Fira Code - I look at it - and I smile inadvertently. It's just another one of the small, pleasant aesthetic experiences that make up programming as a whole for me.
[+] TacticalCoder|4 years ago|reply
> I found myself spending time wondering "what characters is this made of?"

Funny sidenote: I've got my Emacs configured to show any non-ASCII char in source code in bold pink on a pure black background (including zero-width spacing chars). That way the non-ASCII chars do really standout and I rarely wonder "which char is this?".

I don't forbid them: they do just really stand out.

Most of the time the only Unicode chars in source file are anyways the copyright symbol and some chars in author's name (in comment). Sometimes in strings.

[+] ertian|4 years ago|reply
I've had the same experience, with ligatures applying in languages they weren't designed for. It struck me that the font is a strange place to make the decision about what character combinations should be combined. Something like emacs' prettify-symbols-mode seems like a better approach: make the decision per-language. Of course, that's not nearly so simple to implement.
[+] avgcorrection|4 years ago|reply
> Also, "is this a ligature or some Unicode glyph?" was a question I found myself asking.

In code editors that use monospaced fonts the ligatures will often look nicer since things like Unicode arrows will only take up a single “character space”.

[+] h2odragon|4 years ago|reply
Especially when programming, but also at most other times, I want a 1 to 1, unambiguous correspondence between the symbol I entered and the display on the screen.

Making my ":)" into an emoji is wrong. "Do what I meant" input magic bullshit is always going to be wrong about "what you meant" sometimes, and occludes the possibility of "I didn't know what I meant until I saw it" with its helpful corrections.

Have had this argument with fans of "autocomplete" systems, too. An analogy I like is a powered exoskeleton: if you had one you could run faster and jump higher and all these good things: but then when it breaks or you're not wearing it you've less native ability and no familiarity with the unassisted world, which makes you dependent on the tools.

[+] dharmaturtle|4 years ago|reply
> [this] makes you dependent on the tools.

Socrates had a similar opinion w/r/t reading and writing:

> This discovery of yours will create forgetfulness in the learners’ souls, because they will not use their memories; they will trust to the external written characters and not remember of themselves.

I feel like you and Socrates are incorrect for similar reasons.

Humanity advances when it can hide complexity. Tools help with that. To argue against tooling because it makes you dependent on the tooling is like telling the construction worker to put away the jackhammer and pick up the pickaxe. Programmers are super productive (compared to other professions) because we can build tools that make us better programmers. The leverage recurses.

[+] seanmcdirmid|4 years ago|reply
> An analogy I like is a powered exoskeleton: if you had one you could run faster and jump higher and all these good things: but then when it breaks or you're not wearing it you've less native ability and no familiarity with the unassisted world, which makes you dependent on the tools.

Assistive technology is the result of historical progression, so why eschew auto completion because it might fail when you don’t eschew your computer which might fail as well? Should we all just be programming on pen and paper because that’s lower down the progression stack and has less chance of failing? You know that argument was probably made in the 70s by some old school programmer when those fancy new interactive terminals started coming out (I believe dijkstra actually said something to this effect, but can’t find a source).

[+] CJefferson|4 years ago|reply
I'm sure builders would struggle without diggers and cranes, and doctors would struggle without electricity. But why would I purposefully do away with useful modern inventions just so I can remain compitent without them?
[+] blackoil|4 years ago|reply
I wear glasses that help me see `better`. When I don't have them I can't see. If I stop wearing glasses I may get adapted to that, but I prefer glasses and I always wear them.

I also like my code colored/beautified/ligtured.

[+] michaelrpeskin|4 years ago|reply
I mostly agree with you - I hate when my :) it turned into an emoji, or I get smart quotes because the editor has a _different_ code point in there than what I typed. But I do love ligatures because that's just a representation on the screen that makes it easier for me to read. It doesn't change the underlying data, so I'm ok with it.
[+] mrweasel|4 years ago|reply
Even editors that automatically put extra “ to close a string or ) when I hit ( is problematic in my mind. My workflow means that I often put “ or ( after the editor feel like I should, so I end up with ) in wrong places. It drives me nuts.
[+] aidenn0|4 years ago|reply
Font ligatures are always going to be wrong because their logic is both general and simple.

On the other hand, if you actually parse the input and use it to make transformations, it would be possible to show you what the tool your are inputting to believes you mean in a clearer fashion, which is very useful. Automated indenting and syntax highlighting (when done correctly) can catch errors as you type.

[+] dkjaudyeqooe|4 years ago|reply
> Especially when programming, but also at most other times, I want a 1 to 1, unambiguous correspondence between the symbol I entered and the display on the screen.

Ligatures don't necessarily stand in the way of this. It's a matter between the font and the syntax.

[+] thom|4 years ago|reply
I am happy for other people, even those I collaborate with, to set up their editor however they like. Ligatures aren't to my taste, but it's not really affecting me when I read the code and I'm not regularly pairing right now so whatever. Maybe someone's done a scholarly study to test editing and comprehension performance for fonts with and without, but I doubt the results would change my personal choices.

However, all that said, if you ever check in unicode identifiers that I can't easily type then you're on your own.

[+] vikingerik|4 years ago|reply
I'll offer a possibly valid use case for Unicode identifiers: mathematical notation. C# allows Unicode for variable names, and I wrote some code using θ (theta) as a variable for a geometric angle. I really liked having a struct for cylindrical coordinates to name the values as (r, h, θ), which flowed quite well visually, better than writing out "theta" or "angle". And since it was a member of a struct, once I had the symbol in the editor once, the Intellisense code completion would just show the θ in the picker dropdown.

(It was for a personal project and I'm not sure I'd do that in a team environment, but I'd at least ask the other developers if they'd like it. And of course one use of Unicode being good doesn't mean that all uses of Unicode are good.)

[+] WorldMaker|4 years ago|reply
> However, all that said, if you ever check in unicode identifiers that I can't easily type then you're on your own.

Between copy and paste and most language's auto-complete tools and the emoji soft-keyboards in most operating systems today you can "easily type" most any unicode identifier with just a little bit of knowing your tools. (The Windows emoji keyboard has almost all of the Unicode math symbols, for instance.)

[+] dkjaudyeqooe|4 years ago|reply
It should be noted for clarity that unicode in code is orthogonal to this, which is display only.
[+] 9dev|4 years ago|reply
The author points out two problems, which both are ridiculously obscure edge cases: if there’s really a Unicode arrow in code you deal with, it likely won’t matter much if there’s an arrow or something closely resembling an arrow. The second point recommends getting rid of ligatures entirely just because they may, in some situations, do not display the right thing.

Both arguments ignore the 99.9999999999% of times ligatures do what they’re supposed to, and help me identify some symbols quicker. I’ll happily accept being confused once in a year about a strange-looking arrow in a debug log output, or from a weirdly rendered arrow in some ASCII art print.

People complain about weird stuff.

[+] eps|4 years ago|reply
Why on Earth one would want in a character-oriented text (i.e. where every character matters separately) to have some of them collapsed into one is beyond me. Why not take it further and have IDE render all occurrences of "cat" with an emoji.
[+] karmakaze|4 years ago|reply
The last place where you want to have to mentally apply any decoding rules is in "debug log output".
[+] mattarm|4 years ago|reply
I think the author failed to state the primary issue I have with ligatures: code listing using ligatures tend to be harder for me to read because the symbols are unfamiliar to me.

I first ran into this issue trying to learn Haskell, where some beginner websites used fonts like Fira Code in their listing. The "weird" operators I saw in the listings were unclear to me. In some cases I simply wasn't sure how to even reproduce the code in my editor. I think it is something I could grow used to and someday perhaps even enjoy, but as a beginner it was a barrier.

[+] cbm-vic-20|4 years ago|reply
In the case of a "real Unicode arrow", I'd just as soon use a Unicode literal if the language supports it, like '\u2192'.
[+] 3np|4 years ago|reply
The author is also very clear about that they’re not talking about what you use in your local editor. It’s about when you make decisions impacting others. It’s a kind of accessibility.
[+] maweki|4 years ago|reply
It depends on the language. At least for me as a Haskell programmer, the arguments are not really valid.

* The operators do indeed mean the mathematical symbols

* Haskell does not support unicode in operators normally. The operators are ascii.

* I have yet to come across where the ligatures were wrong for my code and as I do not have those unicode operators in my code (and am not really sure how to type them) they were never ambiguous.

I am happy to have ligatures in Haskell. A colleague of mine programs in Agda though, which supports unicode operators and they have their mathematical meaning there. So he's fine without ligatures and does indeed type the unicode symbols using vim. It really depends on the language.

[+] mananaysiempre|4 years ago|reply
> So what’s the problem with programming ligatures?

> (1) They contradict Unicode. [Goes on to mention U+FB01 LATIN SMALL LIGATURE FI and how a ligature for U+003D EQUALS SIGN, U+003E GREATER-THAN SIGN is indistinguishable from U+21D2 RIGHTWARDS DOUBLE ARROW]

No. Nonono. Hell no, one might say. (I’m frankly disturbed to hear this said by a typography expert, because this means something is deeply wrong, perhaps with my understanding here.)

It was never a goal of Unicode to have a code point for every ligature a typographer might ever want. For example, there is a code point for FI and for LONG S T, but not for FJ or FT. Like other “presentation forms” (a thing that Unicode is explicitly not supposed to contain), these exist only for roundtrip compatibility with old encodings (some ancient Adobe-Latin variant maybe?) and are deprecated for any other use (although I’ll be damned if I can find a clear statement to that effect on the Unicode website, there are notes in other places[1]).

The second part holds water to some extent, but given the amount of visual ambiguity afforded by allowing a text to contain arbitrary Unicode (which we must if U+21D2 is at all a consideration), no programming font can solve it, and no programming font tries.

[1]: https://twitter.com/fakeunicode/status/945017346858532864

[+] WorldMaker|4 years ago|reply
> (some ancient Adobe-Latin variant maybe?)

As with so many problems in encoding anywhere have a single well renowned crazy source: some EBCDIC code pages had manually laid out ligatures.

(IBM's shadow remains a heavy one.)

[+] marcus_cemes|4 years ago|reply
I like the ligatures in Fira Code. I find the arrows, boolean operators and the pipe symbol "|>" a lot easier to read as symbols instead of three seperate characters. I can understand why some people would dislike them. I'm not sure about merging together regular letters, although I haven't actually ever noticed this.

In my mind it depends on where you are on the spectrum, the hardcore programmers that are one with the code and want to see every letter in a terminal editor and those that stray more towards the designer and practical side of programming. Just do what works for you, and get burned, otherwise you don't learn but endlessly follow "best practice" advice.

[+] NelsonMinar|4 years ago|reply
I'm not a fan of the ligatures. But I'm not sure this website's "They contradict Unicode". Yes there are code points for ligatures. But it's also very reasonable for a typesetting system to encode the individual characters and just combine them to a ligature glyph for presentation. Which is what programming fonts have to do, since the ligature code points aren't part of the programming language.

I do something much weirder, I program in proportional fonts. Once you get used to it it's really lovely. Unfortunately the way I figured out how to do it requires some aggressive reformatting of code (mostly using tabs instead of spaces) which makes it hard to share code with others unless they buy in to your preferences.

[+] avgcorrection|4 years ago|reply
My impression was that codepoints for ligatures are there for backwards compatibility reasons. In that case they wouldn’t add codepoints for brand new ligatures. So I don’t really get the point that he’s making (if I’m correct).
[+] seanmcdirmid|4 years ago|reply
What’s weird about programming in proportional fonts? I’ve been doing that for a decade now. Auto formatter mandated at work doesn’t allow for manual format directives anyways, so no one notices.

Ligatures can be nice if you can solve the edit problem: keeping an -> as two characters even if it looks like → can help a lot. Unfortunately, editors don’t do that, so they become too annoying to use (maybe when we render code like we render latex will it be accepted).

[+] kej|4 years ago|reply
I like programming ligatures for the same reason I like syntax highlighting: it makes it easier for my brain to quickly scan a line of code. I have yet to be bitten by some ambiguity, and the more prominent difference between == and === has prevented a few subtle bugs.
[+] recursive|4 years ago|reply
Everyone can do whatever they want in their own editor. My personal peeve is being subjected to ligature'd fonts in code examples in programming blogs. I find it particularly egregious when the blog is explaining a new language or syntax to an ostensible beginner.

Fortunately Firefox still supports user styles. Here's how to stop the madness for anyone that cares. https://winaero.com/enable-loading-userchrome-css-userconten...

Inside my userContent.css I've got this gem.

    * { font-variant-ligatures: none !important; }
[+] meepmorp|4 years ago|reply
Counterpoint: I like ligatures in programming fonts.
[+] asdfasgasdgasdg|4 years ago|reply
I mean I don't personally like them but I'm not gonna yuck your yum. As long as you run your code through the autoformatter before you submit, you can program in a variable width font for all I care.
[+] cronix|4 years ago|reply
This only affects you reading code on MY computer. Your computer can display my code in whatever font you wish. This is much to do about nothing. It's simply a presentation layer, and it matters most to the person doing the coding and should be whatever they choose that makes them perform better. For me, ligatures were a big improvement. They shortened code so more is displayed on the screen with no alteration in meaning and made other things just more obvious, intentional and stand out. And when I upload it to github or anywhere else, it's displayed in a traditional font with no ligatures because it's totally nondestructive and has nothing to do with the actual code - only how it appears (to me).
[+] ARandumGuy|4 years ago|reply
This article really irritates me, despite the fact that I broadly agree with the conclusion.

The points on Unicode and wrong substitution feel weak, because there's plenty of valid situations where Unicode isn't displayed "correctly," and plenty of situations where the characters displayed don't match they semantic meaning.

In my opinion, the main reason to avoid ligatures isn't some big moral issue on "correct meaning" or "properly using Unicode." The main issue is that ligatures can cause confusion if the reader doesn't know the ligature (which is most readers).

For what it's worth, I like using font ligatures on my own IDEs. I think they look nice. But I would never choose them for anything displayed for anyone else.

[+] avgcorrection|4 years ago|reply
Ligatures in code fonts are an interesting development. I don’t have any experience with them. The most neat thing about them is that they are very much a only-I-need-to-use-this convenience. It doesn’t really infringe on anyone.

For the most part. I used a beginner Haskell book for some course. And they used the proper symbols for some operators. But then newbies might think that the symbols used in the book is what constitutes what raw Haskell looks like, which is wrong. So that’s very inappropriate.

On the other hand, this is not the same as using ligatures to display things like `==` in an editor; the former is text substitution, while the latter is purely a visual thing. And I am fine with the latter as long as it is not misleading.

These visual ligatures are the closest thing that most languages will get to using “nice-looking” (subjective) symbols instead of just every combination of all the printable ASCII symbols. Now, using Unicode in some new tech is intrusive since that is a decision that affect all users of that tech. The author of this piece did do that in his Pollen by using U+25CA LOZENGE (`◊`) as the central metacharacter. I don’t know how that panned out since I haven’t used that very interesting typesetting language.

Modern/new languages might want to loosen up on the aversion they have towards Unicode. But it’s a chicken and egg problem: input methods suck so most languages don’t want to burden their users with having to use symbols that don’t show up on their keyboards. And in turn input methods suck because we often don’t need anything better (at least us who are monolinguals and/or from the West). Maybe the best that languages that want to use Unicode can do is to provide Unicode symbols as an alternative by making sure that some ASCII soup can always be used instead (kind of like C’s trigraphs…).

[+] pletnes|4 years ago|reply
This reminds me of discussions with older Fortran programmers who argue for ALL CAPS ALWAYS.

I guess ligatures are fine by me, I use them and have not been bitten. Editors should rather focus on showing whitespace somehow, I have been bitten by tab/space/CRLF many times!

[+] d--b|4 years ago|reply
I use ligatures that turn spaces into tabs.
[+] crvdgc|4 years ago|reply
Ligatures help to convey the intended meaning of the code, which outweighs the rare case when they go wrong.

Programming languages' operators like == are actually ASCII arts for the convenience of the machines, never the humans. It is encoding a concept that is not representable in ASCII, so it has to be encoded by a conventional combination of two characters. When reading your own or others code, you have to do this subtle mental labor of decoding the ASCII art back to the concept.

Programming ligatures, on the other hand, alleviate this burden. They conform the intended meaning of the author. It's not a typographical problem, rather it's a communication problem.

For most ligatures, you can guess the underlying ASCII codes, and if you can't guess, you only need to learn once. In an editor or on a webpage, you can copy the code and paste onto something that doesn't have the ligature font enabled to learn its components.

The idea case is Unicode programming like Agda, but it has its own problems like not easy to type and find out how to type, lacking some operators, hard to read with small font size, etc.

Ligatures are a balanced option between the ASCII art and the Unicode programming. Not hell yes, but neither hell no.

[+] neetrain|4 years ago|reply
I personally love ligatures, but

  if you’re preparing your code for others to read—whether on screen or on paper—skip the ligatures.
I can agree with this.