Document shorthands in the Elisp manual section on Symbols
* doc/lispref/symbols.texi (Symbol Components): Mentione "Shorthands". (Creating Symbols): Mention shorthands. Correct references to Common Lisp. (Shorthands): New section. * etc/NEWS (Shorthands): New entry.
This commit is contained in:
parent
66f3087530
commit
58055b5fc3
2 changed files with 169 additions and 26 deletions
|
@ -29,6 +29,9 @@ otherwise.
|
|||
* Creating Symbols:: How symbols are kept unique.
|
||||
* Symbol Properties:: Each symbol has a property list
|
||||
for recording miscellaneous information.
|
||||
* Shorthands:: Properly organize your symbol names but
|
||||
type less of them.
|
||||
|
||||
@end menu
|
||||
|
||||
@node Symbol Components
|
||||
|
@ -67,7 +70,9 @@ important not to have two symbols with the same name. The Lisp reader
|
|||
ensures this: every time it reads a symbol, it looks for an existing
|
||||
symbol with the specified name before it creates a new one. To get a
|
||||
symbol's name, use the function @code{symbol-name} (@pxref{Creating
|
||||
Symbols}).
|
||||
Symbols}). Nonwithstanding each symbol having only one unique _print
|
||||
name_, it is nevertheless possible to refer to that same symbol via
|
||||
different terms called ``shorthands'' (@pxref{Shorthands}).
|
||||
|
||||
The value cell holds a symbol's value as a variable, which is what
|
||||
you get if the symbol itself is evaluated as a Lisp expression.
|
||||
|
@ -166,26 +171,41 @@ definitions. @xref{Name Help,,, emacs, The GNU Emacs Manual}.
|
|||
@section Creating and Interning Symbols
|
||||
@cindex reading symbols
|
||||
|
||||
To understand how symbols are created in GNU Emacs Lisp, you must know
|
||||
how Lisp reads them. Lisp must ensure that it finds the same symbol
|
||||
every time it reads the same set of characters. Failure to do so would
|
||||
cause complete confusion.
|
||||
To understand how symbols are created in GNU Emacs Lisp, you must
|
||||
know how Lisp reads them. Lisp must ensure that it finds the same
|
||||
symbol every time it reads the same sequence of characters in the same
|
||||
context. Failure to do so would cause complete confusion.
|
||||
|
||||
When the Lisp reader encounters a reference to symbol in the source
|
||||
code, it reads all the characters of that name. Then it looks up that
|
||||
name in a table called an @dfn{obarray} to find the symbol that the
|
||||
programmer meant.
|
||||
|
||||
@cindex symbol name hashing
|
||||
@cindex hashing
|
||||
@cindex obarray
|
||||
@cindex bucket (in obarray)
|
||||
When the Lisp reader encounters a symbol, it reads all the characters
|
||||
of the name. Then it hashes those characters to find an index in a
|
||||
table called an @dfn{obarray}. Hashing is an efficient method of
|
||||
looking something up. For example, instead of searching a telephone
|
||||
book cover to cover when looking up Jan Jones, you start with the J's
|
||||
and go from there. That is a simple version of hashing. Each element
|
||||
of the obarray is a @dfn{bucket} which holds all the symbols with a
|
||||
given hash code; to look for a given name, it is sufficient to look
|
||||
through all the symbols in the bucket for that name's hash code. (The
|
||||
same idea is used for general Emacs hash tables, but they are a
|
||||
different data type; see @ref{Hash Tables}.)
|
||||
One the techniques used in this lookup is called hashing, an efficient
|
||||
method of looking something up. For example, instead of searching a
|
||||
telephone book cover to cover when looking up Jan Jones, you start
|
||||
with the J's and go from there. That is a simple version of hashing.
|
||||
Each element of the obarray is a @dfn{bucket} which holds all the
|
||||
symbols with a given hash code; to look for a given name, it is
|
||||
sufficient to look through all the symbols in the bucket for that
|
||||
name's hash code. (The same idea is used for general Emacs hash
|
||||
tables, but they are a different data type; see @ref{Hash Tables}.)
|
||||
|
||||
@cindex shorthands
|
||||
@cindex namespacing
|
||||
@cindex namespaces
|
||||
When looking up names, the reader also considers ``shorthands''. If
|
||||
the programmer supplied them, this allows the reader to find a symbol
|
||||
even if its name isn't typed out fully in the source code. Of course,
|
||||
the reader needs to be aware of some pre-established context about
|
||||
such shorthands, much as one needs context to be to able to refer
|
||||
uniquely to Jan Jones by just the name ``Jan'': it's probably fine
|
||||
when amongst the Joneses, or when Jan has been mentioned recently, but
|
||||
very ambiguous in any other situation. @xref{Shorthands}.
|
||||
|
||||
@cindex interning
|
||||
If a symbol with the desired name is found, the reader uses that
|
||||
|
@ -200,9 +220,11 @@ same obarray. Thus, the reader gets the same symbols for the same
|
|||
names, as long as you keep reading with the same obarray.
|
||||
|
||||
Interning usually happens automatically in the reader, but sometimes
|
||||
other programs need to do it. For example, after the @kbd{M-x} command
|
||||
obtains the command name as a string using the minibuffer, it then
|
||||
interns the string, to get the interned symbol with that name.
|
||||
other programs may want to do it. For example, a hypothetical
|
||||
telephone book program could intern the name of each looked up
|
||||
person's name as a symbol, even if the obarray did not contain it, so
|
||||
that it could attach information to that new symbol such as the last
|
||||
time someone looked it up.
|
||||
|
||||
@cindex symbol equality
|
||||
@cindex uninterned symbol
|
||||
|
@ -212,10 +234,6 @@ symbol has the same four cells as other symbols; however, the only way
|
|||
to gain access to it is by finding it in some other object or as the
|
||||
value of a variable.
|
||||
|
||||
Creating an uninterned symbol is useful in generating Lisp code,
|
||||
because an uninterned symbol used as a variable in the code you generate
|
||||
cannot clash with any variables used in other Lisp programs.
|
||||
|
||||
In Emacs Lisp, an obarray is actually a vector. Each element of the
|
||||
vector is a bucket; its value is either an interned symbol whose name
|
||||
hashes to that bucket, or 0 if the bucket is empty. Each interned
|
||||
|
@ -236,7 +254,10 @@ not work---only @code{intern} can enter a symbol in an obarray properly.
|
|||
@cindex CL note---symbol in obarrays
|
||||
@quotation
|
||||
@b{Common Lisp note:} Unlike Common Lisp, Emacs Lisp does not provide
|
||||
for interning a single symbol in several obarrays.
|
||||
for interning the same name in several different ``packages'', thus
|
||||
creating multiple symbols with the same name but different packages.
|
||||
Emacs Lisp provides a different namespacing system called shorthands
|
||||
()
|
||||
@end quotation
|
||||
|
||||
Most of the functions below take a name and sometimes an obarray as
|
||||
|
@ -258,6 +279,11 @@ change the name of the symbol, but fails to update the obarray, so don't
|
|||
do it!
|
||||
@end defun
|
||||
|
||||
@cindex uninterned symbol (generated code)
|
||||
Creating an uninterned symbol is useful in generating Lisp code,
|
||||
because an uninterned symbol used as a variable in the code you
|
||||
generate cannot clash with any variables used in other Lisp programs.
|
||||
|
||||
@defun make-symbol name
|
||||
This function returns a newly-allocated, uninterned symbol whose name is
|
||||
@var{name} (which must be a string). Its value and function definition
|
||||
|
@ -275,10 +301,17 @@ distinct uninterned symbol whose name is also @samp{foo}.
|
|||
|
||||
@defun gensym &optional prefix
|
||||
This function returns a symbol using @code{make-symbol}, whose name is
|
||||
made by appending @code{gensym-counter} to @var{prefix}. The prefix
|
||||
defaults to @code{"g"}.
|
||||
made by appending @code{gensym-counter} to @var{prefix} and increnting
|
||||
that counter, guaranteeing that no two calls to this function
|
||||
generates a symbol with the same name. The prefix defaults to
|
||||
@code{"g"}.
|
||||
@end defun
|
||||
|
||||
@cindex uninterned symbol (recommendation for generated code)
|
||||
To avoid problems when accidentally interning printed representation
|
||||
of generated code, (@pxref{Printed Representation}), it is recommended
|
||||
to use @code{gensym} instead of @code{make-symbol}.
|
||||
|
||||
@defun intern name &optional obarray
|
||||
This function returns the interned symbol whose name is @var{name}. If
|
||||
there is no such symbol in the obarray @var{obarray}, @code{intern}
|
||||
|
@ -600,3 +633,102 @@ If non-@code{nil}, this specifies the named variable's documentation
|
|||
string. This is set automatically by @code{defvar} and related
|
||||
functions. @xref{Defining Faces}.
|
||||
@end table
|
||||
|
||||
@node Shorthands
|
||||
@section Shorthands
|
||||
@cindex shorthands
|
||||
@cindex symbolic shorthands
|
||||
|
||||
@dfn{Shorthands}, sometimes known as "renamed symbols", are symbolic
|
||||
forms found in Lisp source. They're just like regular symbolic forms,
|
||||
except that when the Lisp reader encounters them, it produces symbols
|
||||
which have a different and usually longer @dfn{print name}
|
||||
(@pxref{Symbol Components}).
|
||||
|
||||
It is useful to think of shorthands as @emph{abbreviating} the full
|
||||
names of intended symbols. Despite this, do not confuse with the
|
||||
Abbrev system @pxref{Abbrevs}.
|
||||
|
||||
@cindex namespace etiquette
|
||||
Shorthands make Emacs Lisp's namespacing etiquette easier to work
|
||||
with. Since all symbols are stored in a single obarray
|
||||
(@pxref{Creating Symbols}), programmers commonly prefix each symbol
|
||||
name with the name of the library where it originates. For example,
|
||||
the functions @code{text-property-search-forward} and
|
||||
@code{text-property-search-backward} both belong to the
|
||||
@code{text-property-search.el} library (@pxref{Loading}). By properly
|
||||
prefixing symbol names, one effectively prevents clashes between
|
||||
similarly named symbols which belong to different libraries and do
|
||||
different things. However, this practice commonly originates very
|
||||
long symbols names, which are bothersome to type and read after a
|
||||
while.
|
||||
|
||||
@defvar elisp-shorthands
|
||||
This variable is an alist whose elements have the form
|
||||
@code{(@var{shorthand-prefix} . @var{longhand-prefix})}. Each element
|
||||
instructs the Lisp reader to read every symbol form which starts with
|
||||
@var{shorthand-prefix} as if it started with @var{longhand-prefix}
|
||||
instead.
|
||||
|
||||
This variable may only be set file-locally (@pxref{File Variables, ,
|
||||
Local Variables in Files, emacs, The GNU Emacs Manual}).
|
||||
@end defvar
|
||||
|
||||
Take this excerpt from following example of a hypothetical string
|
||||
manipulating library @file{some-nice-string-utils.el}.
|
||||
|
||||
@example
|
||||
(defun some-nice-string-utils-split (separator s &optional omit-nulls)
|
||||
"A match-data saving variation on `split-string'."
|
||||
(save-match-data (split-string s separator omit-nulls)))
|
||||
|
||||
(defun some-nice-string-utils-lines (s)
|
||||
"Split string S into a list of strings on newline characters."
|
||||
(some-nice-string-utils-split "\\(\r\n\\|[\n\r]\\)" s))
|
||||
@end example
|
||||
|
||||
As can be seen, it's quite tedious to read or develop this code since
|
||||
the symbol names to type are so long. We can use shorthands to good
|
||||
effect here.
|
||||
|
||||
@example
|
||||
(defun snu-split (separator s &optional omit-nulls)
|
||||
"A match-data saving variation on `split-string'."
|
||||
(save-match-data (split-string s separator omit-nulls)))
|
||||
|
||||
(defun snu-lines (s)
|
||||
"Split string S into a list of strings on newline characters."
|
||||
(snu-split "\\(\r\n\\|[\n\r]\\)" s))
|
||||
|
||||
;; Local Variables:
|
||||
;; elisp-shorthands: (("snu-" . "some-nice-string-utils-"))
|
||||
;; End:
|
||||
@end example
|
||||
|
||||
Even though the two excerpts look different, they are quite identical
|
||||
after Lisp reader is done with them. Both will lead to the very same
|
||||
symbols being interned (@pxref{Creating Symbols}). Thus loading or
|
||||
byte-compiling any of the two files has equivalent results. The
|
||||
shorthands @code{snu-split} and @code{snu-lines} used in the second
|
||||
version are @emph{not} interned in the obarray. This is easily seen
|
||||
by moving point to the location where the shorthands are used and
|
||||
waiting for ElDoc (@pxref{Lisp Doc, , Local Variables in Files, emacs,
|
||||
The GNU Emacs Manual}) to hint at the true full name of the symbol
|
||||
under point in the echo area.
|
||||
|
||||
Since @code{elisp-shorthands} is a file-local variable, it is possible
|
||||
that multiple libraries depending on
|
||||
@file{some-nice-string-utils-lines.el} refer to the same symbols under
|
||||
@emph{different} shorthands, or not using shorthands at all. In the
|
||||
next example, the @file{my-tricks.el} library refers to symbol
|
||||
aforementioned symbol @code{some-nice-string-utils-lines} using the
|
||||
@code{sns-} prefix.
|
||||
|
||||
@example
|
||||
(defun t-reverse-lines (s) (string-join (reverse (sns-lines s)) "\n")
|
||||
|
||||
;; Local Variables:
|
||||
;; elisp-shorthands: (("t-" . "my-tricks-")
|
||||
;; ("sns-" . "some-nice-string-utils-"))
|
||||
;; End:
|
||||
@end example
|
||||
|
|
11
etc/NEWS
11
etc/NEWS
|
@ -3906,6 +3906,17 @@ asynchronously send data back to Emacs.
|
|||
It can be used to create Lisp strings with arbitrary byte sequences
|
||||
(a.k.a. "raw bytes").
|
||||
|
||||
+++
|
||||
** Shorthands
|
||||
Shorthands are a general purpose namespacing system to make Emacs
|
||||
Lisp's symbol-naming etiquette easier to manage. Also known as a
|
||||
"renamed symbol", a shorthand is any symbolic form found in Lisp
|
||||
source that abbreviates a symbol with a different and longer print
|
||||
name. Among other applications, it facilitates the importation of
|
||||
popular libraries such as 's.el' without the polution associated of
|
||||
very short prefixes. For details, see the manual section "(elisp)
|
||||
Shorthands".
|
||||
|
||||
+++
|
||||
** New function 'string-search'.
|
||||
This function takes two string parameters and returns the position of
|
||||
|
|
Loading…
Add table
Reference in a new issue