[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Status
I've got the draft ready to go - revised, retypeset, and photocopied.
I send it tomorrow. I thought you all might be interested in the
approach I've been taking to revising the draft, so I wrote down some
things.
*********************************************************************
The following are the principles I've been following in preparing the
draft:
1. Do not alter the technical content decided by X3J13.
2. Describe the language in terms of its linguistic features and not
in terms of implementation. For example, do not say that evaluation of
subforms in generalized reference must be left to right, but list the
operators for generalized reference that are defined and say that they
will do left to right evaluation of subforms. This prevents you from
having to make a big deal of the fact that user-defined SETF macros
might not do something the specification said must be done.
3. Describe additional semantic constraints imposed by the compiler in
terms of linguistic differences and not in terms of what the compiler
is allowed to do. The real constraint is on programs, not
implementations.
4. Do not anthropomorphize the language or its implementation. Avoid
saying that something is the case ``from Common Lisp's point of
view,'' or that signaling a condition is ``an admission by the program
that it cannot continue execution.'' This sort of expression is not
appropriate for a specification. Along these lines, do not introduce
phrasing that imputes processes, activities, or characteristics that
don't exist. For example, don't say:
``TYPE-OF can return an implementation-dependent type as long as
it is a type that SUBTYPEP can recognize.''
What is this process of recognition? Is there some point when the
language is doing this process? Is this a term that needs to be
defined? Say this instead:
``TYPE-OF can return an implementation-dependent type that is suitable
as an argument to SUBTYPEP.''
This, or something like it, says what you really mean.
5. Avoid saying that the implementation will, must, or can do things
if it can prove some statement. It is better to say that if the
statement is true, the linguistic effect will be or might be something
specific. Probably no implementation will have a theorem prover, and
the failure of the implementation to display the linguistic effect is
due to the failure of the implementor to determine effective test code
to test for the condition, not to the failure to prove. Consider the
classic factorial function, F. Would you describe it as: F produces
factorial of its argument if it can prove that the argument is a
non-negative integer.
6. Do not use Common Lisp function names as verbs. Say this:
``The file produced by {\function compile-file} can be loaded into
Lisp.''
Or say this:
``The file produced by {\function compile-file} can be loaded by using
{\function load} into Lisp.''
Don't say this:
``The file produced by {\function compile-file} can be {\function
load}ed into Lisp.''
If a new word is being defined using a Common Lisp function name, define
it as a term. Say this:
``The {\datatype symbol\/} {\tt foo} is interned in the {\tt slang}
{\datatype package}.''
Don't say this:
``The {\datatype symbol\/} {\tt foo} is {\function intern}ed in the
{\tt slang} {\datatype package}.''
Plain English is the language we assume the reader understands. We are
describing Common Lisp using this language plus a little computer
science and mathematics. In a formal semantics we could use part of
Common Lisp to define the rest, but even so we would not invent words
like SETQ as an English verb.
7. Try not to start a sentence with a Common Lisp function name. Try
to qualify each Common Lisp name with its type, as in:
``The function {\function load} can be used to load a file produced by
{\function compile-file}.''
This provides a lot of local information without a lot of words.
8. Don't give advice to users. This might seem like a heartless thing
to say, but the specification is a statement of what the language
does. What users should do depends on the implementation, the software
organization within which the user operates, the culture, and other
factors. Stating advice is a guess that that advice will be true under
all conditions. If you stick to the facts about the effect of
language constructs, you cannot misguess.
9. Don't make claims that might be false. Do not say that compiled
code is faster than interpreted code. Don't say that compiled code
probably will be faster than interpreted code. Don't say some sort of
error will probably be signaled. Don't state that something will
typically be done. State what will happen or be true in all
implementations (those things that will be true because the
specification states they will be). In fact, don't make any claims at
all beyond the semantics of Common Lisp.
10. Don't provide implementation advice. You might be tempted to want
to talk about great new techniques or something not obvious. But
someday this advice will be passe. Providing implementation details
might confuse someone into believing that the semantics follows
what the implementation advice states.
11. Don't say that some operation uses some Common Lisp function
unless that is what is required by the language. For example, don't
say compile-file uses READ to read expressions unless you mean that a
Lisp that is otherwise in conformance with Common Lisp fails to
conform because compile-file does not use READ. Don't assume readers
will know you don't mean literally a phrase or statement. That is,
don't assume that if you say that compile-file uses READ, the reader
will know you mean that in some implementations it might not as long
as the same effect is obtained.
12. Try to build in as few assumptions as possible about current
implementation technology. Whenever you say something about a
requirement, make sure the statement is true at least of classic
implementations, compiler-only ones, and interpreter-only ones. Don't
assume the existence of stack frames, garbage collectors, tags, linear
memory, computer addresses, operating systems, native code, byte code,
traversing interpreters, linkers, or any concept or term currently
related to computers that is not needed by the specification.
Use Lisp objects as the lowest level memory model.
13. Don't overspecify. Don't say too much in the belief that
overspecification is the means to precision. Being precise is not the
same as specifying all behavior. Being precise is saying exactly what
is required and not one word more. Think as carefully about what you
don't say as about what you do say. When you specify something, think
about whether everything you have said is required for conformance. If
not, think of those things that are required and find a way to say
only those things. This is the hardest principle.
14. Don't use an algorithmic specification. If you specify something
by algorithm you are specifying that that very algorithm is required
unless you take pains to say it isn't. Think of what part of the
algorithm is required or what facts about the process or the effects
are required. For example, if you are describing an operation that
sorts, talk about the result satisfying a set of constraints, not some
sorting algorithm. Sometimes you can think of no other way to describe
something than an algorithm. In that case, explain that it is the
effect and not the algorithm that matters.
15. Don't define a new term unless you really need it. Sometimes you'd
be surprised at how short a descriptive phrase you can come up with.
16. Use standard American usage, punctuation, and spelling. Pick a
dictionary or two, a set of usage guides, and stick to them. I use the
Random House Dictionary of the English Language (Second Edition,
Unabridged) and Webster's Second International Dictionary
(Unabridged), and Follett's Modern American Usage and Fowler's Modern
English Usage. I use the first spelling of all variant spellings (this
is supported by the Chicago Manual of Style). I use minimal
punctuation, trying to write sentences that are unambiguous and
understandable when all punctuation is stripped. Put commas and
periods inside closing double quotes except double quotes in Common
Lisp strings.
I know much American usage is not logical.
I use ``between'' instead of ``among'' when I want to emphasize that
the relationships described hold between pairs of objects rather than
among the objects as a group (Gowers Complete Plain Words supports
this).
Don't say this:
``x and/or y''
Say this:
``x, y, or both''
17. Typesetting: "foo" is a Lisp string and ``foo'' is foo in quotes.
Don't use single quotes (`foo'). The following is the proper typesetting
of hyphens etc:
a. implementation-dependent (hyphen)
b. the range 0--9, Chapters 1--5 (en dash)
c. this fails---it is stupid (em dash)
Italics correction (typeset \/) is used only with italics or slanted
fonts, except just before a period or comma:
This is a {\word word\/} in the middle of a sentence.
This is sentence ends with a {\word word}.
This sentence has in the middle a {\word word}, which is cute.
This is sentence seems to end with a {\word word\/}; but it really
doesn't.
The following are neither italics nor slant: \function, \bf, \tt.
18. Don't say ``allow'' when you mean ``provides a mechanism.'' The
operator SETF allows you to supply a generalized reference rather than
only a variable because it provides a mechanism to update any location
specified by a generalized reference. The function APPLY allows you to
supply a symbol in place of a function.
19. Don't use idioms, especially American ones - this is an
international document. Don't use jargon, especially US computer
jargon. People besides US Lisp hackers will read this specification.
As much of it as possible should be understandable to ordinary
intelligent people. This specification is not a netmail message.
20. Don't write an essay on the various factors or ramifications of
some point. For example, don't explain that depending on RANDOM to
launch missiles might not have a harmless side effect even though it
depends on things whose individual effects are harmless. This is
interesting, but it is irrelevant. People are smart enough to know
that words like ``harmless'' are being used in a narrow field of
discourse and can apply it wisely.
Don't explain all the ways a user interface to a restart might be
written, because that's something the implementor will worry about,
not the reader of the specification.
Depend on the intelligence of the readers to determine the boundaries
of your meaning and don't worry overly that they might not. It's fun
to argue the corner cases, but it's not fun to read those arguments.
21. If you find yourself reading dictionaries to dredge up
justification for a word, a phrasing, or an interpretation, rewrite.
If you find that the word you've chosen relies on a secondary or
uncommon definition, it's the wrong word. If when you strip all
puncutation, the sentence is confusing or ambiguous, rewrite it unti
the punctuation doesn't matter. Your descriptions should not need once
ounce of justification. If one person fails to understand it, you
wrote the wrong thing.
22. Read your descriptions with an eye towards literal interpretation.
If there is a humorous intrepretation, rewrite. Here is an example
from an article about C++:
``If I am writing a program in assembly language, I must constantly
worry about the state of the machine.''
Does he mean that when he is so hacking, the machine might be falling
apart? Or that the machine is suffering distress at being programmed
in such a primitive manner? What he means is that there is a set of
bits and conditions that represent the state of the computation that
is maintained by the computer, and correct assembly programs must
maintain, alter, inspect that state. This is an additional concern
the assembly language programmer must face. And does he really mean he
torments himself over it, or does he simply need to pay careful
attention to it?
The point is, if there is unintentional humor in what you say, the
reader will be distracted and lose what you're trying to say. And the
reader will question your carefulness.