【问题标题】:What does this Lisp code mean?这个 Lisp 代码是什么意思?
【发布时间】:2013-11-09 05:32:20
【问题描述】:

https://www.thc.org/root/phun/unmaintain.html Lisp 被认为是"LISP is a dream language for the writer of unmaintainable code." 然后继续提供一些代码示例。在最近的 Hacker News 评论中,这些被视为“can literally be read and understood in about a second by anyone who knows lisp.”。

我的问题是,作为一个在 Clojure 方面只有很少经验的人——他们是什么意思?

  1. (lambda (*<8-]= *<8-[= ) (or *<8-]= *<8-[= ))

    我想其中一些语法的含义类似于 clojure 中的 #(blah %) 语法,对吧?

  2. (defun :-] (<) (= < 2))

    大部分都在这里丢失。定义一个名为 :-] 的函数,它接受一个参数

【问题讨论】:

  • lambda 定义了一个函数,它接受两个参数并返回应用于两个参数的or 函数。您已正确地将第二部分中定义的函数识别为采用单个参数并与 2 比较是否相等的函数。
  • "2.(defun :-] (<) (= < 2)) 大部分都在这里丢失了。定义一个名为 :-] 的函数,它接受一个参数 (:-] 2) 是否返回 true?调用(:-] 'socksy) 是否返回错误?毕竟,您确实尝试过,对吗? :)
  • 尴尬的是,我没有,因为当时我没有安装 Common Lisp。现在我已经安装了它,并相应地在 REPL 中玩耍。 :)

标签: lambda lisp common-lisp


【解决方案1】:

他们的观点只是可用标识符的范围更大,但是某些字符的语义重载使得编写 看起来 可能在做一些奇怪事情的代码变得容易。

如果你仔细看看第一个样本,

(lambda (*<8-]= *<8-[= ) (or *<8-]= *<8-[= ))

将变量*&lt;8-]=重命名为a,将*&lt;8-[=重命名为b,我们看到这是一个非常简单的函数:

(lambda (a b) (or a b))

在第二种情况下,它只是指出,由于 +&lt; 等不是特殊运算符或任何东西,它们只是名称为 "+" 和 @987654332 的符号@,您可以将它们用作变量名。同样,我们可以重命名变量并转

(defun :-] (<) (= < 2))

进入

(defun :-] (a) (= a 2))

这个比较不寻常,因为冒号前缀表示一个关键字(Common Lisp 中一种特殊的自评估常量),但 SBCL 似乎可以处理它:

CL-USER> (defun :-] (<) (= < 2))
:-]
CL-USER> (:-] 2)
T
CL-USER> (:-] 3)
NIL

将函数定义放在关键字符号上有点不寻常,但它并非闻所未闻,而且很有用。例如,参见Naming functions with keywords

【讨论】:

【解决方案2】:

这让我想起了我们今天在工作 IM 上的一次对话,我的一位同事评论说这似乎是 in the Sidekiq source

def self.❨╯°□°❩╯︵┻━┻
  puts "Calm down, bro"
end

Scheme 标准的最新版本也支持 Unicode,事实上,以下代码适用于 Racket 和 Guile(可能也适用于大多数其他 Scheme 实现):

(define (❨╯°□°❩╯︵┻━┻)
  (display "Calm down, bro")
  (newline))

这个 Common Lisp 版本在使用 SBCL 测试时可以正常工作:

(defun ❨╯°□°❩╯︵┻━┻ ()
  (format t "Calm down, bro~%"))

【讨论】:

    【解决方案3】:

    Lisp 和 Common Lisp 的一个特点是它没有运算符和复杂的运算符语法之类的东西。标识符都是符号。

    符号由少量字符或空格分隔。例如右括号结束它之前的任何符号。

    所以

    ((foo)bar)
    

    ((foo) bar)
    

    读起来一样。

    否则其他字符,如 *、=、-、_、&、%、... 是符号的有效字符,即使没有转义。

    CL-USER > '(*foo =foo -foo _foo &foo %foo)
    (*FOO =FOO -FOO _FOO &FOO %FOO)
    

    在实践中,您会看到类似上面的符号,但不是问题中提到的那些。

    当读取表改变或数字输入改变时,真的很烦人。

    CL-USER 51 > (setf *read-base* 36)
    36
    
    CL-USER 52 > '(dear dad)
    (625059 17221)
    
    CL-USER 53 > (+ dear dad)
    642280
    

    甚至

    CL-USER 54 > (|SETF| |*PRINT-BASE*| 10)
    10
    
    CL-USER 55 > (+ dear dad)
    DRL4
    

    另请注意,并非每个 Lisp 实现都允许使用关键字作为名称的函数:

    CL-USER 1 > (defun :foo (a) (* a a))
    
    Error: Defining function :FOO visible from package KEYWORD.
      1 (continue) Define it anyway.
      2 (abort) Return to level 0.
      3 Return to top loop level 0.
    
    Type :b for backtrace or :c <option number> to proceed.
    Type :bug-form "<subject>" for a bug report template or :? for other options.
    
    CL-USER 2 : 1 > 
    

    【讨论】:

      猜你喜欢
      • 2011-05-28
      • 2011-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多