Go to the previous, next section.

Programming

There are several ways to "program" the Emacs Calculator, depending on the nature of the problem you need to solve.

  1. Keyboard macros allow you to record a sequence of keystrokes and play them back at a later time. This is just the standard Emacs keyboard macro mechanism, dressed up with a few more features such as loops and conditionals.

  2. Algebraic definitions allow you to use any formula to define a new function. This function can then be used in algebraic formulas or as an interactive command.

  3. Rewrite rules are discussed in the section on algebra commands. See section Rewrite Rules. If you put your rewrite rules in the variable EvalRules, they will be applied automatically to all Calc results in just the same way as an internal "rule" is applied to evaluate `sqrt(9)' to 3 and so on. See section Automatic Rewrites.

  4. Lisp is the programming language that Calc (and most of Emacs) is written in. If the above techniques aren't powerful enough, you can write Lisp functions to do anything that built-in Calc commands can do. Lisp code is also somewhat faster than keyboard macros or rewrite rules.

Programming features are available through the z and Z prefix keys. New commands that you define are two-key sequences beginning with z. Commands for managing these definitions use the shift-Z prefix. (The Z T (calc-timing) command is described elsewhere; see section Troubleshooting Commands. The Z C (calc-user-define-composition) command is also described elsewhere; see section User-Defined Compositions.)

Creating User Keys

Any Calculator command may be bound to a key using the Z D (calc-user-define) command. Actually, it is bound to a two-key sequence beginning with the lower-case z prefix.

The Z D command first prompts for the key to define. For example, press Z D a to define the new key sequence z a. You are then prompted for the name of the Calculator command that this key should run. For example, the calc-sincos command is not normally available on a key. Typing Z D s sincos RET programs the z s key sequence to run calc-sincos. This definition will remain in effect for the rest of this Emacs session, or until you redefine z s to be something else.

You can actually bind any Emacs command to a z key sequence by backspacing over the `calc-' when you are prompted for the command name.

As with any other prefix key, you can type z ? to see a list of all the two-key sequences you have defined that start with z. Initially, no z sequences (except z ? itself) are defined.

User keys are typically letters, but may in fact be any key. (META-keys are not permitted, nor are a terminal's special function keys which generate multi-character sequences when pressed.) You can define different commands on the shifted and unshifted versions of a letter if you wish.

The Z U (calc-user-undefine) command unbinds a user key. For example, the key sequence Z U s will undefine the sincos key we defined above.

The Z P (calc-user-define-permanent) command makes a key binding permanent so that it will remain in effect even in future Emacs sessions. (It does this by adding a suitable bit of Lisp code into your `.emacs' file.) For example, Z P s would register our sincos command permanently. If you later wish to unregister this command you must edit your `.emacs' file by hand. (See section General Mode Commands, for a way to tell Calc to use a different file instead of `.emacs'.)

The Z P command also saves the user definition, if any, for the command bound to the key. After Z F and Z C, a given user key could invoke a command, which in turn calls an algebraic function, which might have one or more special display formats. A single Z P command will save all of these definitions.

To save a command or function without its key binding (or if there is no key binding for the command or function), type ' (the apostrophe) when prompted for a key. Then, type the function name, or backspace to change the `calcFunc-' prefix to `calc-' and enter a command name. (If the command you give implies a function, the function will be saved, and if the function has any display formats, those will be saved, but not the other way around: Saving a function will not save any commands or key bindings associated with the function.)

The Z E (calc-user-define-edit) command edits the definition of a user key. This works for keys that have been defined by either keyboard macros or formulas; further details are contained in the relevant following sections.

Programming with Keyboard Macros

The easiest way to "program" the Emacs Calculator is to use standard keyboard macros. Press C-x ( to begin recording a macro. From this point on, keystrokes you type will be saved away as well as performing their usual functions. Press C-x ) to end recording. Press shift-X (or the standard Emacs key sequence C-x e) to execute your keyboard macro by replaying the recorded keystrokes. See section 'Keyboard Macros' in the Emacs Manual, for further information.

When you use X to invoke a keyboard macro, the entire macro is treated as a single command by the undo and trail features. The stack display buffer is not updated during macro execution, but is instead fixed up once the macro completes. Thus, commands defined with keyboard macros are convenient and efficient. The C-x e command, on the other hand, invokes the keyboard macro with no special treatment: Each command in the macro will record its own undo information and trail entry, and update the stack buffer accordingly. If your macro uses features outside of Calc's control to operate on the contents of the Calc stack buffer, or if it includes Undo, Redo, or last-arguments commands, you must use C-x e to make sure the buffer and undo list are up-to-date at all times. You could also consider using K (calc-keep-args) instead of M-RET (calc-last-args).

Calc extends the standard Emacs keyboard macros in several ways. Keyboard macros can be used to create user-defined commands. Keyboard macros can include conditional and iteration structures, somewhat analogous to those provided by a traditional programmable calculator.

Naming Keyboard Macros

Once you have defined a keyboard macro, you can bind it to a z key sequence with the Z K (calc-user-define-kbd-macro) command. This command prompts first for a key, then for a command name. For example, if you type C-x ( n TAB n TAB C-x ) you will define a keyboard macro which negates the top two numbers on the stack (TAB swaps the top two stack elements). Now you can type Z K n RET to define this keyboard macro onto the z n key sequence. The default command name (if you answer the second prompt with just the RET key as in this example) will be something like `calc-User-n'. The keyboard macro will now be available as both z n and M-x calc-User-n. You can backspace and enter a more descriptive command name if you wish.

Macros defined by Z K act like single commands; they are executed in the same way as by the X key. If you wish to define the macro as a standard no-frills Emacs macro (to be executed as if by C-x e), give a negative prefix argument to Z K.

Once you have bound your keyboard macro to a key, you can use Z P to register it permanently with Emacs. See section Creating User Keys.

The Z E (calc-user-define-edit) command on a key that has been defined by a keyboard macro tries to use the edit-kbd-macro command to edit the macro. This command may be found in the `macedit' package, a copy of which comes with Calc. It decomposes the macro definition into full Emacs command names, like calc-pop and calc-add. Type M-# M-# to finish editing and update the definition stored on the key, or, to cancel the edit, type M-# x.

If you give a negative numeric prefix argument to Z E, the keyboard macro is edited in spelled-out keystroke form. For example, the editing buffer might contain the nine characters `1 RET 2 +'. When you press M-# M-#, the read-kbd-macro feature of the `macedit' package is used to reinterpret these key names. The notations RET, LFD, TAB, SPC, DEL, and NUL must be written in all uppercase, as must the prefixes C- and M-. Spaces and line breaks are ignored. Other characters are copied verbatim into the keyboard macro. Basically, the notation is the same as is used in all of this manual's examples, except that the manual takes some liberties with spaces: When we say ' [1 2 3] RET, we take it for granted that it is clear we really mean ' [1 SPC 2 SPC 3] RET, which is what read-kbd-macro wants to see.

If `macedit' is not available, Z E edits the keyboard macro in "raw" form; the editing buffer simply contains characters like `1^M2+' (here `^M' represents the carriage-return character). Editing in this mode, you will have to use C-q to enter new control characters into the buffer.

