more deprecation

* Add "Deprecated Interfaces" chapter to the manual.

 * Add list of deprecated interfaces along with a policy note to a
   comment near DEFINE-DEPRECATED-FUNCTION.

 * Add a proper deprecation warning for SB-C::MERGE-TAIL-CALLS.

 * Fix the deprecation warning for WITH-SPINLOCK. (Accidentally
   referred to WITH-RECURSIVE-SPINLOCK before.)
This commit is contained in:
Nikodemus Siivola 2012-05-02 14:48:35 +03:00 committed by Nikodemus Siivola
parent 760de025ce
commit 11802a47e0
6 changed files with 437 additions and 10 deletions

View file

@ -0,0 +1,385 @@
@node Deprecated Interfaces
@comment node-name, next, previous, up
@chapter Deprecated Interfaces
This chapter documents the deprecation process used for SBCL
interfaces, and lists legacy interfaces in various stages of
deprecation.
This should not be confused with those things the ANSI Common Lisp
standard calls ``deprecated'': the entirety of ANCL CL is supported by
SBCL, and none of those interfaces are subject to censure.
@section Why Deprecate?
While generally speaking we try to keep SBCL changes as backwards
compatible as feasible, there are situations when existing interfaces
are deprecated:
@itemize
@item @strong{Broken Interfaces}
Sometimes it turns out that an interface is sufficiently misdesigned
that fixing it would be worse than deprecating it and replacing it
with another.
This is typically the case when fixing the interface would change its
semantics in ways that could break user code subtly: in such cases we
may end up considering the obvious breakage caused by deprecation to
be preferable.
Another example are functions or macros whose current signature makes
them hard or impossible to extend in the future: backwards compatible
extensions would either make the interface intolerably hairy, or are
sometimes outright impossible.
@item @strong{Internal Interfaces}
SBCL has several internal interfaces that were never meant to be used
in user code -- or at least never meant to be used in user code
unwilling to track changes to SBCL internals.
Ideally we'd like to be free to refactor our own internals as we
please, without even going through the hassle of deprecating things.
Sometimes, however, it turns out that our internal interfaces have
several external users who aren't using them advicedly, but due to
misunderstandings regarding their status or stability.
Consider a deprecated internal interface a reminder for SBCL
maintainers not to delete the thing just yet, even though it is seems
unused -- because it has external users.
When internal interfaces are deprecated we try our best to provide
supported alternatives.
@item @strong{Aesthetics & Ease of Maintenance}
Sometimes an interface isn't broken or internal, but just inconsistent
somehow.
This mostly happens only with historical interfaces inherited from
CMUCL which often haven't been officially supported in SBCL before, or
with new extensions to SBCL that haven't been around for very long in
the first place.
The alternative would be to keep the suboptimal version around
forever, possibly alongside an improved version. Sometimes we may do
just that, but because every line of code comes with a maintenance
cost, sometimes we opt to deprecate the suboptimal version instead:
SBCL doesn't have infinite developer resources.
We also believe that sometimes cleaning out legacy interfaces helps
keep the whole system more comprehensible to users, and makes
introspective tools such as @code{apropos} more useful.
@end itemize
@section What Happens During Deprecation?
Deprecation proceeds in three stages, each lasting approximately a
year. In some cases it migh move slower or faster, but year per stage
is what we aim at in general.
During each stage warnings (and errors) of increasing severity are
signaled, which note that the interface is deprecated, and point users
towards any replacements when applicable.
@enumerate
@item @strong{Early Deprecation}
During early deprecation the interface is kept in working condition,
but a style-warning will be signalled for uses of it at compile-time.
The internals may change at this stage: typically because the interface
is re-implemented on top of its successor. While we try to keep things
as backwards-compatible as feasible (taking maintenance costs into account),
sometimes semantics change slightly.
For example, when spinlock API was deprecated, spinlock objects ceased
to exist, and the whole spinlock API became a synonym for the mutex
API -- so code using the spinlock API continued working, but silently
switched to mutexes instead. However, if someone relied on
@code{(typep lock 'spinlock)}
returning @code{NIL} for a mutexes, trouble could ensue.
@item @strong{Late Deprecation}
During late deprecation the interface remains as it was during early
deprecation, but the compile-time warning is upgraded to a full
warning.
@item @strong{Final Deprecation}
During final deprecation the symbols still exist, but using the
interface will cause not only the compile-time full warning, but also
a runtime error.
@end enumerate
After final deprecation the interface is deleted entirely.
@section List of Deprecated Interfaces
@subsection Early Deprecation
@itemize
@item @strong{SB-EXT:QUIT}
Deprecated in favor of @code{sb-ext:exit} as of 1.0.56.55 in May 2012.
Expected to move into late deprecation in May 2013.
The design of @code{sb-ext:quit} proved too broken to fix in a
backwards-compatible manner, so it had to be deprecated and replaced.
Problems with it were manifold: when called in the main thread it
cause the entire process to exit. When called in another thread with
@code{:recklessly-p} it also caused the entire process to exit.
However, when called in another thread without @code{:recklessly-p} it
instead caused that thread to terminate abnormally without terminating
the process. Its behaviour versus other threads than the one it was
called in was also underspecified, and dependent on things such as the
current session. Any conceivable change that would have made it sane
would also have silently broken code that depended on the old
behaviour.
@strong{Remedy}
For code needing to work with legacy SBCLs, if you were calling
@code{quit} with @code{:recklessly-p t}, use
@sp 1
@lisp
(defun system-exit (&optional (code 0))
(alien-funcall (extern-alien "exit" (function void int)) code))
@end lisp
@sp 1
instead. In modern SBCLs simply call either @code{sb-posix:exit} or
@code{sb-ext:exit}.
If you were calling it without @code{:recklessly-p}, be advised
that your code may not function as expected when called from threads
other than the main one (see above) -- in any case, you can support
legacy SBCLs using the following conditionalization:
@sp 1
@lisp
(defun lisp-exit (&key (code 0) abort)
#+#.(cl:if (cl:find-symbol "EXIT" :sb-ext) '(and) '(or))
;; Assuming process exit is what is desired -- if thread termination
;; is intended, use SB-THREAD:ABORT-THREAD instead.
(sb-ext:exit :code code :abort abort)
#-#.(cl:if (cl:find-symbol "EXIT" :sb-ext) '(and) '(or))
(sb-ext:quit :unix-status code :recklessly-p abort))
@end lisp
@sp 1
@sp 1
@item @strong{SB-UNIX:UNIX-EXIT}
Deprecated as of 1.0.56.55 in May 2012. Expected to move into late
deprecation in May 2013.
When the SBCL process termination was refactored as part of changes that
led to @code{sb-ext:quit} being deprecated, @code{sb-unix:unix-exit}
ceased to be used internally. Since @code{SB-UNIX} is an internal package
not intended for user code to use, and since we're slowly in the process
of refactoring things to be less Unix-oriented, @code{sb-unix:unix-exit}
was initially deleted as it was no longer used. Unfortuntely it became
apparent that it was used by several external users, so it was re-instated
in deprecated form.
While the cost of keeping @code{sb-unix:unix-exit} indefinitely is
trivial, the ability to refactor our internals is important, so its
deprecation was taken as an opportunity to highlight that
@code{SB-UNIX} is an internal package and @code{SB-POSIX} should be
used by user-programs instead -- or alternatively calling the foreign
function directly if the desired interface doesn't for some reason
exist in @code{SB-POSIX}.
@strong{Remedy}
For code needing to work with legacy SBCLs, use eg. @code{system-exit}
as show above in remedies for @code{sb-ext:quit}. In modern SBCLs
simply call either @code{sb-posix:exit} or @code{sb-ext:exit} with
appropriate arguments.
@sp 1
@item @strong{SB-C::MERGE-TAIL-CALLS Compiler Policy}
Deprecated as of 1.0.53.74 in November 2011. Expected to move into
late deprecation in November 2012.
This compiler policy was never functional: SBCL has always merged tail
calls when it could, regardless of this policy setting. (It was also
never officially supported, but several code-bases have historically
used it.)
@strong{Remedy}
Simply remove the policy declarations. They were never necessary: SBCL
always merged tail-calls when possible. To disable tail merging,
structure the code to avoid the tail position instead.
@sp 1
@item @strong{Spinlock API}
Deprecated as of 1.0.53.11 in August 2011. Expected to move into late
deprecation in August 2012.
Spinlocks were an internal interface, but had a number of external users
and were hence deprecated instead of being simply deleted.
Affected symbols: @code{sb-thread::spinlock},
@code{sb-thread::make-spinlock}, @code{sb-thread::with-spinlock},
@code{sb-thread::with-recursive-spinlock},
@code{sb-thread::get-spinlock}, @code{sb-thread::release-spinlock},
@code{sb-thread::spinlock-value}, and @code{sb-thread::spinlock-name}.
@strong{Remedy}
Use the mutex API instead, or implement spinlocks suiting your needs
on top of @code{sb-ext:compare-and-swap},
@code{sb-ext:spin-loop-hint}, etc.
@end itemize
@subsection Late Deprecation
@itemize
@item @strong{SB-THREAD:JOIN-THREAD-ERROR-THREAD and SB-THREAD:INTERRUPT-THREAD-ERROR-THREAD}
Deprecated in favor of @code{sb-thread:thread-error-thread} as of
1.0.29.17 in June 2009. Expected to move into final deprecation in
June 2012.
@strong{Remedy}
For code that needs to support legacy SBCLs, use eg.:
@sp 1
@lisp
(defun get-thread-error-thread (condition)
#+#.(cl:if (cl:find-symbol "THREAD-ERROR-THREAD" :sb-thread)
'(and) '(or))
(sb-thread:thread-error-thread condition)
#-#.(cl:if (cl:find-symbol "THREAD-ERROR-THREAD" :sb-thread)
'(and) '(or))
(etypecase condition
(sb-thread:join-thread-error
(sb-thread:join-thread-error-thread condition))
(sb-thread:interrupt-thread-error
(sb-thread:interrupt-thread-error-thread condition))))
@end lisp
@sp 1
@sp 1
@item @strong{SB-INTROSPECT:FUNCTION-ARGLIST}
Deprecated in favor of @code{sb-introspect:function-lambda-list} as of
1.0.24.5 in January 2009. Expected to move into final deprecation in
January 2012.
Renamed for consistency and aesthetics. Functions have lambda-lists,
not arglists.
@strong{Remedy}
For code that needs to support legacy SBCLs, use eg.:
@sp 1
@lisp
(defun get-function-lambda-list (function)
#+#.(cl:if (cl:find-symbol "FUNCTION-LAMBDA-LIST" :sb-introspect)
'(and) '(or))
(sb-introspect:function-lambda-list function)
#-#.(cl:if (cl:find-symbol "FUNCTION-LAMBDA-LIST" :sb-introspect)
'(and) '(or))
(sb-introspect:function-arglist function))
@end lisp
@sp 1
@sp 1
@item @strong{Stack Allocation Policies}
Deprecated in favor of @code{sb-ext:*stack-allocate-dynamic-extent*}
as of 1.0.19.7 in August 2008, and are expected to be removed in
August 2012.
Affected symbols: @code{sb-c::stack-allocate-dynamic-extent},
@code{sb-c::stack-allocate-vector}, and
@code{sb-c::stack-allocate-value-cells}.
These compiler policies were never officially supported, and turned
out the be a flawed design.
@strong{Remedy}
For code that needs stack-allocation in legacy SBCLs, conditionalize
using:
@sp 1
@lisp
#-#.(cl:if (cl:find-symbol "*STACK-ALLOCATE-DYNAMIC-EXTENT*" :sb-ext)
'(and) '(or))
(declare (optimize sb-c::stack-allocate-dynamic-extent))
@end lisp
@sp 1
However, unless stack allocation is essential, we recommend simply
removing these declarations. Refer to documentation on
@code{sb-ext:*stack-allocate-dynamic*} for details on stack allocation
control in modern SBCLs.
@sp 1
@item @strong{SB-SYS:OUTPUT-RAW-BYTES}
Deprecated as of 1.0.8.16 in June 2007. Expected to move into final
deprecation in June 2012.
Internal interface with some external users. Never officially
supported, deemed unnecessary in presence of @code{write-sequence} and
bivalent streams.
@strong{Remedy}
Use streams with element-type @code{(unsigned-byte 8)}
or @code{:default} -- the latter allowing both binary and
character IO -- in conjunction with @code{write-sequence}.
@end itemize
@subsection Final Deprecation
No interfaces are currently in final deprecation.
@section Historical Interfaces
The following is a partial list of interfaces present in historical
versions of SBCL, which have since then been deleted.
@itemize
@item @strong{SB-KERNEL:INSTANCE-LAMBDA}
Historically needed for CLOS code. Deprecated as of 0.9.3.32 in August
2005. Deleted as of 1.0.47.8 in April 2011. Plain @code{lambda} can be
used where @code{sb-kernel:instance-lambda} used to be needed.
@sp 1
@item @strong{SB-ALIEN:DEF-ALIEN-ROUTINE, SB-ALIEN:DEF-ALIEN-VARIABLE, SB-ALIEN:DEF-ALIEN-TYPE}
Inherited from CMUCL, naming convention not consistent with preferred
SBCL style. Deprecated as of 0.pre7.90 in December 2001. Deleted as of
1.0.9.17 in September 2007. Replaced by
@code{sb-alien:define-alien-routine},
@code{sb-alien:define-alien-variable}, and
@code{sb-alien:define-alien-type}.
@end itemize

