@c Generated by the sb-manual contrib. Do not edit.

@node deprecation
@cindex 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

@anchor{Declaration sb-ext deprecated}
@ddindex @sortas{deprecated sb-ext} deprecated [sb-ext]
@deffn{Declaration} 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 deffn
@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 @code{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

