

Ask HN: Why not use variable-width fonts for programming? - gkya

Should all the programmers agree that they will not tabulate code and indentation interval will be fixed (i.e. one tab or n spaces no matter what, no alignments), would there still be a merit to prefer monospaced typeface over variable-width?<p>I&#x27;ve been programming for a long while, and all that time have I used monospace fonts.  I haven&#x27;t approached the subject empirically, and neither have thought deeply, but as is scratches my mind, I thought I&#x27;d ask this to people who are more experienced and knowledgeable than me on the subject via HN.
======
tlb
I've tried it and didn't like it. You often have successive similar lines with
slightly different identifiers, and if they don't quite line up it's visually
jarring. A graphics example:

    
    
          var p0X = lo.convWeekToX(0);
          var p0Y = lo.convFlowToY(m.rev0);
          var p1X = lo.convWeekToX(0);
          var p1Y = lo.convFlowToY(m.exp0);
          var p2X = lo.convWeekToX(m.breakevenWeek);
          var p2Y = lo.convFlowToY(m.breakevenFlow);
          ctx.moveTo(p0X, p0Y);
          ctx.lineTo(p1X, p1Y);
          ctx.lineTo(p2X, p2Y);
    

That, rendered in a font where X, Y and Z aren't the exact same width, makes
you want to scratch your eyeballs out:

. var p0X = lo.convWeekToX(0);

. var p0Y = lo.convFlowToY(m.rev0);

. var p1X = lo.convWeekToX(0);

. var p1Y = lo.convFlowToY(m.exp0);

. var p2X = lo.convWeekToX(m.breakevenWeek);

. var p2Y = lo.convFlowToY(m.breakevenFlow);

. ctx.moveTo(p0X, p0Y);

. ctx.lineTo(p1X, p1Y);

. ctx.lineTo(p2X, p2Y);

------
lutusp
Where indentation is present/relevant, monospaced fonts are critical for
interpreting a program's logical structure at a glance. And in more than
trivial programming, indentation is always present/relevant.

> Should all the programmers agree that they will not tabulate code and
> indentation interval will be fixed (i.e. one tab or n spaces no matter what,
> no alignments) ...

In indentation, never use tabs. Always use spaces. Tabs are open to
reinterpretation as you change editing environments, spaces aren't. I can't
tell you how many times I've heard from novice Python programmers whose
programs appeared to be structurally correct but failed to run as expected,
after which a more experienced programmer suggested that the embedded tabs be
removed and the code reviewed and manually re-indented.

