more deprecation
authorNikodemus Siivola <nikodemus@random-state.net>
Wed, 2 May 2012 11:48:35 +0000 (14:48 +0300)
committerNikodemus Siivola <nikodemus@sb-studio.net>
Wed, 2 May 2012 18:07:36 +0000 (21:07 +0300)
 * 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.)

doc/manual/deprecated.texinfo [new file with mode: 0644]
doc/manual/sbcl.texinfo
src/code/early-extensions.lisp
src/code/thread.lisp
src/compiler/policies.lisp
src/compiler/policy.lisp

diff --git a/doc/manual/deprecated.texinfo b/doc/manual/deprecated.texinfo
new file mode 100644 (file)
index 0000000..97b0b13
--- /dev/null
@@ -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
index e13c47f..6c316dc 100644 (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
index 1d297c3..bde43c1 100644 (file)
     (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)))
index 5188793..09c2cc4 100644 (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))
 
index 53b21e4..3717744 100644 (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
index 413e425..c6b31aa 100644 (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.