muflax65ngodyewp.onion/content_blog/hack/xmonad.mkd

9.1 KiB

title alt_titles date techne episteme
Meditation on XMonad
XMonad
2010-05-03 :done :discredited

Ignorance is the root of all suffering - ignorance about reality, about what is. By holding wrong assumptions, we create false expectations and false needs. 1

I will not reflect on large parts of reality, but only a small one: window managers (WM). 2

The most basic ignorance about WMs is the ignorance about their existence. The computer does not just show data to us, but it can show it to us in any way we want. It is this basic understanding that leads to the first conclusion: If the way data is shown to us is lacking, it is not our fault, but the computer is not doing it's job properly. Furthermore, if we have to spend a lot of time just telling the computer how we would like to see something, we are actually doing someone (or rather, something) else's work.

Therefore, tiling WMs. If you arrange your own windows, why are you using a WM at all? Wouldn't it be more honest, instead of saying "I'm running Windows / KDE / OS X to show my windows", to admit "Windows / KDE / OS X is running me to show it's windows."? Sure, the computer can not read your mind and some occasional hints might be necessary, but the less work you do, the better.

Desire creates suffering. This is maybe the most misunderstood of Buddhist truths. People hear "desire creates suffering" and think "What? Is this going to be a moral how material possessions are bad for me? Money, cars, houses and so on lead to greed, obsession, and so on. I get it.". This is not what this is about. The problem with desire is not the desire itself. It is not a problem that we want to be happy, to be rich and so on. The problem is, instead, that what we want is impossible. Our desires fail us. We are mistaken about the nature of reality and expect the wrong things. We think that money could make us happier, so we want more of it, but it ultimately won't. From wrong assumptions you can only get bad results.

In retrospect, I can see this clearly now on my journey to a better window manager. It was my unwillingness to let go of old habits, my wrong ideas about what I really need or want, that made adopting a new WM hard. So I went first to WMs that offered great configuralibity and many features. "You can do anything you want!" But this lead to useless features and distractions. It is only now that most WMs fail me because my hardware setup is a bit tricky, that I can understand. Only now when I understand better what my brain really needs, do I grow tired of those full of bad design. Xmonad, in a way, is peace for me. It is mathematical in nature. The fact that it is written in Haskell might seem like a gimmick at first, but the connection is in fact very deep. I understand now that it could not have been written in anything else. Xmonad exemplifies the idea of purely functional programming. "Normal" programming is almost always imperative - the programmer tells the computer how to do something. But in functional programming, the hacker instead tells the computer what something is. This is a profound difference.3

In any other customizable WM I have ever used, I would create a complex configuration to tell it exactly what I wanted it to do in some case or another. I would do the bulk of the lifting, so to speak, either by constantly adjusting the windows the WM handled wrong or by writing elaborate procedures to automate this work. But with Xmonad, this is different. It is not my job to figure out how to arrange windows, so I should never have to tell my WM anything about this. The only thing I ever have to tell it is about what is. I should never write something like "to go to the next tag, you read in all tags, sort them, filter some out, find the current one and then shift to the next in the list". I instead write: "I want the next non-empty, non-visible tag now". I give Xmonad a few simple hints and that is it. "If it's name is in this list, I want it floating. If I'm currently out of space here, try a different screen. There is a status bar I'm running, so be careful not to overlap it."

For the first time, I feel like my WM is actually intelligent and wants to help me. It is not my slave, not my servant who follows my orders. It does not look down on me, thinking itself smarter than me, only an obstacle to its flawless performance. Instead, Xmonad is my friend. It understands window handling and can take care of it. I only tell it some personal preferences. If it doesn't think I need something, it is probably right.

It is astonishing how easily we pick up delusions. We see something once and think it should always be that way. Rarely do we question "Is this really necessary? Is there no other way?"

For me, those are some of the delusions that clouded my judgement about WMs.

"I need space! I want to see my desktop wallpaper!" What for? Have I not something better to do than to stare at pretty pictures?

"I want to tell my WM what window is in the foreground and what in the background." The very concept is wrong. There is no "foreground" with focus - you either see something or you don't. A window you can not read might as well not be there at all.

"I understand now, I use a tiling WM. But I want to control what window is where!" Why? The very idea of a tiling WM is that the WM figures out what to show you and how. You simply tell it what application has your focus right now and what other applications belong to it (by giving them all the same tag / workspace).

"Xmonad has no stacked layout like wmii! I can not easily put dozens of windows in one column!" Why would you do this in the first place? You certainly can not read them all. Let Xmonad only show you the ones that matter and search for other ones if you need them. Or think about grouping them better. Why open 20 PDFs in separate windows if your viewer can take care of that?

"Xmonad has no title bars.4 I will miss those!" Are you sure? What do you use them for? The window content itself tells you what the window is. If the content is not visible, then a title bar will only waste space. If you need to find something, let the WM do it for you. If you want status reports, use notifications.

By embracing not complexity, but simplicity, confusion ends. The best solution to a problem is to make it obsolete - as Gordon Bells said, "The cheapest, fastest, and most reliable components are those that aren't there.".

By concentrating not on how, but on what, false desires disappear. By letting go off false desires, suffering ends.

<%= image("guru.png", "Guru Meditation") %>


  1. Yeah, I have been reading Buddhist philosophy and history again. Can you tell? ↩︎

  2. The old monks have understood one thing: Truths about reality must be visible everywhere. There can not be any aspect of reality that is not permeated by them. Thus, we can improve our efforts by just focusing on one simple object. Traditionally, one's breath, a candle or a rock have served this purpose. Some Zen traditions use 只管打坐 (shikantaza, "simply correct sitting") for this. If you can't understand reality just by sitting down and concentrating, then reality can't be understood at all. Therefore we must be able to see all those Buddhist observations in everything we use, including the most fundamental GUI software - our window manager. ↩︎

  3. The classical example to demonstrate this is Quicksort. If you have ever programmed something, Quicksort was probably among it, but just to help you remember, I'm gonna tell you again what Quicksort is. We define Quicksort recursively like so: An empty sort is always sorted. To sort a list with at least one element, we take the first element (called the pivot) in the list and then separate the rest into two lists, one containing all the elements that are smaller and one containing all that are larger than the pivot. Now, to get the sorted result, we simply sort the first list, than add the pivot and finally add the sorted second list. Think about how you would solve this in an imperative language. In C, it would go something like this:

    #!c
    void swap(int *a, int *b)
    {
      int t=*a; *a=*b; *b=t;
    }
    void sort(int arr[], int beg, int end)
    {
      if (end > beg + 1) {
        int piv = arr[beg], l = beg + 1, r = end;
        while (l < r) {
          if (arr[l] <= piv)
            l++;
          else
            swap(&arr[l], &arr[--r]);
        }
        swap(&arr[--l], &arr[beg]);
        sort(arr, beg, l);
        sort(arr, r, end);
      }
    }
    

    This is a typical example - we tell the computer exactly what to do to get the result we are interested in. But remember I said that in a functional language, we tell the computer what something is. I already told you what Quicksort is, so let's write this down in Haskell:

    #!haskell
    qsort [] = []
    qsort (x:xs) = qsort lesser ++ [x] ++ qsort greater
         where lesser  = [y | y <- xs, y < x]
               greater = [y | y <- xs, y >= x]
    

    And that's it. ↩︎

  4. Technically, you can add them, but they are not normally there. ↩︎