More here:
[https://www.google.com/search?q=python+tabs](https://www.google.com/search?q=python+tabs)

~~~
gkya
I write Python, but it is only _among_ the languages I use and the languages
there are. Here is some Python displayed with Raleway font:
<[http://cadadr.tumblr.com/post/75836598049/here-is-some-
pytho...](http://cadadr.tumblr.com/post/75836598049/here-is-some-python-
displayed-with-the-raleway>). The code is indented with 4 spaces. I cannot see
any problems with the left outline of the code (I am not arguing it is _good_
though, I am only arguing that it _functions_ ).

Also, if each interval of indentation is _n_ spaces, won't the indentation
look aligned anyway, as the width of a space character is constant?

> In indentation, never use tabs. Always use spaces. Tabs are open to
> reinterpretation [...]

I take this as a good property of tabs, given that spaces aren't used for
micro-alignment, that indentation is formed only of tabs. This enables
different people with different tastes to easily collaborate: I personally
like wide indentation, so I keep my tab width as wide as 8 space characters.
But, say, if you were to read my code and liked smaller intervals of
indentation, you can set your tab width to, say, two spaces, and view the code
as you like it, whereas with hard spaces, this is impossible without actually
changing the file.

~~~
lutusp
Fair enough. But try this (or any of its many equivalents) with a proportional
font or tabs:

    
    
          #!/usr/bin/env python
          # -*- coding: utf-8 -*-
          
          s = ''
          
          for y in range(1,13):
            for x in range(1,13):
              s += '%4d' % (x*y)
            s += '\n'
            
          print(s)
          
             1   2   3   4   5   6   7   8   9  10  11  12
             2   4   6   8  10  12  14  16  18  20  22  24
             3   6   9  12  15  18  21  24  27  30  33  36
             4   8  12  16  20  24  28  32  36  40  44  48
             5  10  15  20  25  30  35  40  45  50  55  60
             6  12  18  24  30  36  42  48  54  60  66  72
             7  14  21  28  35  42  49  56  63  70  77  84
             8  16  24  32  40  48  56  64  72  80  88  96
             9  18  27  36  45  54  63  72  81  90  99 108
            10  20  30  40  50  60  70  80  90 100 110 120
            11  22  33  44  55  66  77  88  99 110 121 132
            12  24  36  48  60  72  84  96 108 120 132 144
          

Or this:

    
    
            #!/usr/bin/env python
            # -*- coding: utf-8 -*-
            
            from numpy import arange
            
            # dimensional parameters for the set
            
            yl = -1.2
            yh = 1.2
            ys = .05
            
            xl = -2.05
            xh = 0.55
            xs = 0.03
            
            def mandelbrot(c):
              z = 0
              for n in range(10):
                z = z*z + c
                if(abs(z) > 2):
                  return '.'
              return '*'
              
            s = ''
            for y in arange(yl,yh,ys):
              for x in arange(xl,xh,xs):
                s += mandelbrot(complex(x,y))
              s += '\n'
              
            print(s)
            
            .......................................................................................
            .......................................................................................
            ..............................................................**.......................
            ...............................................................*.......................
            ................................................................*..**..................
            ................................................................***....................
            ...............................................................****....................
            ...........................................................***********.................
            ............................................................**********.................
            ...........................................................***********.................
            ...................................................*.......***********..........*......
            .................................................****..********************.....*......
            ................................................***********************************....
            .................................................********************************......
            ...............................................**********************************......
            .............................................************************************......
            .............................................*************************************.....
            ..........................**......*.........*****************************************..
            ............................***********.....***************************************....
            ............................********************************************************...
            ..........................*********************************************************....
            .....................*....*********************************************************....
            ......................************************************************************.....
            .....................***********************************************************.......
            ..*****************************************************************************........
            .....................***********************************************************.......
            ......................************************************************************.....
            .....................*....*********************************************************....
            ..........................*********************************************************....
            ............................********************************************************...
            ............................***********.....***************************************....
            ..........................**......*.........*****************************************..
            .............................................*************************************.....
            .............................................************************************......
            ...............................................**********************************......
            .................................................********************************......
            ................................................***********************************....
            .................................................****..********************.....*......
            ...................................................*.......***********..........*......
            ...........................................................***********.................
            ............................................................**********.................
            ...........................................................***********.................
            ...............................................................****....................
            ................................................................***....................
            ................................................................*..**..................
            ...............................................................*.......................
            ..............................................................**.......................
            .......................................................................................

------
lakwn
To me it's really a matter of symmetry. Having lines of code that do similar
things look aligned is readable and beautiful.

Hence in Ruby, for example, I love how the "case" statement makes it easy for
several conditions to be aligned:

    
    
      case
      when a == 0
      when b == 0
      end
    

In C++, "a == 0" and "b == 0" don't align:

    
    
      if (a == 0)
      {
      }
      else if (b == 0)
      {
      }
    

Now imagine that on a much wider scale. With variable-width fonts the only
thing that would ever align would be the beginning of lines. A visual
nightmare that affects readability.

------
dalke
There's a long tradition of using fixed width fonts. As a result, some of the
'infrastructure' is built with that assumption.

For example, people will draw ASCII pictures for simple diagrams in the code
and comments. In some of my code (I work with chemistry) I listed the element
symbols laid out as a periodic table-like grid. This only works with fixed
width fields.

And of course multi-line parameters are usually continued inside of the
leading '(', as in this forward declaration:

    
    
        int reorder(int num_results, search_result *results,
                    const char *ordering);
    

Not surprisingly, there is a StackOverflow question on this topic, at
[http://stackoverflow.com/questions/218623/why-use-
monospace-...](http://stackoverflow.com/questions/218623/why-use-monospace-
fonts-in-your-ide) .

Equally not surprisingly, and sadly, it's marked "closed as not constructive".

~~~
gkya
> For example, people will draw ASCII pictures for simple diagrams in the code
> and comments. In some of my code (I work with chemistry) I listed the
> element symbols laid out as a periodic table-like grid. This only works with
> fixed width fields. > And of course multi-line parameters are usually
> continued inside of the leading '(', as in this forward declaration:

Thus did I express in the initial post, that I assume we do not do this kind
of alignments, and the interval of indentation is fixed, i.e. is always a
multiple of a given number of spaces, or exactly one tab character.

~~~
dalke
I gave that example for two reasons. One is that it's not possible to assume
the world can change. There's a big installed base.

The second is that your solution - fixed indentation levels, etc - doesn't
work for this case. Or as a challenge, what's your better way of writing this
yacc-style BNF in a proportional font?

    
    
        atom_symbols ::=
         'H' |                                                                                'He'
        |'Li'|'Be'|                                                  'B' |'C' |'N' |'O' |'F' |'Ne'
        |'Na'|'Mg'|                                                  'Al'|'Si'|'P' |'S' |'Cl'|'Ar'
        |'K' |'Ca'|'Sc'|'Ti'|'V' |'Cr'|'Mn'|'Fe'|'Co'|'Ni'|'Cu'|'Zn'|'Ga'|'Ge'|'As'|'Se'|'Br'|'Kr'
        |'Rb'|'Sr'|'Y' |'Zr'|'Nb'|'Mo'|'Tc'|'Ru'|'Rh'|'Pd'|'Ag'|'Cd'|'In'|'Sn'|'Sb'|'Te'|'I' |'Xe'
        |'Cs'|'Ba'|     'Hf'|'Ta'|'W' |'Re'|'Os'|'Ir'|'Pt'|'Au'|'Hg'|'Tl'|'Pb'|'Bi'|'Po'|'At'|'Rn'
        |'Fr'|'Ra'|     'Rf'|'Db'|'Sg'|'Bh'|'Hs'|'Mt'|'Ds'|'Rg'
    
        |'La'|'Ce'|'Pr'|'Nd'|'Pm'|'Sm'|'Eu'|'Gd'|'Tb'|'Dy'|'Ho'|'Er'|'Tm'|'Yb'|'Lu'
        |'Ac'|'Th'|'Pa'|'U' |'Np'|'Pu'|'Am'|'Cm'|'Bk'|'Cf'|'Es'|'Fm'|'Md'|'No'|'Lr';
    

Every example I can think of is uglier, and harder to understand. The only
solution is that everyone switches to a source code encoding which includes
enough presentation capabilities that it supports embedded tables. I don't see
that happening any time soon.

Do you have a better suggestion of how to lay this out in some alternative
environment?

~~~
gkya
I do not have a counter-example, and think that in this case, a monospaced
font is necessary for good presentation. However, I'd not format this code in
this shape in the first place, instead list them linearly with line breaks
where due:

    
    
      atom_symbols ::=
        'H' | 'He' ... 'Na' |
        'Be' ...;
    

This way it is easier to edit, automatically wrap (not meaning that the
periodic table will change drastically soon, but this might have been a table
of sth. else) and read the snippet. This is more of a matter of personal
delight though.

~~~
dalke
Now you're throwing away data in preference of your own beliefs. That's a
dangerous path.

Of course if this is a table of something else then it _might_ be okay to use
a different formatting. But that I could easily give a counter-example,
suggests that there are plenty of counter-examples.

You argue that a linear list, without spacing, has advantages. My assertion is
that you don't have the experience to make that judgement. Anyone using this
layout will have chemistry experience, and often decades of practice of
looking at the periodic table in standard form. When I consider at your
suggested layout, I find it a bit jarring.

For one, the symbols you wrote are out-of-order, which means it's hard to
infer some information from the table.

For example, what is the age of the this instance of the table? A chemist
knows, from experience with the standard periodic table layout, and my use of
that layout, that Rg is the newest element on the list. This immediately
places it as a pre-2009 table, which means I should update it.

Here's an example from Python heapq.py implementation, rewritten slightly to
work in HN (I switched from triple-quoted strings to '#' comments):

    
    
        # The strange invariant above is meant to be an efficient memory
        # representation for a tournament.  The numbers below are `k', not a[k]:
        # 
        #                                0
        #
        #               1                                 2
        # 
        #       3               4                5               6
        #
        #   7       8       9       10      11      12      13      14
        #
        # 15 16   17 18   19 20   21 22   23 24   25 26   27 28   29 30 
        #
        #
        # In the tree above, each cell `k' is topping `2*k+1' and `2*k+2'.
    

This is a tree structure layout in ASCII. It's useful information, and it
can't easily be structured or represented in a proportional font.

------
gkya
BTW, I haven't changed my editor's font to a variable-width font and am not
telling that we _should_ go this way; just wanted to start a discussion on the
topic.

