Burgers

To The Economist’s credit, The Big Mac Index is for a large part a
joke. Just think of how many RMB you would have to pay to get a
Big Mac on the moon. It is incredible how much the RMB is overvalued
by that measure. Think about that the next time some clown tells you
that the RMB exchange rate is the cause of all US budget problems.

Robert, my bogus-meter is blinking. Why did you forward an obviously-wrong claim like electricity not being internationally traded?
Remember Enron?
(And check out DoE and this list of electricity exporting countries.)

OpenDocument for Spreadsheets

From time to time I am asked if Gnumeric supports or will support the OpenDocument standard. I am sad to report that the question is meaningless. The purpose of a standard ought to be interoperability; this standard is not a step in that direction.

Executive summary: The OpenDocument Standard v1.0 completely ignores semantics of spreadsheets, thus virtually ensuring that if two implementations of the standard existed then they could not use each other’s spreadsheets. That, in turn, renders the alleged standard pointless for spreadsheets.

The OpenDocument standard v1.0 is 708 pages long. You would think that in such an elephant they could find the space to hammer out a usable spec for spreadsheets. But no, they do not.

Formulas (or formulae if you are feeling learned) is an important part of what goes into spreadsheets. What does the alleged standard have to say about those? Basically you go to page 184-186 and find the two (equivalent) formula examples that it has:

  =sum([.A1:.A5])
  =sum([.A1];[.A2];[.A3];[.A4];[.A5])

Pedantics — that would be me — would point out that both these fail to comply with the formula requirement “Every formula should begin with a namespace prefix specifying the syntax and semantics used within the formula.” Hmmm… Or maybe “=” is that prefix and anyone seeing it will magically understand the syntax and semantics.

Regardless, we learn

  • the existence of a function named sum. I hope you can make good use of it, because it is the only function we get to know about. (There is a handful more in contexts unrelated to formulas.)
  • that there exists operators. Which ones seems to be a secret, apart from the fact that some of them are logical.
  • that numbers can be part of formulas. We will have to assume that regular C-like syntax for them is used.
  • that strings can be part of formulas. There is no clue about how to write them; I will guess that you put them in quotes, but what about embedded quotes, then?

There is what appears to be the beginning of a value system on pages 184-185. You get numbers, dates, times, booleans, and strings. Notice the absence of error values and “empty”, let alone arrays. Excel has those, Gnumeric has them, and OOo-calc has at least error values. Thus there is no chance that someone following the OpenDocument standard can approximate Excel semantics, nor for that matter is there any chance that OOo-calc can implement the standard with its current value system.

It gets worse. Let us assume that a proper value system was in place. If you wanted to have any hope of achieving interoperability you would them have to define function (and operator) semantics for a set of functions large enough to be useful. Details matter. For example, for our friend sum above, Excel will completely ignore strings like “42” (with the quotes) in referenced cells, but it will convert them to numbers and include them in the sum when given as direct arguments to SUM. (Yes, that is sick.) In technical terms, Excel does not have referential integrity. OOo-calc lacks referential integrity too and in the direct-argument case produces an error, i.e., it is sick in a different way. (For completeness, Gnumeric ignores all strings for SUM; this might change.) As a cuter example, OOo-calc manages to evaluate “1”+1 to TRUE!

So there. As far as spreadsheets are concerned, the OpenDocument Standard v1.0 is the equivalent of giving precise punctuation rules for sentences without telling if it is for English, German, French, or something else.

Only vaguely related is the question of whether Gnumeric should be able to read OOo-calc files. The answer is yes, and we do have some support for it. In practice it is probably easier to interoperate via the xls format.

[Formatting updated 2015]

Gnumeric 1.5.2

The weekend saw the release of Gnumeric version 1.5.2.
It should probably have a catchy name, but it does not.

This is a lots-of-little-things release that ought to make for a smoother ride.

Dependencies Re-Redux

I finally did manage to hack the dependency tracking code into a
state where invalidation of a sheet (done because the user performed the
undo-able removal of the sheet) is distinct from the destruction of
the sheet.

That sounds technical but the nice results are: (1) we no longer
have to clear the undo/redo queues when someone deletes a sheet;
(2) we now track and undo changes to other sheets’ cells when a
sheet is removed; (3) we track and undo changes to global names’
definitions when a sheet is removed.

These are not things you notice when they work, but you do when they
do not work. Chalk one up for user experience.

Tofu with Sprinkles

We sometimes go to a buffet place on weekends and _A_ has
managed to talk herself into being allowed to have ice cream for
dessert.

Enter _L_. He was only about one year old at the time, but he very
quickly figured out that the white soft stuff was desireable and
made it clear that the building would come down if he did not get
some. Pronto. That was a bit of a problem since ice cream does
not figure prominently in the recommended diet for a one-year old.

Solution: soft tofu, with sprinkles.

Therefore, according to _L_, ice cream is something that is served warm and
with sprinkles. He has figured out the difference in the meantime,
but he still seems to prefer the tofu. Fine with me.

Libc is Broken, Part 1a

Robert, I said “int”, not “long”.
The code you presented does not work for platforms where the two are
different. There is no strtoi so you get to use strtol and do the
extra range checking.

It also does not work because there is no
requirement that strtol set errno for any condition
but overflow and underflow. In particular for the empty string.

It also does not work because libc functions may
set errno when no error is detected. And, in fact, they
often do.

And, finally, it also does not work for strings like “010”.
You get 8, but you should get 10 when someone mumbles “decimal”.

