mirror of
git://git.code.sf.net/p/sbcl/sbcl
synced 2026-09-10 07:26:40 -04:00
525 lines
18 KiB
Plaintext
525 lines
18 KiB
Plaintext
@c Generated by the sb-manual contrib. Do not edit.
|
|
|
|
@node deprecation
|
|
@chapter Deprecation
|
|
|
|
@menu
|
|
* Why Deprecate?: why deprecate?.
|
|
* The Deprecation Pipeline: the deprecation pipeline.
|
|
* Deprecation Conditions: deprecation conditions.
|
|
* Introspecting Deprecation Information: introspecting deprecation information.
|
|
* Deprecation Declaration: deprecation declaration.
|
|
* Deprecation Examples: deprecation examples.
|
|
* Deprecated Interfaces in SBCL: deprecated interfaces in sbcl.
|
|
@end menu
|
|
|
|
In order to support evolution of interfaces in SBCL as well as in user
|
|
code, SBCL allows declaring functions, variables and types as
|
|
deprecated. Users of deprecated things are notified by means of
|
|
warnings while the deprecated thing in question is still available.
|
|
|
|
This chapter documents the interfaces for being notified when using
|
|
deprecated thing and declaring things as deprecated, the deprecation
|
|
process used for SBCL interfaces, and lists legacy interfaces in
|
|
various stages of deprecation.
|
|
|
|
@emph{Deprecation} in this context should not be confused with those
|
|
things the ANSI Common Lisp standard calls @emph{deprecated}: the
|
|
entirety of ANSI CL is supported by SBCL, and none of those
|
|
interfaces are subject to censure.
|
|
|
|
@node why deprecate?
|
|
@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
|
|
advisedly, 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
|
|
|
|
@node the deprecation pipeline
|
|
@section The Deprecation Pipeline
|
|
|
|
SBCL uses a @emph{deprecation pipeline} with multiplestages: as
|
|
time time goes by, deprecated things move from earlier stages of
|
|
deprecation to later stages before finally being removed. The
|
|
intention is making users aware of necessary changes early but
|
|
allowing a migration to new interfaces at a reasonable pace.
|
|
|
|
Deprecation proceeds in three stages, each lasting approximately a
|
|
year. In some cases it might move slower or faster, but one 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.
|
|
|
|
@itemize
|
|
@item @strong{Early Deprecation}
|
|
|
|
During early deprecation the interface is kept in working
|
|
condition. However, when a thing in this deprecation stage is
|
|
used, an @code{sb-ext:early-deprecation-warning}, which is a
|
|
@code{style-warning}, is signaled 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 the 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
|
|
|
|
@example
|
|
(typep lock 'spinlock)
|
|
@end example
|
|
|
|
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:
|
|
when a thing in this deprecation stage is used, a
|
|
@code{sb-ext:late-deprecation-warning}, which is a full @code{warning}, is
|
|
signaled at compile-time.
|
|
|
|
@item @strong{Final Deprecation}
|
|
|
|
During final deprecation the symbols still exist. However, when
|
|
a thing in this deprecation stage is used, a
|
|
@code{sb-ext:final-deprecation-warning}, which is a full @code{warning}, is
|
|
signaled at compile-time and an @code{error} is signaled at run-time.
|
|
|
|
@item @strong{After Final Deprecation}
|
|
|
|
The interface is deleted entirely.
|
|
@end itemize
|
|
|
|
@node deprecation conditions
|
|
@section Deprecation Conditions
|
|
|
|
@code{sb-ext:deprecation-condition} is the superclass of all
|
|
deprecation-related warning and error conditions. All common slots and
|
|
readers are defined in this condition class.
|
|
|
|
@anchor{Condition sb-ext deprecation-condition}
|
|
@ttindex @sortas{deprecation-condition sb-ext} deprecation-condition [sb-ext]
|
|
@deffn{Condition} sb-ext:deprecation-condition
|
|
Superclass for deprecation-related error and warning
|
|
conditions.
|
|
@end deffn
|
|
@anchor{Condition sb-ext early-deprecation-warning}
|
|
@ttindex @sortas{early-deprecation-warning sb-ext} early-deprecation-warning [sb-ext]
|
|
@deffn{Condition} sb-ext:early-deprecation-warning
|
|
This warning is signaled when the use of a variable,
|
|
function, type, etc. in @code{:early} deprecation is detected at
|
|
compile-time. The use will work at run-time with no warning or
|
|
error.
|
|
@end deffn
|
|
@anchor{Condition sb-ext late-deprecation-warning}
|
|
@ttindex @sortas{late-deprecation-warning sb-ext} late-deprecation-warning [sb-ext]
|
|
@deffn{Condition} sb-ext:late-deprecation-warning
|
|
This warning is signaled when the use of a variable,
|
|
function, type, etc. in @code{:late} deprecation is detected at
|
|
compile-time. The use will work at run-time with no warning or
|
|
error.
|
|
@end deffn
|
|
@anchor{Condition sb-ext final-deprecation-warning}
|
|
@ttindex @sortas{final-deprecation-warning sb-ext} final-deprecation-warning [sb-ext]
|
|
@deffn{Condition} sb-ext:final-deprecation-warning
|
|
This warning is signaled when the use of a variable,
|
|
function, type, etc. in @code{:final} deprecation is detected at
|
|
compile-time. An error will be signaled at run-time.
|
|
@end deffn
|
|
@anchor{Condition sb-ext deprecation-error}
|
|
@ttindex @sortas{deprecation-error sb-ext} deprecation-error [sb-ext]
|
|
@deffn{Condition} sb-ext:deprecation-error
|
|
This error is signaled at run-time when an attempt is made to use
|
|
a thing that is in @code{:final} deprecation, i.e. call a function or access
|
|
a variable.
|
|
@end deffn
|
|
@node introspecting deprecation information
|
|
@section Introspecting Deprecation Information
|
|
|
|
The deprecation status of functions and variables can be inspected
|
|
using the @code{sb-cltl2:function-information} and
|
|
@code{sb-cltl2:variable-information} functions provided by the @code{sb-cltl2}
|
|
contributed module.
|
|
|
|
@node deprecation declaration
|
|
@section Deprecation Declaration
|
|
|
|
The @code{sb-ext:deprecated} declaration can be used to declare objects
|
|
in various namespaces as deprecated.
|
|
|
|
@quotation
|
|
@emph{Note}: See the @code{namespace} @code{clhs} glossary entry in the glossary of
|
|
the Common Lisp Hyperspec.)
|
|
@end quotation
|
|
|
|
@itemize
|
|
@item [@strong{declaration}] @code{sb-ext:deprecated}
|
|
|
|
Syntax: @code{(sb-ext:deprecated stage since &rest object-clauses)}
|
|
|
|
stage ::= @{@code{:early} | @code{:late} | @code{:final}@}
|
|
|
|
since ::= @{@code{<version>} | (@code{<software>} @code{<version>})@}
|
|
|
|
object-clause ::= (namespace @code{<name>} [@code{:replacement} @code{<replacement>}])
|
|
|
|
namespace ::= @{@code{cl:variable} | @code{cl:function} | @code{cl:type}@}
|
|
|
|
where the terminal @code{<name>} is the name of the deprecated thing,
|
|
@code{<version>} and @code{<software>} are strings describing the version
|
|
in which the thing has been deprecated and @code{<replacement>} is a
|
|
name or a list of names designating things that should be used
|
|
instead of the deprecated thing.
|
|
|
|
Currently the following namespaces are supported:
|
|
|
|
@itemize
|
|
@item @code{cl:function}: Declare functions, compiler-macros or macros as
|
|
deprecated.
|
|
|
|
When declaring a function to be in @code{:final} deprecation, there
|
|
should be no actual definition of the function as the
|
|
declaration emits a stub function that signals a
|
|
@code{sb-ext:deprecation-error} at run-time when called.
|
|
|
|
@item @code{cl:variable}: Declare special and global variables, constants
|
|
and symbol-macros as deprecated.
|
|
|
|
When declaring a variable to be in @code{:final} deprecation, there
|
|
should be no actual definition of the variable as the
|
|
declaration emits a symbol-macro that signals a
|
|
@code{sb-ext:deprecation-error} at run-time when accessed.
|
|
|
|
@item @code{cl:type}: Declare named types (i.e. defined via @code{deftype}),
|
|
standard classes, structure classes and condition classes as
|
|
deprecated.
|
|
@end itemize
|
|
@end itemize
|
|
|
|
@node deprecation examples
|
|
@section Deprecation Examples
|
|
|
|
Marking functions as deprecated:
|
|
|
|
@example
|
|
(defun foo ())
|
|
(defun bar ())
|
|
(declaim (deprecated :early ("my-system" "1.2.3")
|
|
(function foo :replacement bar)))
|
|
|
|
;; Remember: do not define the actual function or variable in case of
|
|
;; :final deprecation:
|
|
(declaim (deprecated :final ("my-system" "1.2.3")
|
|
(function fez :replacement whoop)))
|
|
@end example
|
|
|
|
Attempting to use the deprecated functions:
|
|
|
|
@example
|
|
(defun baz ()
|
|
(foo))
|
|
| STYLE-WARNING: The function CL-USER::FOO has been deprecated...
|
|
=> BAZ
|
|
(baz)
|
|
=> NIL ; no error
|
|
|
|
(defun danger ()
|
|
(fez))
|
|
| WARNING: The function CL-USER::FEZ has been deprecated...
|
|
=> DANGER
|
|
(danger)
|
|
|- ERROR: The function CL-USER::FEZ has been deprecated...
|
|
@end example
|
|
|
|
@node deprecated interfaces in sbcl
|
|
@section Deprecated Interfaces in SBCL
|
|
|
|
@menu
|
|
* List of Deprecated Interfaces: list of deprecated interfaces.
|
|
* Historical Interfaces: historical interfaces.
|
|
@end menu
|
|
|
|
This sections lists legacy interfaces in various stages of deprecation.
|
|
|
|
@node list of deprecated interfaces
|
|
@subsection List of Deprecated Interfaces
|
|
|
|
@menu
|
|
* Early Deprecation: early deprecation.
|
|
* Late Deprecation: late deprecation.
|
|
* Final Deprecation: final deprecation.
|
|
@end menu
|
|
|
|
@node early deprecation
|
|
@subsubsection Early Deprecation
|
|
|
|
@itemize
|
|
@item @code{sockint::win32-*}
|
|
|
|
Deprecated in favor of the corresponding prefix-less functions
|
|
(e.g. @code{sockint::bind} replaces @code{sockint::win32-bind}) as of
|
|
1.2.10 in March 2015. Expected to move into late deprecation in
|
|
August 2015.
|
|
|
|
@item @code{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,
|
|
@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. Unfortunately 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 e.g.
|
|
@code{system-exit}. In modern SBCLs, simply call either @code{sb-posix:exit}
|
|
or @code{sb-ext:exit} with appropriate arguments.
|
|
|
|
@item @code{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.
|
|
|
|
@item The 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.
|
|
|
|
@item @code{sockint::handle->fd}, @code{sockint::fd->handle}
|
|
|
|
Internally deprecated in 2012. Declared deprecated as of 1.2.10
|
|
in March 2015. Expected to move into final deprecation in August
|
|
2015.
|
|
@end itemize
|
|
|
|
@node late deprecation
|
|
@subsubsection Late Deprecation
|
|
|
|
@itemize
|
|
@item @code{sb-thread:join-thread-error-thread} and
|
|
@code{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 e.g.:
|
|
|
|
@example
|
|
(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 example
|
|
|
|
@item @code{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}
|
|
|
|
@example
|
|
For code that needs to support legacy SBCLs, use e.g.:
|
|
|
|
(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 example
|
|
|
|
@item 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:
|
|
|
|
@example
|
|
#-#.(cl:if (cl:find-symbol "*STACK-ALLOCATE-DYNAMIC-EXTENT*" :sb-ext)
|
|
'(and) '(or))
|
|
(declare (optimize sb-c::stack-allocate-dynamic-extent))
|
|
@end example
|
|
|
|
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.
|
|
|
|
@item @code{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
|
|
|
|
@node final deprecation
|
|
@subsubsection Final Deprecation
|
|
|
|
No interfaces are currently in final deprecation.
|
|
|
|
@node historical interfaces
|
|
@subsection Historical Interfaces
|
|
|
|
The following is a partial list of interfaces present in historical
|
|
versions of SBCL, which have since then been deleted.
|
|
|
|
@itemize
|
|
@item @code{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 SB-KERNEL:INSTANCE-LAMBDA used to be needed.
|
|
|
|
@item @code{sb-alien:def-alien-routine}, @code{sb-alien:def-alien-variable},
|
|
@code{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
|
|
|