View file

@ -91,6 +91,7 @@ provided with absolutely no warranty. See the @file{COPYING} and
* Networking::
* Profiling::
* Contributed Modules::
* Deprecated Interfaces::
* Concept Index::
* Function Index::
* Variable Index::
@ -116,6 +117,7 @@ provided with absolutely no warranty. See the @file{COPYING} and
@include sb-bsd-sockets/sb-bsd-sockets.texinfo
@include profiling.texinfo
@include contrib-modules.texinfo
@include deprecated.texinfo
@include backmatter.texinfo
@bye

View file

@ -1123,6 +1123,45 @@
(deprecation-warning state since name replacements)
form))
;;; STATE is one of
;;;
;;; :EARLY, for a compile-time style-warning.
;;; :LATE, for a compile-time full warning.
;;; :FINAL, for a compile-time full warning and runtime error.
;;;
;;; Suggested duration of each stage is one year, but some things can move faster,
;;; and some widely used legacy APIs might need to move slower. Internals we don't
;;; usually add deprecation notes for, but sometimes an internal API actually has
;;; several external users, in which case we try to be nice about it.
;;;
;;; When you deprecate something, note it here till it is fully gone: makes it
;;; easier to keep things progressing orderly. Also add the relevant section
;;; (or update it when deprecation proceeds) in the manual, in
;;; deprecated.texinfo.
;;;
;;; EARLY:
;;; - SB-THREAD::SPINLOCK (type), since 1.0.53.11 (08/2011) -> Late: 08/2012
;;; - SB-THREAD::MAKE-SPINLOCK, since 1.0.53.11 (08/2011) -> Late: 08/2012
;;; - SB-THREAD::WITH-SPINLOCK, since 1.0.53.11 (08/2011) -> Late: 08/2012
;;; - SB-THREAD::WITH-RECURSIVE-SPINLOCK, since 1.0.53.11 (08/2011) -> Late: 08/2012
;;; - SB-THREAD::GET-SPINLOCK, since 1.0.53.11 (08/2011) -> Late: 08/2012
;;; - SB-THREAD::RELEASE-SPINLOCK, since 1.0.53.11 (08/2011) -> Late: 08/2012
;;; - SB-THREAD::SPINLOCK-VALUE, since 1.0.53.11 (08/2011) -> Late: 08/2012
;;; - SB-THREAD::SPINLOCK-NAME, since 1.0.53.11 (08/2011) -> Late: 08/2012
;;; - SETF SB-THREAD::SPINLOCK-NAME, since 1.0.53.11 (08/2011) -> Late: 08/2012
;;; - SB-C::MERGE-TAIL-CALLS (policy), since 1.0.53.74 (11/2011) -> Late: 11/2012
;;; - SB-EXT:QUIT, since 1.0.56.55 (05/2012) -> Late: 05/2013
;;; - SB-UNIX:UNIX-EXIT, since 1.0.56.55 (05/2012) -> Late: 05/2013
;;;
;;; LATE:
;;; - SB-SYS:OUTPUT-RAW-BYTES, since 1.0.8.16 (06/2007) -> Final: anytime
;;; - SB-C::STACK-ALLOCATE-DYNAMIC-EXTENT (policy), since 1.0.19.7 -> Final: anytime
;;; - SB-C::STACK-ALLOCATE-VECTOR (policy), since 1.0.19.7 -> Final: anytime
;;; - SB-C::STACK-ALLOCATE-VALUE-CELLS (policy), since 1.0.19.7 -> Final: anytime
;;; - SB-INTROSPECT:FUNCTION-ARGLIST, since 1.0.24.5 (01/2009) -> Final: anytime
;;; - SB-THREAD:JOIN-THREAD-ERROR-THREAD, since 1.0.29.17 (06/2009) -> Final: 09/2012
;;; - SB-THREAD:INTERRUPT-THREAD-ERROR-THREAD since 1.0.29.17 (06/2009) -> Final: 06/2012
(defmacro define-deprecated-function (state since name replacements lambda-list &body body)
(let* ((replacements (normalize-deprecation-replacements replacements))
(doc (let ((*package* (find-package :keyword)))

View file

@ -94,7 +94,7 @@ stale value, use MUTEX-OWNER instead."
,@body))
(sb!xc:defmacro with-spinlock ((lock) &body body)
(deprecation-warning :early "1.0.53.11" 'with-recursive-spinlock 'with-mutex)
(deprecation-warning :early "1.0.53.11" 'with-spinlock 'with-mutex)
`(with-mutex (,lock)
,@body))

View file

@ -61,10 +61,6 @@ more reliable bactracing across foreign calls.")
(if (zerop safety) 0 3)
("no" "maybe" "yes" "yes"))
(define-optimization-quality merge-tail-calls
3
"Deprecated: has no effect on compiled code. (Never really did.)")
(define-optimization-quality insert-debug-catch
(if (> debug (max speed space))
3

View file

@ -76,11 +76,16 @@ EXPERIMENTAL INTERFACE: Subject to change."
;;; Is it deprecated?
(defun policy-quality-deprecation-warning (quality)
(when (member quality '(stack-allocate-dynamic-extent stack-allocate-vector
stack-allocate-value-cells))
(deprecation-warning :late "1.0.19.7" quality '*stack-allocate-dynamic-extent*
:runtime-error nil)
t))
(case quality
((stack-allocate-dynamic-extent stack-allocate-vector stack-allocate-value-cells)
(deprecation-warning :late "1.0.19.7" quality '*stack-allocate-dynamic-extent*
:runtime-error nil)
t)
((merge-tail-calls)
(deprecation-warning :early "1.0.53.74" quality nil :runtime-error nil)
t)
(otherwise
nil)))
;;; *POLICY* holds the current global compiler policy information, as
;;; an alist mapping from optimization quality name to quality value.