弃用函数的最佳实践

Best practices for deprecating functions

有没有人有任何聪明的方法来表示函数已被弃用?我想到了:

我也不是很喜欢。一个破坏代码,另一个使输出混乱。我确实希望人们停止使用旧功能,并且发现在文档中声明它们已弃用然后在将来的某个时候删除它们很少有效;人们在被移除后仍然 'surprised'。

有人在这方面有什么好的想法吗?

最好的办法通常是在编译时发出警告:

(defvar *deprecation-warnings* t)

(defvar *deprecation-locations*
  (make-hash-table :test #'equal))

(defmacro define-deprecated-function (f args &body forms)
  `(progn
     (defun ,f ,args ,@forms)
     (define-compiler-macro ,f (&whole form &rest args)
       (declare (ignore args))
       (when *deprecation-warnings*
         (warn "Deprecated function ~S~@[ in ~A~]"
               ',f *compile-file-truename*))
       (when *compile-file-pathname*
         (pushnew *compile-file-truename*
                  (gethash ',f *deprecation-locations*)
                  :test #'equal))
       form)))

(defun report-deprecations (&key (clear nil) (stream t))
  (maphash (lambda (f locations)
             (format stream "~&~S ~{~A~^, ~}~%" f locations))
           *deprecation-locations*)
  (when clear
    (clrhash *deprecation-locations*))
  (values))

对于其他类型的东西(通用函数等)也有类似的东西。

那你可以说

(define-deprecated-function foo (...)
  ...)

所有调用 foo 的代码现在都会在编译时收到警告。 report-deprecations 会告诉人们什么东西被弃用了以及在哪里。

当然,当弃用的功能消失时,人们仍然会无视警告并大声抱怨。该问题没有解决方案。

[一直不知道这里应该写'deprecation'还是'depreciation'...]