考虑这个简单的代码示例:
(defstruct test
(:example nil :type (simple-array single-float)))
(defparameter test-struct
(make-test :example (make-array 10 :element-type 'single-float
:initial-element 1.0)))
Run Code Online (Sandbox Code Playgroud)
我们可以看到,没有什么可以疯狂的,定义了一个带有单个槽的简单结构.我们还指定:example
插槽是强类型,预期是单个浮点数组.这里没有问题,一切正常.
我们test-struct
现在写一个文件:
(with-open-file (out "~/Desktop/out.test"
:direction :output
:if-exists :supersede)
(format out "~s" test-struct))
Run Code Online (Sandbox Code Playgroud)
同样,没有惊喜,我们在桌面上获得一个漂亮的小文件,其中包含以下内容:
#S(TEST :EXAMPLE #(1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0))
Run Code Online (Sandbox Code Playgroud)
然而,紧张开始蔓延,因为我们注意到没有任何迹象表明这个特定的文字数组应该包含单个浮点数.有了这种怀疑,让我们尝试加载这个结构:
(defparameter loaded-struct
(with-open-file (in "~/Desktop/out.test")
(read in nil)))
Run Code Online (Sandbox Code Playgroud)
我们在这里,SBCL愉快地将我们放入调试器:
问题是:有没有办法指示SBCL验证结构中的这个数组插槽是否是有效类型并加载它?或者换句话说,是否可以在不诉诸构建自定义编写器和构造函数的情况下读取具有强类型插槽的结构?
我想定义一个LISP宏dolist
,让我定义一个可选的输出参数。在下面的案例研究中,此宏将称为doread
。它将从文件中读取行并返回以这种方式找到的行数。
(let ((lines 0))
(doread (line file lines)
;; do something with line
(incf lines)))
Run Code Online (Sandbox Code Playgroud)
问题是要使它lines
在上面的宏中起作用
我可以使用&key来完成我想做的事情,但不能使用&optional&key来做(因为我想控制文件的读取方式,所以需要&key;例如,使用read
or read-line
或其他方法)。
现在下面的作品但到作品走错了路。这里的out
参数必须是a &key
而不是&optional:
;; this way works...
(defmacro doread ((it f &key out (take #'read)) &body body)
"Iterator for running over files or strings."
(let ((str (gensym)))
`(with-open-file (,str f)
(loop for ,it = (funcall ,take ,str nil)
while ,it do
(progn ,@body))
,out)))
;; lets me define something …
Run Code Online (Sandbox Code Playgroud) 我想将函数(*x 2)应用于列表中的每个其他元素,并使用循环宏返回整个列表.我到目前为止提出的解决方案是这样的:
(defun double-every-other (xs)
(loop for x in xs by #'cddr collect (* x 2)))
Run Code Online (Sandbox Code Playgroud)
但是,这会使每个其他元素加倍,只返回加倍的元素,所以如果我执行:
(double-every-other '(1 2 3 4))
Run Code Online (Sandbox Code Playgroud)
结果将是:
'(4 8)
Run Code Online (Sandbox Code Playgroud)
但我希望结果如下:
'(1 4 3 8)
Run Code Online (Sandbox Code Playgroud)
有没有办法可以使用(循环)?
我需要知道引用和列表之间的区别.例如:
cl-prompt> (equal (first (list * 1 2)) *)
T
cl-prompt> (equal (first '(* 1 2)) *)
NIL
Run Code Online (Sandbox Code Playgroud)
我不明白这是什么问题.
我正在尝试编写一个仅将列表作为参数的函数,并计算该符号a
在列表中出现的次数,而不计算列表中子列表中的任何 a。
我对 Lisp 很陌生,所以请尽可能使用基本代码,这样我就可以理解它在做什么,即使它效率低下。
(defun times (l)
(setf x 'a)
(cond
((null l) nil)
((equal x (car l)) (+ 1 (times x (cdr L))))
(t (times x(cdr l)))))
Run Code Online (Sandbox Code Playgroud)
所以(times '(a b (a) c))
应该返回 1。但是我得到的错误是,当它应该得到一个参数时,这个行时间得到了两个参数。
我使用 vscode+merlin 来读取 OCaml 代码。有时它可以给我一个类型,但有时它只告诉我一个类型'a
,这与告诉我什么都没有一样。我必须通过阅读代码来猜测值的类型。阅读代码来得出值的类型很重要,但有时我怀疑我的猜测是否正确。
所以我想要一个可以在运行时获取值类型的方法,就像 Java 或 C# 中的反射一样。
var a = 1;
Console.WriteLine(a.GetType());
Run Code Online (Sandbox Code Playgroud)
有没有办法在 OCaml 中做同样的事情?
如果我在Racket中尝试这个:
(expt 2 1000)
Run Code Online (Sandbox Code Playgroud)
我得到的数字比宇宙中所有原子大许多倍:
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376
Run Code Online (Sandbox Code Playgroud)
我甚至可以(expt 2 10000)
在我的T450笔记本电脑上使用仍然只需要一秒钟.据我了解,这只能因为尾递归而成为可能.它是否正确?如果是这样,Racket的尾递归是纯函数式编程,还是幕后隐藏的副作用?另外,当我看到Common Lisp时loop
,它是否基于引擎盖下的尾递归?一般来说,我想我想知道这些递归/循环的功能是如何实现的.
我正在尝试编写一个函数来比较 Common Lisp 中的两个列表。
符号“&”表示任何元素序列,符号“$”表示任何单个元素。
(defun match (filter data)
(cond
((atom filter) (eq filter data))
((atom data) NIL)
((eq (car filter) '|$|)
(match (cdr filter) (cdr data)))
((eq (car filter) '|&|)
(cond
((match (cdr filter) data))
(data (match filter (cdr data)))))
((match (car filter) (car data))
(match (cdr filter) (cdr data)))))
Run Code Online (Sandbox Code Playgroud)
工作正常:
(match '(a b c) '(a b c)) ; => T
(match '(a $ c) '(a b c)) ; => T
(match '(a ff c) '(a b c)) ; …
Run Code Online (Sandbox Code Playgroud) 我正在将一些Scheme代码转换为Common Lisp.我不知道Scheme.我知道一点Common Lisp.
这是Scheme代码:
(define (close-enuf? h1 h2 #!optional tolerance scale)
(if (default-object? tolerance)
...))
Run Code Online (Sandbox Code Playgroud)
我将该Scheme代码转换为此Common Lisp:
(defun close-enuf? (h1 h2 &optional tolerance scale)
(if (xxx tolerance)
...))
Run Code Online (Sandbox Code Playgroud)
除此之外xxx
,这看起来不错吗?
现在,关于xxx
什么是Common Lisp等价物default-object?
我找到了这个定义default-object?
:
The predicate default-object?, which is true only of default objects, can be used to determine which optional parameters were supplied, and which were defaulted.
Run Code Online (Sandbox Code Playgroud)
我不确定那是什么意思.是否说default-object?
如果参数的值是默认值(不是传入的值),则返回true?
该floor
Hyperspec对文章dotimes
有这个例子:
(defun palindromep (string &optional
(start 0)
(end (length string)))
(dotimes (k (floor (- end start) 2) t)
(unless (char-equal (char string (+ start k))
(char string (- end k 1)))
(return nil))))
Run Code Online (Sandbox Code Playgroud)
如果floor
返回两个值,例如(floor 5 2)
- > 2
和1
,如何dotimes
知道只使用第一个值而忽略第二个值的计数形式?