标签: common-lisp

如何在Lisp中记忆递归函数?

我是Lisp的初学者.我正在尝试记忆递归函数来计算Collat​​z序列中的项数(对于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 memoization

18
推荐指数
1
解决办法
4345
查看次数

Common Lisp相当于C枚举

我想学习一些Lisp语言(Common Lisp的)最近,我不知道是否有给定的数字,就像你可以在C通过枚举做一个名字的一种方法.

我不需要枚举的完整功能集.最后我只想有快速可读的代码.

我已经尝试了全局和小函数,但总是伴随着性能的降低.只需将数字插入代码总是更快.

lisp enums common-lisp

18
推荐指数
3
解决办法
4878
查看次数

如何在Common Lisp中拼接到宏外的列表?

说我有一个函数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

18
推荐指数
1
解决办法
3458
查看次数

如何删除LISP中的嵌套括号

如何在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 common-lisp parentheses

18
推荐指数
6
解决办法
1万
查看次数

使用两个反引号和逗号,Common Lisp

我正在学习常见的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)

仅使用列表和'?

syntax list common-lisp comma

18
推荐指数
1
解决办法
4064
查看次数

为什么我们需要在Lisp中使用funcall?

为什么我们必须使用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,因为它会被遮蔽,但这不是问题.

lisp common-lisp funcall

18
推荐指数
2
解决办法
7748
查看次数

关键字如何在Common Lisp中运行?

问题不是关于使用关键字,而是关于关键字实现.例如,当我使用关键字参数创建一些函数并进行调用时:

(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)

lisp common-lisp

18
推荐指数
1
解决办法
9205
查看次数

关键字符号和带引号的符号有什么区别?

关键字符号有什么区别

:foo
Run Code Online (Sandbox Code Playgroud)

和引用的符号:

'foo
Run Code Online (Sandbox Code Playgroud)

两者都代表自己,可以用作标识符.我可以看到关键字符号主要用于命名参数,但我问自己是否也不可能使用带引号的符号来实现它?

换句话说:为什么我需要两者?

lisp symbols common-lisp

18
推荐指数
2
解决办法
1465
查看次数

了解如何实现一次性lisp宏

在Peter Seibel的书"Practical Common Lisp"中,我们可以找到一次非常复杂的宏的定义(参见页面底部http://www.gigamonkeys.com/book/macros-defining-your-own.html).

我在过去3周内第10次阅读这个宏定义,无法理解它是如何工作的.:(更糟糕的是,我不能自己开发这个宏,即使我理解它的目的以及如何使用它.

我对这个臭名昭着的宏观系统"衍生"特别感兴趣,一步一步!有帮助吗?

lisp macros common-lisp practical-common-lisp

17
推荐指数
2
解决办法
2321
查看次数

用于参数检查和其他偏执狂的常见Lisp习语?

这个问题涉及编码约定,最佳实践和生产风格,关键任务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)

design-by-contract common-lisp

17
推荐指数
1
解决办法
949
查看次数