Subject: bug#73626: 30.0.91; Type specifiers of functions

From: Andrea Corallo <[email-masked]>
Date: Tue, 19 Nov 2024 04:55:25 -0500

Eli Zaretskii <[email-masked]> writes:

>> From: Andrea Corallo <[email-masked]>
>> Cc: [email-masked]
>> Date: Wed, 13 Nov 2024 19:27:52 -0500
>>
>> Okay this is what I'm working on.  I felt the need to add a more general
>> '(elisp)Type Specifiers' node as this was never documented and I think
>> deserves its own space.
>>
>> I referenced it from '(emacs)Name Help' where I mentioned we report
>> function type specifiers.  Also I could reference it from '(elisp)
>> Declare Form' so that the concept of type specifier (there already
>> mentioned) is explained.
>>
>> There are some mentions of type specifiers in cl.texi which I guess I'll
>> add some xref as well.
>>
>> WDYT?
>
> Thanks, some minor comments below.
>
>> diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi
>> index f15b4c5e89d..0f85ff0c832 100644
>> --- a/doc/emacs/help.texi
>> +++ b/doc/emacs/help.texi
>> @@ -322,6 +322,13 @@ Name Help
>>  yet further information is often reachable by clicking or typing
>>  @key{RET} on emphasized parts of the text.
>>
>> +The function type, if known, is expressed with a function type specifier
>> +(@pxref{Type Specifiers,,,elisp, The Emacs Lisp Reference Manual}), it
>
> It would be good to have "function type specifier" in @dfn here, and
> also have a @cindex entry for that.
>
>> -@var{type} is a type specifier in the form @w{@code{(function
>> +@var{type} is a @ref{Type Specifier} in the form @w{@code{(function
>
> "Type Specifiers", in plural.  More importantly, using @ref in such a
> way is not a good idea in Texinfo, it looks good only in the HTML
> format.  For other formats, it is better to use the wordier
>
>   @var{type} is a @dfn{type specifier} (@pxref{Type Specifiers}) in
>   the form...
>
>> +@node Type Specifiers
>> +@subsection Type Specifiers
>
> Please add an index entry here
>
>   @cindex type specifier

>> +A type specifier is an expression that denotes a type. A type represents
>                                                         ^^
> Two spaces between sentences.
>
>> +a set of possible values.  Type specifiers can be classified in
>> +primitives and composites.
>
> Since type specifiers are mostly (only?) used for functions, perhaps
> the section should explicitly talk about "function type specifiers",
> or at least mention "function" in several places in the text?

They are also usable under `cl-the', 'cl-defstruct' and probably few
other cl facilities.  (BTW I'd like to have 'cl-the' or a new 'the'
wired to the compile machinery for the future).

>> +@subsubsection Primitive type specifiers.
>> +Primitive types specifiers are the basic types (i.e. not composed by other
>
> "i.e." needs a @: after it, since the period doesn't end a sentence.
>
>> +Built-in primitive types (like @code{integer}, @code{float},
>> +@code{string} etc) are listed in @xref{Type Hierarchy}.
>
> @ref, not @xref.  The latter is only pertinent at the beginning of a
> sentence, since it produces a capitalized "See".
>
>> +@subsubsection Composite type specifiers.
>> +Composite type specifiers allow the definition of complex types by
>> +combining simpler types.
>
> Instead of having @subsections here, I'd use a @table (with the
> composite type specifiers being a nested @table inside that).
>
> A
> @table is easier to read and grasp, and also can save you typing,
> since you can say
>
>   @table @code
>
> and avoid the need to use @code for each symbol.
>
>> +@item @code{and}
>> +
>> +Similarly the @code{and} type specifier describes a type that satisfies
>> +at all the given types.
>    ^^
> That "at" should be removed.
>
>> +The @code{function} type specifier in the form @w{@code{(function
>> +(ARG-1-TYPE ... ARG-N-TYPE) RETURN-TYPE)}} used to describe the argument
>
> The symbols you have in UPPER-CASE should be actually in @var and in
> lower-case, as we always do with meta-syntactic arguments (i.e., with
> symbols that stand for something other than themselves literally).
>
>> +types and return type of a function. Argument types can be interleaved
>                                       ^^
> Two spaces.
>
>> +The @code{integer} type specifier is used to define a subset of integers
>> +by specifying a range. This allows to precisely control which integers
>                         ^^
> Likewise.
>
>> +are valid for a given type.
>> +
>> +The general form is:
>> +@example
>> +(integer lower-bound upper-bound)
>> +@end example
>> +Where @code{lower-bound} is the minimum integer value in the range and
>> +@code{upper-bound} the maximum.  It is possible to use @code{*} to
>> +indicate no lower or uper limit.
>> +
>> +The following represents all integers from -10 to 10.
>> +@example
>> +(integer -10 10)
>> +@end example
>> +
>> +The following represents 10.
>> +@example
>> +(integer 10 10)
>> +@end example
>> +
>> +The following represents all integers from negative infinity to 10.
>> +@example
>> +(integer * 10)
>> +@end example
>
> I wonder whether the description of the 'integer' type should be in
> the "primitive types" part, since 'integer' is a primitive type, and
> mentioned there?

'integer' is a primitive type when used alone, but is a compound one if
used as (integer min max).  I think I've clarified that.

> A general note: I miss some higher-level background information here,
> which would explain how these types are generated and how and for what
> purposes they are used.  Such background doesn't have to be too
> detailed or too technical, but it is important to provide the
> rationale for this feature.

Okay I tried to add some brief context.

Attached the latest version where I tried to implement the suggestions.

Thanks!

  Andrea

diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi
index f15b4c5e89d..079ea76156f 100644
--- a/doc/emacs/help.texi
+++ b/doc/emacs/help.texi
@@ -322,6 +322,15 @@ Name Help
 yet further information is often reachable by clicking or typing
 @key{RET} on emphasized parts of the text.
 
+@cindex function type specifier
+
+The function type, if known, is expressed with a @dfn{function type
+specifier} (@pxref{Type Specifiers,,,elisp, The Emacs Lisp Reference
+Manual}), it will be specified if the type was manually declared by the
+programmer or inferred by the compiler.  Note that function type
+inference works only when native compilation is enabled (@pxref{native
+compilation,,, elisp, The Emacs Lisp Reference Manual}).
+
 @vindex help-enable-symbol-autoload
   If you request help for an autoloaded function whose @code{autoload}
 form (@pxref{Autoload,,, elisp, The Emacs Lisp Reference Manual})
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index bf80a21ee9f..bb548441cbc 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -2733,10 +2733,10 @@ Declare Form
 generation and for deriving more precisely the type of other functions
 without type declaration.
 
-@var{type} is a type specifier in the form @w{@code{(function
-(ARG-1-TYPE ... ARG-N-TYPE) RETURN-TYPE)}}.  Argument types can be
-interleaved with symbols @code{&optional} and @code{&rest} to match the
-function's arguments (@pxref{Argument List}).
+@var{type} is a @dfn{type specifier} (@pxref{Type Specifiers}) in the
+form @w{@code{(function (ARG-1-TYPE ... ARG-N-TYPE) RETURN-TYPE)}}.
+Argument types can be interleaved with symbols @code{&optional} and
+@code{&rest} to match the function's arguments (@pxref{Argument List}).
 
 @var{function} if present should be the name of function being defined.
 
diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi
index 34ea7cf4996..d847f438e0f 100644
--- a/doc/lispref/objects.texi
+++ b/doc/lispref/objects.texi
@@ -247,6 +247,7 @@ Programming Types
 * Closure Type::        A function written in Lisp.
 * Record Type::         Compound objects with programmer-defined types.
 * Type Descriptors::    Objects holding information about types.
+* Type Specifiers::     Expressions which describe types.
 * Autoload Type::       A type used for automatically loading seldom-used
                         functions.
 * Finalizer Type::      Runs code when no longer reachable.
@@ -1499,6 +1500,92 @@ Type Descriptors
 An example of a type descriptor is any instance of
 @code{cl-structure-class}.
 
+@node Type Specifiers
+@subsection Type Specifiers
+@cindex type specifier
+
+A type specifier is an expression that denotes a type.  A type
+represents a set of possible values.  Type specifiers can be classified
+in primitives and compounds.
+
+Type specifiers are in use for several purposes including: documenting
+function interfaces through declaration (@pxref{Declare Form}),
+specifying structure slot values (@pxref{Structures,,, cl, Common Lisp
+Extensions for GNU Emacs Lisp}), type-checking through @code{cl-the}
+(@pxref{Declarations,,, cl, Common Lisp Extensions for GNU Emacs Lisp})
+and others.
+
+@table @asis
+@item Primitive type specifiers
+Primitive types specifiers are the basic types (i.e.@: not composed by other
+type specifiers).
+
+Built-in primitive types (like @code{integer}, @code{float},
+@code{string} etc) are listed in @ref{Type Hierarchy}.
+
+@item Compound type specifiers
+Compound types serve the purpose of defining more complex or precise
+type specifications by combining or modifying simpler types.
+
+List of compound type specifiers:
+
+@table @code
+@item (or @var{type-1} .. @var{type-n})
+The @code{or} type specifier describes a type that satisfies at least
+one of the given types.
+
+@item (and @var{type-1} .. @var{type-n})
+Similarly the @code{and} type specifier describes a type that satisfies
+all the given types.
+
+@item (not @var{type})
+The @code{not} type specifier defines any type except the specified one.
+
+@item (member @var{value-1} .. @var{value-n})
+The @code{member} type specifier allows to specify a type that includes
+only the explicitly listed values.
+
+@item (function (@var{arg-1-type} ... @var{arg-n-type}) @var{return-type})
+The @code{function} type specifier is used to describe the argument
+types and return type of a function.  Argument types can be interleaved
+with symbols @code{&optional} and @code{&rest} to match the function's
+arguments (@pxref{Argument List}).
+
+The following is to represent a function with: a first parameter of type
+@code{symbol}, a second optional parameter of type @code{float} and
+returning an @code{integer}:
+@example
+(function (symbol &optional float) integer)
+@end example
+
+@item (integer @var{lower-bound} @var{upper-bound})
+
+@code{integer} can be used as well as a compound type specifier to
+define a subset of integers by specifying a range.  This allows to
+precisely control which integers are valid for a given type.
+
+@var{lower-bound} is the minimum integer value in the range and
+@var{upper-bound} the maximum.  It is possible to use @code{*} to
+indicate no lower or uper limit.
+
+The following represents all integers from -10 to 10.
+@example
+(integer -10 10)
+@end example
+
+The following represents 10.
+@example
+(integer 10 10)
+@end example
+
+The following represents all integers from negative infinity to 10.
+@example
+(integer * 10)
+@end example
+
+@end table
+@end table
+
 @node Autoload Type
 @subsection Autoload Type