Fascinating interview by Richard Stallman on Russia TV
geremy condra
debatem1 at gmail.com
Mon Jul 19 04:22:19 EDT 2010
On Sun, Jul 18, 2010 at 7:53 AM, David Kastrup <dak at gnu.org> wrote:
<snip rant and anti-rant>
> File: elisp, Node: Writing Emacs Primitives, Next: Object Internals, Prev: Memory Usage, Up: GNU Emacs Internals
>
> E.5 Writing Emacs Primitives
> ============================
>
> Lisp primitives are Lisp functions implemented in C. The details of
> interfacing the C function so that Lisp can call it are handled by a few
> C macros. The only way to really understand how to write new C code is
> to read the source, but we can explain some things here.
>
> An example of a special form is the definition of `or', from
> `eval.c'. (An ordinary function would have the same general
> appearance.)
>
> DEFUN ("or", For, Sor, 0, UNEVALLED, 0,
> doc: /* Eval args until one of them yields non-nil, then return that
> value. The remaining args are not evalled at all.
> If all args return nil, return nil.
> usage: (or CONDITIONS ...) */)
> (Lisp_Object args)
> {
> register Lisp_Object val = Qnil;
> struct gcpro gcpro1;
>
> GCPRO1 (args);
>
> while (CONSP (args))
> {
> val = Feval (XCAR (args));
> if (!NILP (val))
> break;
> args = XCDR (args);
> }
>
> UNGCPRO;
> return val;
> }
>
> Let's start with a precise explanation of the arguments to the
> `DEFUN' macro. Here is a template for them:
>
> DEFUN (LNAME, FNAME, SNAME, MIN, MAX, INTERACTIVE, DOC)
>
> LNAME
> This is the name of the Lisp symbol to define as the function
> name; in the example above, it is `or'.
>
> FNAME
> This is the C function name for this function. This is the name
> that is used in C code for calling the function. The name is, by
> convention, `F' prepended to the Lisp name, with all dashes (`-')
> in the Lisp name changed to underscores. Thus, to call this
> function from C code, call `For'. Remember that the arguments must
> be of type `Lisp_Object'; various macros and functions for creating
> values of type `Lisp_Object' are declared in the file `lisp.h'.
>
> SNAME
> This is a C variable name to use for a structure that holds the
> data for the subr object that represents the function in Lisp.
> This structure conveys the Lisp symbol name to the initialization
> routine that will create the symbol and store the subr object as
> its definition. By convention, this name is always FNAME with `F'
> replaced with `S'.
>
> MIN
> This is the minimum number of arguments that the function
> requires. The function `or' allows a minimum of zero arguments.
>
> MAX
> This is the maximum number of arguments that the function accepts,
> if there is a fixed maximum. Alternatively, it can be `UNEVALLED',
> indicating a special form that receives unevaluated arguments, or
> `MANY', indicating an unlimited number of evaluated arguments (the
> equivalent of `&rest'). Both `UNEVALLED' and `MANY' are macros.
> If MAX is a number, it may not be less than MIN and it may not be
> greater than eight.
>
> INTERACTIVE
> This is an interactive specification, a string such as might be
> used as the argument of `interactive' in a Lisp function. In the
> case of `or', it is 0 (a null pointer), indicating that `or'
> cannot be called interactively. A value of `""' indicates a
> function that should receive no arguments when called
> interactively. If the value begins with a `(', the string is
> evaluated as a Lisp form.
>
> DOC
> This is the documentation string. It uses C comment syntax rather
> than C string syntax because comment syntax requires nothing
> special to include multiple lines. The `doc:' identifies the
> comment that follows as the documentation string. The `/*' and
> `*/' delimiters that begin and end the comment are not part of the
> documentation string.
>
> If the last line of the documentation string begins with the
> keyword `usage:', the rest of the line is treated as the argument
> list for documentation purposes. This way, you can use different
> argument names in the documentation string from the ones used in
> the C code. `usage:' is required if the function has an unlimited
> number of arguments.
>
> All the usual rules for documentation strings in Lisp code (*note
> Documentation Tips::) apply to C code documentation strings too.
>
> After the call to the `DEFUN' macro, you must write the argument
> list that every C function must have, including the types for the
> arguments. For a function with a fixed maximum number of arguments,
> declare a C argument for each Lisp argument, and give them all type
> `Lisp_Object'. When a Lisp function has no upper limit on the number
> of arguments, its implementation in C actually receives exactly two
> arguments: the first is the number of Lisp arguments, and the second is
> the address of a block containing their values. They have types `int'
> and `Lisp_Object *'.
>
> Within the function `For' itself, note the use of the macros
> `GCPRO1' and `UNGCPRO'. `GCPRO1' is used to "protect" a variable from
> garbage collection--to inform the garbage collector that it must look
> in that variable and regard its contents as an accessible object. GC
> protection is necessary whenever you call `Feval' or anything that can
> directly or indirectly call `Feval'. At such a time, any Lisp object
> that this function may refer to again must be protected somehow.
>
> It suffices to ensure that at least one pointer to each object is
> GC-protected; that way, the object cannot be recycled, so all pointers
> to it remain valid. Thus, a particular local variable can do without
> protection if it is certain that the object it points to will be
> preserved by some other pointer (such as another local variable which
> has a `GCPRO')(1). Otherwise, the local variable needs a `GCPRO'.
>
> The macro `GCPRO1' protects just one local variable. If you want to
> protect two variables, use `GCPRO2' instead; repeating `GCPRO1' will
> not work. Macros `GCPRO3', `GCPRO4', `GCPRO5', and `GCPRO6' also
> exist. All these macros implicitly use local variables such as
> `gcpro1'; you must declare these explicitly, with type `struct gcpro'.
> Thus, if you use `GCPRO2', you must declare `gcpro1' and `gcpro2'.
> Alas, we can't explain all the tricky details here.
>
> `UNGCPRO' cancels the protection of the variables that are protected
> in the current function. It is necessary to do this explicitly.
>
> Built-in functions that take a variable number of arguments actually
> accept two arguments at the C level: the number of Lisp arguments, and
> a `Lisp_Object *' pointer to a C vector containing those Lisp
> arguments. This C vector may be part of a Lisp vector, but it need not
> be. The responsibility for using `GCPRO' to protect the Lisp arguments
> from GC if necessary rests with the caller in this case, since the
> caller allocated or found the storage for them.
>
> You must not use C initializers for static or global variables unless
> the variables are never written once Emacs is dumped. These variables
> with initializers are allocated in an area of memory that becomes
> read-only (on certain operating systems) as a result of dumping Emacs.
> *Note Pure Storage::.
>
> Do not use static variables within functions--place all static
> variables at top level in the file. This is necessary because Emacs on
> some operating systems defines the keyword `static' as a null macro.
> (This definition is used because those systems put all variables
> declared static in a place that becomes read-only after dumping, whether
> they have initializers or not.)
>
> Defining the C function is not enough to make a Lisp primitive
> available; you must also create the Lisp symbol for the primitive and
> store a suitable subr object in its function cell. The code looks like
> this:
>
> defsubr (&SUBR-STRUCTURE-NAME);
>
> Here SUBR-STRUCTURE-NAME is the name you used as the third argument to
> `DEFUN'.
>
> If you add a new primitive to a file that already has Lisp primitives
> defined in it, find the function (near the end of the file) named
> `syms_of_SOMETHING', and add the call to `defsubr' there. If the file
> doesn't have this function, or if you create a new file, add to it a
> `syms_of_FILENAME' (e.g., `syms_of_myfile'). Then find the spot in
> `emacs.c' where all of these functions are called, and add a call to
> `syms_of_FILENAME' there.
>
> The function `syms_of_FILENAME' is also the place to define any C
> variables that are to be visible as Lisp variables. `DEFVAR_LISP'
> makes a C variable of type `Lisp_Object' visible in Lisp. `DEFVAR_INT'
> makes a C variable of type `int' visible in Lisp with a value that is
> always an integer. `DEFVAR_BOOL' makes a C variable of type `int'
> visible in Lisp with a value that is either `t' or `nil'. Note that
> variables defined with `DEFVAR_BOOL' are automatically added to the list
> `byte-boolean-vars' used by the byte compiler.
>
> If you define a file-scope C variable of type `Lisp_Object', you
> must protect it from garbage-collection by calling `staticpro' in
> `syms_of_FILENAME', like this:
>
> staticpro (&VARIABLE);
>
> Here is another example function, with more complicated arguments.
> This comes from the code in `window.c', and it demonstrates the use of
> macros and functions to manipulate Lisp objects.
>
> DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p,
> Scoordinates_in_window_p, 2, 2,
> "xSpecify coordinate pair: \nXExpression which evals to window: ",
> "Return non-nil if COORDINATES is in WINDOW.\n\
> COORDINATES is a cons of the form (X . Y), X and Y being distances\n\
> ...
> If they are on the border between WINDOW and its right sibling,\n\
> `vertical-line' is returned.")
> (coordinates, window)
> register Lisp_Object coordinates, window;
> {
> int x, y;
>
> CHECK_LIVE_WINDOW (window, 0);
> CHECK_CONS (coordinates, 1);
> x = XINT (Fcar (coordinates));
> y = XINT (Fcdr (coordinates));
>
> switch (coordinates_in_window (XWINDOW (window), &x, &y))
> {
> case 0: /* NOT in window at all. */
> return Qnil;
>
> case 1: /* In text part of window. */
> return Fcons (make_number (x), make_number (y));
>
> case 2: /* In mode line of window. */
> return Qmode_line;
>
> case 3: /* On right border of window. */
> return Qvertical_line;
>
> default:
> abort ();
> }
> }
>
> Note that C code cannot call functions by name unless they are
> defined in C. The way to call a function written in Lisp is to use
> `Ffuncall', which embodies the Lisp function `funcall'. Since the Lisp
> function `funcall' accepts an unlimited number of arguments, in C it
> takes two: the number of Lisp-level arguments, and a one-dimensional
> array containing their values. The first Lisp-level argument is the
> Lisp function to call, and the rest are the arguments to pass to it.
> Since `Ffuncall' can call the evaluator, you must protect pointers from
> garbage collection around the call to `Ffuncall'.
>
> The C functions `call0', `call1', `call2', and so on, provide handy
> ways to call a Lisp function conveniently with a fixed number of
> arguments. They work by calling `Ffuncall'.
>
> `eval.c' is a very good file to look through for examples; `lisp.h'
> contains the definitions for some important macros and functions.
>
> If you define a function which is side-effect free, update the code
> in `byte-opt.el' which binds `side-effect-free-fns' and
> `side-effect-and-error-free-fns' so that the compiler optimizer knows
> about it.
>
> ---------- Footnotes ----------
>
> (1) Formerly, strings were a special exception; in older Emacs
> versions, every local variable that might point to a string needed a
> `GCPRO'.
>
<moar snip>
To me, this is amazing documentation. I would love it if there were
something this explicit for the C API.
Geremy Condra
More information about the Python-list
mailing list