微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有没有办法找出原始函数内置在 SBCL 中是如何准确定义的?

如何解决有没有办法找出原始函数内置在 SBCL 中是如何准确定义的?

我正在使用 Emacs、SBCL 和 Slime 学习 Common Lisp。

我想确切地知道什么是内置函数代码定义。

我知道如何使用 (documentation ...)(describe ...)。但是,它们仅提供高级别的信息。我想看看代码详情。

nth 内置函数为例。

Documentation 给我们:

CL-USER> (documentation 'nth 'function)
"Return the nth object in a list where the car is the zero-th element."

Describe 给我:

CL-USER> (describe 'nth)
COMMON-LISP:NTH
  [symbol]

NTH names a compiled function:
  Lambda-list: (SB-IMPL::N LIST)
  Declared type: (FUNCTION (UNSIGNED-BYTE LIST) (VALUES T &OPTIONAL))
  Derived type: (FUNCTION (T T) (VALUES T &OPTIONAL))
  Documentation:
    Return the nth object in a list where the car is the zero-th element.
  Inline proclamation: MAYBE-INLINE (inline expansion available)
  KNown attributes: foldable,flushable,unsafely-flushable
  Source file: SYS:SRC;CODE;LIST.LISP

(SETF NTH) names a compiled function:
  Lambda-list: (SB-KERNEL::NEWVAL SB-IMPL::N LIST)
  Derived type: (FUNCTION (T UNSIGNED-BYTE LIST) (VALUES T &OPTIONAL))
  Inline proclamation: INLINE (inline expansion available)
  Source file: SYS:SRC;CODE;SETF-FUNS.LISP

(SETF NTH) has a complex setf-expansion:
  Lambda-list: (SB-IMPL::N LIST)
  (undocumented)
  Source file: SYS:SRC;CODE;DEFSETFS.LISP
; No value

我想看到类似的东西:

(unkNown-command 'nth)

哪个会返回类似:

(defun nth (x xs)
  (if (equal x 0)
      (car xs)
      (my-nth (- x 1) (cdr xs))))

Lisp 语言非常棒,拥有由优秀程序员构建的庞大生态系统。我希望有一些工具或命令。

谢谢

解决方法

首先,一些一般性说明

  • 在您自己的代码中,点击Meta-.应该会带您到代码的来源
  • 这对于通过 Quicklisp 安装的库“正常工作”。

现在是 SBCL 代码本身:

  • 如果代码位于“预期位置”,则在内置函数(如上面示例中的 nth)上点击 Meta-. 也会 带你到它的源头。我相信默认值是 /usr/share/sbcl-source/src/code/,但可能有一种方法可以配置它。

  • 但是,还有另一种实用的方式来查看:如果您查看上面 (describe ...) 的输出,该行是:

Source file: SYS:SRC;CODE;LIST.LISP
  • 注意:不是最后一行,是针对(setf nth),略有不同

  • 这会告诉您SBCL 源代码中的哪个文件可以找到函数定义。

  • 因此,在 [repo](https://github.com/sbcl/sbcl/tree/master/src) 中,如果您找到 src/code/list.lisp,您应该找到 the definition you're looking for ;在此转载:

(defun nth (n list)
  "Return the nth object in a list where the car is the zero-th element."
  (declare (explicit-check)
           (optimize speed))
  (typecase n
    ((and fixnum unsigned-byte)
     (block nil
       (let ((i n)
             (result list))
         (tagbody
          loop
            (the list result)
            (if (plusp i)
                (psetq i (1- i)
                       result (cdr result))
                (return (car result)))
            (go loop)))))
    (t
     (car (nthcdr n list)))))
,

当此类信息可用时,应可通过 function-lambda-expression 访问:

* (FUNCTION-LAMBDA-EXPRESSION #'nth)
(LAMBDA (SB-IMPL::N LIST)
  (DECLARE (SB-INT:EXPLICIT-CHECK)
           (OPTIMIZE SPEED))
  (BLOCK NTH
    (TYPECASE SB-IMPL::N
      ((AND FIXNUM UNSIGNED-BYTE)
       (BLOCK NIL
         (LET ((SB-IMPL::I SB-IMPL::N) (SB-IMPL::RESULT LIST))
           (TAGBODY
            LOOP
             (THE LIST SB-IMPL::RESULT)
             (IF (PLUSP SB-IMPL::I)
                 (PSETQ SB-IMPL::I (1- SB-IMPL::I)
                        SB-IMPL::RESULT (CDR SB-IMPL::RESULT))
                 (RETURN (CAR SB-IMPL::RESULT)))
             (GO LOOP)))))
      (T (CAR (NTHCDR SB-IMPL::N LIST))))))
NIL
NTH

但是,它并不总是可用,在这种情况下,您必须转到 the SBCL source code repository

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。