我是Lisp的初学者.我正在尝试记忆递归函数来计算Collatz序列中的项数(对于Project Euler中的问题14 ).我的代码是:
(defun collatz-steps (n)
(if (= 1 n) 0
(if (evenp n)
(1+ (collatz-steps (/ n 2)))
(1+ (collatz-steps (1+ (* 3 n)))))))
(defun p14 ()
(defvar m-collatz-steps (memoize #'collatz-steps))
(let
((maxsteps (funcall m-collatz-steps 2))
(n 2)
(steps))
(loop for i from 1 to 1000000
do
(setq steps (funcall m-collatz-steps i))
(cond
((> steps maxsteps)
(setq maxsteps steps)
(setq n i))
(t ())))
n))
(defun memoize (fn)
(let ((cache (make-hash-table :test #'equal)))
#'(lambda (&rest …Run Code Online (Sandbox Code Playgroud) 我想学习一些Lisp语言(Common Lisp的)最近,我不知道是否有给定的数字,就像你可以在C通过枚举做一个名字的一种方法.
我不需要枚举的完整功能集.最后我只想有快速和可读的代码.
我已经尝试了全局和小函数,但总是伴随着性能的降低.只需将数字插入代码总是更快.
说我有一个函数foo:
(defun foo (x y &rest args)
...)
后来我想用功能栏包装它:
(defun bar (x &rest args)
(foo x 100 args))
假设bar然后被调用如下: (bar 50 1 2 3)
使用这个设置,args是一个包含尾随参数的bar体内的列表,因此当我将它传递给foo时,而不是得到相当于(foo 50 100 1 2 3)我的(foo 50 100 '(1 2 3)).如果这些是宏,我会在条形体内使用``(foo,x 100,@ args)`将args拼接到函数调用中.但是,@只能在反引号列表中使用.
如何在常规函数中进行相同类型的拼接?
如何在Common LISP中递归删除嵌套括号,例如
(unnest '(a b c (d e) ((f) g))) => (a b c d e f g)
(unnest '(a b)) => (a b)
(unnest '(() ((((a)))) ())) => (a)
Run Code Online (Sandbox Code Playgroud)
谢谢
我正在学习常见的lisp,我在理解两个反引号和两个逗号的用法时遇到问题:
``(a ,,(+ 1 2))
Run Code Online (Sandbox Code Playgroud)
我的意思是,我不知道为什么它被评估为:
`(A ,3)
Run Code Online (Sandbox Code Playgroud)
而不是像这样的东西:
`(A 3)
Run Code Online (Sandbox Code Playgroud)
我在解释自己,为了评估表格前面的两个反引号,两个逗号都被"消耗",所以没有一个逗号应该离开,但还有一个.看起来怎么样
``(a ,,(+ 1 2))
Run Code Online (Sandbox Code Playgroud)
仅使用列表和'?
为什么我们必须使用funcallCommon Lisp中的高阶函数?例如,为什么我们必须使用:
(defun foo (test-func args)
(funcall test-func args))
Run Code Online (Sandbox Code Playgroud)
而不是更简单:
(defun bar (test-func args)
(test-func args))
Run Code Online (Sandbox Code Playgroud)
来自程序背景,我有点惊讶,因为我更习惯的语言(例如Python,C#)不需要区分.特别是,至少在源代码级别,C#编译器将其转换为类似的东西func.invoke().
我看到的唯一问题是,这意味着我们不能再调用全局函数test-func,因为它会被遮蔽,但这不是问题.
问题不是关于使用关键字,而是关于关键字实现.例如,当我使用关键字参数创建一些函数并进行调用时:
(defun fun (&key key-param) (print key-param)) => FUN
(find-symbol "KEY-PARAM" 'keyword) => NIL, NIL ;;keyword is not still registered
(fun :key-param 1) => 1
(find-symbol "KEY-PARAM" 'keyword) => :KEY-PARAM, :EXTERNAL
Run Code Online (Sandbox Code Playgroud)
如何使用关键字传递参数?关键字是值本身的符号,那么如何使用关键字绑定相应的参数?
关于关键字的另一个问题 - 关键字用于定义包.我们可以定义一个以现有关键字命名的包:
(defpackage :KEY-PARAM) => #<The KEY-PARAMETER package, 0/16 ...
(in-package :KEY-PARAM) => #<The KEY-PARAMETER package, 0/16 ...
(defun fun (&key key-param) (print key-param)) => FUN
(fun :KEY-PARAM 1) => 1
Run Code Online (Sandbox Code Playgroud)
系统如何区分:KEY-PARAM包名和功能参数名之间的用法?如果我们定义函数KEY-PARAM并导出它(实际上不是函数,而是名称),我们也可以做一些更复杂的事情:
(in-package :KEY-PARAM)
(defun KEY-PARAM (&key KEY-PARAM) KEY-PARAM) …Run Code Online (Sandbox Code Playgroud) 关键字符号有什么区别
:foo
Run Code Online (Sandbox Code Playgroud)
和引用的符号:
'foo
Run Code Online (Sandbox Code Playgroud)
两者都代表自己,可以用作标识符.我可以看到关键字符号主要用于命名参数,但我问自己是否也不可能使用带引号的符号来实现它?
换句话说:为什么我需要两者?
在Peter Seibel的书"Practical Common Lisp"中,我们可以找到一次非常复杂的宏的定义(参见页面底部http://www.gigamonkeys.com/book/macros-defining-your-own.html).
我在过去3周内第10次阅读这个宏定义,无法理解它是如何工作的.:(更糟糕的是,我不能自己开发这个宏,即使我理解它的目的以及如何使用它.
我对这个臭名昭着的宏观系统"衍生"特别感兴趣,一步一步!有帮助吗?
这个问题涉及编码约定,最佳实践和生产风格,关键任务Common-Lisp代码.我仔细阅读了Google的Common-Lisp样式指南(http://tinyurl.com/qfvnqcx),但没有找到任何明确解决我特定问题的内容,我通过示例表达,与C/C++,Java等形成对比.我还快速浏览了Github上的Common-Lisp代码库,我没有看到很多参数检查和中间值检查,我在C/C++,Java等中看到过.
在我的商店里,我们非常习惯于检查论点和其他价值观,并在论证不符合合同/先决条件等时提前退出.例如,考虑以下(设计,不完美,典型,但请 - 不要' t-waste-time-criticizing,micro-example,它预示着CL的例子):
ErrorCode o_symb_to_g_symb (char * symb, uint len)
{ if (len < 2) { return ERROR_LENGTH; }
if (symb[0] != 'O' || symb[1] != '!') { return ERROR_SYNTAX; }
char * result = (char *) malloc (len + 1);
if (NULL == result) { return ERROR_MALLOC; }
if (result != strncpy (result, symb, len + 1))
{ return ERROR_STRNCPY; }
result[0] = 'G';
return result; }
Run Code Online (Sandbox Code Playgroud)
这与Doug Hoyte的第67页"Let Over Lambda"的代码大致相同,只是在整个过程中尽可能地检查(http://letoverlambda.com/).
(defun o!-symbol-to-g!-symbol …Run Code Online (Sandbox Code Playgroud) common-lisp ×10
lisp ×7
comma ×1
enums ×1
funcall ×1
list ×1
macros ×1
memoization ×1
parentheses ×1
symbols ×1
syntax ×1