[ art / civ / cult / cyb / diy / drg / feels / layer / lit / λ / q / r / sci / sec / tech / w / zzz ] archive provided by lainchan.jp

lainchan archive - /λ/ - 15234

File: 1459115716832.png (42.72 KB, 225x300, mwl_00_1.jpg)


Hi /lainons/


I saw this posted around here, I figured you guys might like a translation (and I need to practice my moonrunes).

It looks from the table of contents like it's a pretty basic tutorial, so you probably won't get much out of it if you're already writing crazy lisp macros. But maybe it'll be useful if you're a complete beginner just looking to be exposed to the language, and are into weeb shit ~

(Feel free to tell me my translation's shit and offer corrections)


1. Thank you
2. Most lispers here are beginners actually


File: 1459116138768-0.png (123.17 KB, 150x200, mwl_00_2.jpg)

File: 1459116138768-1.png (112.97 KB, 150x200, mwl_00_3.jpg)

thank *you*

the guide is split between more character/story-heavy manga sections, and more detailed technical texts.

Wakana: Suzu! Come hang this up
"UMA Research Club Members ??Gathering"
[TN: UMA = Unidentified Mysterious Animal]

Suzu: What? Me?
Wakana: Yes! It's because you have the highest UMA encounter rate!

Suzu: I'm going now...
Rikka: Pay attention, okay?

???: Meow

Suzu: Mirin...

Suzu: Huh?

???: Meooow!

Mirion: Meooow!
Lico: Waaaa!

Suzu: Hya~

Lico: Uhhh..
Suzu: Are you okay?

Lico: I'm fine
Suzu: That was a big noise though, right?


File: 1459116227959-0.png (126.91 KB, 150x200, mwl_00_4.jpg)

File: 1459116227959-1.png (134.74 KB, 150x200, mwl_00_5.jpg)

File: 1459116227959-2.png (66.1 KB, 150x200, mwl_00_6.jpg)


Lico: I'm fine!
Suzu: But..
Lico: It's just a scratch!
Suzu: Okay..

Lico: By the way, do you know that cat?
Suzu: You mean Mirin, the communal cat?

Lico: Can I pet it?
Suzu: Yeah

Lico: But excuse me. I'm Lico.
Suzu: Ah, Nice to meet you. I'm Suzu Kanzaki.

Lico: Suzu! The word is in danger, we have to do something!
Suzu: Is it because you just hit your head back there?
Lico: NO!

Lico: What I mean is,
Lico: I'm just a god that happened to pass by, right?
Lico: Already it will happen soon. This town's rising water levels have triggered the Earth's submergence
Suzu: What??

Lico: For now, Suzu,
Lico: Take this.

Suzu: LISP?
Suzu: This is a technical book. What am I supposed to do with it?

Lico: This is a unique item that escaped that cat's GetREWARS
[TN: I have no idea]
Lico: Take this book as a token of my gratitude...

Lico: And use it!
Lico: Will you be able to learn from the past somehow and find a way to do something!?

Suzu: But this is a computer book...
Lico: Suzu...If you try your best, you can take down a tiger with a sponge, right?

A Manga Guide to Lisp: Introduction


File: 1459116374152-0.png (133.21 KB, 160x200, mwl00_h.jpg)

File: 1459116374152-1.png (96.94 KB, 160x200, mwl_01.jpg)

File: 1459116374152-2.png (135.5 KB, 160x200, mwl_02.jpg)


While Lisp has many meanings, here I intend to cover Common Lisp. Nonetheless, the foundations of the different kinds of Lisps are similar, so please don't say things like "I want to do Scheme, so I will go." > <

The rest of this page will briefly cover how to install a Lisp implementation. If you've already prepared your environment, please skip this section.

*Implementation Installation*
There are many implementations of Common Lisp. The only I recommend to beginners is CLISP, because it runs on many platforms, and has an easy-to-use interactive environment. On Windows, you can download the binary from the win32 link on the official site [1]. On Mac OS X, *BSD, Linux, etc, you should be able to install it from your package manager.

To the people who say "In any case, I want to write high-speed running programs!", I recommend SBCL. If you try your best, you can write programs with speed that won't even lose to C. For more details, please see the official site [2].

[1] http://clisp.cons.org
[2] http://www.sbcl.org

Parentheses are Friends
Suzu: Lisp has lots of parentheses, doesn't it

Lico: Parentheses are friends, don't worry
Suzu: I don't really get it, but

Lico: Parentheses wrap everything up
Lico: They have such tenderness ~

Suzu: If it's friends...it can't really be helped
Lico: Uh huh

Does everybody like parentheses? Lisp programs have a great number of parenthese appearing in them. As opposed to the many people who accept Python and Haskell, which have few paretheses and meaningful indentation, there are unfortunately many who reject Lisp with its conspicious amount of parentheses. The appearance of many parentheses might be difficult to approach, but in friends, content, not appearance is what's important.

;;; a program that searches for the factorial of n
;;; aren't there many busy friends?
(defun fact (n)
(cond ((= n 0) 1)
(t (* (fact (1- n))

Decreasing Friends
Lico: In LISP, 1+2 is written as (+ 1 2)
Suzu: (The parentheses came out so quickly)

Lico: 1+2+3 is like this!
Suzu: Isn't this already too many parentheses?

Lico: Like this, for Suzu!
Suzu: If it's this, it's easy to read!

Suzu: But our friends decreased

Since many Lisp implementations provide an interactive environment, you can teest Lisp right away. Just write the program you want to run and press Enter. It's easy, don't you think? If you input (+ 1 1), 2 will come out. If you input (+ 1 2 3), 6 will come out. (+ (+ 1 2) 3) is also the same, but its easier to read with less parentheses. More friends isn't always better, right?

;; When calculating 1+2+3, there are 2 situations to consider,
;; adding 1 and 2 first, and adding 2 and 3 first.

;; calculating (1+2)+3
(+ (+ 1 2) 3)

;; calculating 1+(2+3)
(+ 1 (+ 2 3))

;; When the sum is the same regardless of where you
;; start from, you can write it like this
(+ 1 2 3)


File: 1459116482004-0.png (132.67 KB, 160x200, mwl_03.jpg)

File: 1459116482004-1.png (142.05 KB, 160x200, mwl_04.jpg)


Inland Sea
Lico: For subtraction, multiplication, and division,
Lico: If you use - * / then it's the same as addition

Lico: 2 * 3 * 4 * 5 is
Suzu: It's exactly 120

Suzu: (* 8888888889 9999999999) also gives an answer, right!
Lico: That's excessive...

Lico: LISP is different from commercial calculators in that area, since it's generous, so it can display even very big numbers!

You can freely try easy calculations like this. 5*4/2 becomes (/ (* 5 4) 2). In Lisp you can also use fractions. You can calculate 8/6 like (/ 8 6), and the result is 4/3 (it will reduce a fraction to its lowest terms!). By the way, if you try and do the calculation that Suzu did in the manga (88...89 * 99...99), you can get a good feeling.

;; ※「;」から行末までは無視されるので
;;   プログラムの横に結果を添える
;;   (「;」以降は書かなくて良い)

;; * Since everything from ";" to the end of the line is ignored,
;; it adds the effect of the program on the side.
;; (It's okay not to write anything after the ";")

;; 1+1/3
(+ 1 (/ 3 3)) ;=>結果は4/3

;; using decimals instead of fractions
(float (+ 1 (/ 1 3))) ;=>1.34

;; the square root of two
(sqrt 2) ;=>1.4142135

;; you can also use complex numbers
(sqrt -1) ;=>#C(0 1)

Ultra Ancient Civilization
Suzu: In the end, what can you do with LISP?
Lico: You can do anything

Lico: Make games or OS's, or save the world.

Suzu: How can you save...
Lico: It's because LISP is an OOPArt that ancient people left behind.
[TN: OOPArt = Out-of-place artifact, refers to a historical object found in an unusual context, "that could challenge conventional historical chronology"]

Lico: Since in Japan in Kyoto, there's traces of the ancient LISP civilization, but there's also traces of LISP being used on mars!
Suzu: Wh-what

For historical reasons, there are many introductions of Lisp as "a language for AI", but actually you can use it for many different purposes. There are also people who say "Lisp is only used by one type of person", but in fact an expansive class, from middle schoolers to old people use it. Ah, if you know any elementary schoolers who are using Lisp, please get in touch.

;; calculations with fractions are exact
(+ 1/3 1/3 1/3) ;=>1

;; calculations with decimals have measurement error
(+ 0.3 0.3 0.3) ;=>0.90000004

;; the result of dividing whole numbers is a fraction
(* (/ 1 123) 123) ;=>1

;; the result of dividing decimals is a decimal
(* (/ 1.0 123.0) 123)



More to come soon! (I'll try and remember the code tags too)


Awesome stuff. Even though I already know Lisp this would be a fun introduction to the language for newbies.

I look forward to seeing more


You may be a beginner, but I would challenge the assertion that most Lispers here are beginners.

Thank you. This is interesting.


That little beginner's guide is kinda cute. That's fun.


File: 1459173347841.png (2.16 MB, 200x200, the_manga_guide_to_lisp.pdf)

Thanks for translating, Lainon.


Pretty cool. On page 10 there's an unclosed parentheses in the comment.


you and OP are the kinds of people that make this world a better place


thanks for this!

and thanks Lainon!

part 2 is up next


File: 1459263395966-0.png (203.6 KB, 150x200, mwl_05_1.png)

File: 1459263395966-1.png (159.61 KB, 150x200, mwl_05_2.png)


Lico: To get back the thing that cat took, Cudders are important!

Lico: Cudders are round, with a fleecy body and long tail.
Suzu: Woah!

Suzu: Where are they?
Lico: We're gonna catch one now
Suzu: ....

Lico: To catch a cudder, if we put some bread in the center of this pentagram like this, it'll be done.
Suzu: Very eerie...

Lico: They gather around the bait, and then we'll capture them.
Lico: ...usually.
Suzu: What's the pentagram?

Lico: Except the cudders aren't coming to the border?
Lico: Huh?

Suzu: ...
Lico: ...

Lico: car...

Lico: I made a spelling mistake!?
Suzu: Don't give up!

Lico: Since we can't really trust the trap, let's just go find one!
Suzu: I'm starting to not really trust Lico


File: 1459263478761-0.png (198.72 KB, 150x200, mwl_05_3.png)

File: 1459263478761-1.png (132.72 KB, 150x200, mwl_05_4.png)


[How to catch a cudder]
① Put some bread in the place where there seem to be cudders .... then it's this way. That's all!

Lico: Ahh, an unseasonable Japanese wolf-
Wolf: Wahaha

Lico: So I'm entrusting the rest to you, Suzu. (It's scary!)
Suzu: Cudder-catching is difficult... though, isn't the Japanese wolf extinct?

??: Something's bitten.

Lico: It's a cudder
Cudder: I wasn't caught by this bait
Suzu: You were caught!

Suzu: Anyway, it's good that we found a cudder

Lico: We found a cudder so soon, too

Suzu: Huh?
↑: Untrustworthy trap
Lico: What should we do.....

Cudder: Bread, bread

Manga Guide to Lisp: Part 2



I'll post the tutorial part later today or maybe tomorrow, depending on how fast I can finish it. (and hopefully with fewer spelling mistakes!)


This is certainly not how I imagined the decrement register.


File: 1459343359290-0.png (133.21 KB, 160x200, mwl00_h.jpg)

File: 1459343359290-1.png (117.72 KB, 160x200, mwl_06.jpg)


*Programs are Expressions*
In Lisp, programs (or more correctly, parts of programs) are called "expressions". Until you are experienced, it might be good to replace "expression" with "program" while reading. The important property of expressions is that the parts composing an expression are also expressions (subexpressions). Since (+ 1 (+ 2 3)) is an expression, one of its parts, (+ 2 3), is also an expression. Moreover, even 1 and 2 are expressions.

*Execution is Evaluation*
In Lisp, running a program is referred to as "evaluating an expression". In other words, running the program (+ 1 2) would be called "evaluating the expression (+ 1 2)".

*The Result of Execution is the Value of an Expression*
If you evaluate the expression (+ 1 2), you will get the result 3. This result of executing the program is called "the value of the expression (+ 1 2)".

*Subexpressions also have Values*
Expressions have values, but subexpressions also have values. Considering the expression (+ 1 (+ 2 3)), the subexpression (+ 2 3) has the value 5, and the expression 1 has the value 1. If you input 1 into your interactive environment, you can confirm that the value of 1 is 1.

Lico: In Lisp, there's a container called cons that you can put two things in.

Lico: Make a cons with 1 and 2 in it with (cons 1 2)
Suzu: It becomes the value (1 . 2), right?

Lico: To take out the first thing in a cons, use car.
Suzu: car... why a car?

Lico: Because cars drive on the left side of the road.

A cons is a box with two items in it. The expression (cons 1 2) makes a cons with 1 and 2 in it. This displays as (1 . 2). Though there are parentheses here, please note that this is not an expression (program), but a value (result of execution). The left side of an expression is called the car, and you can take its item out using car.

;; make a cons
(cons 1 2) ;=>(1 . 2)

;; take out the car of a cons
(car (cons 1 2)) ;=>1

;; (1 . 2) is not a valid expression
(1 . 2) ;=>ERROR!


File: 1459343581239-0.png (127.58 KB, 160x200, mwl_07.jpg)

File: 1459343581239-1.png (87.96 KB, 160x200, mwl_08.jpg)

File: 1459343581239-2.png (128.25 KB, 160x200, mwl_ss01.jpg)


Many Car Accidents
Lico: To take the second item out of a cons,
Lico: use cdr

Lico: Like this
Suzu: ...it pretty much opens it, but why cdr?

Lico: Of course, it's because a cudders is a vehicle that drives on the right side of the road.

Lico: Cudders are the superior vehicle ridden by the people who mastered Lisp
Suzu: Cudder!

The right side of a cons is called the cdr, and you can take out its item using cdr. Since the cdr of the cons made with (cons 1 2) is 2, the value of (cdr (cons 1 2)) is 2. Incidentally, there is an urban legend that "car" is an abbreviation of "contents of the address part of register", and "cdr" of "contents of the decrement part of register".

[TN: "urban legend" or not, afaict this is in fact where "car" and "cdr" come from]

(cdr (cons 1 2)) ;=>2

(cons (cdr (cons 1 2)) 3)
;=>(2 . 3)

(cdr (cons (cdr (cons 1 2)) 3))

(car (cons 1 2)) ;=>1

(car (cons (car (cons 1 2)) 3))

Suzu: Since there are a lot of cudders, should we hand them out to others?
Lico: A lot of cudders...

Lico: Now that you mention it, you can also put a cons in a cons, you know.

Suzu: In that case, to take out a cons in a cons, I wonder if you use car or cdr twice
Suzu: It's full of cudders..

Cudder: That's right!
Lico: If the cudders multiply, nobody is happy...

If you evaluate expressions like (cons (cons 1 2) (cons 3 4)), you can make conses with conses in them. Of course, you can also make conses with conses with conses in them. If it's hard to understand, it might be good to draw a picture.

(car (cons (cons 1 2)
(cons 3 4)))
;=>(1 . 2)

(cdr (cons (cons 1 2)
(cons 3 4)))
;=>(3 . 4)

(cdr (cdr (cons (cons 1 2)
(cons 3 4))))

Cat Senpai
Wakana: Is that a white tiger?
Rikka: Isn't it cute?

Wakana: I'll capture one for you, so please lure out a tiger!
Rikka: What a nice kid...

Rikka: Meoww~

Wakana: Just like a cat!
Rikka: Because it is a cat
Suzu: It's true..

White, like a white tiger. White, like a blank space. In the last section, we used an expression written on multiple lines. Since lisp treats multiple consecutive spaces, tabs, or newlines as one space, when there is a lot of stuff between parentheses you can add some newlines to make it easier to read.

Lico: Aerobraking!

;; calculating (1+2)*(3-4)*(5+6)
;;on one line
(* (+ 1 2) (- 3 4) (+ 5 6))

;;one multiple lines
(* (+ 1 2)
(- 3 4)
(+ 5 6))


it is quite cute, though! ^3^

in the next installment, we'll learn about defining functions!


Monitoring. Thanks OP


File: 1459365567231.png (3.43 MB, 200x200, the_manga_guide_to_lisp.pdf)

Added names.
Changed font to Anime ACE (a for non-profit-use manga-like font)

Tell me if I fucked it up.

I'd say that's going a bit too far.


File: 1459415459695.png (55.46 KB, 134x200, lisp_girl.jpg)

Ahhh! I was hoping that someone would do a redraw with the translated text, and it actually happened. It looks pretty well-done as well. Nice work.


This is fantastic, great job, this is awesome!


File: 1459489814319.png (72.03 KB, 167x200, 1392776482850.gif)

Whoa, good job. Both of you.


File: 1459552771097.png (57.96 KB, 200x197, reallyconfusinganatomy.jpg)

thanks lainon, this is awesome!

more thanks lainons!


File: 1459552935367-0.png (103.77 KB, 150x200, mwl_09_1.jpg)

File: 1459552935367-1.png (123.34 KB, 150x200, mwl_09_2.jpg)

I'm really not confident in my translation for this section, so if something doesn't make sense, it's probably because I fucked up.  ごめん!


Suzu: I'm back

Rikka: So what have you been picking up these days?

Suzu: How did you know!!
Rikka: Probably a half, didn't you just tell me?
Wakana: What did you pick up?  A bluetongued lizard?

Suzu: Uh...a god?
Cudder: I'm never unable to eat even rotten oranges...

Wakana: Amazing!  A green tentacle god!
Cudder: A word for a person
Wakana: What place are you the evil god of?

Lico: That's not an evil god, it's a cudder!!
Wakana: Who are you?

Rikka: Oh, nice to meet you, god.
Suzu: How do you know Lico?

Rikka: Well, since it's half, right?

Wakana: Amazing!  A little girl and god!  I wonder what kind of blessing this is?
Wakana: A god came~
Lico: Very calm


File: 1459553002584-0.png (127.05 KB, 150x200, mwl_09_3.jpg)

File: 1459553002584-1.png (81.24 KB, 150x200, mwl_09_4.jpg)

I don't know anything about Dobon...


Wakana: All right!  One card!
Wakana: One step away!

Lico: Dobon!!

Wakana: Sweet!
Dobon Returned

Lico: ...how were both cards 13..
Suzu: I wonder if it's because she's that kind of kid? [??]


Rikka: Okay, okay, don't gods eat tofu?

Lico: Why tofu?
Rikka: How is it?

Lico: Ordinary~

Wakana: Speaking of which, what did you come here to do, Lico?

Lico: Well, actually...

A Manga Guide to Lisp

Suzu: Part 3


File: 1459553651122-0.png (127.32 KB, 160x200, mwl_10.jpg)

File: 1459553651122-1.png (132.19 KB, 160x200, mwl_11.jpg)


Suzu: Putting in the same expressions over and over again is kind of difficult, you know?
Wakana: Shake!

Lico: That's why you should use functions!

[TN: '5jyo' means 5th power]

Lico: If you write what you want to do in a function, then wrap the function's name in parentheses

Suzu: Functions do their work when they are surrounded by friends...
Lico: I love friends!

When you want to do the same calculations over and over, you should make a function.  Functions are made like this:
(defun function-name (function-arguments)
When you put the function's name in parentheses, "what-you-want-to-do" will be evaluated.  A more detailed explanation will be later, but let's turn to look briefly at how to use functions.

;;; a function the finds the area of a square
(defun square (x)
  (* x x))
;;; a function that finds the area of a triangle
(defun triangle (w h)
  (/ (* w h) 2))
;;; a function that finds the area of a circle
(defun circle (r)
  (* r r pi))

;; making functions work
(square 4)      ;=>16
(triangle 5 6)  ;=>15
(circle 2)      ;=>12.566

Lico: Putting a function's name in parentheses and making it work...
Lico: is called that.

[calling a function]
(5jyo 2) is calling 5jyo

Lico: Now, attaching a number...
Lico: is called that.

(5jyo 2)'s argument is 2

Lico: And then the result of a function call...
Lico: is called that.

[a function's value]
(5jyo 2)'s value is 32

Cudder: "The return value of a function" is also called "the value that the function returns" [TN: I promise this sounds less dumb in Japanese]
Suzu: I'll take the above three panels and make vocabulary cards~
Suzu: oh
Cudder: Right!

Let's look again at how to make a function.
(defun function (parameter-1 parameter-2 ...)
Next let's look at a function invocation.
(function argument-1 argument-2 ...)
When you evaluate this expression, first the arguments are evaluated.  Then, the actual function is called, and the function's body is evaluated.  When this happens, the values of the parameters become the values of the arguments.

;;; make a function called add
;;; add has parameters x and y
(defun add (x y)
  (+ x y))  ;=> ADD

;; pass the parameters 1 and 2 to add
;; in an environment with x's value being 1, and y's being 2,
;; (+ x y) is evaluated, and the function's value becomes 3
(tasu 1 2)  ;=>3


File: 1459553819644-0.png (123.88 KB, 160x200, mwl_12.jpg)

File: 1459553819644-1.png (138.07 KB, 160x200, mwl_13.jpg)

File: 1459553819644-2.png (101.63 KB, 160x200, mwl02_h.jpg)


  Octopus also live here
Lico: The things you've used up until now, like + and cons, are also functions

Lico: Function names and arguments are wrapped in parentheses
[function] [arguments]
Suzu: Ah~

Suzu: Huh?
Suzu: The number of arguments that + takes isn't fixed?
[number of arguments] [function call]

Lico: That's because + is a big-hearted function, right
Cudder: I'm small-hearted!
Suzu: ....

The things appearing so far, +, -, *, /, float, sqrt, car, and cdr are all functions.  Many functions take a fixed number of arguments.  For example, cons takes 2, and car and cdr each take one.  However, + and * take 0 or more, and - and / take at least one argument.  The details of making functions like this will come later.

;; a slightly different example
(+)   ;=>0
(*)   ;=>1
(- 2) ;=>-2

;;; a function that takes 1 or 2 arguments
(defun inc (x &optional (y 1))
  (+ x y)) ;=>INC

;; passing 1 or 2 arguments
(inc 5)    ;=>6
(inc 6 7)  ;=>13

  ヴェ◯タース [TN: I have no idea what this is]
Suzu: Since things wrapped in parentheses are a function call,
Suzu: defun is also a funcion?

Lico: defun actually isn't a function.  There are special forms that don't evaluate their arguments.
Lico: Tiger~

Lico: Look at this expression and try to understand
Lico: It evaluates its arguments, right.

Lico: defun, which doesn't do this, is surely special-
Cudder: I'm quite normal!
Suzu: ....

In function call expressions, the arguments (in order from the left) are evaluated, but in defun expressions the arguments are not evaluated.  This is because defun is not a function.  Other than functions, the things that are enclosed in parentheses include special operators and macros.  These latter two things don't evaluate their arguments.  defun is a macro.

;; the function print, which displays its argument and then returns it
;; in addition to its value, it prints 3
(print (+ 1 2))  ;=>3

;; see that 3 and 7 are displayed by print,
;; and the arguments of the expression are evaluated
(+ (print (+ 1 2))
   (print (+ 3 4)))  ;=>10

;; the special operator quote returns its arguments "unchanged"
(quote (+ 1 2))  ;=>(+ 1 2)

Cudder: Pneumatic Trough
[please take freely]

Cudder: about 3!

*Using Files*
Once you've made a function once, you can use it many times, but after you restart your environment, you'll have to remake the function.  If it's difficul to input the same function so many times, you should use a text editor to write the function into a file, then load it from your environment.

;;; /usr/home/zick/test.lisp
(defun add (x y)
  (+ x y))

(defun inc (x &optional (y 1))
  (+ x y))

Once you've created a file as mentioned above, when you evaluate the expression
(load "/usr/home/zick/test.lisp")
you'll be able to use the functions add and inc.  On windows, remember to that it's important to input "\\" for "\".



I don't know where all this wide text is coming from, sorry guys > <


This is actually a pretty decent intro to Lisp, thanks again for the translation. I didn't know cudders could talk.


File: 1459605591327.png (5.12 MB, 200x200, the_manga_guide_to_lisp.pdf)

I didn't proof-check this one.
> there are 'bout 24 sub-parts with 3-6 images per part.
Hoping I haven't bitten off more than I can chew here. This last part took me 'bout 2 hours and 30 min.

I've also noticed the file size increasing drastically, if it keeps going we'll probably end up with a file over 50MB.
Not sure what I feel about that.

Also have my doubts about using this Anime ACE font for code-parts as well, the "&" looks weird.



If you're okay with the font besides the way it shows in code, can you just change the font for the code parts?


Sure, to what?


Appreciating the effort put into this, it's really cute

Maybe try running it through a PDF "compression" tool. If saved incorrectly (the default in most apps) PDFs are way bigger than they need to be.
If not maybe just release it as a zip of jpegs like a manga release).


File: 1460136006273-0.png (112.94 KB, 150x200, mwl_14_1.jpg)

File: 1460136006273-1.png (126.69 KB, 150x200, mwl_14_2.jpg)

Sorry for the wait. My moonrunes aren't quite as good as I want them to be...

the bit in this chapter concerning people being able to see Lico may be mistranslated; I'm hoping I caught the gist of it though.


[ Suzu meets Lico while chasing a cat. ]

[ The world is in trouble and your power may be important! Lico was a god. ]

[ In order to recover the item that will save this town, Lico caught some cudders. ]

[ And then...LISP. There was LISP ]

Reference Book

Rikka: That was a summary of a Manga Guide to Lisp. Well, see you tomorrow~

[ The Next Day ]

Aya: Yesterday, weren't strange creatures being caught?
Aya: Were they UMAs?
Wakana: Ah, that's right

Cudder: Nu
Cudder: Would that be this kind of face?

Aya: No!!
Lico: Cudder!
Cudder: This face...

Wakana: Lico, you really stand out at school during lunch time!
Lico: You noticed too, Wakana?
Lico: Just in case, I put up a border so that no one higher than third-year, except Suzu, can see me

Wakana: .....
Wakana: A memory of being enveloped in an orange light...

Wakana: Sorry for spacing out there!
Aya: Uwa! Uza!!


File: 1460136093238-0.png (113.63 KB, 150x200, mwl_14_3.jpg)

File: 1460136093238-1.png (97.58 KB, 150x200, mwl_14_4.jpg)


Cudder: Sorry for being cute~
Lico: Which is cuter?

Lico: Aya-tan
Aya: What's "tan"!

Wakana: Elementary schoolers can see you, but if a bad situation makes you drink medicine...
Aya: Nooo! It's a misunderstanding, so stop it!

Wakana: Even so, since Aya has the ability to see the supernatural, even though her grade is such, I think she can see you.
Aya: Sorry...

Lico: That was unexpected.
Wakana: Yeah...
Aya: Can't you use your head and do something...

Wakana: Oh! It was compatible after all~

Wakana: This should do for now
Aya: Compatible...

Lico: But anyway, that cat came here
Wakana: The one Suzu was chasing?
Lico: Yeah

Wakana: So, are you okay?
Aya: I wonder if that cat is okay...
Aya: Do you mean Kanzaki?



If worse comes to worst, you could always just split it up into 3 or 4 "volumes"


File: 1460138846786-0.png (144.39 KB, 160x200, mwl03_h.jpg)

File: 1460138846786-1.png (127.4 KB, 160x200, mwl_15.jpg)

File: 1460138846786-2.png (136.02 KB, 160x200, mwl_16.jpg)


*Expressions and Values*
One of Lisp's interesting traits is that you can make "programs that write programs". This feature is called a "macro", and to demonstrate its power, this section will present an easy way to use eval. eval is an expression-evaluating function. For more details, please read the sequal manga.

*read and eval*
Before they are loaded into your interpreter, expressions are just strings of characters. When they are loaded into your interpeter, they are turned into a unique internal representation. Then, this is evaluated. Sometimes people misunderstand and think that it evaluates strings of characters, so be please careful. Shortening your functions' names will not change their execution speed! Because of this, you can think of Lisp as evaluating lists. In fact, in Lisp there is the function read, which accepts input (strings of characters) and turns it into a list, and the function eval, which accepts and evaluates a list.

*Evaluating Input*
(print (eval (read)))
When the above expression is evaluated, the interpreter waits for input from the keyboard. If you input an appropriate expression, it will display its value.

Fountain of Wisdom
Wakana: What were you doing with Suzu yesterday?
Lico: We were talking about the LISP language.
Aya: Language?

Wakana: Programming language? My grandma told me the one that prints hello world!

Lico: Yep
Wakana: Oh~

Wakana: If you put a quotation mark, its value is itself?
Lico: Yup
Aya: Um, is what you're using now the Lisp language?

If you put a quotation mark in front of an expression, the expression becomes that value. In fact, the expression 'expr is an abbreviation for (quote expr), and quote is a special operator which returns its argument "without evaluating it". The value of 'helloword, helloworld, is called a symbol type (variety) value, while numbers and cons come out the same. Using a quotation mark is called "quoting".

Aya: In- In Japanese, please!

;; get a symbol
'lico ;=>lico
'suzu ;=>suzu

;; put symbols into a cons
(cons 'lico 'suzu)
;=>(lico . suzu)

;; a number has the same value when quoted
'1 ;=>1
1 ;=>1

Enter Egghead
Wakana: What do cudders eat?
Cudder: Actually, I don't like it that much
Lico: Mainly bread.

Aya: Lico, what is the quotation mark you were talking about?
Lico: You put them in front of parentheses.
[ This => ' ]

Lico: This expression evaluates to its value, like this, right
Aya: What's that called?

Wakana: The expression evaluates to a list, right~
Lico: Yep
Aya: Ah, too much!

You can also quote expressions that are wrapped in parentheses. These values are list type. Lists are either "the empty list, nil", or "a cons with a list in the cdr". Since recursive definitions can be puzzling, looking at an example might be easier to understand. nil is a special literal that represents the empty list, and its value is also nil.

;; a list with the empty list in its cdr
;; the ". nil" in (2 . nil) is omitted
(cons 2 nil) ;=>(2)

;; a list with a list in its cdr
;; here ". (" is omitted
(cons 1 (cons 2 nil) ;=>(1 2)
(cons '+ (cons 1 (cons 2 nil)))
;=>(+ 1 2)

;; the value obtained is the same as the value of the above expression
'(+ 1 2) ;=>(+ 1 2)


File: 1460138917844-0.png (117.45 KB, 160x200, mwl_17.jpg)

File: 1460138917844-1.png (118.86 KB, 160x200, mwl_18.jpg)


AT Field
Wakana: Can't you evaluate a list expression?
Lico: You can!

Lico: If you use this function, you can evaluate a value as an expression.

Wakana: That's an abbreviation of evaluation, right?
Lico: That's correct
Lico: Incidentally, evaluation is often called "eval-ing"
[TN: given that they are talking about Japanese jargon, there isn't much I can do here]

Wakana: No way!
Lico: It's true!

The function eval accepts a value representing an expression, then returns the result of evaluating it. In other words, eval's argument is an expression which evaluates to a value representing an expression. If eval's return value is a value representing an expression, you can use it as another argument to eval. This is very fun, right! Incidentally, the people around me normally say "eval".
[TN: This is referring to that japanese verb ebaru, as a slang shortening of "evaluation".

(eval '(+ 1 2))  ;=>3

'(cons '+
(cons 1 (cons 2 nil))))
;=>(+ 1 2)

(cons 1 (cons 2 nil)))))

Coincidence Senpai
Aya: Ow!

Rikka: Are you okay?
Aya: Uhh..

Aya: Sorry, I'm just a dumb kid... I can never get understanding...
Rikka: What a coincidence~
Aya: Wha?

Rikka: Me too~
Rikka: It's no problem..

There seem to be a lot of people confused by discussions on quote and eval. However, don't worry if you don't understand immediately. If you start getting tired, you should draw a picture of the cons. If you get good at drawing pictures of expressions' conses, you will surely start understanding. For how to draw a picture, please see Section 1.2

(cons 'b nil)  ;=>(b)
(cons 'a (cons 'b nil))
;=>(a b)

(cdr (cons 'a (cons 'b nil)))
(cdr '(a b) ;=>(b)

(car '(quote a)) ;=> quote
(car ''a) ;=> quote



until next time, where we will learn about if!


File: 1460150974214-0.png (556.35 KB, 200x200, Cat.png)

File: 1460150974214-1.png (397.93 KB, 150x200, girl-a.png)

I could redraw it in a slightly sharper style if anyone's interested as I have a lot of free time ( uni work is still on "introduction to programming" while I'm learning Forth and trying to implement it in ASM on the LMC ).

Also examples of what style I'll use (here's two I made earlier)...


Oh, yes, please do this! Maybe also create a buttcoin wallet so we can reward you for your efforts.

However, the original artist might think it pretty egregious if he saw this and try to hunt you down, so be careful.


It will take some time (need to setup the RPi with the tools again) and I would be fine with source code (forth/asm), pdfs/papers (forth/asm/EE because I'm useless at it) and/or circuit diagrams for register & stack machines if you want to give something.

If you want to send bitcoin I can set it up ( would be used on books ) but learning resources are really what I need ( uni only have 2 books on Haskell and it's on the other campus... nothing on Forth, ASM on anything other than i386 and one book on lisp... and I've spent most of my grant on books ).


File: 1460157613243.png (978.22 KB, 200x150, 2016-04-08 23.59.34.jpg)

Something like this? Or should I try the slightly more serious style?
( messed up the nose and need to buy a new pen... today just isn't my day )


Shrinking it with
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.pdf input.pdf
worked perfectly, thanks for the suggestion, I'll do that in the next posts.

I'll try putting in these next pages in tomorrow, again thanks for translating. I've been working all weekend.

Also, glittergirl, I was wondering if you ever hang out in the IRC?


File: 1460387059488.png (1.5 MB, 200x200, the_manga_guide_to_lisp.pdf)

1h, 40m


File: 1460410075716-0.png (143.54 KB, 150x200, mwl_19_1.jpg)

File: 1460410075716-1.png (109.4 KB, 150x200, mwl_19_2.jpg)


[ A few days ago ]

Nazuna: We'll settle this meaningless dispute
Nazuna: If I win, you give me the that thing and the cudder

Lico: And if I win, you'll leave this place!
Nazuna: Agreed

Nazuna: Go full throttle, Mirin!
Mirin: Nyalright!

Cudder: Ah, isn't that a white cudder? Isn't it impossible?
Lico: The flavor doesn't matter..

Nazuna: Whoever is in the lead by sunrise wins!
[ White Cudder
* Rare
* High Power
* Paper Lantern ]
[ Yellow Cudder
* Lemon Flavor
* Light x2 ]


Lico: Do over!

Lico: That wasn't a fair race!
Nazuna: I refuse!
Nazuna: It should be judged by the rules. Furthermore-
Nazuna: Your cudder also can't be a partner to someone who doesn't have the thing. [TN: not sure about this]

Mirin: What a pitiful loser meow~

Mirin: If you can catch me, you can have a rematch meow~
Nazuna: Your own behavior- !

Mirin: Nyalright!

Mirin: Meow'll never be caught by this slowpoke~
Lico: Mmmm


File: 1460410150420-0.png (122.12 KB, 150x200, mwl_19_3.jpg)

File: 1460410150420-1.png (107.5 KB, 150x200, mwl_19_4.jpg)


[ And so, present day... ]
Mirin: Mmmm

Suzu: Mirin~
[ Small-type UMA Capture Case (U Research Equipment) ]

Lico: As expected of you, Suzu!
Suzu: Why do you have those clothes, Lico
Lico: And what about your head, Suzu?

Suzu: Well,
Rikka: This should be helpful for catching a cat, right?
Suzu: is what she said

Lico: Well,
Lico: Now that I've caught you, what next?

[ Byon! ]

Suzu: ?

Nazuna: As promised, let's prepare for the rematch.
Suzu: Wa, an amazing cat came!
Lico: It's the boss!

Nazuna: Hmm...

Nazuna: If your partner is a youkai cat, it's no use.
Mirin: N-nyeah~, it's nyo use~

Nazuna: In three days, let's make a final decision by cudder racing.

Manga Guide to Lisp 05

Nazuna: Farewell!

Lico: Suzu, you're the youkai cat
Suzu: This?!



I lurk on IRC, but I don't really follow the channel that much...


Is it silly that I am upset by the quality of this book? It just doesn't seem as good as the others in the series, the linear algebra one was top notch.


okay ;w;

well, this is a self-published manga though (isn't it?), and the "The Manga Guide To ..." series you're talking about (https://www.nostarch.com/manga) are, well.. published by professionals?


File: 1460750070283-0.png (138.61 KB, 160x200, mwl04_h.jpg)

File: 1460750070283-1.png (127.16 KB, 160x200, mwl_20.jpg)


Let's settle this dispute

*hello world*
jhe value of the expression 'helloworld is helloworld, so you can use it it display the string "helloworld". This is a little much, though. If you do (print 'helloworld), it's clearer that you are printing something, but we want to put a space between hello and world. To do that, we will use an expression like this.
(print "hello world")

Something wrapped in double quotes (") becomes a "string". Like numbers, they return themselves when evaluated, so you don't need to quote them. Displaying a string with print with also display the quotes. This is ugly, so let's print just the contents of a string.
(format t "hello world~%")
This will display hello world.

"~%" isn't displayed, and instead a newline is. This is a function of format, and (print "~%") with display "~%" unchanged. To print a "~%" with format, do (format t "~~%")

The long awaited difficult 4koma
Lico: To change a value according to a conditional, use if.

Lico: If x is 0, this expression becomes 1, otherwise it's 2.

Suzu: if is a little different, isn't it. Is it a special being?
Lico: Yup, it's not a function.

Lico: if always evaluates its first argument, but only evaluates its second and third arguments as necessary.

if is a special operator, which always evaluates its first argument (argument 1), but evalutes only one of arguments 2 and 3, and that value becomes the values of the whole if expression. Incidentally, an expression which uses a special operator is called a special form. = is a function that checks whether 2 (or more precisely, at least 1) numbers are equal. For more details please read the next manga.

;;; a function that prints "x=0" if its argument is 0
;;; and prints "x/=0" if it's not 0
(defun test1 (x)
(if (= x 0)
(print 'x=0)
(print 'x/=0)))

;; the value changes depending on the argument
(test 0) ;=>x=0
(test 1) ;=>x/=0
(test -1) ;=>x/=0


File: 1460750486184-0.png (130.56 KB, 160x200, mwl_21.jpg)

File: 1460750486184-1.png (122.98 KB, 160x200, mwl_22.jpg)

File: 1460750486184-2.png (136.49 KB, 160x200, mwl_23.jpg)


Lico: if evaluates its second argument when its first argument is not nil, and its third argument when it is.
[ (if condition
argument3) ]
[ the arrows say "not nil" and "nil" ]

Lico: t and nil are special values that represent truth and false. Furthermore, predicates' names often have a P at the end.
Lico: consp, listp, etc

Cudder: Do they produce idols?

When if's first argument is something other than nil, it evaluates its second argument, and when it is nil, it evaluates its third argument. Functions that return t or nil are called "predicates" and are often used as the first argument to if. For example, = is a predicate. There are other predicates, like consp, which returns t when its argument is a cons. Many predicates have a P attached to the end of their names. P is an abbreviation of predicate.

;; using a predicate
(= 0 0) ;=>t
(= 0 1) ;=>nil
(< 0 0) ;=>nil
(< 0 1) ;=>t

;;; a function that distinguishes zero, positive, and negative
(defun test2 (x)
(if (= x 0)
(print 'x=0)
(if (< x 0)
(print 'x<0)
(print 'x>0))))

And now, cond [TN: in Japanese, this is "kondo wa kondo". joke desu]
Lico: More powerful than if, there is also cond!
Cudder: It's a macro!

Lico: Write multiple conditions in a line!

Suzu: And this also only evaluates arguments as necessary?
Cudder: Yeah!
Cudder: cond extends if!

Lico: We'll talk about that now~

cond takes an arbitary number of (conditional expression) form arguments. cond first evaluates the first conditional, then if it is not nil, evaluates the corresponding expression, and if it is nil, evaluates the next conditional. An if which also has an if in one of its arguments can be written as a simpler cond. Please compare the preveious manga's test2 and the test3 below.

;;; a function that is the same as test2
(defun test3 (x)
((= x 0)
(print 'x=0))
((< x 0)
(print 'x<0))
(t (print 'x>0))))

;; determines whether its argument is zero, positive or negative
(test3 0) ;=>x=0
(test3 1) ;=>x>0
(test3 -1) ;=>x<0

Don't worry, you'll get it
Lico: You can also call a function from within itself.

Suzu: A function calling itself is puzzling~
Lico: It's called a recursive call

Lico: This function is the sum from zero to its argument
Cudder: It makes its argument smaller one by one

Suzu: It's confusing after all
Lico: When you get used to it, it's okay

You can implement iteration with recursive function calls. The function f on the left, if x is bigger than 0, calls f with x minus 1. It makes the argument smaller one by one, so that it finishes when it becomes 0. Hey, if you pass a negative number to f, it will become an infinite loop. In this case, exit the interpreter with Ctrl-C.

;;; a function that finds the factorial
;;; (1- n) is the same as (- n 1)
(defun fact (n)
(cond ((= n 0) 1)
(t (* fact (1- n)

;; since n is 0, return 1
(fact 0) ;=>1
;; multiply 1 and a recursive (fact 0)
(fact 1) ;=>1
;; multiply 2 and a recursive (fact 1)
(fact 2) ;=>2
;; multiple 3 and a recursive (fact 2)
(fact 3) ;=>6



are you the webm in the irc channel too?


keep in mind that my Japanese is still pretty weak, and my translation, while passable, surely doesn't do justice to the original.


This is quite fun, thank you for your work.

One thing though. Her name appears as りこ rather than リコ, so I'm wondering why you chose Lico instead of Riko.




At the bottom of the main page is a short list of characters; I'm using that for reference on how the author thinks they should be romanized.

Though I suppose this suggests I should not be spelling out "Cudder"...


Okay, I see. Author's choice. On the other hand the same page has

>the Japanese wolf have been extinct, haven't it?

>a vehicle that drive on the right side of the road
>Japanese drives a car on the left side

so what do they know.


File: 1460812393561.png (1.86 MB, 200x200, the_manga_guide_to_lisp.pdf)

yes, that's me, the guy with the IRC bot written in R.
Who are you?


File: 1460928029811-0.png (108.86 KB, 150x200, mwl_24_1.jpg)

File: 1460928029811-1.png (106.48 KB, 150x200, mwl_24_2.jpg)

I'm trying to be a little less literal in this translation, to hopefully make the dialogue a little less stilted.


Wakana: Ah!

Wakana: It's the unseasonable Japanese wolf...

Rikka: Hasn't the Japanese wolf gone extinct?

Girl: Th- Thank you
Rikka: Don't worry about it.
Wakana: Senpai...what happened just now?


File: 1460928080945-0.png (100.95 KB, 150x200, mwl_24_3.jpg)

File: 1460928080945-1.png (70.05 KB, 150x200, mwl_24_4.jpg)


Wakana: What?

Mysterious Cat: Oh, Miss Miyo?

Miyo: ...
Miyo: Nazuna, your timing is a poor as ever.
Nazuna: Uh...

Nazuna: However, Miss Miyo, what you came here for...
Miyo: It's going well. By the weekend, even this place will be underwater.

Miyo: And you?
Nazyma: There's no problem. Those guys have become completely powerless.

Miyo: ...I see.

Wakana: I'm ba~ck!
Rikka: We're home

Suzu: What did you buy?
Wakana: You'll find out soon!

Manga Guide to Lisp
Rikka: Part 6


Honestly I think that 'L' and 'C' are just cool and exotic letters for nihonjins.

R is an interesting choice for an IRC bot...


>'L' and 'C' are just cool and exotic letters for nihonjins
That's perfectly fine. But for special snowflake romanizations they should have the name in katakana in the manga pages, rather than in hiragana. It was this inconsistency that was strange to see, not Lico itself.


So, do we have something complete to upload to Library Genesis yet?


P.S. When you finish this, please immortalize it by uploading it here. http://libgen.io/librarian/


File: 1461116234321-0.png (116.09 KB, 160x200, mwl05_h.jpg)

File: 1461116234321-1.png (118.26 KB, 160x200, mwl_25.jpg)


I think you might be overestimating how consistently katakana is generally used.


*Self-evaluating Expressions*
If you evaluate a number, it returns itself. The same is true of strings.
4     ;=>4
"str" ;=>"str"
Expressions that evaluate to themselves like this are called self-evaluating expressions.

*Expressions that don't become themselves*
Lists (expressions wrapped in parantheses) don't always evaluate to themselves.
(+ 1 2)       ;=>3
(quote lico) ;=>lico
Since list expressions are calls to things like functions, special operators, or macros, they generally evaluate to values that are different from the original expression. (However, it is possible to intentionally write an expression whose value is itself). Similarly, symbols (like lico above) do not always result in themselves, since symbols are interpreted as variables.

Variables are names for values (or more precisely, containers for values). For more details, please continue reading.

Shut-in Producing Machine
Lico: Next, let's try and use variables.

Lico: You use let to make variables!
[a's initial value]

Wakana: Variables name values, right?
Lico: Basically

Lico: You can't use variables made with let outside of let
Cudder: let makes shut-ins!

To use variables, you use the special operator let.
(let ((variable1 initial-value1)
(variable2 initial-value2)
First the initializing expressions are evaluated, and variables containing those values are created. Then the final expression is evaluated, and its value is the value of the whole let.

;; make variables x and y
(let ((x (+ 1 2)) ;x = 3
(y (* 3 4))) ;y = 12
(+ x y)) ;=>15(=3+12)

;; x cannot appear outside the let
x ;=>ERROR!


File: 1461116396199-0.png (122.19 KB, 160x200, mwl_26.jpg)

File: 1461116396199-1.png (131.2 KB, 160x200, mwl_27.jpg)

File: 1461116396199-2.png (137.13 KB, 160x200, mwl_28.jpg)


Persuading with setq
Lico: You can assign a value to a variable!
Cudder: To assign, use setq!

Lico: If you do (setq a 2), a's value will become 2
[a's value changes]

Cudder: setq is a special operator!
Suzu: That makes sense, but what is the q in setq?

[ setq
persuade ]
[TN: setq (settokyuu) sounds like persuade (settoku)]

When you want to assign a value to a variable, use the special operator setq. setq takes a variable as its first argument, and a value to assign as its second. setq doesn't evaluate its first argument. Incidentally, the origin of the name is
it doesn't evaluate its first argument
= it quotes it
= set + quote
= setq

(let ((x 1) (y 2))
(setq x (+ x y)) ;xに3を代入 ;assign 3 to x
(+ x y)) ;=>5

;; keep in mind that (A B) is an
;; abbreviation for (A . B . nil)
(let ((x 'hello) (y 'world))
(setq y (cons y nil))
(cons x y))
;=>(hello world)

Heed Side-Effects
Lico: You can write multiple expressions in let and functions

Lico: The expressions are evaluated from the left, and the final expression's value is the value of the entire let.

Wakana: The values in the middle are thrown out, right?
Lico: Yup, so you can use things like print and setq

Lico: print and setq have important "side-effects"
Cudder: Side-effects of medicine is how I got this body...
Wakana: go on

After let makes its variables, you can evaluate multiple expressions. Expressions are evaluated in turn from the left, and the value of the last expression becomes the value of the whole let. Since the values of expressions evaluated on the way are discarded, you can use them for "side effects" like assigning variables or printing strings.

;; the value of x + y is discarded
(let ((x 1) (y 2))
(+ x y) ;this expression is pointless
(* x y))

;; the value of x + y is discarded but printed
(let ((x 1) (y 2))
(print (+ x y));not pointless!
(* x y))

;; you can also do this in functions
(defun check20 ()
(print "How old are you?")
(if (< (read) 20)
[TN: 'kodomo and 'otona are 'child and 'adult. I don't know if you guys want me to translate things that don't matter so much like function names and variables, or leave them for that sweet weeb flavor]

[Cudder-becoming medicine]

Lico: To make variables you can use anywhere, use defvar.

Lico: After evaluating this expression once, you can use the variable *b* anywhere.

Suzu: Why is it wrapped in *s?
Lico: Variables made with defvar are special variables, so you attach *s
Lico: That's the convention, at least

Lico: defvar-made variables are special variables!
Cudder: Special! Special! Special!
[ What's this? ]

You can only use variables made with let inside the let. To make variables you can use anywhere, you use the macro defvar. Variables made with defvar are special variables, and so have a different property from normal variables made with let (lexical variables). (Which is omitted from this explanation). Because of this, to make them stand out, *s are customarily put at the beginning and end of their names.

Cudder: My favorite is juiciness broken into little pieces!

;; make a special variable *count*
(defvar *count* 0)

;; *count* can appear anywhere
;; (setq returns the value it assigns)
(defun counter ()
(setq *count* (1+ *count*)))

;; evaluation increments that value
(counter) ;=>1
(counter) ;=>2
(counter) ;=>3


we're halfway through!

next chapter is cdr-racing!


Does anyone have the linear algebra and calculus versions? I read the databases one and it was great.


This is an original web comic made by a Japanese artist, not to be confused with the Manga Guide To series (which I'm guessing is what you're looking for?).
I checked out the calculus one at the library once and it was a lot better than I thought it'd be, though I already knew calculus so I can't comment on how well they teach you. I don't know where to find them online.



Whatever book you need, Library Genesis likely has it.

If you find a book elsewhere, please consider it your duty to upload the worlds largest ebook collection.



*upload to


Sweet never heard of this thanks!


I patiently await more LISP cuteness. Lico wills it.


File: 1462932157256.png (163.4 KB, 200x200, lisp_girl_closeup.png)

Same. I'm still interested in seeing this finished as well, considering how well it was coming along. Keep up the good work!


Ditto. Get this finished OP, lest I have to empty my wallet in order to get it done.


File: 1463943972835-0.png (197.18 KB, 150x200, mwl_24_1.jpg)

File: 1463943972835-1.png (195.91 KB, 150x200, mwl_24_2.jpg)

I can't into PDF.


File: 1463944030500-0.png (180.05 KB, 150x200, mwl_24_3.jpg)

File: 1463944030500-1.png (128.45 KB, 150x200, mwl_24_4.jpg)

Will do the rest of part six tomorrow if anyone cares.


File: 1463950019160.png (135.52 KB, 200x200, 10.png)

No need to ask. We appreciate it a lot.


This thread is the best thing to happen on lainchan IMO. Thanks to everyone who contributed, gonna catch up now.


File: 1464001543061.png (129.06 KB, 200x190, part6.jpg)

Part 6 is done.

I ran the images through waifu2x since the text was getting way too small in places. Vertical speech bubbles are the bane of my existence.

Since there's no further translation right now I've been thinking of redoing the other five parts with waifu2x and the monospaced font for the code sections.


Thank you, lainon.


Sorry for the delay, friends. I kind of got caught up with finals and graduation.

But enough excuses! I'll try spending most of today making up for the lost time.


File: 1464185247369-0.png (121.95 KB, 150x200, mwl_29_1.jpg)

File: 1464185247369-1.png (114.39 KB, 150x200, mwl_29_2.jpg)


Eme: What? The white cudder? Of course it's in this match.

Cudder(?): Lico,
Eme: Ugh, she's using the raw cudder?!

[<Raw Cudder> This cudder is green everywhere]
Raw Cudder: Raw

Eme: It has about 1/3 the horsepower of the white cudder.

Eme: But if the rider is Lico,
Eme: What? Can it be?

[The same day, one year previously]
Yomi: -like that.

Yomi: Since tomorrow the surgery is launched, you should all get out.

Rokko(?): Rokko is good~
Rokko(?): I'll escape to a high place~

Yomi: Oh? And you two?

Nazuma: There's something we still have to settle.

Mirin: White!

White Cudder: Myaa~
Mirin: Nya


File: 1464185300154-0.png (132.71 KB, 150x200, mwl_29_3.jpg)

File: 1464185300154-1.png (92.32 KB, 150x200, mwl_29_4.jpg)


[Thus, before the race]

Announcer: Well, since today's main event, the cudder race, will begin shortly, I will introduce the racers!
Mirin: If I win this time, I'll GET the skill of a god, nyaa~
[<Mirin> The sponsors' favorite.]

Because if I win, you'll return the part you took last time!
[<Lico> She rides a cudder well-known to only a select few, and may be the top power holder if not for the cudder's difference.]

Jodorowsky: I will defeat Mirin and become the boss cat
[<Jodorowsky> Mirin's rival? He seems to be an underdog.]

[<Mystery Racer>]
Run without dividing the centerline to the utmost of my ability, that's my motto.
[There's a bunch I'd like to say, but I'll pass on that for now]

Fugaa! Fushuu! Fushorururu!
[Huh? What's this cat?]

Now begin at once!

???: Lico

Rikka: Cat youkai 2 and
Wakana: 3 will come to cheer!
Wakana: Suzu is at the goal

Do convience stores these days even sell such a thing?
[TN: I can't tell if he's asking if convenience stores sell those cat ears, or if they will sell to a cudder like him]

Wakana: Here, take this, Lico
Lico: Bread?
Wakana: Yeah

Rikka: If I don't stop, won't I become a shell?
Lico: You've got game brain

A Manga Guide to Lisp VII
Announcer: Thank you. I'm a bird youkai.



I'm not super confident about some of these translations, but I think I got the main point mostly across.

(The technical stuff is so much easier)


>I'll try spending most of today making up for the lost time.
Don't burn yourself out lainon, especially before this is finished. Do it at whatever pace you like, as we know you're not dead.


File: 1464889521950-0.png (125.43 KB, 160x200, mwl06_h.jpg)

File: 1464889521950-1.png (135.9 KB, 160x200, mwl_30.jpg)

File: 1464889521950-2.png (134.38 KB, 160x200, mwl_31.jpg)


*Variables with the Same Name*
In Lisp, it's possible to make to make a variable with the same name as one that already exists.

(let ((x 10))       ;value of variable x (exterior) is 10
(print x) ;output 10
(let ((x (* x x)));value of variable x (interior) is 100
(print x)) ;output 100
(print x) ;output 10

Like this, this outer let's variable is hidden by the inner let.

*Lexical Variables and Special Variables*
The usable scope of lexical variables made with let is restricted to the body of the let. However, the scope in which it's possible to use the variable continues to exist.

(let ((count 0))
(defun lexical-count ()
(setq count (1+ count))))

Each time you call lexical-count, its value increases. The usable scope of special variables made with defvar is infinte, but their lifespan is finite.

(defvar *count* 0)
(defun special-count ()
(setq *count* (1+ *count*)))
(let ((count 999)) ;has no effect
(lexical-count)) ;=>1(increases)
(let ((*count* 999));has an effect
(special-count)) ;=>1000(always)

When you make a variable with the same name as a special variable, it does something interesting. More details another time.

Relatively Easy
Lico: To evaluate the same expression a fixed number of times, dotimes is very convenient.

<- evaluated 3 times
Lico: 0, 1, and 2 are displayed, and the value of the expression is end

Wakana: When you combine it with let, even factorial seems easy to write!

dotimes is a macro that evaluates (at least one) expression a fixed number of times.

(dotimes (variable count result)

"count" specifies the number of repetitions. "body" is evaluated as many times as the value of "count". In "body" you can use "variable". The value of "variable" is assigned the number of the current repetition (0 to count-1). The value of the whole expression is the value of "result" when the repetition is finished.

;; finds the factorial of 5
(let ((ret 1))
(dotimes (i 5 ret)
(setq ret (* ret (1+ i)))))

do is Full of Friends
Lico: For more complicated repetitions use do.
Jodorowski: There's a lot of time before the race.

Lico: This time 1, 3, and 9 are displayed

Rikka: Compared with dotimes it's very difficult to read~
Lico: For do's expressive power-

Jodorowski: -it picked up easyness to read, I hear
Blue Cudder: I know

do is a macro for general repetitions. It can do more fine-grained assignments than dotimes.

(do ((var1 init1 update1)
(var2 init2 update2)
(end-condition result)

[Blue Cudder

First, all the "init"s are evaluated and assigned to the "var"s. Next, the end-condition is evaluated, and if it's anything but nil, "result" becomes the value of the whole expression. If it is nil, after evaluating the body, the values of the "update"s are assigned to the "var"s, and the body is evaluated again.

;; makes a list of 4 to 1
;; (pay attention to the timing of the assignments)
(do ((i 1 (1+ i))
(acc nil (cons i acc)))
((>= i 5) acc)
(format t "~A ~A~%" i acc))
;=>(4 3 2 1)


File: 1464889651067-0.png (122.71 KB, 160x200, mwl_32.jpg)

File: 1464889651067-1.png (136.98 KB, 160x200, mwl_33.jpg)


Lico: do takes a set of 3, but you can omit the "update"

Lico: If you omit it, the variable's value won't change on the repetition.
you can assign with setq

Wakana: You use them just like variables made with let, right?

Cudder: do is developed with an expression using let!
Lico: We haven't talked about making macros yet

Variables made with do are exactly the same as variables made with let. That is, they can be used only within the scope they are restricted to (in this case, the interior of the do), and they can be assigned to with setq. However, it's important to keep in mind that overusing setq will make it difficult to read.

[Purple Cudder
Details unknown
(Nothing more to write)]

;; factorial of five (using setq)
(do ((i 1 (1+ i))
(ret 1))
((> i 5) ret)
(setq ret (* ret i)))

;; factorial of 5 (without using body of do)
(do ((i 1 (1+ i))
(ret 1 (* ret i)))
((> i 5) ret))

Cudder-tails are probably hard
(recursion) (do)
Lico: You can write repetitions
Lico: with both do and recursion

Lico: There are people who always use recursion, but there are also many people who like do.

Wakana: Recursion seems less efficient, because of all the function calls

Lico: If you use tail recursion, it's probably about the same
Cudder: But only "probably"!

Announcer: Let the countdown begin! 5!

Since processing function calls can take a bit of time, typically repetitions using do are faster. However, when a function uses a recursive call at the end (the point after which their are no more expressions that need to be evaluated) (tail recursion), many implementations will replace the recursive call with a simple jump, so that it is just as efficient as a do.

;;; factorial using tail recursion
;;; since after the call to trf there are no
;;; expressions to evaluated, it is optimized
(defun trf (n &optional (a 1))
(cond ((= n 0) a)
(t (trf (1- n)
(* a n)))))

;; trf's second argument is optional
(rtf 5) ;=>120

[Cudders Only]


>Cudder-tails are probably hard
what's especially odd about this pun is that tail recursion is called "end recursion" in japan

it turns out even when I'm pushing myself I work pretty slow, so don't worry too much~


I'd be pretty happy with this.

also I'm pretty happy about the little edits to make the text sound more natural. staring at japanese all day makes it surprisingly hard to make natural-sounding english :<


bump mixed with anticipation and hope


File: 1469769205956-0.png (95.51 KB, 172x200, 5ed944d5b4b8f96853f5544d587e2e70761769af572b09fbc40cdd823fbb8ffe.png)

File: 1469769205956-1.png (55.35 KB, 200x200, ac0b8cbce7ee48ebcdeb265168bf0fbcb59945903aedde57e361fb3a86c4d6b6.jpg)


File: 1471702373404-0.png (135.32 KB, 150x200, mwl_34_1.jpg)

File: 1471702373404-1.png (116.24 KB, 150x200, mwl_34_2.jpg)


Jodorowsky: Amateur! There's poison in the purple cudder!
[Mysery Racer (Out)]

[Mirin, deftly clearing the right corner after a perilous down-slope in the first half of the course,]
[next enters a road alongside the river]
TN: pretty unsure about this sentence

Jodorowsky: We'll go straight! Cudder!!

Blue Cudder: ACM Standby!
Drop dead, Mirin!

Jodorowsky: Now!
Blue Cudder: Fire!
Mirin: !?


[If the anti cudder missile "Amulet" is hit on the side, it can be dealt with without exploding.]
Lico: What's that?
Jodorowsky: Prepare the next bullet...?

[Jodorowsky (Out)]
Jodorowsky: Damn... Damn Monster...


File: 1471702424365-0.png (127.98 KB, 150x200, mwl_34_3.jpg)

File: 1471702424365-1.png (104.25 KB, 150x200, mwl_34_4.jpg)

Tama: ..Next is you..
Cudder: Did you say something?

Lico: Cudder! Right!
Tama: ..unh you won't get away..

Lico: Quickly! Right!
Lico: Next! With all your strength, right!

Tama: Crush...

Lico: You're soft, monster!
Tama: !?

[Tama (Out)]

Mirin: This has been a considerably fun farce, nyaa! ...Now

Mirin: Let's go all out!

Cudder: Meow!
Lico: !?

[The white cudder, having gone all out, is three times faster!]
They pulled ahead!
Lico: Cudder
[The distance between Lico and Mirin widens in an instant]

Lico: Commence military operations!

A Manga Guide to Lisp 8
What are these guys...



Sorry for the long delay! I'm not dead, but I decided it'd be easier for me to go ahead and transcribe the handwritten kanji into text for the rest of them, first. Now I should be able to go through and actually translate them at a more consistent pace.

We'll see, at least.



These are really cute! Where did you find them?


Woah. Thought this thread was officially dead. (I guess it isn't officially alive either, 3 weeks between replies is pretty damn long, even for lainchan). Only two I ever found on pixiv, both by the same guy: tanakamura. Hope you continue the work. I really enjoy seeing the new pages


File: 1481905516965-0.png (109.16 KB, 160x200, mwl07_h.jpg)

File: 1481905516965-1.png (129.32 KB, 160x200, mwl_35.jpg)


*Special Variables*
If you make a variable with the same name as a special variable, something interesting happens.
(defvar *s* 1)
(defun get-s () *s*)
(get-s) ;=>1
(let ((*s* 10))
(get-s)) ;=>10
(get-s) ;=>1

The value of *s* is changed to 10 only while the interior of the let is evaluated. When the let is exitted, the value of *s* once more returns to 1. This is different from the behavior of normal (lexical) variables.
(let ((lex 1))
(defun get-lex () lex))
(get-lex) ;=>1
(let ((lex 10))
(get-lex)) ;=>1

The visible scope of lexical variables is the inside of let, but "middle" here means the middle of the surface of the written text. They are not visible from, for example, the middle of functions called from here. One the other hand, in the case of special variables, if you make a variable with the same name in a let, it is available while the middle of the let is being evaluated. When the let is exited this value disappears.

Stopping Midway
Lico: To exit a function partway through, use return-from

Lico: When return-from is evaluated, the function stops in the middle of what it's doing.

Cudder: If you combine it with a conditional branch it can be pretty convenient.
Cudder: By the way..

Cudder: I'm tired, can I stop running soon?
Lico: Keep on going for a little while longer.

If you use the special operator return-from, you can leave a function midway through. The first argument of return-from is the name of the function you're leaving, and the second argument designates the value of the function you're leaving (the return value). If you omit the second argument, the function's value becomes nil.

;;; If the argument is not a number, error,
;;; If it is a number, return it times three
(defun 3-bai (n)
(if (not (numberp n))
(return-from 3-bai 'error))
(format t "~A*3=~A~%"
n (* n 3))
(* n 3))

;; numbers are multiplied by three
(3-bai 4) ;=>27
;; symbols are error
(3-bai 'lico-san) ;=>error


File: 1481905687864-0.png (108.37 KB, 160x200, mwl_36.jpg)

File: 1481905687864-1.png (124.13 KB, 160x200, mwl_37.jpg)

File: 1481905687864-2.png (121.35 KB, 160x200, mwl_38.jpg)


Stopping Midway 2
To leave from the middle of do or dotimes, use return

Cudder: Its usage is about the same as return-from

Cudder: (return x) is the same as (return-from nil x)

Lico: Isn't chatting while you run tiring?
Cudder: My speech stops around here...

To leave the middle of iterations using do and dotimes, use the macro return. return returns the value assigned to its first argument, and returns nil if the argument is omitted. (return x) and (return-from nil x) have the same meaning, but I'll return to this in a bit. [TN: everything after the comma is basically a wild guess.]

;;; accept a specified number of inputs,
;;; then return their product
;;; when 0 is input, immediately return 0
(defun kakeru (n)
(let ((x 1))
(dotimes (_ n x)
(print "input number")
(setq x (* x (read)))
(if (= x 0)
(return 0)))))

Good bye, Cudder
Lico: If you use block, you can give a name to expressions, too!

Lico: When block is evaluated, its arguments starting with the second are evaluated in sequence
Wakana: Lico is in which place?
Pen: Second place, it seems

Lico: However, if you use return-from you can exit a block midway through.
← block name

Cudder: do is implicitly enclosed by a block named nil

If you use the special operator block, you can create a sequence of expressions that it is possible to leave midway.
(block name expr1 expr2 ... exprn)
When block is evaluated, the expressions are evaluated from "expr1" to "exprn", with the value of exprn becoming the value of the whole block expression. However, if the expression (return-from name value) is evaluated in the middle of the block, evaluation stops there, and "value" becomes the value of the whole block expression.

;; leave nested dotimes
(block b1
(dotimes (i 5)
(dotimes (j 5)
(format t "~A ~A~%" i j)
(if (= i j 2)
(return-from b1)))))

Mirin: Ew! You're still following me!?

Cudder: Meow!
Mirin: Surely we can go faster than this! [TN: unsure]

Nogu: What's going on? Ugh, the raw cudder is chasing the white cudder?? [TN: Last verb here is a "suffix indicating hatred and contempt, or disdain for another's action"]
Eme: Yeah, that's right.

Nogu: Perhaps the white cudder has changed color to green?
Eme: How disappointing
Eme: Is changing a thing cudders can do? [TN: unsure]

As already mentioned, return can replace return-from. This is because things like do and dotimes are implicitly surrounded by a (block nil ...) expression. When there is another block with the same name, evaluating return-from exits the innermost block. For that reason, if you use return in nested do or dotimes, you will leave the innermost iteration. Also, functions can be considered to implicitly surrounded by a block with the same name.

(block nil 1 (return 2) 3)
(block b
(block b
(return-from b 1))
2) ;=>2


File: 1481906383549-0.png (128.11 KB, 150x200, mwl_39_1.jpg)

File: 1481906383549-1.png (125.48 KB, 150x200, mwl_39_2.jpg)


Eme: They're running while switching cudders using a relay system!

Eme: If they pay attention to their stamina and run without all their power, even the raw cudder...
Nogu: Are they catching up with the white cudder?
[red text] long distance
[blue text] short distance short distance short distance

Eme: That's not
Cudder: Yeah...

Lico: The connection to the final stage, the urban course.
Cudder: Baton Pass
Cudder: Hup!
Lico: Ah, I hear that that road can be decided freely or something...

Lico: Alright, go!
Cudder: We have to go!
Cudder: Impossible..

[The course's final route can be chosen freely, but the key is to arrive at the goal.]

[The route is largely divided into two: a risky short way and]
[An easily-run detour road.]

Lico: Mirin is probably going the latter...So if we take the shortcut we'll come out ahead!
Lico: Since the white cudder is fast..

Cudder: They went straight?
Lico: !?

Lico: There's no use, let's go right
Cudder: Can't we arrive faster than by going right?

Lico: It seems like Mirin also thought that. It's a trap!
Cudder: ?

If you go skillfully you can kill a tiger with a sponge.


File: 1481906424256-0.png (117.1 KB, 150x200, mwl_39_3.jpg)

File: 1481906424256-1.png (112.11 KB, 150x200, mwl_39_4.jpg)


Mirin: ...They didn't follow. Did they make a mistake and choose the safe road?

Mirin: But!
Mirin: Completely naive!

Mirin: As far as cudder-riding is concerned, dealing with oncoming cars in the same lane is -
Mirin: Elementary!

Mirin: If they're local roads!
Mirin: It's the same as breathing!

Mirin: If we cross that bridge I see, then the goal will be
Mirin: easy victory, nyaa ♪

Mirin: Where did you come from!?

Cudder: Cudder!

Eme: They're antenna drifting!
Nogu: What's that!?

Mirin: Such an idiot!

A Manga Guide to Lisp
Cudder: 9


File: 1481907534134-0.png (116.32 KB, 160x200, mwl08_h.jpg)

File: 1481907534134-1.png (127.67 KB, 160x200, mwl_40.jpg)

File: 1481907534134-2.png (126.48 KB, 160x200, mwl_41.jpg)


A Manga Guide to Lisp
Nogu Eme

With lists, cons. This is everything.

Cons is this sort of box. You can put what you'd like in the car-part, the left-hand side of box, and the cdr-part, the right-hand side. The symbol nil is the empty list, and is a list type. A cons with nil in the cdr-part is also called a list. Additionally, a cons with a list in the cdr-part is a list, too. A, B, and C in the sketch below are all lists.

I'm illustrating a cons inside of a cdr-part with an arrow, and a nil inside of a cdr-part with a slash. This sort of list is accurately called a "well-behaved list". A cons with something other than a list in its cdr-part will actually also be called a list, but more accurately is called a "misbehaving list".

[TN: If I were less of an asshole I might translate "well-behaved" and "misbehaving" as "well-formed" and "ill-formed" or something.]

Eme: A Manga Guide to Lisp
Nogu: This issue has been hijacked by us, Nogu and Eme.

Eme: Lico tried to use a railway track as a shortcut.
Nogu: Running while avoiding cars is better than going the wrong way in one-way traffic..
[Lico to TOP!]

Eme's Hat: Please bring that sort of discussion of rank smoothly to discussion of lists.

Eme: Did you say something?

When you're representing a series of things, a list is what you use. When you make a list, you use the function list.

;; make a list lining up 1, 2, 3
(list 1 2 3) ;=>(1 2 3)

;; to represent "first place is lico, second place is mirin"
(list 'lico 'mirin)
;=>(lico mirin)

The things that a list contains are called the elements of the list. The special list with no elements is called the empty list.

;; make a list with 2 elements
(list 'a 'b) ;=>(a b)

;; make a list with 1 element
(list 'a) ;=>(a)

;; make the empty list
(list) ;=> nil

American 2
Eme: Use car to take out the first element of a list

Nogu: The most left-hand thing will come out!

Eme: Incidentally, why car takes out the leftmost element..
Eme: Do you know?
Nogu: I don't know

Eme: It's because cars drive on the left side of the road
Nogu: !?

To take out the first element of a list, use the function car.

;; fetch the first element (element 1)
(car (list 1 2 3)) ;=>1

;; who is the first-place racer?
(car (list 'lico 'mirin))

The function car is a function to get out the car-part of a cons. However, you can also use it to get at the first element of a list.

If you are asking why car is used to get the the first element of a list, it's because lists are made with conses.

;; a list with one element
(list 1) ;=>(1)
(cons 1 nil) ;=>(1)

;; a list with two elements
(list 1 2) ;=>(1 2)
(cons 1 (cons 2 nil)) ;=>(1 2)


File: 1481907582027-0.png (112.69 KB, 160x200, mwl_42.jpg)

File: 1481907582027-1.png (114.52 KB, 160x200, mwl_43.jpg)


Cutting, Cutting, Cudder
Eme: To get the list that is this list with its first element removed -
Nogu: Use cdr, chef!

Nogu: The list will remain a list no matter how many times you take the cdr?

Eme: It's like Kintaro candy

To remove the first element from a list, use the function cdr. When its argument is the empty list, the value of the function becomes the empty list.

;; a list's cdr is always a list
(cdr (list 1 2 3) ;=>(2 3)
(cdr (list 2 3)) ;=>(3)
(cdr (list 3)) ;=>nil
(cdr (list)) ;=>nil

When you want to get the second element of a list, after you call cdr, call car. For the third element, call car after calling cdr twice.

(car (cdr (list 1 2 3))) ;=>2
(car (cdr (cdr (list 1 2 3))))

You'll Get The Hang of It
Eme: list and quote are a little similar

Nogu: list is a function, quote is a special operator!

Eme: Right. list is evaluated, but quote isn't.

Eme: It might be hard to understand at first, but you'll get the hang of it quickly.
Nogu: Really?

You can also make a list with quote. However, make sure to be aware that quote is a special operator, while list is a function. list will evaluate its arguments, quote will not evaluate its argument. Please be especially careful when using symbols for a list's elements.

;; make a list with list
(list 'a 'b 'c) ;=>(a b c)

;; make a list with quote
'(a b c) ;=>(a b c)

mistake using list
(list a b c) ;=>error

mistake using quote
'('a 'b 'c) ;=>('a 'b 'c)

Pen: The above sent from our studio!


File: 1481907889540-0.png (116.79 KB, 150x200, mwl_44_1.jpg)

File: 1481907889540-1.png (117.18 KB, 150x200, mwl_44_2.jpg)


[Start Point]
Pen: This is a report on the situation in the race.

[The present lead is Lico, with Mirin a little behind]
[Who have now both entered the final stretch!]

Mirin: The difference, the remaining distance, if I use the white cudder's speed...
[Easy victory!!]

Mirin: From the beginning

Mirin: Even if the raw cudder is superior to the white cudder on one point...
Mirin: Meow!?

Raw Cudder: That's inexcusable.

Mirin: Bread!?
Mirin: This is...

???: Bread...

Cudder: It's bread...
Cudder: ...Bread

Mirin: Meow

[The raw cudder's strength over the white cudder is-]
Cudder: Bread
Mirin: Mrowwwwwww
Cudder: Bread

Cudder: Bread
Mirin: Meow!!
[Mirin regretfully retires...]
Cudder: Bread


File: 1481907947414-0.png (111.48 KB, 150x200, mwl_44_3.jpg)

File: 1481907947414-1.png (100.99 KB, 150x200, mwl_44_4.jpg)


Lico: Going?

Lico: Try your best tomorrow

Lico: If its a rematch I'll accept your challenge!
Lico: Of course!

Nazuna: I've already finished my business, so say what you'd like.
Lico: The boss character is careless.
Nazuna: I am a cat, after all.

Suzu: This will somehow save the word, right?
Eme: It appears that I will be the one to take down Lico
Nogu: Ah, it's Eme's turn now.
Lico: What are we doing tomorrow?

[Next Day]

Lico: Now that the world-submergence has been resolved, I'll be departing..
Suzu: There's something I want to ask you, Lico
Lico: What?

Suzu: Where do we use LISP?

Lico: Suzu is so sensitive!

A Manga Guide to Lisp
Suzu: Part 10


File: 1481909547053-0.png (124.03 KB, 160x200, mwl09_h.jpg)

File: 1481909547053-1.png (121.61 KB, 160x200, mwl_45.jpg)


*defvar Precautions*
defvar is macro used to create new variables. If a variable with the same name already exists, evaluating defvar does nothing.

(defvar v 0)
v ;=>0
(defvar v 1)
v ;=>0

For that reason, when using defvar in an interactive environment, take care as to whether a variable with that name already exists. There is also a macro very similar to defvar, defparameter. It, like defvar, makes new special variables, but in the case where a variable with the same name exists, it assigns a new value to the variable.

(defparameter w 0)
w ;=>0
(defparameter w 1)
w ;=>1

*Overwriting cons*
It is possible to modify the contents of the car-part and cdr-part of a cons. The function rplaca will overwrite the car-part, and rplacd the cdr-part.

(defvar cell (cons 1 2))
(rplaca cell 0)
cell ;=>(0 . 2)

Setting Age
Lico: If you use cons you can add and element to the head of a list!

Suzu: They're made with cons.
Lico: Right

Lico: It's easy to append things to the head of a list!

[This one's contents]
Suzu: And to append something to the end of a list?
Lico: We'll do that at the end

Use cons to add an element to the head of a list.
cons is a function that makes conses, of course. Since it only makes one cons, it can append an element to the head of a list very quickly. Appending an element to the end of a list is a little more complicated process. More on this later.

Lico: Bad title!

;; append 3 to the head of the empty list
(cons 3 nil) ;=>(3)

;; append 2 to the head of the list (3)
(cons 2 '(3)) ;=>(2 3)

;; append 1 to the head of the list (2 3)
(cons 1 '(2 3)) ;=>(1 2 3)


File: 1481909622849-0.png (138.02 KB, 160x200, mwl_46.jpg)

File: 1481909622849-1.png (127.91 KB, 160x200, mwl_47.jpg)

File: 1481909622849-2.png (137.65 KB, 160x200, mwl_48.jpg)


How to Remember
Lico: Let's try and make a variable with a list in it!

Lico: If you use this in cons,

Suzu: It's just called cons because it doesn't change the contents, right?

Lico: To change the contents of a variable, use setq!
Suzu: It persuades, right?

cons just creates a new cons. If you create a new cons with a list in its cdr-part, you can make a list with one element appended to it, but the previous list won't be overwritten. Because of this, when the contents of the variable is a list, and you want to append an element there, you need to use cons and setq. There is a macro push which will do this once. push takes a variable as its second argument.

[setq persuade] [TN: 説得 is pronounced settoku, setq would be pronounced something like settokyuu]

;; make a variable racer
(defvar racer (list 'mirin))
racer ;=>(mirin)

;; append an element with cons and setq
(setq racer (cons 'lico racer))
racer ;=>(lico mirin)

;; append an element with push
(push 'tama racer)
racer ;=>(tama lico mirin)

Lico: To reverse a list,
Lico: use reverse!

Lico: Look at this

Suzu: It became the opposite
Lico: Yup!

Lico: It reversed!

If you use the function reverse, you can get a list with the order of its elements inverted. reverse newly creates a reversed list. Because of this, the contents of the list passed as its argument are not modified. To overwrite the contents while creating a new list, use the function nreverse. Please keep in mind that when using nreverse on a variable, it is still necessary to reassign with setq.

Mirin: Reverse

;; creating a reversed list
(defvar rank
(list 'lico 'mirin 'tama))
(reverse rank)
;=> (tama mirin lico)

;; the variable's contents are unchanged
rank ;=>(lico mirin tama)

;; reversing the contents of the variable
(setq rank (nreverse rank))
rank ;=>(tama mirin lico)

World-Saving Attributes
Lico: To append something to the end of a list, use append.

Suzu: Doesn't that concatenate lists?

Lico: Suzu is so attentive but..

Lico: You can't save the world worring about small things
Suzu: Right

[TN: "small" and "attentive" are the same word here, 細かい. I think it has a lot of connotations that I don't really understand, given how it's being used.]

The function append concatenates lists. Like reverse, a new list is created without modifying the list passed as an argument. If you want to modify the list, use nconc. Since these functions search for the end of the list from the beginning, if the list is long they can take a long time. To append one element at a time to a list, it's probably better to use cons and push.

Suzu: Am I attentive?
Wakana: Don't worry about it!

;; make a variable
(defvar racer2 (list 'lico))
(defvar cat (list 'mirin tama))

;; concatenate (make a new list)
(append racer2 cat)
;=>(lico mirin tama)
racer2 ;=>(lico)

;; modify the variable's contents
(setq racer (nconc racer2 cat))
racer2 ;=>(lico mirin tama)


File: 1481911428909-0.png (102.41 KB, 150x200, mwl_49_1.jpg)

File: 1481911428909-1.png (113.25 KB, 150x200, mwl_49_2.jpg)


Well then,

Let's begin to seal this at once. (??)
What's that?

Lico: "Lisp-like things" are self-built processes (??)
Suzu: Cudder
Lico: So,
Cudder: Hold on!!

Cudder: Stop it!

Cudder: You're the evil god obsessed with the dark side of LISP!
Suzu: Whaa
Suzu: What's that?
Cudder: Cudders have the ability to notice evil gods.

Yomi: Nice to meet you, Miss Lico
Yomi: I am

Yomi: The mastermind behind the plan to submerge the world, Yomi.

Cudder: As expected, you've been pulling your hands out of sight. [TN: unsure]
Lico: Wh- What-
Cudder: ....pay attention!

Lico: If that's the case
Lico: We'll defeat you and SAVE THE EARTH!


File: 1481911462807-0.png (135.91 KB, 150x200, mwl_49_3.jpg)

File: 1481911462807-1.png (106.05 KB, 150x200, mwl_49_4.jpg)


[Since ancient times, it's said that the users of LISP created LISP.]
[If the function of the self-built LISP implementation continues to expand,]

[You haven't really understood the meaning of Lisp]

[People call that]
Cudder: LISP-like things!!

Suzu: I don't really understand, but I get that Cudder took the good part!
Cudder: It is said that, the excellent LISP, destroys like steel, is light like a feather.

Cudder: Now, this level's fight has pridefully begun a mutual implementation...

[TN: "Lisp-like things" or "things like LISP" is clearly not the best way to translate that (LISPのようなもの), but I don't totally understand what is. Perhaps just "LISP"? "a sort of LISP"?]

Suzu: And now?
Cudder: I feel this fight remains unresolved.

And generally in this area... [TN: unsure]

Yomi: All the same. If it's like this-

Yomi: Fishing match!!

Cudder: Huh?

A Manga Guide to Lisp 11

Lico: Alright!


File: 1481912850025-0.png (141.24 KB, 160x200, mwl10_h.jpg)

File: 1481912850025-1.png (123.59 KB, 160x200, mwl_50.jpg)


*Combinations of CAR and CDR*
To perform more complicated operations with conses, like (car (car x)) or (car (cdr x)), you'll write an expression that applies car and cdr multiple times. To do this sort of thing, there are very convenient functions like caar and cadr. caar fetches the car of the car of a cons. cadr fetches the car of the cdr of a cons.

By putting more a's or d's in between c and r, you can create even complicated conses in one operation. In Common Lisp, functions using up to 4 a's or d's have been provided.

*Why setq is necessary with nreverse and nconc*
When you've assigned a list to a variable, the variable points to the cons at the head of the list. If you overwrite the cons here, it is possible that the cons at the head moves to somewhere other than the head. For example, the cons at the head of an nreverse'd list might move to the end of the list. So the variable will end up pointing at a weird place (like the end of the list). Therefore, when you call a function that overwrites a cons, it's necessary to make the variable point to the new head of the list with setq.

Cudder: Food for me...

[3 hours later]
Lico and Yomi: Can't fish...

Suzu: This is a long match, huh
Lico: Speaking of long, you can get the length of a list with length!

Lico: Like this, it returns the number of elements.

Suzu: But, when do we reach the conclusion?
Lico: Please ask the fish.

The number of elements in a list is called the length of the list. The length of a list can be obtained with the length function.
(length nil) ;=>0
(length '(a)) ;=1
(length '(a b)) ;=>2
(length '((a b) (c d))) ;=>2
You can define a function yourself that does the same thing as length if you use the predicate null, which returns t when its argument is nil.

;;;make length with do
(defun my-len1 (lst)
(do ((lst lst (cdr lst))
(len 0 (1+ len)))
((null lst) len)))

;;;make length with recursion
(defun my-len2 (lst)
(if (null lst)
(1+ (my-len2 (cdr lst)))))


File: 1481912912026-0.png (129.5 KB, 160x200, mwl_51.jpg)

File: 1481912912026-1.png (140.2 KB, 160x200, mwl_52.jpg)

File: 1481912912026-2.png (131.31 KB, 160x200, mwl_53.jpg)


Fast Food
Lico: To get the nth element of a list, use nth!
[TN: These sound much less dumb in Japanese, I promise. Maybe I'll make a "vocabulary list" of things like the Japanese word for "nth element" or something.]

Lico: The first element is considered the zeroth element.
Cudder: My part is to purr, right? [???]

Lico: If the number you want is fixed, you can use functions like first and second!

Lico: Here, 1 is the head!
Yomi: Whichever is good, but I'm hungry...

nth takes a number and a list as its arguments, and returns a specific element from the list. Which element it returns is decided at run-time. Alternatively, if you decide which element to return in advance, you can use the functions first, second, ..., tenth. car and first do exactly the same thing. second is the same as cadr.

;; you can also do this
(nth (read) (list 1 2 3))

;; make nth with do
(defun my-nth1 (n lst)
(do ((n n (1- n))
(lst lst (cdr lst)))
((= n 0) (car lst))))

;; make nth with recursion
(defun my-nth2 (n lst)
(if (= n 0)
(car lst)
(my-nth2 (1- n) (cdr lst))))

Bus also Live Here
Suzu: Are there fish in this lake?

Lico: I don't know if fish live in this lake, but whether a specific element is included in a list,

Lico: If I use member, I'll know!

Suzu: When the element isn't there, it'll return nil, right?
Lico: When it is there, it returns the place it found it.

It is possible to search for a specific element in a list using the function member. It might seem like a predicate, but if the element is present, instead of t, it returns the place where it found it. It might seem like the location is ambiguous, but if you try and make member yourself, you'll understand. To check if two elements are equal, it uses the predicate eql.

;;; make member with do
(defun my-mem1 (elm lst)
(do ((lst lst (cdr lst)))
((null lst) nil)
(if (eql (car lst) elm)
(return lst))))

;;; make member with recursion
(defun my-mem2 (elm lst)
((null lst) nil)
((eql (car lst) elm) lst)
(my-mem2 elm (cdr lst)))))

Lico: Here's something called an association list.

Suzu: Bannas are yellow and apples are red!
Lico: The banna and apple here are called keys

Lico: You can use the keys to look up something in the list!

Suzu: That's amazing!
Yomi: I'm hungry...

(key value) lists, or lists whose elements are cons of the form (key . value), are called association lists. Association lists represent a relation between keys and values, so you can look things up using the keys with the function assoc.
;; make an appropriate association list
(defvar *alist*
'((banana yellow)
(apple red)))

;; looking up by key
(assoc 'banana *alist*)
;=>(banana yellow)
;; only return the value
(second (assoc 'apple *alist*))

;;; make assoc by using do
(defun my-asc (key lst)
(do ((lst lst (cdr lst)))
((null lst) nil)
(if (eql (caar lst) key)
(return (car lst)))))

Banana: slip


File: 1481913602435-0.png (135.56 KB, 150x200, mwl_54_1.jpg)

File: 1481913602435-1.png (123.64 KB, 150x200, mwl_54_2.jpg)


Cudder: Is this your strong point?
Suzu: Yup

Yomi: Fish...
Lico: There were...

Lico: This is a victory for Lico's team, now!
Yomi: You devil!!
Yomi: Team match?!

Yomi: Ugh, I'll get my revenge!
Lico: It's things like LISP

Suzu: Ah, walking on the surface of water is cool ~
Lico: Suzu! Now is not the time for that!

Yomi: Miss Lico can sink to the bottom of the ocean [???]
Lico: Even though I won, Why!

Yomi: Why? Because I...am an evil god

[Certainly an evil god]

Yomi: Then,
Yomi: Good bye, everybody!

Lico: Eh??

Suzu: That's...
Suzu: an ichthyosaurus-type UMA

Suzu: It's a UMA like in my club notebook right before my eyes!

Suzu: That's lucky anyhow!

Ichthy: Imprisoned in this lake by changes in the earth's crust in the Cretaceous Period for several ten thousand years...

Ichthy: I obtained the evil god's power, now is the time to once more put dinosaurs into the world!!
Suzu: Dinosaur talked!
Cudder: Cat time passed right through.. [TN: I have no idea]


File: 1481913634683-0.png (135.36 KB, 150x200, mwl_54_3.jpg)

File: 1481913634683-1.png (140.95 KB, 150x200, mwl_54_4.jpg)


Ichthy: First, I'll finish you all off!

Cudder: Do something! We'll be eaten!
Lico: Something like lisp is in the lake...

Te- Teeth-!?
Suzu: It came off..
Cudder: It came off with that book?

Lico: LISP, LISP saved the word!!
Suzu is scary...

Suzu: Ah, speaking of which, this lake

Suzu: This must be an artificial lake created in the Showa period [TN: 1926 ~ 1989]
Suzu: Not the Cretaceous Period...

[Thus the world's crisis was avoided.]
[If you think about it, this week may have just been a dream.]

Wakan: Suzu-

Wakana: You saw a dinosaur at the lake?
Suzu: How did you know?


That's because Suzu's UMA encounter rate is top!
No influence?

Manga Guide to Lisp

[TN: I really don't know]


File: 1481914685083-0.png (156.33 KB, 160x200, mwl11_h.jpg)

File: 1481914685083-1.png (124.59 KB, 160x200, mwl_55.jpg)


Lico: Of course, because cudders are vehicles that drive on the right side of the road!

*Lisp in Lisp*
Many of Lisp's functions can be written using Lisp. For example, so far we've written length, nth, member, and assoc in Lisp.

If you have car, cdr, cons, eq, and atom, called five functions, function definition (defun), and a conditional (cond), you can write everything in Lisp. But that being the case, it is not necessary to write programs using only these. It is better to have programs proactively using the functions and macros Common Lisp prepares in advanced. However, it's not bad to use Lisp making Lisp's functions yourself. By rewriting complicated function using simple ones, you can deepen your understanding of the functions, and also become familiar with writing programs in Lisp. When you're studying a new function, certainly, please consider whether you can rewrite it using functions you already know. I believe that making Lisp in Lisp is the shortcut to mastering Lisp.

*First Lisp*
Even the essay in which Lisp was first introduced defined lisp using Lisp itself. Looking at its history, it seems like it is correct to write Lisp in Lisp.

Lico: Cudders are the supreme vehicle of the people who used Lisp, that they themselves coud ride. [TN: not super sure about the last clause]
Suzu: Nice Cudder

Toothless Explanation
Lico: Using this, really save the word
Suzu: The teeth were just pulled out, but

Lico: Speaking of pulling out, to remove a specific element from a list, use remove!

Wakana: It copies the list, removing only the specified element.

Aya: Understanding is fast and helps

To remove a specific element from a list, use remove. If there are multiple of the specified elements, all of them are removed. Like reverse, remove creates a new list. Supposing you want to directly modify the list without recreating one, use the function delete.

;; remove b from the list
(remove 'b '(a b c))
;=>(a c)

;; since there are multiple bs, all of them are removed
(remove 'b '(b a b c b))
;=>(a c)

;; destructively modifying a list
(defvar lst1 (list 1 2 3))
(setq lst1 (delete 2 lst1))
lst1 ;=>(1 3)


File: 1481914744917-0.png (127.67 KB, 160x200, mwl_56.jpg)

File: 1481914744917-1.png (122.09 KB, 160x200, mwl_57.jpg)

File: 1481914744917-2.png (114.84 KB, 160x200, mwl_58.jpg)


You'll Definitely Get It
Lico: Let's consider how to copy a list
Aya: Use a copy machine!

Lico: First, make a new cons, and
Lico: make its car be the same as the car of the source

[The text on the blackboard is "copy source" and "copy destination"]

Lico: if the cdr-part is a cons,
Lico: put the result of doing the same thing into the cdr part of the new cons

Wakana: It seems easy to write if you use recursion!
Suzu: I think it seems complex, but?

There is a function that copies lists, called copy-list, but here we'll try and think about writing it ourselves. To copy the empty list, nil, simply return nil. Otherwise, create a new cons, make its car-part be the same as the source of the copy, and for the cdr-part repeat this operation recursively.

;;; copy a list (recursion)
(defun lcp1 (lst)
(if (null lst)
(cons (car lst)
(lcp1 (cdr lst)))))

;; list is copied perfectly
(lcp1 nil) ;=>nil
(lcp1 '(a)) ;=>(a)
(lcp1 '(a b c)) ;=>(a b c)

Final Inversion
Lico: You can do the same thing without recursion using do!

Lico: If you use do, write it easily by appending elements to the head of the list using push.

Wakana: ...In that case,
Wakana: Won't the order of the list be flipped?

Lico: That's why at the end,
Lico: you invert it using nreverse!

Let's now consider copying a list with do. In the case of following the list from its head with do, towards the empty list, pushing each car-part in succession, you'll make a list with reverse order from the source list. Here were complete the copy of the list by reversing the list. Finally if you don't call nreverse, use a function with the same behavior as reverse.

;;; list-copying function (do)
;;; (initial value of the variable acc is nil)
(defun lcp2 (lst)
(do ((lst1 lst (cdr lst1))
((null lst1)
(nreverse acc))
(push (car lst1) acc)))

Tail-Recursion is Fast
Lico: Let's rewrite the expression using do with tail-recursion.

Wakana: Provide the list to create as its second argument.

Lico: And finally complete it by reversing it
Aya: The explanation is too fast so I don't understand...

Lico: Since it's tail-recursion
Wakana: The explanation was simplified.

We'll make a function that copies a list using tail-recursion. The plan is the same as with do. The difference is that, since the arguments are reset by the recursion, it's as if push changes the cons. Incidentally, if you've been following the matter this far you probably wrote remove. Please do your best and write remove three different ways.

;;; function to copy a list
;;; (tail recursion)
(defun lcp3 (lst &optional acc)
(if (null lst)
(nreverse acc)
(lcp3 (cdr lst)
(cons (car lst)

(lcp3 '(a b c)) ;=>(a b c)



Merry Christmas, Lainchan!

Finally finished things up. The translation is, as usual, kind of poor, but the practice was nice.

The last chapter, the special chapter, I'll try and finish up before the end of the month.

Please enjoy!



Thanks OP and great job!

A merry Christmas to you too!


thank you very much, kind lainon
i wish you happy holidays!