有没有一种方法可以找出基元函数(内置)是如何在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代码本身:

  • 如果代码在";预期地点";,点击Meta-也将带您了解其源代码。我相信默认值是/usr/share/sbcl-source/src/code/,但可能有一种配置方法

  • 然而,还有另一种实用的方法可以查看:如果您查看上面(describe ...)的输出,则行为:

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

  • 这个命令告诉em>您可以在SBCL源代码中找到函数定义的文件。

  • 因此,在[repo](https://github.com/sbcl/sbcl/tree/master/src(中,如果您找到src/code/list.lisp,您应该找到您要查找的定义;在此复制:

(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

但是,它并不总是可用的,在这种情况下,您必须转到SBCL源代码存储库。

最新更新