Mercurial > hg > xemacs-beta
changeset 5252:378a34562cbe
Fix style, documentation for rounding functions and multiple values.
src/ChangeLog addition:
2010-08-30 Aidan Kehoe <kehoea@parhasard.net>
* floatfns.c (ceiling_one_mundane_arg, floor_one_mundane_arg)
(round_one_mundane_arg, truncate_one_mundane_arg):
INTEGERP is always available, no need to wrap calls to it with
#ifdef HAVE_BIGNUM.
(Fceiling, Ffloor, Fround, Ftruncate, Ffceiling, Fffloor)
(Ffround, Fftruncate):
Correct some code formatting here.
* doprnt.c (emacs_doprnt_1):
Remove some needless #ifdef WITH_NUMBER_TYPES, now number.h is
always #included.
man/ChangeLog addition:
2010-08-30 Aidan Kehoe <kehoea@parhasard.net>
* lispref/eval.texi (Evaluation, Multiple values):
Document our implementation of multiple values; point the reader
to the CLTL or the Hyperspec for details of exactly when values
are discarded.
* lispref/numbers.texi (Numeric Conversions): Document the
optional DIVISOR arguments to the rounding functions, and
document that they all return multiple values.
(Rounding Operations): Ditto.
* cl.texi (Multiple Values):
Document that we've moved the multiple values implementation to
core code, and cross-reference to the Lispref.
(Numerical Functions): The various rounding functions are now
identical to the built-in rounding functions, with the exception
that they return lists, not multiple values; document this.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Mon, 30 Aug 2010 15:23:42 +0100 |
parents | b0ba3598beb1 |
children | b6a398dbb403 |
files | man/ChangeLog man/cl.texi man/lispref/eval.texi man/lispref/numbers.texi src/ChangeLog src/doprnt.c src/floatfns.c |
diffstat | 7 files changed, 195 insertions(+), 141 deletions(-) [+] |
line wrap: on
line diff
--- a/man/ChangeLog Mon Aug 30 15:21:04 2010 +0100 +++ b/man/ChangeLog Mon Aug 30 15:23:42 2010 +0100 @@ -1,3 +1,22 @@ +2010-08-30 Aidan Kehoe <kehoea@parhasard.net> + + * lispref/eval.texi (Evaluation, Multiple values): + Document our implementation of multiple values; point the reader + to the CLTL or the Hyperspec for details of exactly when values + are discarded. + + * lispref/numbers.texi (Numeric Conversions): Document the + optional DIVISOR arguments to the rounding functions, and + document that they all return multiple values. + (Rounding Operations): Ditto. + + * cl.texi (Multiple Values): + Document that we've moved the multiple values implementation to + core code, and cross-reference to the Lispref. + (Numerical Functions): The various rounding functions are now + identical to the built-in rounding functions, with the exception + that they return lists, not multiple values; document this. + 2010-08-21 Aidan Kehoe <kehoea@parhasard.net> * lispref/objects.texi (Character Type):
--- a/man/cl.texi Mon Aug 30 15:21:04 2010 +0100 +++ b/man/cl.texi Mon Aug 30 15:23:42 2010 +0100 @@ -2987,44 +2987,8 @@ @node Multiple Values, , Loop Facility, Control Structure @section Multiple Values -@noindent -Common Lisp functions can return zero or more results. Emacs Lisp -functions, by contrast, always return exactly one result. This -package makes no attempt to emulate Common Lisp multiple return -values; Emacs versions of Common Lisp functions that return more -than one value either return just the first value (as in -@code{compiler-macroexpand}) or return a list of values (as in -@code{get-setf-method}). This package @emph{does} define placeholders -for the Common Lisp functions that work with multiple values, but -in Emacs Lisp these functions simply operate on lists instead. -The @code{values} form, for example, is a synonym for @code{list} -in Emacs. - -@defspec multiple-value-bind (var@dots{}) values-form forms@dots{} -This form evaluates @var{values-form}, which must return a list of -values. It then binds the @var{var}s to these respective values, -as if by @code{let}, and then executes the body @var{forms}. -If there are more @var{var}s than values, the extra @var{var}s -are bound to @code{nil}. If there are fewer @var{var}s than -values, the excess values are ignored. -@end defspec - -@defspec multiple-value-setq (var@dots{}) form -This form evaluates @var{form}, which must return a list of values. -It then sets the @var{var}s to these respective values, as if by -@code{setq}. Extra @var{var}s or values are treated the same as -in @code{multiple-value-bind}. -@end defspec - -The older Quiroz package attempted a more faithful (but still -imperfect) emulation of Common Lisp multiple values. The old -method ``usually'' simulated true multiple values quite well, -but under certain circumstances would leave spurious return -values in memory where a later, unrelated @code{multiple-value-bind} -form would see them. - -Since a perfect emulation is not feasible in Emacs Lisp, this -package opts to keep it as simple and predictable as possible. +This functionality has been moved to core XEmacs, and is documented in +the XEmacs Lisp reference, @pxref{(lispref.info)Multiple values}. @node Macros, Declarations, Control Structure, Top @chapter Macros @@ -3506,58 +3470,6 @@ square root of the argument. @end defun -@defun floor* number &optional divisor -This function implements the Common Lisp @code{floor} function. -It is called @code{floor*} to avoid name conflicts with the -simpler @code{floor} function built-in to Emacs 19. - -With one argument, @code{floor*} returns a list of two numbers: -The argument rounded down (toward minus infinity) to an integer, -and the ``remainder'' which would have to be added back to the -first return value to yield the argument again. If the argument -is an integer @var{x}, the result is always the list @code{(@var{x} 0)}. -If the argument is an Emacs 19 floating-point number, the first -result is a Lisp integer and the second is a Lisp float between -0 (inclusive) and 1 (exclusive). - -With two arguments, @code{floor*} divides @var{number} by -@var{divisor}, and returns the floor of the quotient and the -corresponding remainder as a list of two numbers. If -@code{(floor* @var{x} @var{y})} returns @code{(@var{q} @var{r})}, -then @code{@var{q}*@var{y} + @var{r} = @var{x}}, with @var{r} -between 0 (inclusive) and @var{r} (exclusive). Also, note -that @code{(floor* @var{x})} is exactly equivalent to -@code{(floor* @var{x} 1)}. - -This function is entirely compatible with Common Lisp's @code{floor} -function, except that it returns the two results in a list since -Emacs Lisp does not support multiple-valued functions. -@end defun - -@defun ceiling* number &optional divisor -This function implements the Common Lisp @code{ceiling} function, -which is analogous to @code{floor} except that it rounds the -argument or quotient of the arguments up toward plus infinity. -The remainder will be between 0 and minus @var{r}. -@end defun - -@defun truncate* number &optional divisor -This function implements the Common Lisp @code{truncate} function, -which is analogous to @code{floor} except that it rounds the -argument or quotient of the arguments toward zero. Thus it is -equivalent to @code{floor*} if the argument or quotient is -positive, or to @code{ceiling*} otherwise. The remainder has -the same sign as @var{number}. -@end defun - -@defun round* number &optional divisor -This function implements the Common Lisp @code{round} function, -which is analogous to @code{floor} except that it rounds the -argument or quotient of the arguments to the nearest integer. -In the case of a tie (the argument or quotient is exactly -halfway between two integers), it rounds to the even integer. -@end defun - @defun mod* number divisor This function returns the same value as the second return value of @code{floor}. @@ -3568,7 +3480,24 @@ of @code{truncate}. @end defun -These definitions are compatible with those in the Quiroz +@noindent +The following functions are identical to their built-in counterparts, +without the trailing @code{*} in their names, but they return lists +instead of multiple values. @pxref{(lispref.info)Rounding Operations} + +@defun floor* number &optional divisor +@end defun + +@defun ceiling* number &optional divisor +@end defun + +@defun truncate* number &optional divisor +@end defun + +@defun round* number &optional divisor +@end defun + +All the above definitions are compatible with those in the Quiroz @file{cl.el} package, except that this package appends @samp{*} to certain function names to avoid conflicts with existing Emacs 19 functions, and that the mechanism for returning
--- a/man/lispref/eval.texi Mon Aug 30 15:21:04 2010 +0100 +++ b/man/lispref/eval.texi Mon Aug 30 15:23:42 2010 +0100 @@ -24,6 +24,7 @@ * Eval:: How to invoke the Lisp interpreter explicitly. * Forms:: How various sorts of objects are evaluated. * Quoting:: Avoiding evaluation (to put constants in the program). +* Multiple values:: Functions may return more than one result. @end menu @node Intro Eval @@ -708,3 +709,102 @@ Functions}), which causes an anonymous lambda expression written in Lisp to be compiled, and @samp{`} (@pxref{Backquote}), which is used to quote only part of a list, while computing and substituting other parts. + +@node Multiple values +@section Multiple values +@cindex multiple values + +@noindent +Under XEmacs, expressions can return zero or more results, using the +@code{values} and @code{values-list} functions. Results other than the +first are typically discarded, but special operators are provided to +access them. + +@defun values arguments@dots{} +This function returns @var{arguments} as multiple values. Callers will +always receive the first element of @var{arguments}, but must use +various special operators, described below, to access other elements of +@var{arguments}. + +The idiom @code{(values (function-call argument))}, with one +argument, is the normal mechanism to avoid passing multiple values to +the calling form where that is not desired. + +XEmacs implements the Common Lisp specification when it comes to the +exact details of when to discard and when to preserve multiple values; +see Common Lisp the Language or the Common Lisp hyperspec for more +details. The most important thing to keep in mind is when multiple +values are passed as an argument to a function, all but the first are +discarded. +@end defun + +@defun values-list argument +This function returns the elements of the lst @var{argument} as multiple +values. +@end defun + +@defspec multiple-value-bind (var@dots{}) values-form forms@dots{} +This special operator evaluates @var{values-form}, which may return +multiple values. It then binds the @var{var}s to these respective values, +as if by @code{let}, and then executes the body @var{forms}. +If there are more @var{var}s than values, the extra @var{var}s +are bound to @code{nil}. If there are fewer @var{var}s than +values, the excess values are ignored. +@end defspec + +@defspec multiple-value-setq (var@dots{}) form +This special operator evaluates @var{form}, which may return multiple +values. It then sets the @var{var}s to these respective values, as if by +@code{setq}. Extra @var{var}s or values are treated the same as +in @code{multiple-value-bind}. +@end defspec + +@defspec multiple-value-call function forms@dots{} +This special operator evaluates function, discarding any multiple +values. It then evaluates @var{forms}, preserving any multiple values, +and calls @var{function} as a function with the results. Conceptually, this +function is a version of @code{apply'}that by-passes the multiple values +infrastructure, treating multiple values as intercalated lists. +@end defspec + +@defspec multiple-value-list form +This special operator evaluates @var{form} and returns a list of the +multiple values given by it. +@end defspec + +@defspec multiple-value-prog1 first body@dots{} +This special operator evaluates the form @var{first}, then the +forms @var{body}. It returns the value given by @var{first}, preserving +any multiple values. This is identical to @code{prog1}, except that +@code{prog1} always discards multiple values. +@end defspec + +@defspec nth-value n form +This special operator evaluates @var{form} and returns the @var{n}th +value it gave. @var{n} must be an integer of value zero or more. +If @var{form} gave insufficient multiple values, @code{nth-value} +returns @code{nil}. +@end defspec + +@defvar multiple-values-limit +This constant describes the exclusive upper bound on the number of +multiple values that @code{values} accepts and that +@code{multiple-value-bind}, etc. will consume. +@end defvar + +To take full advantage of multiple values, Emacs Lisp code must have +been compiled by XEmacs 21.5 or later, which is not yet true of the +XEmacs packages. Matched @code{values} and @code{multiple-value-bind} +calls will work in code included in the XEmacs packages when run on +21.5, though the following incantation may be necessary at the start of +your file, until appropriate code is included in XEmacs 21.4: + +@example +(eval-when-compile (when (eq 'list (symbol-function 'values)) + (define-compiler-macro values (&rest args) + (cons 'list args)) + (define-compiler-macro values-list (list) list))) +@end example + +Such code cannot, unfortunately, rely on XEmacs to discard multiple +values where that is appropriate.
--- a/man/lispref/numbers.texi Mon Aug 30 15:21:04 2010 +0100 +++ b/man/lispref/numbers.texi Mon Aug 30 15:23:42 2010 +0100 @@ -871,9 +871,15 @@ There are four functions to convert floating point numbers to integers; they differ in how they round. These functions accept integer arguments -also, and return such arguments unchanged. +also, and return such arguments unchanged. They return multiple values, +@pxref{(cl.info)Multiple values}. -@defun truncate number +All these functions take optional @var{divisor} arguments, and if this +argument is specified, the @var{number} argument is divided by +@var{divisor} before the calculation is made. An @code{arith-error} +results if @var{divisor} is 0. + +@defun truncate number &optional divisor This returns @var{number}, converted to an integer by rounding towards zero. @end defun @@ -881,23 +887,21 @@ @defun floor number &optional divisor This returns @var{number}, converted to an integer by rounding downward (towards negative infinity). - -If @var{divisor} is specified, @var{number} is divided by @var{divisor} -before the floor is taken; this is the division operation that -corresponds to @code{mod}. An @code{arith-error} results if -@var{divisor} is 0. @end defun -@defun ceiling number +@defun ceiling number &optional divisor This returns @var{number}, converted to an integer by rounding upward (towards positive infinity). @end defun -@defun round number +@defun round number &optional divisor This returns @var{number}, converted to an integer by rounding towards the -nearest integer. Rounding a value equidistant between two integers -may choose the integer closer to zero, or it may prefer an even integer, -depending on your machine. +nearest integer. + +Rounding a value equidistant between two integers chooses the even +integer. GNU Emacs and older XEmacs did not guarantee this, and the +direction of rounding depended on the underlying machine and the C +implementation. @end defun @node Arithmetic Operations @@ -1154,24 +1158,35 @@ @code{ftruncate}, the nearest integer in the direction towards zero; @code{fround}, the nearest integer. -@defun ffloor number +All these functions take optional @var{divisor} arguments, and if this +argument is specified, the @var{number} argument is divided by +@var{divisor} before the calculation is made. An @code{arith-error} +results if @var{divisor} is 0. Also, they return multiple values, +@pxref{(cl.info)Multiple values}; the second value is the remainder. + +@defun ffloor number &optional divisor This function rounds @var{number} to the next lower integral value, and returns that value as a floating point number. @end defun -@defun fceiling number +@defun fceiling number &optional divisor This function rounds @var{number} to the next higher integral value, and returns that value as a floating point number. @end defun -@defun ftruncate number +@defun ftruncate number &optional divisor This function rounds @var{number} towards zero to an integral value, and returns that value as a floating point number. @end defun -@defun fround number +@defun fround number &optional divisor This function rounds @var{number} to the nearest integral value, and returns that value as a floating point number. + +Rounding a value equidistant between two integral values chooses the +even value. While this is specified by Common Lisp, GNU Emacs and older +XEmacs did not make this guarantee, and the direction of rounding +depended on the underlying machine and the C implementation. @end defun @node Bitwise Operations
--- a/src/ChangeLog Mon Aug 30 15:21:04 2010 +0100 +++ b/src/ChangeLog Mon Aug 30 15:23:42 2010 +0100 @@ -1,3 +1,16 @@ +2010-08-30 Aidan Kehoe <kehoea@parhasard.net> + + * floatfns.c (ceiling_one_mundane_arg, floor_one_mundane_arg) + (round_one_mundane_arg, truncate_one_mundane_arg): + INTEGERP is always available, no need to wrap calls to it with + #ifdef HAVE_BIGNUM. + (Fceiling, Ffloor, Fround, Ftruncate, Ffceiling, Fffloor) + (Ffround, Fftruncate): + Correct some code formatting here. + * doprnt.c (emacs_doprnt_1): + Remove some needless #ifdef WITH_NUMBER_TYPES, now number.h is + always #included. + 2010-08-26 Adam Sjøgren <asjo@koldfront.dk> * glyphs-eimage.c (gif_instantiate): Try harder to find an
--- a/src/doprnt.c Mon Aug 30 15:21:04 2010 +0100 +++ b/src/doprnt.c Mon Aug 30 15:23:42 2010 +0100 @@ -591,11 +591,7 @@ Lisp_Object obj = largs[spec->argnum - 1]; if (CHARP (obj)) obj = make_int (XCHAR (obj)); -#ifdef WITH_NUMBER_TYPES if (!NUMBERP (obj)) -#else - if (!INT_OR_FLOATP (obj)) -#endif { /* WARNING! This MUST be big enough for the sprintf below */ CIbyte msg[48]; @@ -606,9 +602,10 @@ } else if (strchr (double_converters, ch)) { -#ifdef WITH_NUMBER_TYPES - if (INTP (obj) || FLOATP (obj)) - arg.d = XFLOATINT (obj); + if (INTP (obj)) + arg.d = XINT (obj); + else if (FLOATP (obj)) + arg.d = XFLOAT_DATA (obj); #ifdef HAVE_BIGNUM else if (BIGNUMP (obj)) arg.d = bignum_to_double (XBIGNUM_DATA (obj)); @@ -631,9 +628,6 @@ } } #endif -#else /* !WITH_NUMBER_TYPES */ - arg.d = XFLOATINT (obj); -#endif /* WITH_NUMBER_TYPES */ } else {
--- a/src/floatfns.c Mon Aug 30 15:21:04 2010 +0100 +++ b/src/floatfns.c Mon Aug 30 15:23:42 2010 +0100 @@ -1300,11 +1300,7 @@ } else { -#ifdef HAVE_BIGNUM if (INTEGERP (number)) -#else - if (INTP (number)) -#endif { return values2 (number, Qzero); } @@ -1566,11 +1562,7 @@ floor_one_mundane_arg (Lisp_Object number, Lisp_Object divisor, int return_float) { -#ifdef HAVE_BIGNUM if (INTEGERP (number)) -#else - if (INTP (number)) -#endif { if (return_float) { @@ -1971,11 +1963,7 @@ round_one_mundane_arg (Lisp_Object number, Lisp_Object divisor, int return_float) { -#ifdef HAVE_BIGNUM if (INTEGERP (number)) -#else - if (INTP (number)) -#endif { if (return_float) { @@ -2258,11 +2246,7 @@ truncate_one_mundane_arg (Lisp_Object number, Lisp_Object divisor, int return_float) { -#ifdef HAVE_BIGNUM if (INTEGERP (number)) -#else - if (INTP (number)) -#endif { if (return_float) { @@ -2301,7 +2285,7 @@ */ (number, divisor)) { - ROUNDING_CONVERT(ceiling, 0); + ROUNDING_CONVERT (ceiling, 0); } DEFUN ("floor", Ffloor, 1, 2, 0, /* @@ -2316,7 +2300,7 @@ */ (number, divisor)) { - ROUNDING_CONVERT(floor, 0); + ROUNDING_CONVERT (floor, 0); } DEFUN ("round", Fround, 1, 2, 0, /* @@ -2333,7 +2317,7 @@ */ (number, divisor)) { - ROUNDING_CONVERT(round, 0); + ROUNDING_CONVERT (round, 0); } DEFUN ("truncate", Ftruncate, 1, 2, 0, /* @@ -2347,7 +2331,7 @@ */ (number, divisor)) { - ROUNDING_CONVERT(truncate, 0); + ROUNDING_CONVERT (truncate, 0); } /* Float-rounding functions. */ @@ -2364,7 +2348,7 @@ */ (number, divisor)) { - ROUNDING_CONVERT(ceiling, 1); + ROUNDING_CONVERT (ceiling, 1); } DEFUN ("ffloor", Fffloor, 1, 2, 0, /* @@ -2379,7 +2363,7 @@ */ (number, divisor)) { - ROUNDING_CONVERT(floor, 1); + ROUNDING_CONVERT (floor, 1); } DEFUN ("fround", Ffround, 1, 2, 0, /* @@ -2395,7 +2379,7 @@ */ (number, divisor)) { - ROUNDING_CONVERT(round, 1); + ROUNDING_CONVERT (round, 1); } DEFUN ("ftruncate", Fftruncate, 1, 2, 0, /* @@ -2410,7 +2394,7 @@ */ (number, divisor)) { - ROUNDING_CONVERT(truncate, 1); + ROUNDING_CONVERT (truncate, 1); } #ifdef FLOAT_CATCH_SIGILL