2020-06-24

Little surprises #6: "Stop helping me!" edition

I got a little technological help today. Unfortunately it was not the helpful kind of help.

I attend some remote precense meeting that are mediated by a bespoke telephone-based system rather than by internet. This is driven in part by the institutional inertia that comes with having had the system for a long time, but mostly by security concerns. So I dial in, switch to speaker, and prop my cell phone against my monitor stand. It has to be a cell phone because we don't have a landline.

The conference involves our sponsors, so we keep a separate chat channel open for communication amungst ourselves.

On the conference today I finsihed answering a questions and waited for a response. And waited. And waited. And noticed that the line seemed deader than usual. I enquire on the chat channel if there is a problem with the conference, and a colleague (another parent of young children as it happens) writes back "I don't know, but someone has to get in the car seat to get a ice cream."

A horrified glance out the window is enough to confirm the worst. There is the babysitter loading the toddler into my wife's car. The phone has linked to the car and my colleagues and sponsers are hearing all about the proposed trip to get ice cream.

I want it to do that, but not now

I have no one to blame but myself. Unless I can blame Apple a little, too. That sounds good. I'll do that.

Usually I want the phone to pair with the car as soon as it comes on and without asking me if that is a good idea. But maybe the behavior should be varied when there is already a phone call in progress? Especially if I am already using the speaker. Or something. I'm frustrated that progress in AI has produced a lot of powerful spying tools and general creepiness, but damn all context sensitive decision making for real life.

2020-06-21

Little surprises #5: qmake edition

The last edition of "Little surprises" reminded my of an incident from a while ago.

This one involves the input file format fo Qt's qmake tool.

Like a lot of other tools, the input language uses # to indicate a comment extending to the end of the line, and \ as the last charqacter on a line to indicate line continuation (the current logical line is extended to include the next file line). It also uses lists of white-space separated tokens as in:

SUBDIRS=external-library module1 module2 tests

If a list gets to have more than a few entries, it can be made much more readable by using line continuation:

SUBDIRS = external-library \
          module1 \
          module2 \
          tests   # Should anything go here?

A practice further encourage if you use Qt creator because the IDE builds lists of files and directories in this way.

What about the last line?

Should you put a line continuation marker on the last line of such a list?1

Pros:
  • consistency (which may appeal to any obsessive tendency that you might have)
  • reduces the number of ways to make a mistake if you reoder the list
Cons
  • you don't need to
  • you need to worry about what is on the next line, introducing a new way to make mistakes

As I can be a little obsessive about consistency in code and insist on a whitespace line after a list like that anyway I choose to put the trailing continuation in there. The thing that I discovered is that in qmake the "need to worry about what goes on the next line" bit includes comments. That is, if I write

SUBDIRS = external-library \
          module1 \
          module2 \
          tests \
# Explanation of what I want to do next
ANOTHER_KEYWORD

The system will consider ANOTHER_KEYWORD as an item on the list.

I'm not aware that this is documented anywhere.

What?

From my point of view this the violates the principle of least surprise. If I append the comment to the line containing test, then I have a end-of-line comment and that should be the end of it. That said, if I think about actually parsing a file like this I can see two implementation strategies that would lead to this behavior as a side-effect,2 and though they are not the ones I would have chosen I don't think they are dumb either.

Arguably this lends weight to the "don't do that" side of the argument about continuing the last line, but I have chosen instead keep the consistency and insist that such a list must be trailed by a empty line.


1 This kind of question doesn't come up in my mind alone. Note that C++ enum offers explicit support for ending the list with a comma.

2 (A) Multiple passes with comment elimination coming before line continuation and full line comments removed entirely. (B) Line-at-a-time parsing and full line comments are handled by silently loading the next line.

When did that happen?

Of course babies and toddlers grow fast. You know that from constantly having to retire clothes and shoes and bring new, bigger ones home amung other little hints. But you don't really notice the gradual change unless something focusses your attention.

