How To Program In dc
And Actually Have A Program Run
And Also Do What You Meant It To Instead Of Always Printing "Stack is freaking empty" Or segfault Or Some Shit Instead
Because I'm Warning You Right Now, It Will Drive You Batty And You Will Want To Probably Leave And Go Live In Harmony With Nature If You Use It Too Long, I'm Serious
Part one: What the hell is dc and who hated me enough to make it?
A question well asked. dc is the oldest language for Unix, written before C itself! It is, in fact, a reverse-polish-notation arbitrary-precision stack calculator, with special features for writing macros and storing results.
This means, in layman's terms, "It's jibberish that can do math with really big numbers".
As an opening test for you and me, if you're on a Unix system of any sort (including Mac OS X), open a terminal and start dc. (The command to start it is 'dc'.) If you're on Debian, you may have to install it. I don't know why the hell this is. You may also be able to use Cygwin or whatever the kids are doing these days.
Once you've fired the beast up, enter the sacred incantation of doom: (trumpets!)
(Gosh darnit. I can never remember this stuff.)
...again.
...of doom: (trumpets!)
&lbracket;dx&rbracket; dx
Deep breaths. 1, 2. 1, 2. 1 2 rprprprprp. Damn you, brackets!
Damn you both!
All right, I'm back.
SPARE OOOOOOOM: (strumpets!)
<dx> dx
Um. Hang on. Where's that stupid guide? Ah. E2 HTML tags: "[ to show ["...
Okay, 91 and 93. Two good numbers. Funny thing about those two, neither one of 'em is prime. I know that because I happen to have a prime number generator sitting right here, written in none other than dc. I queried the jolly little fellow by firsting entering the command "100 lex", and then issuing,"91 ;0n" and "93 ;0n". That won't work for you, as you don't have the prime number tester, which is not (as you might now think) called 'lex' in a fit of silly pretense.
(You haven't asked about the Limburger, sir.)
of brocolli: (seals bark)
[dx] dx
There it is. Silly bugger.
Now, hit enter to feed this command to dc. It should print "Segmentation fault" on the next line. This output is layman's terms for "Your computer is trying to kill you." I'll explain why the program prints this later on. Of course, if you've had lambda calculus, I think you can guess.
Part Two: Introduction to dc
dc is a stack calculator, which means...
Okay, I've just realized that writing a dc tutorial would be actual work. Instead of doing that work, I'm just gonna give you an example program so that you can learn dc on your own time, using the man page, or just ignore it forever.
Here's an outline for already-decent-programmers:
- Everything happens with the stack.
- n shows and removes the top item on the stack. f prints the whole stack. p prints without removing it, but with a newline.
- A number alone gets itself put on the stack.
- +,-,*,/,% and a few other basics operate on the top two items of the stack and put the result on the stack.
- d duplicates the top item, r swap the top two items.
- Every ASCII character is a variable (or "register"). For 'A' for instance, sA stores the top stack item in A, lA pulls it out without destroying it, SA (capital S!) pushes another item into A as a stack, LA pulls off the top item of A as a stack, :A and ;A do arrays...
- [ and ] are for creating strings, which can act as macros. The x command treats the top stack item as a macro, removes it and executes it.
- Macros should be stored in variables for later use. For instance, the commands [d *] sq would store in 'q' a macro that squares the top number on the stack. lqx would execute it.
- If a variable is storing a macro, it can be executed "conditionally" using a comparison, such as =,!=, etc. with a variable name. So !=A would execute A if the top two numbers on the stack aren't equal.
- Looping is best done by storing the macro in a variable and doing a conditional check that re-executes the macro itself.
- See the freaking example.
"FizzBuzz" is a children's game, and also a simple programming test. The object is to print the numbers 1 to 100, except that instead of numbers divisible by three you print "Fizz", by five print "Buzz", and by both print "FizzBuzz". (A grammarian is choking to death somewhere. In fact, probably two are.) Here is dc source code for FizzBuzz in dc:
[sg []] sX
[
[Buzz] l5 0 !=X
[Fizz] l3 0 !=X
n p sG
] sA
[ln p sG] sB
[
ln 3 % s3
ln 5 % s5
l3 l5 * d 0 =A 0 !=B
ln 1 + d sn
101 >C
] sC
1 sn
lCx
And, since I hate you, here's an even shorter version (65 characters):
[sg[]]sx1[ddd3%d[Fizz]r0!=xnr5%d[Buzz]r0!=xn*0=xpsg1+dd101>M]dsMx
Have fun with dc. Or rather, don't learn dc and have fun with Common Lisp instead. This guide has been brought to you by the Reformed Presbyterian Church. Probably.