The M-# m (read-kbd-macro) command reads an Emacs "region" of spelled-out keystrokes and defines it as the current keyboard macro. It is a convenient way to define a keyboard macro that has been stored in a file, or to define a macro without executing it at the same time. The M-# m command works only if `macedit' is present.

Conditionals in Keyboard Macros

The Z [ (calc-kbd-if) and Z ] (calc-kbd-end-if) commands allow you to put simple tests in a keyboard macro. When Calc sees the Z [, it pops an object from the stack and, if the object is a non-zero value, continues executing keystrokes. But if the object is zero, or if it is not provably nonzero, Calc skips ahead to the matching Z ] keystroke. See section Logical Operations, for a set of commands for performing tests which conveniently produce 1 for true and 0 for false.

For example, RET 0 a < Z [ n Z ] implements an absolute-value function in the form of a keyboard macro. This macro duplicates the number on the top of the stack, pushes zero and compares using a < (calc-less-than), then, if the number was less than zero, executes n (calc-change-sign). Otherwise, the change-sign command is skipped.

To program this macro, type C-x (, type the above sequence of keystrokes, then type C-x ). Note that the keystrokes will be executed while you are making the definition as well as when you later re-execute the macro by typing X. Thus you should make sure a suitable number is on the stack before defining the macro so that you don't get a stack-underflow error during the definition process.

