Go forward to Argument Qualifiers. Go backward to Defining Simple Commands. Go up to Lisp Definitions.

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.