Next: Argument Qualifiers, Previous: Defining Simple Commands, Up: Lisp Definitions

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

clause is used.

(interactivenumtag)

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 valid.

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.