[Hello World!]p
dc is one of the oldest unix utilities, and is part of almost every distribution. DC stands for Desktop Calculator, but as well as offering a command line reverse polish calculator, it’s really a programming language in its own right.
dc is a stack based programming language, and is as terse as possible. Almost all operations are a single character, and whitespace is only needed to separate numbers from each other. As a taster, here’s a program which prints out the numbers 1 to 100:
Let’s break this down:
So the lines after the initial string are just responsible for storing it in register ‘A’, pushing an initial 1 onto the stack, then executing what we’ve just stored in register ‘A’. The main work is done inside the string we store in register ‘A’.
Now let’s break down that first string:
So this string prints the value on the stack, adds one to it and then if it’s less than 101, it executes register ‘A’ again, so forming a loop. The d in character 5 duplicates the top of the stack because the conditional operator > consumes both of its arguments from the stack, and we need the counter to be on the stack for the next invocation of register ‘A’.
That’s just a very simple example of what you can do with dc that you couldn’t do with a normal calculator. Here’s another, slightly more involved example.
dc macros like the one above can be passed functions in much the same way as with more sophisticated programs. Any function can be put on the stack or stored in a register, and anything on the stack or at the top of a register is visible to other functions which can then invoke them.
We can use this to write functions which take other functions as arguments. The function below takes a function from the top of the stack, and applies it to each remaining element of the stack, storing the results in a temporary register before pushing them back onto the stack at the end.
To show the brevity (and unreadability) of dc, the whole thing can be written as one line with no whitespace at all:
This function gets stored in register ‘S’, so to create a stack with the numbers 1 2 3 4, and a function which squares those numbers, we would write the following:
This function doesn’t print anything out - there are no ‘p’ calls. [d*] squares each number (duplicates it then multiplies the two numbers together). The results are on the stack, and can be seen by typing ‘f’ to see the full stack:
There’s a lot more you can do with dc. It’s arbitrary precision, you can control the input and output radix, accept input from the user whilst executing and more. I hope to put together some more articles about these features soon, but in the mean time, the manual and the Wikipedia page are good places to find out more.