There is a local store we go to occassionaly. My daughter loves the place. Partly becuase there is lots of room to run around but also because they have a giant gumball machine with a spiral ramp for the treats to roll down.1 The store was fully closed down for a couple of months, what with the plague abroad on the land, but they are open again (short hours and low occupancy limits, but doing business).

It's been four or five months since we'd been there, but we went yesterday.

Everytime we've gone before I had to help her insert the coin2 because she couldn't see the slot (positioned above here eyes and sunken behind the handle). Yesterday, she had it in there before I even finished saying "Thank you" to the person who changed a dollar for me.

She must have put on nearly three inches since our last visit.


1 Thankfully she doesn't know you're suppose to chew them, she just thinks they are balls to roll and throw. We cherish and encourage this understanding of the situation.

2 Her economic philosophy right now seems to be "Coins are good because I can put them in machines". And she seems to understand that quarters are more useful that way than other coins.

2020-06-18

Little surprises #4: string concatenation edition

Another one that came up at work today. A method was behaving as if an argument was taking on it's default value even though there was an argument right there in the code.

Abstracted to it's bare essentials it starts with a method

class Thing {
   // c'tors and so on
   void method(const std::string & s1, 
               const std::string & s2 = "");
};
which was called in a section of code that had significant history
Thing thing;
thing.method("string"// oldWayToDeduceString(),
             "second string");

Do you see it?

Only one argument is being passed to Thing::method due to string concatenation and the comma that used to separate the first argument from the second being commented out. The compiler doesn't complain because the second argument takes on it's default value.

The real failure here (and it was mine, if you really need to know) was not removing the commented code after testing and before committing this code the last time 'round.

2020-06-12

Wordo of the day

And someone else's for once. Anyway, seen in my news feed:

fiend of the court
in a context where it is clearly meant to be the customary translation of amicus curiae.

A little amused poking around shows that the diabolical version has occassionally been used with malice aforethought. I think I'll have a look at some of those.

2020-06-11

2020-06-08

Un-natural scripts

“I liken starting one’s computing career with Unix, say as an under-graduate, to being born in East Africa. It is intolerably hot, your body is covered with lice and flies, you are malnourished and you suffer from numerous curable diseases. But, as far as young East Africans can tell, this is simply the natural condition and they live within it. By the time they find out differently, it is too late. They already think that the writing of shell scripts is a natural act.”
— Ken Pier, Xerox PARC

As I've mentioned before I'm basically a unix guy. I believe I first encountered the OS in the mid eighties and first used it seriously in 1989 (a C course taught out of the New Testament with exercises coded on Xenix systems). For all that, I'm not unaware of the tradeoffs involved and find The UNIX-HATERS Handbook (the sourse of the quote) to be both ammusing and informative.

However, my current professional project is cross-platform by customer requirement: it needs to run on Windows as well as Linux. So this is the perfect opportunity to upgrade my skills in Python for all those tasks where I might have written a shell script. Right?

But the habit of thinking in terms of Unix utilities doesn't go away easily.

Last week I needed to prepend some text to a large number of source files. My project is nearing its first delivery to the customer and, being new to both contract programming and project leadership, I started the work without putting the usual legal boilerplate in all the source files.1 Hundreds of them. Obviously some kind of scripted approach was in order.

The issue is while appending is trivial in the Unix file model, there is no OS level support for insertion before the end (the authors of TUHH are laughing up a storm at this point). You must either employ a temporary file or read the whole file into memory before beginning. Anything involving temporary files is hard to get right (especially if you are worried about security which probably doesn't apply here but it makes me cautious all the time), and reading all of an input into memory is a different kind of risk (again with known inputs it's not a huge risk but thinking of these things is part of the job, right?).

This is the point at which my memory throws up a bit of useful Unix lore: sed like several other old tools has a "in place" editing mode meaning that someone else has already dealt with the hard parts. As far as my searching could tell, python doesn't provide a nice wrapper for this.

So I wrote this little tool in /bin/sh and sed. It's not part of our deliverables so it doesn't have to be cross-platform. And that leaves only two issues: a few of the files are UTF-8 with BOM instead of ASCII and actually getting sed to prepend.

