What does this Lisp code mean?

2019-08-15 14:29发布

In https://www.thc.org/root/phun/unmaintain.html Lisp is regarded such that "LISP is a dream language for the writer of unmaintainable code." and then proceeds to provide some code examples. These were regarded as somthing [that] "can literally be read and understood in about a second by anyone who knows lisp." on a recent Hacker News comment.

My question is, as someone with only a very small bit of experience in Clojure — what do they mean?

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

    I imagine that some of this syntax means something like the #(blah %) syntax from clojure, right?

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

    Mostly lost here. Defining a function called :-] that takes an argument < and checks if it's = to 2? Perhaps (<) is a partial function regarding less than?

3条回答
2楼-- · 2019-08-15 14:49

One speciality of Lisp and Common Lisp is that it does not have things like operators and a complex operator syntax. Identifiers are all symbols.

Symbols are delimited by a small amount of characters or whitespace. For example the closing parentheses ends any symbol before it.

So

((foo)bar)

and

((foo) bar)

are read the same.

Otherwise other characters like *, =, -, _, &, %, ... are valid characters of a symbol, even without escaping.

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

In practice you will see symbols like above, but not those mentioned in the question.

Really disturbing it gets when the read table is changed or when the numeric input is changed.

CL-USER 51 > (setf *read-base* 36)
36

CL-USER 52 > '(dear dad)
(625059 17221)

CL-USER 53 > (+ dear dad)
642280

or even

CL-USER 54 > (|SETF| |*PRINT-BASE*| 10)
10

CL-USER 55 > (+ dear dad)
DRL4

Also note that not every Lisp implementation allows functions with keywords as names:

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 > 
查看更多
Lonely孤独者°
3楼-- · 2019-08-15 14:59

Their point is just that the range of available identifiers is larger, but the semantic overloading of certain characters makes it easy to write code that looks like it might be doing something weird.

If you take a closer look at the first sample,

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

and rename the variable *<8-]= to a, and *<8-[= to b, we see that it's a pretty simple function:

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

In the second case, it's just making the point that since things like +, <, and so on aren't special operators or anything, they're just symbols with the names "+" and "<", you can use them as variable names. Again, we can rename variables and turn

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

into

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

This one is rather unusual, since the colon prefix indicates a keyword (a special sort of self-evaluating constant in Common Lisp), but SBCL seems to handle it:

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

Putting function definitions on keyword symbols is somewhat unusual, but it's not unheard of, and can be useful. E.g., see Naming functions with keywords.

查看更多
Summer. ? 凉城
4楼-- · 2019-08-15 14:59

That reminds me of a conversation we had on our work IM today, where one of my coworkers commented that this appears in the Sidekiq source:

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

The latest versions of the Scheme standards support Unicode, too, and in fact, the following code works in Racket and Guile (and probably most other Scheme implementations too):

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

And this Common Lisp version worked when tested with SBCL:

(defun ❨╯°□°❩╯︵┻━┻ ()
  (format t "Calm down, bro~%"))
查看更多
登录 后发表回答