The Universe of Discourse


Sat, 27 Feb 2021

Fuckin' user interface design, I swear

I'm so old I can remember when forms were introducted to the web; as you can imagine it was a big advance. The initial spec included the usual text boxes, radio buttons, and so forth, two types of “submit” buttons, and a “reset” button. Clicking “reset” would reset the form contents to a defined initial state, normally empty.

So you'd have a bunch of form widgets, and then, at the bottom, a Submit button, and next to it, a Reset button.

Even as an innocent youth, I realized this was a bad design. It is just setting people up for failure. They might get the form all filled out, be about to submit it, but click a few pixels off, hit the Reset button by mistake, and have to start all over again.

Obviously, the Submit button should be over on the left, just under the main form, where the user will visit it in due course after dealing with the other widgets, and the Reset button should be way over on the right, where it is less likely to be hit by accident.

(Or, more likely, it shouldn't be anywhere; in most cases it is nothing but an attractive nuisance. How often does someone need to reset the form anyway? How badly would they have to screw it up to decide that it would be quicker to start over than to simply correct their errors?)

Does my “obviously” come across as superior and condescending? Honestly, it comes from a place of humility. My thinking is like this:

  • The field of user inteface design is skilled work
  • I have no training or experience in this field
  • Also, I have no talent in design generally (Just look at this page!)
  • Experience has proved that I am very stupid about this whole area
  • But this particular problem is apparent even to a blockhead like me
  • So it must be extremely obvious

But maybe I'm not giving myself enough credit. I said “obviously” but it sure wasn't obvious to many people at the time. I remember 90% of the forms I encountered having that Reset button at the bottom, at least into the late 1990s.

A still from _The Simpsons_, showing
the sushi chef's instruction book, open to the page about “FUGU”.  A
surly purple fish is depicted.  Several large sections are marked off
with dotted lines and labeled with skulls.  Only one narrow sliver
lacks a skull-and-crossbones.

And it's on my mind because my co-workers had a discussion about it at work last week: don't put the Cancel button right next to the Submit button. If this was obvious to dumbass me in 1994, why isn't it common knowledge by now?

Don't put the Yes button right next to the No button. That encourages mistakes. Obviously.

Don't put the commonly-used "close this window" keyboard shortcut right next to the infrequently-used and irreversible "quit this application" shortcut. In particular, don't put "close this window" on control-W and "quit this application" on control-Q. I'm looking at you, Firefox.


And that brings me to my real point. Can we talk about Google Meet?

These three buttons are at the bottom of the Google Meet videoconferencing app. The left one temporarily mutes and unmutes the microphone. The right one controls the camera similarly.

Three circular
red-and-white buttons, one with an icon of a microphone, one with an
icon of a hanging-up telephone handset, and one with an icon of a
video camera.

And if you click the button in between, you immediately leave the meeting and quit the app.

Now, as I said I'm pretty damn stupid when it comes to design, but geez, louise. Couldn't Google find someone less stupid than me?

[ Addendum 20210228: Google fucks up again. ]


[Other articles in category /tech] permanent link

Tue, 16 Feb 2021

The ideal gas law

Katara is toiling through A.P. Chemistry this year. I never took A.P. Chemistry but I did take regular high school chemistry and two semesters of university chemistry so it falls to me to help her out when things get too confusing. Lately she has been studying gas equilibria and thermodynamics, in which the so-called ideal gas law plays a central role: $$ PV=nRT$$

This is when you have a gas confined in a container of volume !!V!!. !!P!! is the pressure exerted by the gas on the walls of the container, the !!n!! is the number of gas particles, and the !!T!! is the absolute temperature. !!R!! is a constant, called the “ideal gas constant”. Most real gases do obey this law pretty closely, at least at reasonably low pressures.

The law implies all sorts of interesting things. For example, if you have gas in a container and heat it up so as to double the (absolute) temperature, the gas would like to expand into twice the original volume. If the container is rigid the pressure will double, but if the gas is in a balloon, the balloon will double in size instead. Then if you take the balloon up in an airplane so that the ambient pressure is half as much, the balloon will double in size again.

I had seen this many times and while it all seems reasonable and makes sense, I had never really thought about what it means. Sometimes stuff in physics doesn't mean anything, but sometimes you can relate it to a more fundamental law. For example, in The Character of Physical Law, Feynman points out that the Archimedean lever law is just an expression of the law of conservation of energy, as applied to the potential energy of the weights on the arms of the lever. Thinking about the ideal gas law carefully, for the first time in my life, I realized that it is also a special case of the law of conservation of energy!

The gas molecules are zipping around with various energies, and this kinetic energy manifests on the macro scale as as pressure (when they bump into the walls of the container) and as volume (when they bump into other molecules, forcing the other particles away.)

The pressure is measured in units of dimension !!\frac{\rm force}{\rm area}!!, say newtons per square meter. The product !!PV!! of pressure and volume is $$ \frac{\rm force}{\rm area}\cdot{\rm volume} = \frac{\rm force}{{\rm distance}^2}\cdot{\rm distance}^3 = {\rm force}\cdot{\rm distance} = {\rm energy}. $$ So the equation is equating two ways to measure the same total energy of the gas.

Over on the right-hand side, we also have energy. The absolute temperature !!T!! is the average energy per molecule and the !!n!! counts the number of molecules; multiply them and you get the total energy in a different way.

The !!R!! is nothing mysterious; it's just a proportionality constant required to get the units to match up when we measure temperature in kelvins and count molecules in moles. It's analogous to the mysterious Cookie Constant that relates energy you have to expend on the treadmill with energy you gain from eating cookies. The Cookie Constant is !!1043 \frac{\rm sec}{\rm cookie}!!. !!R!! happens to be around 8.3 joules per mole per kelvin.

(Actually I think there might be a bit more to !!R!! than I said, something about the Boltzmann distribution in there.)

Somehow this got me and Katara thinking about what a mole of chocolate chips would look like. “Better use those mini chips,” said Katara.


[Other articles in category /physics] permanent link

Mon, 15 Feb 2021

Mystery twitter language

Today someone tweeted about an earlier blog article of mine, saying

10° bir kvadratda ən böyük şəhərləri görə biləcəyiniz bir xəritə olan bir sayt.

I looked at that and frowned, and said “What language is that? … is it Azerbaijani?” And it is Azerbaijani! Last time I encountered Azerbaijani I did not recognize it. So I not only learned something last April, I remembered it the following February when it came up again. Yay me!


[Other articles in category /lang] permanent link

Sat, 13 Feb 2021

Paul L. Smith as Bluto

Yesterday I wondered who Robert Altman had cast as Bluto in his 1980 live-action film Popeye. The answer turned out to be Paul L. Smith, who seemingly was born to play the part:

Paul L. Smith
is a heavyset, slightly overwight man with a thick, curly black beard
and mustache.  In this (grayscale) picture his shirt, which appears to
be velour, is open at the neck, dispolaying a necklace with a large
star resting among a profusion of curly black chest hair.  He is
wearing a battered leather hat with a wide brim, and is looking
sidelong at the camera, with a smile of amusement.

I have thought for years about how Shelley Duval was seemingly born to play the part of Olive Oyl. (I remember the Mad magazine parody making this observation at the time, and it wasn't funny because it was so obvious.) I have somtimes wondered if Altman got the idea to make a Popeye movie specifically so that he could cast Duval as Olive Oyl.

Anyway, Paul L. Smith, who already looked like Bluto. He was in a fair number of TV productions in the 70s and 80s, and I think it's possible that I saw him in one or another one. But the only other role of his that I remember clearly is from David Lynch's 1984 Dune. He plays Glossu “the Beast” Rabban. Who in many ways is not that different from Bluto: Large, violent, dangerous for his brutality but not his cunning.

Obviously the Baron wanted to cast Feyd-Rautha as Popeye, but events got away from him and Paul became Popeye instead. In a Dune-Popeye crossover I can see Alia as Swee'Pea. That means that Chani has to be Olive, which I can live with.

The correspondence isn't perfect, of course. There is nobody in Popeye like Lady Jessica or Stilgar. (Leto is obviously Poopdeck Pappy.) On the other side, where is J. Wellington Wimpy? It's been a while since I read the book, but I don't remember him appearing. Reverend Mother Gaius Helen Mohiam is clearly the Sea Hag.

Me spinach musk flow! If ya controlsk the spinach, ya controlsk the uni-voice! Ag-ag-ag-ag-ag!


[Other articles in category /misc] permanent link

Mon, 08 Feb 2021

Down in the dumps

I was reading The Life and Prankes of Long Meg of Westminster (1655), which opens with the story of how Long Meg first came to London with a posse of three or four girlfriends. After long travel they came within sight of London, “which joyed their hearts greatly.” But as they got closer, Meg's friends became less cheerful, and she said to them:

What Lasses in a dumpe, and we so nigh London?

If someone had asked me to guess when “in a dump” or “in the dumps” had been coined, I think I would have guessed sometime in the early 20th century. Nope! The Big Dictionary has cites back to 1535, which is when Long Meg takes place. It also cites a 1785 dictionary for “down in the dumps” specifically. The phrase is not connected with the dump where you dump a load of trash, which is of much later coinage.

It transpires that the lasses are in a dumpe because they realize that time has come to pay the carrier who has helped transport them to London, and believe he is likely to try to cheat them and take everything they have. Meg says she will reason sweetly with the carrier, and if that doesn't work, she will beat the crap out of him.

The carrier does try to take everything they have, but becomes much more helpful after Meg has beaten him with a cudgel.

Here it is if you would like to read it yourself.


[Other articles in category /lang] permanent link

Sun, 07 Feb 2021

More things that changed in later editions of Snow White

As you know, I've recently been looking into the original version of Snow White from 1812. ([1] [2]) I knew that the 1812 version of the Grimm stories was a lot rougher and more gruesome than the later editions, but I missed many of the details. For example, in the later versions, the evil queen orders her hunter to bring back Snow White's liver and lungs as proof that he has murdered her. In the first edition, she wants the liver and lungs so that she can eat them.

After Snow White is poisoned with the apple, the dwarfs put her in a glass coffin. A prince happens by and begs them to give it to him, which they do. In the later versions, the servants carrying away the coffin stumble, the apple is dislodged from Snow White's throat, and she returns to life.

In the original version, they get the coffin back to the prince's palace without mishap. There the prince has the servants carry it from room to room so that he can gaze at it always. (Ugh.)

Finally, the servants are so fed up with this that one of them takes Snow White out of the coffin, stands her up, and, saying

We are plagued the whole day long, just because of such a dead girl

he clouts her in the back from pure spite.

The apple is dislodged, and Snow White marries the prince.


[Other articles in category /book] permanent link

Sat, 06 Feb 2021

Hacking the git shell prompt

Git comes with a very complicated shell function,, called __git_ps1, for interpolating Git information into your shell prompt. A typical use would be:

    PS1='>>> $(__git_ps1) :) '

PS1 is the variable that contains the shell's main prompt. Before printing the prompt, the shell does variable and command interpolation on this string. This means that if PS1 contains something like $(command args...), the shell replaces that string with the output from running command args…. Here, it runs __git_ps1 and inserts the output into the prompt. In the simplest case, __git_ps1 emits the name of the currently-checked-out branch, so that the shell will actually print this prompt:

    >>> the-branch :) 

But __git_ps1 has many other features besides. If you are in the middle of a rebase or cherry-pick operation, it will emit something like

    the-branch|REBASE-i 1/5

or

    the-branch|CHERRY-PICKING

instead. If HEAD is detached, it can still display the head location in several formats. There are options to have the emitted string indicate when the working tree is dirty and other things. My own PS1 looks like this:

    PS1='[$(_path) $(__git_ps1 "(%s)" )]> '

The _path command is something I wrote to emit the path of the current working directory, abbreviated in a contextually dependent way. It makes my prompt look like this:

    [lib/app (the-branch)]> 

Here lib/app is the path relative to the root of the repository.

The %s thing is an additional formatting instruction to __git_ps1. After it computes the description string, __git_ps1 inserts it into "(%s)" in place of the %s, and emits the result of that replacement. If you don't give __git_ps1 an argument, it uses "(%s) " as a default, which has an extra space compared with what I have.

Lately I have been experimenting with appending .mjd.yyyymmdd to my public branch names, to help me remember to delete my old dead branches from the shared repository. This makes the branch names annoyingly long:

    gh1067-sort-dates-chronologically.mjd.20210103
    gh1067-sort-dates-no-test.mjd.20210112
    gh1088-cache-analysis-list.mjd.20210105

and these annoyingly long names appear in the output of __git_ps1 that is inserted into my shell prompts.

One way to deal with this is to have the local branch names be abbreviated and configure their upstream names to the long versions. And that does work: I now have a little program called new-branch that creates a new branch with the local short name, pushes it to the long remote name, and sets the upstream. But I also wanted a generic mechanism for abbreviating or transforming the branch name in the prompt.

The supplied __git_ps1 function didn't seem to have an option for that, or a callback for modifying the branch name before inserting it into the prompt. I could have copied the function, modified the parts I wanted, and used the modified version in place of the supplied version, but it is 243 lines long, so I preferred not to do that.

But __git_ps1 does have one hook. Under the right circumstances, it will attempt to colorize the prompt by inserting terminal escape codes. To do this it invokes __git_ps_colorize_gitstring to insert the escape codes into the various prompt components before it assembles them. I can work with that!

The goal is now:

  • Figure out how to tell __git_ps1 to call __git_ps_colorize_gitstring
  • Figure out how __git_ps1 and __git_ps_colorize_gitstring communicate prompt components
  • Write my own __git_ps_colorize_gitstring to do something else

How to tell __git_ps1 to call __git_ps_colorize_gitstring

You have to do two things to get __git_ps1 to call the hook:

  1. Set GIT_PS1_SHOWCOLORHINTS to some nonempty string. I set it to true, which is a little deceptive, because false would have worked as well.

  2. Invoke __git_ps1 with two or more arguments.

Unfortunately, invoking the __git_ps1 with two or more arguments changes its behavior in another way. It still computes a string, but it no longer prints the string. Instead, it computes the string and assigns it to PS1. This means that

  PS1="$(__git_ps arg arg….)"

won't work properly: the next time the shell wants to prompt, it will evaluate PS1, which will call __git_ps arg arg…, which will set PS1 to some string like (the-branch). Then the next time the shell wants to print the prompt, it will evaluate PS1, which will be just some dead string like (the-branch), with nothing in it to call __git_ps1 again.

So we need to use a different shell feature. Instead of setting PS1 directly, we set PROMPT_COMMAND. This command is run before the prompt is printed. Although this doesn't have anything to do directly with the prompt, the command can change the prompt. If we set PROMPT_COMMAND to invoke __git_ps1, and if __git_ps1 modifies PS1, the prompt will change.

Formerly I had had this:

    PS1='[$(_path) $(__git_ps1 "(%s)")]> '

but instead I needed to use:

    GIT_PS1_SHOWCOLORHINTS=true
    PROMPT_COMMAND='__git_ps1 "[$(_path) " " ] "' "(%s)"

Here __git_ps1 is getting three arguments:

  1. "[$(_path) "
  2. " ] "
  3. "(%s)"

__git_ps1 computes its description of the Git state and inserts it into the third argument in place of the %s. Then it takes the result of this replacement, appends the first argument on the front and the second on the back, and sets the prompt to the result. The shell will still invoke _path in the course of evaluating the first string, before passing it to __git_ps1 as an argument. Whew.

How __git_ps1 communicates prompt components to __git_ps_colorize_gitstring

The end result of all this rigamarole is that __git_ps1 is now being called before every prompt, as before, but now it will also invoke __git_ps_colorize_gitstring along the way. What does that actually get us?

The internals of __git_ps_colorize_gitstring aren't documented because I don't think this is a planned use case, and __git_ps_colorize_gitstring isn't an advertised part of the interface. __git_ps1 does something to construct the prompt, possibly colorizing it in the process, but how it does the colorizing is forbidden knowledge. From looking at the code I can see that the colorizing is done by __git_ps_colorize_gitstring, and I needed to know what was going in inside.

The (current) interface is that __git_ps1 puts the various components of the prompts into a family of single-letter variables, which __git_ps_colorize_gitstring modifies. Here's what these variables do, as best as I have been able to ascertain:

b contains a description of the current HEAD, either the current branch name or some other description

c indicates if you are in a bare repository

i indicates if changes have been recorded to the index

p contains information about whether the current head is behind or ahead of its upstream branch

r describes the rebase / merge / cherry-pick state

s indicates if there is something in the stash

u indicates whether there are untracked files

w indicates whether the working tree is dirty

z is the separator between the branch name and the other indicators

Oddly, the one thing I wanted to change is the only one that __git_ps_colorize_gitstring doesn't modify: the b variable that contains the name or description of the current branch. Fortunately, it does exist and there's nothing stopping me from writing a replacement __git_ps_colorize_gitstring that does modify it.

Write a replacement for __git_ps_colorize_gitstring to do something else

So in the end all I needed was:

    GIT_PS1_SHOWCOLORHINTS=true
    PROMPT_COMMAND='__git_ps1 "[$(_path) " " ] "' "(%s)"

    __git_ps1_colorize_gitstring () {
        b=${b%%.[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]}
        b=${b%%.mjd}
    }

The ${b%%PAT} thing produces the value of the variable b, except that if the value ends with something matching the pattern PAT, that part is removed. So the first assignment trims a trailing .20210206 from the branch name, if there is one, and the second trims off a trailing .mjd. If I wanted to trim off the leading gh also I could use b=${b##gh}.

There's probably some way to use this in addition to the standard __git_ps_colorize_gitstring, rather than in place of it. But I don't know how.

In conclusion

This was way harder to figure out than it should have been.


[Other articles in category /prog] permanent link

Wed, 03 Feb 2021

We visit the town of Gap

Katara and I went to visit the town of Gap, PA. In Gap there are so many eagles that they have these special bins for getting rid of the extras.


[Other articles in category /misc] permanent link

Tue, 02 Feb 2021

Hildebert and the mouse

This is the famous self-portrait of Hildebert, a 12th century scribe in what is now the Czech Republic. In this picture, Hildebert is shaking his fist at a mouse, which is eating his lunch.

A pen drawing,
in black and red ink, or some sort of neutral-colored medium.  The
rest of this article describes the drawing in detail.

There is quite a lot going on here! First off, Hildebert is carrying one of his quill pens behind his ear. This seems to me like a good way to get ink in your hair, and I wonder if medieval scribes often had smudges on their forheads.

I think the thing in his hand is a piece of bread. But what is on the table? I think the mouse is eating Hildebert's cheese (we can see the already-cut piece under the mouse's butt) and there seems to have been a small roast bird of some type, which the mouse has upset but which has not yet hit the floor. The table with the mouse is labeled Mensa hildeberti, “Hildebert's table”, in case it was unclear just whose lunch was being stolen.

Hildebert seems to be wearing a long garment with fancy matching sleeves and collar, and over that what looks like a chiton. I wonder if Hildebert really wore a chiton?

On the left of the picture is a really interesting piece of equipment. Until I saw this picture, it had never occurred to me that the lap desk had been invented before I was born. But here it is, almost nine hundred years ago. And it certainly is a lap desk, having no legs. In this picture the lap desk is supported by a backward-headed lion, but in actual practice such luxuries are probably hard to come by, so Hildebert would have put the desk on his lap.

The two long curvy things on the left edge of the lap desk are not legs. They are inkhorns: sawn-off animal horns, filled with ink. When you need to get more ink on your quill, you dip the end in the inkhorn. I had heard of inkhorns but until I saw this picture I had never understood how you used them: they won't stand up, and if you lay them down the ink will spill. But Hildebert's picture makes it perfectly clear: the lap desk has a couple of round holes in it, and you slide the inkhorns into the holes until they stop. Very nice! Next to the inkhorns are two extra quills, and along the bottom edge of the lap desk there is a ridge to keep the paper or parchment from sliding into your lap. I am pretty sure that the lion is holding the desk by the bottom edge, so that it is presented to Hildebert sideways. Hildebert is too enraged by the mouse to care about this.

Also on the desk is a booklet, in which (according to Wikipedia) Hildebert has written:

Pessime mus, saepius me provocas ad iram. Ut te deus perdat

I think I can make this out. (Medieval scribes used a great many abbreviations. For example, iram is written as “irã”. Similarly, the hildeberti above the table is abbreviated to “hildebti”. If you are interested, I discussed scribal abbreviations a couple of years ago.)

Wikipedia's translation of this is:

Most wicked mouse, you incite me to anger once too often. May God destroy you.

I think the phrasing and the fist-shaking, directed at a mouse, are meant by Hildebert to be a humorous overreaction.

Underneath Hildebert is a drawing of his colleague Everwin (EVERWINVS). Everwin seems to be painting some sort of decoration with a brush. Check out his fancy sleeves and matching socks!

I am not sure what Hildebert is holding in his left hand or whether it intersects the lion's arm. My best guess is that it is Hildebert's table knife, and that the picture means to show it passing in front of the lion, not intersecting the lion.

Many thanks to Marnanel Thurman for bringing this to my attention.


[Other articles in category /art] permanent link

Mon, 01 Feb 2021

The magic mirror in Snow White

A few weeks ago I was thinking about Snow White and in the course of doing that I looked up the original German version of 1812. (Snow White herself is story #53, on page 238.)

The magic mirror is introduced this way:

Die Königin … hatte auch einen Spiegel, vor trat sie alle Morgen und fragte: …

(“The queen… also had a mirror, before which she stood every morning and asked…”)

The mirror is simply einen Spiegel, a mirror, not a specifically magic mirror. That seems to have been a later interpolation. In the 1857 edition, it says Sie hatte einen wunderbaren Spiegel…. There is no wunderbaren in the original.

I prefer the original. The mirror recites poetry; to say it is a magic mirror is superfluous.

But on second thought, is it? There is another explanation: in the original version, perhaps the mirror is an ordinary one, and the queen is psychotic.

Certainly nobody else hears the mirror speaking. And the queen tells the hunter not only to kill Snow White in the forest, but to bring back Snow White's lungs and liver, so that the she may eat them. With salt! (die will ich mit Salz kochen und essen.) Now I prefer the original even more. The later version, which unequivocally states that the mirror is magic, is much less terrifying.

I suppose the argument against this reading is that the mirror also provides the queen with real information: Snow White is still alive, and living with the seven dwarfs. I think the original text does imply that the queen was aware of the seven dwarfs, but how might she have known that Snow White was still alive? Well, she did eat the lungs and liver, which had actually come from a young wild boar (junger Frischling). Perhaps she was satisfied at first, but then there was something about the taste, or the texture, not quite what she expected… it gnawed at her for hours, and then in a flash of rage she realized what she had actually eaten…

[ Addendum 20210202: In case you wanted to see it,
Screenshot of the original 1812 text of _Kinder und Hausmärchen_, which reads as I quoted above.
 Note, by the way, that in 1812 the umlaut marks in Königin etc. still looked like small letter ‘e’; they had not yet been reduced to diareses. ]

[ Addendum 20210207: another startling detail that was revised in the later editions. ]

[ Addendum 20210321: The more I think about the queen's psychosis, the more obvious it seems that this is the correct explanation. ]


[Other articles in category /book] permanent link