]> git.eshelyaron.com Git - emacs.git/commitdiff
Document shorthands in the Elisp manual section on Symbols
authorJoão Távora <joaotavora@gmail.com>
Thu, 23 Sep 2021 16:45:24 +0000 (17:45 +0100)
committerJoão Távora <joaotavora@gmail.com>
Mon, 27 Sep 2021 00:07:11 +0000 (01:07 +0100)
* 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.

doc/lispref/symbols.texi
etc/NEWS

index ed36f5139a8563574b6f111d7aa5ab689d4c088b..775f5e5dbc505a27d482811cd28b571d84922a58 100644 (file)
@@ -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
index bc468c6df4cb8a3dc493c5f16bc16744273e2072..d003d0d092684f006a270ea24ea35e0e9fccb3c8 100644 (file)
--- a/etc/NEWS
+++ b/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