written, I often don’t recall instantly what the problem at
hand was or how I solved it. Now you’ve got me thinking
that maybe I’m just in the wrong language. When you’re
at this higher level of abstraction, maybe it’s easier to see
your intent.
In terms of debugging your code, obviously the power
of a terse language such as K or Q is that, presumably,
it’s easier to find bugs by inspection. How do you debug
them?
AW In C I never learned to use the debugger so I used
to never make mistakes, but now I make mistakes and I
just put in a print statement. K is interpreted, so it’s a lot
easier. If I’m surprised at the value of some local at some
point, I can put in a print, and that’s really all I do.
BC That works well when you have deterministic inputs.
What if the nature of the problem is just less reproducible—for example, if you were in an event-driven system
where you had a confluence of events that led to a
problem?
AW It has been 20 years now that I’ve had Wall Street
customers—they’re doing 2 billion transactions a day and
they have trillion-row databases—and in those 20 years,
there was one time where we couldn’t reproduce the bug.
That was nasty. I knew the kinds of operations that they
were doing and I finally found it by just reading my code.
BC Was this a bug in K or Q, or was it in the C base
implementation?
AW It was a bug in C, in my implementation.
BC Is the nature of the problems that K and Q solve such
that you just don’t have nonreproducible problems?
AW It seems ridiculous, but it’s only recently that we’ve
been doing multithreading, so I guess we might start to
see things that are much harder to reproduce. Of course
it has been event-driven since 1988. I don’t know why it
is, but it has always been the case that people can quickly
find a tiny script that will show the problem.
BC I think it’s fair to say that you’ve written a lot of flawless code.
AW Yes. I went millions and millions of hours with no
problems—probably tens of millions of hours with no
problems.
BC That’s a relief to hear because it seems that societally we have come to accept bugs as being endemic in
software. When you’re talking about the program being
its own proof, I think it gets to the fact that really these
programs are much more like proofs. A proof is either correct, or it’s flawed: there’s no middle ground for a proof.
AW I want to see if I can get better. Kx is doing fantastic,
and it takes just a few hours a month for me, so now I
have a clean slate. Every few years I have to do a new
language, but the customers don’t really like that.
BC Q was the last iteration of that process. What are some
of the differences between Q and K?
AW K was all symbolic. It was 20 symbols with a prefix
and an infix meaning. With Q, the idea was to have all
the monadic cases be words. So now infix are the symbols
and prefix are the words.
BC This gives it what you call the wordiness—I think what
others might call readability. For those who are not in
that world, will a Q program look more readable than a K
program?
AW Absolutely, because a lot of these symbols are familiar
to people from other languages—plus, minus, times,
greater than, less than. If they’re looking at a K program
that’s using all 20 of them, they will know a half or a
third of them, whereas if they’re looking at a Q program
they will know about two-thirds of them.
BC How important is the readability to the uninitiated?
AW From a sales point of view, I think it has helped a lot.
For someone who programs a few hours a week, I don’t
think it would make any difference once they learned K
or Q.
BC There are other changes, as well. For example, Q
seems to be much more closely tied to the data.
AW Right. It’s a little confusing because every three or
four years I do an entirely new implementation of K.
There was a 1993 K and then there was a year 2000 K.
It’s the 2000 K that’s underneath Q, so that implementation of K and Q are exactly the same, except that Q has
a library of 50 additional operations, which are table-related, written in K.
BC If you were to write a program, would you be using
the primitives that Q offers or would you write it in K?
AW Most programming I do would be in K, but if it was a
lot of relational-table stuff, I would use Q because a lot of
those words are already defined.
BC When you’re actually in the practice of writing code,
do you try many drafts?
AW I’ve found the best thing is just to get something running, and then I’ll redo it probably 10 or 20 times until I
can’t get it any smaller.
BC Do you redo it for aesthetics?
AW Yes. What I tell my community is if you can find a
shorter, more elegant program that isn’t much slower
than my code, I want to hear about it. And if it’s shorter
and faster, I absolutely want to hear about it.
BC Although I don’t know that I’ve got the same discipline, I share your sense of aesthetics about beautiful
code. I don’t see that sense of aesthetics being very widespread in software. Shouldn’t it be, though?