From: David Kastrup <dak@gnu.org>
To: help-gnu-emacs@gnu.org
Subject: Re: Fascinating interview by Richard Stallman on Russia TV
Date: Sun, 18 Jul 2010 16:53:53 +0200 [thread overview]
Message-ID: <87oce4hmda.fsf__38138.5607448921$1291847641$gmane$org@lola.goethe.zz> (raw)
In-Reply-To: 6e469332-eb46-4b81-aee3-10e5aa4e92cb@i31g2000yqm.googlegroups.com
Emmy Noether <emmynoether3@gmail.com> writes:
> On Jul 18, 12:27 am, David Kastrup <d...@gnu.org> wrote:
>
>> What did you ever do to _deserve_ others working for you?
>
> What did we do to deserve him to write that elisp manual of 800+
> pages ? NOTHING.
So once one gives you something, you demand everything?
> He gave it to us in the hope that his software will spread like a
> VIRUS.
Yup. It is called "culture". It is _supposed_ to spread exponentially.
That's what the peculiar brain structure of humans is good for.
Communicating knowledge instead of inheriting it. That's the
fundamental advantage we have over other animals. Not something lightly
given up.
> A person arrives in the state of a newbie and wants to exit in a state
> of having made a contribution to FSF.
That's the problem of the person. It has not been a goal of the GNU
project to turn every person into somebody useful. They have the
freedom to try, getting everything for their start that anybody else has
available.
> How can one do it without adequate documentation ?
Emacs development is active, so there are people considering the
documentation adequate for starting to work on Emacs.
> Xah Lee has been complaining for a year. First you deprive people of
> ESSENTIAL documentation to contribute.
You can't "deprive" anybody of anything that is not there to start with.
> DEFUN ("or", For, Sor, 0, UNEVALLED, 0,
> "Eval args until one of them yields non-NIL, then return that value.
> \n\
> The remaining args are not evalled at all.\n\
> If all args return NIL, return NIL.")
> (args)
> Lisp_Object args;
> {
> register Lisp_Object val;
> Lisp_Object args_left;
> struct gcpro gcpro1;
>
> if (NULL(args))
> return Qnil;
>
> args_left = args;
> GCPRO1 (args_left);
>
> do
> {
> val = Feval (Fcar (args_left));
> if (!NULL (val))
> break;
> args_left = Fcdr (args_left);
> }
> while (!NULL(args_left));
>
> UNGCPRO;
> return val;
> }
>
> I saw that on comp.lang.c and found no one capable of explaining it.
If you see other context-free stuff on comp.lang.c, the situation will
not be different. The above code is rather trivial. But you'll find
the respective parts explained in the Emacs Lisp manual. In fact, the
above is likely extracted from exactly there, from
(info "(elisp) Writing Emacs Primitives")
I append the whole at the bottom to not interrupt the flow of
non-thought.
> And where does the manual explain the C struct or ADT of the basic
> cons cell ? which file has the definition ? where is his eval_quote
> function definition ?
eval_quote? What's that?
> Basically, Richard Mathew Stall man is a STALLER of PROGRESS. He
> expected the XEMACS people to EXPLAIN HIM EVERY SINGLE line of code.
> What did he do to expect all this ?
He was the maintainer of upstream Emacs, and it was his decision what
code was going there. And he had to keep maintainability in mind.
Something which was less of a priority with XEmacs developers, and
likely part of the reason that they are running out of fresh blood much
worse than Emacs these days.
> He was even paid money , as claimed by the XEMACS people.
>
> What did he do to deserve and EXPECT a line by line explanation from
> them ?????!!!!!! ANSWER this question and dont run away !!!!!!
There was nothing to "deserve". It was his job to keep Emacs going
forward, and his opinion and decision that throwing the Lucid Emacs code
in would not have been good in the long run. It has not been good for
XEmacs in the long run. Whether it would have been better or worse for
a grand unified Emacs, noone will ever know. He decided to play it safe
given the information he had at that time, and Emacs is still there and
going forward.
In spite of trolls like you spouting abuse by the hundreds.
More than can be said for many other projects.
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'.
> He is prone to forgetting like all mortals and if he is prolific to
> write that 900 page manual, I am sure he has hidden notes that he has
> not released. Where was he recording the line by line explanation he
> was receiving from the XEMACS people ? If not in his own very personal
> version ???
What makes you think he received any such explanation? Why would not
the XEmacs people, after writing such explanations, put them in their
own code and manuals?
Your conspiracy theories just stink.
> Answer these very strong arguments ???
Ok, so they stink strongly.
> What did he deserve to get the XEMACS people's explanations ? AND why
> is he INCAPABLE of building upon the XEMACS work ??? This is all about
> documentation, professional jealousies of these mean spirited people
> with double standards. Send him a CC of this thread. I expect him to
> explain some of these issues of documentation.
I quoted the above part from the documentation. I do not consider this
sort of shit worth his attention and certainly won't forward it, lending
it credibility. It is not like he has a secret Email address or
something. I should hope he would have the prudence to just throw crap
like the above away should he receive it from some anonymous idiot not
willing to sign his name under his brain farts.
--
David Kastrup
next prev parent reply other threads:[~2010-07-18 14:53 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <4db5e9a2-1d00-4b02-b988-17829a537aab@x27g2000yqb.googlegroups.com>
2010-07-15 22:21 ` Fascinating interview by Richard Stallman at KTH on emacs history and internals bolega
[not found] ` <75be3e9a-d145-499b-8f5f-ceb734aaa4eb@j8g2000yqd.googlegroups.com>
[not found] ` <bd2d1d84-6090-4898-b7c2-59167fc8e1f5@c10g2000yqi.googlegroups.com>
[not found] ` <i1u85u$7kp$1@lust.ihug.co.nz>
[not found] ` <4c437fcb$0$31260$607ed4bc@cv.net>
2010-07-19 15:42 ` Pascal J. Bourguignon
2010-07-19 17:46 ` Chris F.A. Johnson
[not found] ` <4c4491d4$0$17017$a729d347@news.telepac.pt>
2010-07-19 18:22 ` David Kastrup
[not found] ` <4c4498b3$0$4983$607ed4bc@cv.net>
2010-07-19 19:12 ` David Kastrup
2010-07-17 19:09 ` Fascinating interview by Richard Stallman on Russia TV Emmy Noether
[not found] ` <1f6bd9bb-f7c6-4d0c-9936-d51b881da156@s24g2000pri.googlegroups.com>
2010-07-17 19:56 ` David Kastrup
[not found] ` <87d3ulj30c.fsf@lola.goethe.zz>
[not found] ` <87iq4d6any.fsf@atthis.clsnet.nl>
2010-07-17 23:44 ` Emmy Noether
[not found] ` <1f12874a-8683-40b2-9d7c-af5b801963a5@k39g2000yqd.googlegroups.com>
[not found] ` <87wrstgsgj.fsf@lola.goethe.zz>
2010-07-18 8:23 ` Emmy Noether
[not found] ` <6e469332-eb46-4b81-aee3-10e5aa4e92cb@i31g2000yqm.googlegroups.com>
2010-07-18 14:53 ` David Kastrup [this message]
[not found] ` <87iq4dmcsh.fsf@temporary-address.org.uk>
2010-07-18 9:03 ` Andreas Politz
[not found] ` <4c424c1b$0$1334$a729d347@news.telepac.pt>
2010-07-18 10:46 ` Pascal J. Bourguignon
2010-07-07 20:57 bolega
-- strict thread matches above, loose matches on Subject: below --
2010-07-07 20:56 bolega
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='87oce4hmda.fsf__38138.5607448921$1291847641$gmane$org@lola.goethe.zz' \
--to=dak@gnu.org \
--cc=help-gnu-emacs@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.