Conditionals can be nested arbitrarily. However, there should be exactly one Z ] for each Z [ in a keyboard macro.

The Z : (calc-kbd-else) command allows you to choose between two keystroke sequences. The general format is cond Z [ then-part Z : else-part Z ]. If cond is true (i.e., if the top of stack contains a non-zero number after cond has been executed), the then-part will be executed and the else-part will be skipped. Otherwise, the then-part will be skipped and the else-part will be executed.

The Z | (calc-kbd-else-if) command allows you to choose between any number of alternatives. For example, cond1 Z [ part1 Z : cond2 Z | part2 Z : part3 Z ] will execute part1 if cond1 is true, otherwise it will execute part2 if cond2 is true, otherwise it will execute part3.

More precisely, Z [ pops a number and conditionally skips to the next matching Z : or Z ] key. Z ] has no effect when actually executed. Z : skips to the next matching Z ]. Z | pops a number and conditionally skips to the next matching Z : or Z ]; thus, Z [ and Z | are functionally equivalent except that Z [ participates in nesting but Z | does not.

Calc's conditional and looping constructs work by scanning the keyboard macro for occurrences of character sequences like `Z:' and `Z]'. One side-effect of this is that if you use these constructs you must be careful that these character pairs do not occur by accident in other parts of the macros. Since Calc rarely uses shift-Z for any purpose except as a prefix character, this is not likely to be a problem. Another side-effect is that it will not work to define your own custom key bindings for these commands. Only the standard shift-Z bindings will work correctly.

If Calc gets stuck while skipping characters during the definition of a macro, type Z C-g to cancel the definition. (Typing plain C-g actually adds a C-g keystroke to the macro.)

Loops in Keyboard Macros

The Z < (calc-kbd-repeat) and Z > (calc-kbd-end-repeat) commands pop a number from the stack, which must be an integer, then repeat the keystrokes between the brackets the specified number of times. If the integer is zero or negative, the body is skipped altogether. For example, 1 TAB Z < 2 * Z > computes two to a nonnegative integer power. First, we push 1 on the stack and then swap the integer argument back to the top. The Z < pops that argument leaving the 1 back on top of the stack. Then, we repeat a multiply-by-two step however many times.

Once again, the keyboard macro is executed as it is being entered. In this case it is especially important to set up reasonable initial conditions before making the definition: Suppose the integer 1000 just happened to be sitting on the stack before we typed the above definition! Another approach is to enter a harmless dummy definition for the macro, then go back and edit in the real one with a Z E command. Yet another approach is to type the macro as written-out keystroke names in a buffer, then use M-# m (read-kbd-macro) to read the macro.

The Z / (calc-kbd-break) command allows you to break out of a keyboard macro loop prematurely. It pops an object from the stack; if that object is true (a non-zero number), control jumps out of the innermost enclosing Z < ... Z > loop and continues after the Z >. If the object is false, the Z / has no effect. Thus cond Z / is similar to `if (cond) break;' in the C language.

The Z ( (calc-kbd-for) and Z ) (calc-kbd-end-for) commands are similar to Z < and Z >, except that they make the value of the counter available inside the loop. The general layout is init final Z ( body step Z ). The Z ( command pops initial and final values from the stack. It then creates a temporary internal counter and initializes it with the value init. The Z ( command then repeatedly pushes the counter value onto the stack and executes body and step, adding step to the counter each time until the loop finishes.

By default, the loop finishes when the counter becomes greater than (or less than) final, assuming initial is less than (greater than) final. If initial is equal to final, the body executes exactly once. The body of the loop always executes at least once. For example, 0 1 10 Z ( 2 ^ + 1 Z ) computes the sum of the squares of the integers from 1 to 10, in steps of 1.

If you give a numeric prefix argument of 1 to Z (, the loop is forced to use upward-counting conventions. In this case, if initial is greater than final the body will not be executed at all. Note that step may still be negative in this loop; the prefix argument merely constrains the loop-finished test. Likewise, a prefix argument of -1 forces downward-counting conventions.

The Z { (calc-kbd-loop) and Z } (calc-kbd-end-loop) commands are similar to Z < and Z >, except that they do not pop a count from the stack--they effectively create an infinite loop. Every Z { ... Z } loop ought to include at least one Z / to make sure the loop doesn't run forever. (If any error message occurs which causes Emacs to beep, the keyboard macro will also be halted; this is a standard feature of Emacs. You can also generally press C-g to halt a running keyboard macro, although not all versions of Unix support this feature.)

The conditional and looping constructs are not actually tied to keyboard macros, but they are most often used in that context. For example, the keystrokes 10 Z < 23 RET Z > push ten copies of 23 onto the stack. This can be typed "live" just as easily as in a macro definition.

See section Conditionals in Keyboard Macros, for some additional notes about conditional and looping commands.

Local Values in Macros

Keyboard macros sometimes want to operate under known conditions without affecting surrounding conditions. For example, a keyboard macro may wish to turn on Fraction Mode, or set a particular precision, independent of the user's normal setting for those modes.

Macros also sometimes need to use local variables. Assignments to local variables inside the macro should not affect any variables outside the macro. The Z ` (calc-kbd-push) and Z ' (calc-kbd-pop) commands give you both of these capabilities.

When you type Z ` (with a backquote or accent grave character), the values of various mode settings are saved away. The ten "quick" variables q0 through q9 are also saved. When you type Z ' (with an apostrophe), these values are restored. Pairs of Z ` and Z ' commands may be nested.

If a keyboard macro halts due to an error in between a Z ` and a Z ', the saved values will be restored correctly even though the macro never reaches the Z ' command. Thus you can use Z ` and Z ' without having to worry about what happens in exceptional conditions.

If you type Z ` "live" (not in a keyboard macro), Calc puts you into a "recursive edit." You can tell you are in a recursive edit because there will be extra square brackets in the mode line, as in `[(Calculator)]'. These brackets will go away when you type the matching Z ' command. The modes and quick variables will be saved and restored in just the same way as if actual keyboard macros were involved.

The modes saved by Z ` and Z ' are the current precision and binary word size, the angular mode (Deg, Rad, or HMS), the simplification mode, Algebraic mode, Symbolic mode, Infinite mode, Matrix or Scalar mode, Fraction mode, and the current complex mode (Polar or Rectangular). The ten "quick" variables' values (or lack thereof) are also saved.

Most mode-setting commands act as toggles, but with a numeric prefix they force the mode either on (positive prefix) or off (negative or zero prefix). Since you don't know what the environment might be when you invoke your macro, it's best to use prefix arguments for all mode-setting commands inside the macro.

In fact, C-u Z ` is like Z ` except that it sets the modes listed above to their default values. As usual, the matching Z ' will restore the modes to their settings from before the C-u Z `. Also, Z ` with a negative prefix argument resets algebraic mode to its default (off) but leaves the other modes the same as they were outside the construct.

The contents of the stack and trail, values of non-quick variables, and other settings such as the language mode and the various display modes, are not affected by Z ` and Z '.

Queries in Keyboard Macros

The Z = (calc-kbd-report) command displays an informative message including the value on the top of the stack. You are prompted to enter a string. That string, along with the top-of-stack value, is displayed unless m w (calc-working) has been used to turn such messages off.

The Z # (calc-kbd-query) command displays a prompt message (which you enter during macro definition), then does an algebraic entry which takes its input from the keyboard, even during macro execution. This command allows your keyboard macros to accept numbers or formulas as interactive input. All the normal conventions of algebraic input, including the use of $ characters, are supported.

See section 'Kbd Macro Query' in the Emacs Manual, for a description of C-x q (kbd-macro-query), the standard Emacs way to accept keyboard input during a keyboard macro. In particular, you can use C-x q to enter a recursive edit, which allows the user to perform any Calculator operations interactively before pressing C-M-c to return control to the keyboard macro.

Invocation Macros

Calc provides one special keyboard macro, called up by M-# z (calc-user-invocation), that is intended to allow you to define your own special way of starting Calc. To define this "invocation macro," create the macro in the usual way with C-x ( and C-x ), then type Z I (calc-user-define-invocation). There is only one invocation macro, so you don't need to type any additional letters after Z I. From now on, you can type M-# z at any time to execute your invocation macro.

For example, suppose you find yourself often grabbing rectangles of numbers into Calc and multiplying their columns. You can do this by typing M-# r to grab, and V R : * to multiply columns. To make this into an invocation macro, just type C-x ( M-# r V R : * C-x ), then Z I. Then, to multiply a rectangle of data, just mark the data in its buffer in the usual way and type M-# z.

Invocation macros are treated like regular Emacs keyboard macros; all the special features described above for Z K-style macros do not apply. M-# z is just like C-x e, except that it uses the macro that was last stored by Z I. (In fact, the macro does not even have to have anything to do with Calc!)

The m m command saves the last invocation macro defined by Z I along with all the other Calc mode settings. See section General Mode Commands.

Programming with Formulas

Another way to create a new Calculator command uses algebraic formulas. The Z F (calc-user-define-formula) command stores the formula at the top of the stack as the definition for a key. This command prompts for five things: The key, the command name, the function name, the argument list, and the behavior of the command when given non-numeric arguments.

For example, suppose we type ' a+2b RET to push the formula `a + 2*b' onto the stack. We now type Z F m to define this formula on the z m key sequence. The next prompt is for a command name, beginning with `calc-', which should be the long (M-x) form for the new command. If you simply press RET, a default name like calc-User-m will be constructed. In our example, suppose we enter spam RET to define the new command as calc-spam.

If you want to give the formula a long-style name only, you can press SPC or RET when asked which single key to use. For example Z F RET spam RET defines the new command as M-x calc-spam, with no keyboard equivalent.

The third prompt is for a function name. The default is to use the same name as the command name but with `calcFunc-' in place of `calc-'. This is the name you will use if you want to enter your new function in an algebraic formula. Suppose we enter yow RET. Then the new function can be invoked by pushing two numbers on the stack and typing z m or x spam, or by entering the algebraic formula `yow(x,y)'.

The fourth prompt is for the function's argument list. This is used to associate values on the stack with the variables that appear in the formula. The default is a list of all variables which appear in the formula, sorted into alphabetical order. In our case, the default would be `(a b)'. This means that, when the user types z m, the Calculator will remove two numbers from the stack, substitute these numbers for `a' and `b' (respectively) in the formula, then simplify the formula and push the result on the stack. In other words, 10 RET 100 z m would replace the 10 and 100 on the stack with the number 210, which is a + 2 b with a=10 and b=100. Likewise, the formula `yow(10, 100)' will be evaluated by substituting a=10 and b=100 in the definition.

You can rearrange the order of the names before pressing RET to control which stack positions go to which variables in the formula. If you remove a variable from the argument list, that variable will be left in symbolic form by the command. Thus using an argument list of `(b)' for our function would cause 10 z m to replace the 10 on the stack with the formula `a + 20'. If we had used an argument list of `(b a)', the result with inputs 10 and 100 would have been 120.

You can also put a nameless function on the stack instead of just a formula, as in `<a, b : a + 2 b>'. See section Specifying Operators. In this example, the command will be defined by the formula `a + 2 b' using the argument list `(a b)'.

The final prompt is a y-or-n question concerning what to do if symbolic arguments are given to your function. If you answer y, then executing z m (using the original argument list `(a b)') with arguments 10 and x will leave the function in symbolic form, i.e., `yow(10,x)'. On the other hand, if you answer n, then the formula will always be expanded, even for non-constant arguments: `10 + 2 x'. If you never plan to feed algebraic formulas to your new function, it doesn't matter how you answer this question.

If you answered y to this question you can still cause a function call to be expanded by typing a " (calc-expand-formula). Also, Calc will expand the function if necessary when you take a derivative or integral or solve an equation involving the function.

Once you have defined a formula on a key, you can retrieve this formula with the Z G (calc-user-define-get-defn) command. Press a key, and this command pushes the formula that was used to define that key onto the stack. Actually, it pushes a nameless function that specifies both the argument list and the defining formula. You will get an error message if the key is undefined, or if the key was not defined by a Z F command.

The Z E (calc-user-define-edit) command on a key that has been defined by a formula uses a variant of the calc-edit command to edit the defining formula. Press M-# M-# to finish editing and store the new formula back in the definition, or M-# x to cancel the edit. (The argument list and other properties of the definition are unchanged; to adjust the argument list, you can use Z G to grab the function onto the stack, edit with `, and then re-execute the Z F command.)

As usual, the Z P command records your definition permanently. In this case it will permanently record all three of the relevant definitions: the key, the command, and the function.

You may find it useful to turn off the default simplifications with m O (calc-no-simplify-mode) when entering a formula to be used as a function definition. For example, the formula `deriv(a^2,v)' which might be used to define a new function `dsqr(a,v)' will be "simplified" to 0 immediately upon entry since deriv considers a to be constant with respect to v. Turning off default simplifications cures this problem: The definition will be stored in symbolic form without ever activating the deriv function. Press m D to turn the default simplifications back on afterwards.

Programming with Lisp

The Calculator can be programmed quite extensively in Lisp. All you do is write a normal Lisp function definition, but with defmath in place of defun. This has the same form as defun, but it automagically replaces calls to standard Lisp functions like + and zerop with calls to the corresponding functions in Calc's own library. Thus you can write natural-looking Lisp code which operates on all of the standard Calculator data types. You can then use Z D if you wish to bind your new command to a z-prefix key sequence. The Z E command will not edit a Lisp-based definition.

Emacs Lisp is described in the GNU Emacs Lisp Reference Manual. This section assumes a familiarity with Lisp programming concepts; if you do not know Lisp, you may find keyboard macros or rewrite rules to be an easier way to program the Calculator.

This section first discusses ways to write commands, functions, or small programs to be executed inside of Calc. Then it discusses how your own separate programs are able to call Calc from the outside. Finally, there is a list of internal Calc functions and data structures for the true Lisp enthusiast.

Defining New Functions

The defmath function (actually a Lisp macro) is like defun except that code in the body of the definition can make use of the full range of Calculator data types. The prefix `calcFunc-' is added to the specified name to get the actual Lisp function name. As a simple example,

(defmath myfact (n)
  (if (> n 0)
      (* n (myfact (1- n)))
    1))

This actually expands to the code,

(defun calcFunc-myfact (n)
  (if (math-posp n)
      (math-mul n (calcFunc-myfact (math-add n -1)))
    1))

This function can be used in algebraic expressions, e.g., `myfact(5)'.

The `myfact' function as it is defined above has the bug that an expression `myfact(a+b)' will be simplified to 1 because the formula `a+b' is not considered to be posp. A robust factorial function would be written along the following lines:

(defmath myfact (n)
  (if (> n 0)
      (* n (myfact (1- n)))
    (if (= n 0)
        1
      nil)))    ; this could be simplified as: (and (= n 0) 1)

If a function returns nil, it is left unsimplified by the Calculator (except that its arguments will be simplified). Thus, `myfact(a+1+2)' will be simplified to `myfact(a+3)' but no further. Beware that every time the Calculator reexamines this formula it will attempt to resimplify it, so your function ought to detect the returning-nil case as efficiently as possible.

The following standard Lisp functions are treated by defmath: +, -, *, /, %, ^ or expt, =, <, >, <=, >=, /=, 1+, 1-, logand, logior, logxor, logandc2, lognot. Also, ~= is an abbreviation for math-nearly-equal, which is useful in implementing Taylor series.

For other functions func, if a function by the name `calcFunc-func' exists it is used, otherwise if a function by the name `math-func' exists it is used, otherwise if func itself is defined as a function it is used, otherwise `calcFunc-func' is used on the assumption that this is a to-be-defined math function. Also, if the function name is quoted as in `('integerp a)' the function name is always used exactly as written (but not quoted).

Variable names have `var-' prepended to them unless they appear in the function's argument list or in an enclosing let, let*, for, or foreach form, or their names already contain a `-' character. Thus a reference to `foo' is the same as a reference to `var-foo'.

A few other Lisp extensions are available in defmath definitions:

Non-integer numbers (and extremely large integers) cannot be included directly into a defmath definition. This is because the Lisp reader will fail to parse them long before defmath ever gets control. Instead, use the notation, `:"3.1415"'. In fact, any algebraic formula can go between the quotes. For example,

(defmath sqexp (x)     ; sqexp(x) == sqrt(exp(x)) == exp(x*0.5)
  (and (numberp x)
       (exp :"x * 0.5")))

expands to

(defun calcFunc-sqexp (x)
  (and (math-numberp x)
       (calcFunc-exp (math-mul x '(float 5 -1)))))

Note the use of numberp as a guard to ensure that the argument is a number first, returning nil if not. The exponential function could itself have been included in the expression, if we had preferred: `:"exp(x * 0.5)"'. As another example, the multiplication-and-recursion step of myfact could have been written

:"n * myfact(n-1)"

If a file named `.emacs' exists in your home directory, Emacs reads and executes the Lisp forms in this file as it starts up. While it may seem like a good idea to put your favorite defmath commands here, this has the unfortunate side-effect that parts of the Calculator must be loaded in to process the defmath commands whether or not you will actually use the Calculator! A better effect can be had by writing

(put 'calc-define 'thing '(progn
 (defmath ... )
 (defmath ... )
))

The put function adds a property to a symbol. Each Lisp symbol has a list of properties associated with it. Here we add a property with a name of thing and a `(progn ...)' form as its value. When Calc starts up, and at the start of every Calc command, the property list for the symbol calc-define is checked and the values of any properties found are evaluated as Lisp forms. The properties are removed as they are evaluated. The property names (like thing) are not used; you should choose something like the name of your project so as not to conflict with other properties.

The net effect is that you can put the above code in your `.emacs' file and it will not be executed until Calc is loaded. Or, you can put that same code in another file which you load by hand either before or after Calc itself is loaded.

The properties of calc-define are evaluated in the same order that they were added. They can assume that the Calc modules `calc.el', `calc-ext.el', and `calc-macs.el' have been fully loaded, and that the `*Calculator*' buffer will be the current buffer.

If your calc-define property only defines algebraic functions, you can be sure that it will have been evaluated before Calc tries to call your function, even if the file defining the property is loaded after Calc is loaded. But if the property defines commands or key sequences, it may not be evaluated soon enough. (Suppose it defines the new command tweak-calc; the user can load your file, then type M-x tweak-calc before Calc has had chance to do anything.) To protect against this situation, you can put

(run-hooks 'calc-check-defines)

at the end of your file. The calc-check-defines function is what looks for and evaluates properties on calc-define; run-hooks has the advantage that it is quietly ignored if calc-check-defines is not yet defined because Calc has not yet been loaded.

Examples of things that ought to be enclosed in a calc-define property are defmath calls, define-key calls that modify the Calc key map, and any calls that redefine things defined inside Calc. Ordinary defuns need not be enclosed with calc-define.

Defining New Simple Commands

If a defmath form contains an interactive clause, it defines a Calculator command. Actually such a defmath results in two function definitions: One, a `calcFunc-' function as was just described, with the interactive clause removed. Two, a `calc-' function with a suitable interactive clause and some sort of wrapper to make the command work in the Calc environment.

In the simple case, the interactive clause has the same form as for normal Emacs Lisp commands:

(defmath increase-precision (delta)
  "Increase precision by DELTA."     ; This is the "documentation string"
  (interactive "p")                  ; Register this as a M-x-able command
  (setq calc-internal-prec (+ calc-internal-prec delta)))

This expands to the pair of definitions,

(defun calc-increase-precision (delta)
  "Increase precision by DELTA."
  (interactive "p")
  (calc-wrapper
   (setq calc-internal-prec (math-add calc-internal-prec delta))))

(defun calcFunc-increase-precision (delta)
  "Increase precision by DELTA."
  (setq calc-internal-prec (math-add calc-internal-prec delta)))

where in this case the latter function would never really be used! Note that since the Calculator stores small integers as plain Lisp integers, the math-add function will work just as well as the native + even when the intent is to operate on native Lisp integers.

The `calc-wrapper' call invokes a macro which surrounds the body of the function with code that looks roughly like this:

(let ((calc-command-flags nil))
  (unwind-protect
      (save-excursion
        (calc-select-buffer)
        body of function
        renumber stack
        clear Working message)
    realign cursor and window
    clear Inverse, Hyperbolic, and Keep Args flags
    update Emacs mode line))

The calc-select-buffer function selects the `*Calculator*' buffer if necessary, say, because the command was invoked from inside the `*Calc Trail*' window.

You can call, for example, (calc-set-command-flag 'no-align) to set the above-mentioned command flags. The following command flags are recognized by Calc routines:

renum-stack
Stack line numbers `1:', `2:', and so on must be renumbered after this command completes. This is set by routines like calc-push.

clear-message
Calc should call `(message "")' if this command completes normally (to clear a "Working..." message out of the echo area).

no-align
Do not move the cursor back to the `.' top-of-stack marker.

position-point
Use the variables calc-position-point-line and calc-position-point-column to position the cursor after this command finishes.

keep-flags
Do not clear calc-inverse-flag, calc-hyperbolic-flag, and calc-keep-args-flag at the end of this command.

do-edit
Switch to buffer `*Calc Edit*' after this command.

hold-trail
Do not move trail pointer to end of trail when something is recorded there.

Calc reserves a special prefix key, shift-Y, for user-written extensions to Calc. There are no built-in commands that work with this prefix key; you must call define-key from Lisp (probably from inside a calc-define property) to add to it. Initially only Y ? is defined; it takes help messages from a list of strings (initially nil) in the variable calc-Y-help-msgs. All other undefined keys except for Y are reserved for use by future versions of Calc.

If you are writing a Calc enhancement which you expect to give to others, it is best to minimize the number of Y-key sequences you use. In fact, if you have more than one key sequence you should consider defining three-key sequences with a Y, then a key that stands for your package, then a third key for the particular command within your package.

Users may wish to install several Calc enhancements, and it is possible that several enhancements will choose to use the same key. In the example below, a variable inc-prec-base-key has been defined to contain the key that identifies the inc-prec package. Its value is initially "P", but a user can change this variable if necessary without having to modify the file.

Here is a complete file, `inc-prec.el', which makes a Y P I command that increases the precision, and a Y P D command that decreases the precision.

;;; Increase and decrease Calc precision.  Dave Gillespie, 5/31/91.
;;; (Include copyright or copyleft stuff here.)

(defvar inc-prec-base-key "P"
  "Base key for inc-prec.el commands.")

(put 'calc-define 'inc-prec '(progn

(define-key calc-mode-map (format "Y%sI" inc-prec-base-key)
            'increase-precision)
(define-key calc-mode-map (format "Y%sD" inc-prec-base-key)
            'decrease-precision)

(setq calc-Y-help-msgs
      (cons (format "%s + Inc-prec, Dec-prec" inc-prec-base-key)
            calc-Y-help-msgs))

(defmath increase-precision (delta)
  "Increase precision by DELTA."
  (interactive "p")
  (setq calc-internal-prec (+ calc-internal-prec delta)))

(defmath decrease-precision (delta)
  "Decrease precision by DELTA."
  (interactive "p")
  (setq calc-internal-prec (- calc-internal-prec delta)))

))  ; end of calc-define property

(run-hooks 'calc-check-defines)

Defining New Stack-Based Commands

To define a new computational command which takes and/or leaves arguments on the stack, a special form of interactive clause is used.

(interactive num tag)

where num is an integer, and tag is a string. The effect is to pop num values off the stack, resimplify them by calling calc-normalize, and hand them to your function according to the function's argument list. Your function may include &optional and &rest parameters, so long as calling the function with num parameters is legal.

Your function must return either a number or a formula in a form acceptable to Calc, or a list of such numbers or formulas. These value(s) are pushed onto the stack when the function completes. They are also recorded in the Calc Trail buffer on a line beginning with tag, a string of (normally) four characters or less. If you omit tag or use nil as a tag, the result is not recorded in the trail.

As an example, the definition

(defmath myfact (n)
  "Compute the factorial of the integer at the top of the stack."
  (interactive 1 "fact")
  (if (> n 0)
      (* n (myfact (1- n)))
    (and (= n 0) 1)))

is a version of the factorial function shown previously which can be used as a command as well as an algebraic function. It expands to

(defun calc-myfact ()
  "Compute the factorial of the integer at the top of the stack."
  (interactive)
  (calc-slow-wrapper
   (calc-enter-result 1 "fact"
     (cons 'calcFunc-myfact (calc-top-list-n 1)))))

(defun calcFunc-myfact (n)
  "Compute the factorial of the integer at the top of the stack."
  (if (math-posp n)
      (math-mul n (calcFunc-myfact (math-add n -1)))
    (and (math-zerop n) 1)))

The calc-slow-wrapper function is a version of calc-wrapper that automatically puts up a `Working...' message before the computation begins. (This message can be turned off by the user with an m w (calc-working) command.)

The calc-top-list-n function returns a list of the specified number of values from the top of the stack. It resimplifies each value by calling calc-normalize. If its argument is zero it returns an empty list. It does not actually remove these values from the stack.

The calc-enter-result function takes an integer num and string tag as described above, plus a third argument which is either a Calculator data object or a list of such objects. These objects are resimplified and pushed onto the stack after popping the specified number of values from the stack. If tag is non-nil, the values being pushed are also recorded in the trail.

Note that if calcFunc-myfact returns nil this represents "leave the function in symbolic form." To return an actual empty list, in the sense that calc-enter-result will push zero elements back onto the stack, you should return the special value `'(nil)', a list containing the single symbol nil.

The interactive declaration can actually contain a limited Emacs-style code string as well which comes just before num and tag. Currently the only Emacs code supported is `"p"', as in

(defmath foo (a b &optional c)
  (interactive "p" 2 "foo")
  body)

In this example, the command calc-foo will evaluate the expression `foo(a,b)' if executed with no argument, or `foo(a,b,n)' if executed with a numeric prefix argument of n.

The other code string allowed is `"m"' (unrelated to the usual `"m"' code as used with defun). It uses the numeric prefix argument as the number of objects to remove from the stack and pass to the function. In this case, the integer num serves as a default number of arguments to be used when no prefix is supplied.

Argument Qualifiers

Anywhere a parameter name can appear in the parameter list you can also use an argument qualifier. Thus the general form of a definition is:

(defmath name (param param...
               &optional param param...
               &rest param)
  body)

where each param is either a symbol or a list of the form

(qual param)

The following qualifiers are recognized:

`complete'
The argument must not be an incomplete vector, interval, or complex number. (This is rarely needed since the Calculator itself will never call your function with an incomplete argument. But there is nothing stopping your own Lisp code from calling your function with an incomplete argument.)

`integer'
The argument must be an integer. If it is an integer-valued float it will be accepted but converted to integer form. Non-integers and formulas are rejected.

`natnum'
Like `integer', but the argument must be non-negative.

`fixnum'
Like `integer', but the argument must fit into a native Lisp integer, which on most systems means less than 2^23 in absolute value. The argument is converted into Lisp-integer form if necessary.

`float'
The argument is converted to floating-point format if it is a number or vector. If it is a formula it is left alone. (The argument is never actually rejected by this qualifier.)

`pred'
The argument must satisfy predicate pred, which is one of the standard Calculator predicates. See section Predicates.

`not-pred'
The argument must not satisfy predicate pred.

For example,

(defmath foo (a (constp (not-matrixp b)) &optional (float c)
              &rest (integer d))
  body)

expands to

(defun calcFunc-foo (a b &optional c &rest d)
  (and (math-matrixp b)
       (math-reject-arg b 'not-matrixp))
  (or (math-constp b)
      (math-reject-arg b 'constp))
  (and c (setq c (math-check-float c)))
  (setq d (mapcar 'math-check-integer d))
  body)

which performs the necessary checks and conversions before executing the body of the function.

Example Definitions

This section includes some Lisp programming examples on a larger scale. These programs make use of some of the Calculator's internal functions; see section Calculator Internals.

Bit-Counting

Calc does not include a built-in function for counting the number of "one" bits in a binary integer. It's easy to invent one using b u to convert the integer to a set, and V # to count the elements of that set; let's write a function that counts the bits without having to create an intermediate set.

(defmath bcount ((natnum n))
  (interactive 1 "bcnt")
  (let ((count 0))
    (while (> n 0)
      (if (oddp n)
          (setq count (1+ count)))
      (setq n (lsh n -1)))
    count))

When this is expanded by defmath, it will become the following Emacs Lisp function:

(defun calcFunc-bcount (n)
  (setq n (math-check-natnum n))
  (let ((count 0))
    (while (math-posp n)
      (if (math-oddp n)
          (setq count (math-add count 1)))
      (setq n (calcFunc-lsh n -1)))
    count))

If the input numbers are large, this function involves a fair amount of arithmetic. A binary right shift is essentially a division by two; recall that Calc stores integers in decimal form so bit shifts must involve actual division.

To gain a bit more efficiency, we could divide the integer into n-bit chunks, each of which can be handled quickly because they fit into Lisp integers. It turns out that Calc's arithmetic routines are especially fast when dividing by an integer less than 1000, so we can set n = 9 bits and use repeated division by 512:

(defmath bcount ((natnum n))
  (interactive 1 "bcnt")
  (let ((count 0))
    (while (not (fixnump n))
      (let ((qr (idivmod n 512)))
        (setq count (+ count (bcount-fixnum (cdr qr)))
              n (car qr))))
    (+ count (bcount-fixnum n))))

(defun bcount-fixnum (n)
  (let ((count 0))
    (while (> n 0)
      (setq count (+ count (logand n 1))
            n (lsh n -1)))
    count))

Note that the second function uses defun, not defmath. Because this function deals only with native Lisp integers ("fixnums"), it can use the actual Emacs + and related functions rather than the slower but more general Calc equivalents which defmath uses.

The idivmod function does an integer division, returning both the quotient and the remainder at once. Again, note that while it might seem that `(logand n 511)' and `(lsh n -9)' are more efficient ways to split off the bottom nine bits of n, actually they are less efficient because each operation is really a division by 512 in disguise; idivmod allows us to do the same thing with a single division by 512.

The Sine Function

A somewhat limited sine function could be defined as follows, using the well-known Taylor series expansion for @c{$\sin x$} `sin(x)':

(defmath mysin ((float (anglep x)))
  (interactive 1 "mysn")
  (setq x (to-radians x))    ; Convert from current angular mode.
  (let ((sum x)              ; Initial term of Taylor expansion of sin.
        newsum
        (nfact 1)            ; "nfact" equals "n" factorial at all times.
        (xnegsqr :"-(x^2)")) ; "xnegsqr" equals -x^2.
    (for ((n 3 100 2))       ; Upper limit of 100 is a good precaution.
      (working "mysin" sum)  ; Display "Working" message, if enabled.
      (setq nfact (* nfact (1- n) n)
            x (* x xnegsqr)
            newsum (+ sum (/ x nfact)))
      (if (~= newsum sum)    ; If newsum is "nearly equal to" sum,
          (break))           ;  then we are done.
      (setq sum newsum))
    sum))

The actual sin function in Calc works by first reducing the problem to a sine or cosine of a nonnegative number less than @c{$\pi \over 4$} pi/4. This ensures that the Taylor series will converge quickly. Also, the calculation is carried out with two extra digits of precision to guard against cumulative round-off in `sum'. Finally, complex arguments are allowed and handled by a separate algorithm.

(defmath mysin ((float (scalarp x)))
  (interactive 1 "mysn")
  (setq x (to-radians x))    ; Convert from current angular mode.
  (with-extra-prec 2         ; Evaluate with extra precision.
    (cond ((complexp x)
           (mysin-complex x))
          ((< x 0)
           (- (mysin-raw (- x)))    ; Always call mysin-raw with x >= 0.
          (t (mysin-raw x))))))

(defmath mysin-raw (x)
  (cond ((>= x 7)
         (mysin-raw (% x (two-pi))))     ; Now x < 7.
        ((> x (pi-over-2))
         (- (mysin-raw (- x (pi)))))     ; Now -pi/2 <= x <= pi/2.
        ((> x (pi-over-4))
         (mycos-raw (- x (pi-over-2))))  ; Now -pi/2 <= x <= pi/4.
        ((< x (- (pi-over-4)))
         (- (mycos-raw (+ x (pi-over-2)))))  ; Now -pi/4 <= x <= pi/4,
        (t (mysin-series x))))           ; so the series will be efficient.

where mysin-complex is an appropriate function to handle complex numbers, mysin-series is the routine to compute the sine Taylor series as before, and mycos-raw is a function analogous to mysin-raw for cosines.

The strategy is to ensure that x is nonnegative before calling mysin-raw. This function then recursively reduces its argument to a suitable range, namely, plus-or-minus @c{$\pi \over 4$} pi/4. Note that each test, and particularly the first comparison against 7, is designed so that small roundoff errors cannnot produce an infinite loop. (Suppose we compared with `(two-pi)' instead; if due to roundoff problems the modulo operator ever returned `(two-pi)' exactly, an infinite recursion could result!) We use modulo only for arguments that will clearly get reduced, knowing that the next rule will catch any reductions that this rule misses.

If a program is being written for general use, it is important to code it carefully as shown in this second example. For quick-and-dirty programs, when you know that your own use of the sine function will never encounter a large argument, a simpler program like the first one shown is fine.

Calling Calc from Your Lisp Programs

A later section (see section Calculator Internals) gives a full description of Calc's internal Lisp functions. It's not hard to call Calc from inside your programs, but the number of these functions can be daunting. So Calc provides one special "programmer-friendly" function called calc-eval that can be made to do just about everything you need. It's not as fast as the low-level Calc functions, but it's much simpler to use!

It may seem that calc-eval itself has a daunting number of options, but they all stem from one simple operation.

In its simplest manifestation, `(calc-eval "1+2")' parses the string "1+2" as if it were a Calc algebraic entry and returns the result formatted as a string: "3".

Since calc-eval is on the list of recommended autoload functions, you don't need to make any -level Calc functions, but it's much simpler to use!

It may seem that calc-eval itself has a daunting number of options, but they all stem from one simple operation.

In its simplest manifestation, `(calc-eval "1+2")' parses the string "1+2" as if it were a Calc algebraic entry and returns the result formatted as a string: "3".

Since calc-eval is on the list of recommended autoload functions, you don't need to make any