UTF

Frankly I agree with people who argue that every text tool should be UTF aware. But that doesn't mean that those old Unix utilities are. In this case it was few enough file to simply handle those with manual cut-n-paste, but it leaves the mystery of how those dozen files got that way when most of the code base is plain ASCII.

Being clever with sed

If you just try the obvious sed '1r license.txt' input_file.cpp you get the license after the first line (which is what you want on anything using a shebang, so all is not lost). The next step is "OK, fine, let's make that '0r license.txt'", but sed doesn't support that address (or maybe some do, but the one I was using doesn't).

So you have to get clever. What I ended up with looks like this (only without the explanatory comments after the line-continuation marker which only some shells support):

sed -i.old \              # Edit in place but keep a backup
    -n \                  # No automatic output
    -e "1h" \             # Hold the first line
    -e "1r license.txt" \ # Insert the license at line 1
    -e "2x" \             # On line 2, swap hold and pattern space ...
    -e "2G" \             # ... then append hold to pattern (pattern space becomes Line1\nLine2)
    -e "1!p" \            # All lines but 1 print the pattern (which includes line 1 on line 2).
    input_file.cpp

1 Qt Creator supports adding such blurbs automatically at the time it generates files skeletons for you, but not adding them at a later date.

2020-06-06

Bureaucracies and Language

Bureaucracies, by their nature, need to make precisely deliniated distinctions and they need to distill those distinctions down to sinlge words (for use in reports, questionaires, statistics and so on). Where existing usage does not support exactly the distinction they need they simply assign the denotation they need to an existing word (effectively re-defining it or at least imposing artifical precision on a word that cared some natuural ambiguity).

To chose an example that came up in the public conversation in the US following Hurricane Katrina, the UN defines "refugee" more closely that most dictionaries because they need to distinguish people diplaced over national border from those who are seeking refuge inside the country where their legal situation is well established. This insistance that the word only applies to those whove crossed national borders is stronger than the original organic use of the word.

This last week we learned that the US National Parks Service defines "tear gas" to exclude pepper bombs. I'm not sure what (if any) purpose is served by this distinction, but it certainly isn't one in general use. It's purely a bureaucratic denotation.

As I indicaed above, I understand that such distinctions may serve a purpose for the agency that makes them, but I feel quite strongly that there is no obligation for actual flesh and blood humans to give a damn. Real people should use words with their real meanings and should feel free to laugh at any jobsworth1 who sugggests that their organization's internal usage is more correct than the general population's.


1 A word I'd forgotten about until I saw it in a opinion peice from a British paper this week.

Counterproductive software policy

In the Time Before (tm) I used to make regular pilgrimages to one of my employer's offices nearly an hour away. On these and other drives where I have signficant blocks of time alone I listen to podcasts in the car.1 Today I was dispatched to do the once-a-month in-person shopping that our household needs despite copious (not to say excessive) use of internet shopping and local grocery delivery. I feel there is enough driving in that to justify story time.

Now the default podcast app on my iPhone doesn't interface well with my car's bluetooth audio system. Sometimes it thinks it's connected and running but no sounds comes from any device and it can't be fixed without rebooting the phone. So I tried Radio Public which isn't ideal but works a lot better with the car.2

Of course, sometime I start driving without remembering to start the app. So ... "Hey, creepy Siri." ... "Start Radio Public." And then Siri tells me that she can't do that while I'm driving.

Of course, I'm trying to do it by voice because I'm driving: the point is to keep my hands on the wheel and my eyes on the road.

I appreciate that Apple is concerned about the role of phones in distracted driving, but surely voice control is less distracting (not to mention more leagally acceptable) than diddling the screen with your fingers.3 This particular policy seem to be defeat its own purpose.

Anyone know of a podcast app for iThings that I can control by voice while driving?


1 Escape Pod, Clarkesworld, and Drabblecast if you care.

2 It would be very easy to convince me that this is the car's fault, but so what? I can't easily upgrade the car's entertainment system.

3 I know, I know. Don't call you Shirley.