What does this Lisp code mean?
Asked Answered
S

3

1

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?

Selfimprovement answered 8/11, 2013 at 3:35 Comment(3)
The lambda is defining a function which takes two arguments and returns the or function applied to the two arguments. You have correctly identified the defined function in the second part as a function taking a single argument and comparing for equality with 2.Brownfield
"2. (defun :-] (<) (= < 2)) Mostly lost here. Defining a function called :-] that takes an argument < and checks if it's = to 2?" What happened when you tried it? Did calling (:-] 2) return true? Did calling (:-] 'socksy) return false? You did try it, after all, right? :)Pardoner
Embarassingly, I hadn't, since I didn't have Common Lisp installed at the time. Now I have installed it, and am playing around in the REPL accordingly. :)Selfimprovement
P
7

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.

Pardoner answered 8/11, 2013 at 3:40 Comment(2)
Some discussion about keyword-named functions: xach.livejournal.com/301076.htmlPerform
@LarsBrinkhoff Good find! I added a link in my answer.Pardoner
D
3

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~%"))
Demo answered 8/11, 2013 at 3:53 Comment(0)
B
3

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 > 
Ballance answered 8/11, 2013 at 9:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.