增加/减少数字和/或数字变量的惯用 Common Lisp方法是什么?
Common Lisp中是否有一个函数将字符串作为参数并返回一个关键字?
示例:(keyword "foo")
- >:foo
我在"On Lisp"一书中读到,应该避免cons
在扩展宏的主体中过度使用.为什么被cons
认为是效率低下的操作?Lisp不与cons细胞共享结构吗?
(David James都写了问题和答案.我将编辑它以符合Stackoverflow标准.)
使用SBCL,您可以将Lisp代码编译为机器代码.
像Java,.net,C++甚至C一样,您将需要运行时.因此有两种方法可以编译Common Lisp代码.
首先是制作巨大的二进制文件,这在SBCL文档中有解释.目标机器上不需要SBCL.
另一种方式是更灵活的方法,即以fasl(FASt Load)格式创建机器代码.目标计算机上需要SBCL运行时.
第二种方式如何在类Unix操作系统下工作?
在Lisp解释器中,可以很容易地创建一个eval
可以扩展宏的分支,并且在扩展它的过程中,调用函数来构建扩展表达式.我在使用低级宏之前已经完成了这个,很容易让人感到满意.
但是,在编译器中没有任何函数可以调用来构建扩展代码:在以下示例中可以非常简单地看到该问题:
(defmacro cube (n)
(let ((x (gensym)))
`(let ((,x ,n))
(* ,x ,x ,x))))
Run Code Online (Sandbox Code Playgroud)
当解析器扩展宏时,它会调用gensym
并执行您期望的操作.当由编译器扩展,你会生成代码的let
结合x
,以(gensym)
但gensymmed符号,只需要对编译器做正确的事.因为gensym
在编译宏之前实际上没有调用它,所以它不是很有用.
当宏建立一个列表用作扩展使用map
或时,这对我来说更加奇怪filter
.
那么这是如何工作的呢?当然,编译后的代码不会被编译,(eval *macro-code*)
因为它的效率非常低.有一个写得很好的Lisp编译器吗?
这是一个很容易回答的问题(我猜),但我找了一段时间没找到任何东西,所以我会向你提问.
有typep
确定给定变量是否属于某种特定数据类型,例如整数,散列表等,但是有一个返回数据类型的函数吗?
例如
(defvar *x* 1)
*x*
(typep *x* 'integer)
T
(the-type-function *x*)
INTEGER
Run Code Online (Sandbox Code Playgroud) 主要问题:我将尾部调用优化(TCO)的最重要应用视为递归调用到循环的转换(在递归调用具有某种形式的情况下).更准确地说,当翻译成机器语言时,这通常会转换成某种跳跃系列.编译为本机代码(例如SBCL)的一些Common Lisp和Scheme编译器可以识别尾递归代码并执行此转换.基于JVM的Lisp(例如Clojure和ABCL)在执行此操作时遇到了麻烦.JVM作为一台可以防止或使其变得困难的机器是什么?我不明白.JVM显然没有循环问题.编译器必须弄清楚如何进行TCO,而不是编译它的机器.
相关问题:Clojure 可以将看似递归的代码转换成循环:如果程序员用关键字替换对函数的尾调用,它就好像它正在执行TCO一样recur
.但是,如果有可能让编译器识别尾调用 - 例如SBCL和CCL那样做 - 那么为什么Clojure编译器不能确定它应该按照它处理的方式处理尾调用recur
呢?
(对不起 - 这无疑是一个常见问题解答,我确信上面的评论显示了我的无知,但我找不到早期的问题是不成功的.)
现在,我所做的一切都设法适合单个源文件,而且这个文件非常小.你如何决定拆分成单独文件的数量和内容?
使用Java,可以很容易地确定一个文件中的内容(已经为您做出了决定),但在Lisp中我发现我编写了许多相互构建的小函数,并且很难确定哪些内容应该被拆分出.当我在Lisp中处理更大的项目时,不必重新发明轮子会很好,但我在网上找不到很多关于此的具体信息.
你能分享一些处理Lisp中较大项目的策略,还是指出一些处理这个问题的资源?
我试图找到一个lisp函数来在数字和字符串之间进行转换,经过一些googling后,我喜欢一个具有相同名称的函数.当我进入(itoa 1)
SLIME打印时:
Undefined function ITOA called with arguments (1) .
Run Code Online (Sandbox Code Playgroud)
我该如何进行转换?
有人可以解释以下行为吗?具体来说,为什么函数每次都返回一个不同的列表?为什么每次调用函数时都没有some-list
初始化'(0 0 0)
?
(defun foo ()
(let ((some-list '(0 0 0)))
(incf (car some-list))
some-list))
Run Code Online (Sandbox Code Playgroud)
输出:
> (foo)
(1 0 0)
> (foo)
(2 0 0)
> (foo)
(3 0 0)
> (foo)
(4 0 0)
Run Code Online (Sandbox Code Playgroud)
谢谢!
编辑:
另外,假设我希望'(1 0 0)
每次输出函数,推荐的实现此函数的方法是什么?