有没有办法找出原始函数(内置)是如何在 SBCL 中准确定义的?
Is there a way to find out how the primitive functions (built-in) where exactly defined inside 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)
这会 return 类似于:
(defun nth (x xs)
(if (equal x 0)
(car xs)
(my-nth (- x 1) (cdr xs))))
Lisp 语言非常棒,并且拥有由出色的程序员构建的巨大生态系统。我希望有一些工具或命令。
谢谢
当此类信息可用时,应该可以通过 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。
首先,一些一般性的说明
- 在您的自己的代码中,点击Meta-。应该会带您到代码源
- 这将也对通过 Quicklisp 安装的库“有效”。
现在 SBCL 代码本身:
如果代码位于“预期位置”,则在内置函数上点击 Meta-.(如示例中的 nth
上面)将也带你到它的源头。我相信默认值是 /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
, you should find 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)))))
我正在使用 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)
这会 return 类似于:
(defun nth (x xs)
(if (equal x 0)
(car xs)
(my-nth (- x 1) (cdr xs))))
Lisp 语言非常棒,并且拥有由出色的程序员构建的巨大生态系统。我希望有一些工具或命令。
谢谢
当此类信息可用时,应该可以通过 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。
首先,一些一般性的说明
- 在您的自己的代码中,点击Meta-。应该会带您到代码源
- 这将也对通过 Quicklisp 安装的库“有效”。
现在 SBCL 代码本身:
如果代码位于“预期位置”,则在内置函数上点击 Meta-.(如示例中的
nth
上面)将也带你到它的源头。我相信默认值是/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
, you should find 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)))))