Update: And while I am picking at you, it seems I
have to point you at the ctype man pages too. isdigit
is defined on the special value EOF and an integers within the range
of unsigned char.

In practice, what libc implementations do is something like

  #define EOF (-1)
  #define isdigit(_c) ((__somearray+1)[(_c)] & SOME_BIT)

That can and will core dump if you send a random signed character.

(Glibc has a misguided attempt at making things work for signed
characters also. They essentially add 128 and duplicate half the
table. That works fine unless you want the right answer.)

Libc is Broken, Part 1

It is time for a gripe.

Libc contains a lot of quite APIs. You probably know about the
gets dissaster, but there is a whole lot more.

  • String-to-value conversions. Here is how you
    convert from a string s containing a decimal integer
    into an int i:

      char *end;
    int i;
    long l;
    errno = 0;
    l = strtol (s, &end, 10);
    if (s != end && *end == 0 &&
    errno != ERANGE &&
    l >= INT_MIN && l
    And that is before considering locales (which typically do not
    affect integers, mind you).
  • Time zones. The localtime function
    is great, but having $TZ as as implicit and not explicit argument
    makes it really, really hard to use for anything but the default
    time zone.
  • ctype functions. At least two things are wrong:
    (1) the encoding used is an implicit argument; and (2) they are defined obscurely such that char c = 'a'; isdigit(c) may or may not
    be valid, depending on the platform. Most commonly it is not valid,
    i.e., it may core dump. The right way to do that is,
    for reference, isdigit((unsigned char)c) which is enough to make a sane man crazy. (Alternatively one
    could define c as unsigned char but in
    more practical code the type is often constrained by a parameter type.)

I have the feeling I might return to this subject later.

File Choosers

In the grand tradition of nntp-over-rss, let me kick in a word or two
about file choosers. Start by reading what Federico — wrote on the topic.

Regarding Emacs, Federico missed a few important things. (Any description of Emacs that is smaller than the tar ball is incomplete, naturally.)

  • Case: Completion in Emacs is (optionally, this being Emacs) case insensitive. This is very useful if you are lazy
    with the shift key or just happens to get a lot of filenames via a
    telephone.
  • The Tab key will, after completions have been listed, scroll the completion window when you press it again. (I actually wrote that a decade or so ago.) This makes it possible to
    navigate large directories fairly easily. A drop-down like the one
    the GTK+ file chooser provides is not useful for this. Note, btw.,
    that this feature also makes completion useful in keyboard-only mode.
  • A completing Tab that ends up with multiple choices left does not also list the choices
    for two reasons: (a) it is slow on a 9600 baud terminal and (b) if you are just using the Tab key to speed up entry you generally do not
    want the list of possible matches until you are not making progress. The latter is still valid and
    prevents the UI from getting in your way. The FileChooser’s
    completion is very much getting in the way: it steals focus and
    obscures parts of the dialog you want to see.

In my experience this means that the Emacs completion is useful while
the FileChooser’s is not. That is especially true in directories with hundreds of files. (And that is before we discuss bugs that cause people to overwrite files they did not intend. The current state of save-as is somewhere between “barely usable” and “dangerous to your files”.)

On opening files: suppose I want to add a “gtk-button-images = 0” setting in ~/.gtkrc-2.0. Why do I have to use two different UIs depending on whether that file already exists? The logical extension of that would be to have two entirely
different UIs for save-to-new-file and overwrite-existing-file; we
are lucky no-one in Redmond thought of that, I guess, 🙂
This should not be too hard to fix — I will have a go at it in a
while.

On screen real estate: The GTK+ file chooser gives
me a vew of 7-8 files (typically directories, actually) when it comes
up. To locate a file I have got to scroll which is a bit hard with
such a small viewport. Emacs, on the other hand lists files in
batches of 36 files. Guess which one I find more useful. (This
is actually for a large part a treeview issue.)

All the above comes through a little more negative than I really
wanted it to. I do appreciate all the work that Federico has put
into the FileChooser. My goal is not to assign blame for where we
are — that would be pointless or worse — but to get us to a better state.

Eating Habits

I must be doing something wrong. Getting kids to eat right is supposed
to be a major fight.

Yet _L_ drinks his milk, eats his carrots, cannot get enough broccoli, loves porridge,
and if we are getting pizza then he wants it with spinach.

_A_ is not much worse. While she does complain, that generally stops
after we tell her “you get what you get and you don’t get upset”.
(That is a nice trick from the daycare.)

If I told you that I ate like that myself, my nose would grow faster
than a speeding bullet.

Multihead

Applications that support multiple windows should support multihead
displaying, i.e., it should be possible to put some of the windows
on a separate screen. If you are blessed with two screens it is
a very nice productivity improvement to use that extra screen for
reference materials relating to what you work on. Applications
that support this are cool.

Gnumeric is cool, of course. Emacs is cool. Mozilla is not cool.

Unfortunately multihead support is a bit of a late add-on for GTK+.
The duct tape is visible here and there. For example, every time you
create a widget for the non-default screen, you in effect build it
for the default screen with all the setting that relate to that,
then warp it over to the other screen and redo all the settings.
Anything that relies on settings — icon sizes, fonts, etc. — needs
to be done or redone when the widget is realized.

But GTK+ is better than the rest of the Gnome stack. There are
still places that build X cursors for the wrong display, fail to
catch screen-changed signals, or grab the cursor on the wrong
display. The results range from the cute (popups and menus show on
the wrong screen) over the irritating (application crash) to the
worse (grabbed X cursor).