Lispコーディング環境構築

# はじめに
[Turing Complete FM](https://turingcomplete.fm/)を聞いていたらLispを書いてみたくなったので、Azure VM上でLispのコーディング環境を整えてみました。最後に簡単なプログラムも書いてみます。

# Lispとは
- 1958年にジョン・マッカーシーにより設計された、かなり古くからあるプログラミング言語。Fortranに次いで2番目に古い
- List Processorの略。その名の通りListが重要らしい
- 強い動的型付け言語
- インタプリタ言語であるため、実行時に明示的にコンパイルする必要がない。Lispインタプリタによって逐次命令が解釈され実行される
- Lispについて調べていて思ったのが、Lispのソースコードや公式サイト、リファレンスサイトが見当たらないこと。頼りになるのはwikipediaだけ、みたいな感じ
- ジョン・マッカーシーの書いた原案の論文が聖書みたいな感じになっていて、それを基に様々な実装が生まれている
- LispとclispやSchemeの関係性は、LinuxとubuntuやCentOSの関係性と似たような感じかもしれない
- ジョン・マッカーシーの論文ではS式（カッコがいっぱいのほう）とM式の2つの文法が示されており、論文中ではM式を推している感じだったが、今ではほとんどのLispの実装がS式である
- 様々な方言が存在しており、有名なのはCommon LispとSchemeである。前者は高機能、後者はシンプルで低機能というイメージらしい
- Common Lispにもいくつかの実装がありSBCL(Steel Bank Common List)やGNU CLISPなどがある
- Schemeの仕様書は50ページにも満たないため様々な実装が存在している。他にもJVM上で動作するClojureなどもある

## 原典

http://www-formal.stanford.edu/jmc/recursive.html

Lispが考案された時のジョン・マッカーシーが書いた論文。
この論文を読んだスティーブ・ラッセルが機械語でLispを実装した。

# clispのコーディング環境を整える
以下ではCommon Lispの派閥であるGNU clisp（clisp）が使える環境を整えていく。
clispは元々アタリ(ゲーム会社)のために開発されたらしい。

## Dockerのインストール（Ubuntu 18.04）
Dockerってほんと便利だよね！

[私の記事](https://qiita.com/maplejava/items/7429dfe7c8f33fa7f8eb#docker%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%ABubuntu-1804)を参照してDockerをインストールする。

## clispイメージの実行
Dockerがインストールされたあなたは、以下どちらかのDockerfileを書いて…

- Dockerfile v2 (コンテナ内でlispファイル作ったりしたい版)
```
FROM ubuntu:18.04
RUN apt-get -y update && apt-get install -y vim && apt-get install -y clisp
```
- Dockerfile latest (ホストでコンソールに入る版)
```
FROM ubuntu:18.04
RUN apt-get -y update && apt-get install -y clisp
CMD clisp
```
以下のコマンドを打つだけ！
```
docker build -t my-clisp-image .
docker run -it --rm my-clisp-image
```
clispのコンソールが起動します。

# clispの文法

- 前置記法（ポーランド記法）である。ちなみに逆ポーランド記法の言語もある（Forthという言語）。そうするとカッコが不要らしい

```lisp
(print(+ 1 1))
```

早速FizzBuzzでも書いてみよう！

```lisp:FizzBuzz.lisp
(defun fizzbuzz (x)
  (cond
   ((zerop (mod x 15)) "Fizzbuzz")
   ((zerop (mod x 3))  "Fizz")
   ((zerop (mod x 5))  "Buzz")
   (t x)))

(defun fizzbuzz-solver (s e)
  (unless (> s e)
    (print (fizzbuzz s))
    (fizzbuzz-solver (1+ s) e)))

(fizzbuzz-solver 1 100)
```
ちなみに、[この記事](https://qiita.com/maplejava/items/792eb8a9f11fb5dc3ea1)で紹介したElixirでFizzBuzzを書くと以下のような感じ。
```elixir:FizzBuzz.exs
#! /usr/bin/env elixir

defmodule FizzBuzz do
  def run(limit) do
    print(1, limit)
  end

  defp print(n, limit) when n == limit do
    cond do
      rem(n, 15) == 0 -> IO.puts "#{n}: FizzBuzz"
      rem(n, 5)  == 0 -> IO.puts "#{n}: Fizz"
      rem(n, 3)  == 0 -> IO.puts "#{n}: Buzz"
      true            -> nil
    end

  end

  defp print(n, limit) do
    print(n, n)
    print(n + 1, limit)
  end

end

input = 10

FizzBuzz.run(input);

# elixir ./fizzbazz.exs で実行
# ----
# 3: Buzz
# 5: Fizz
# 6: Buzz
# 9: Buzz
# 10: Fizz
```
どちらの言語も色があっていいね！

# Lispの魅力
最後に、Lispを使っていて気づいた魅力を書きます。

Lispは、カッコばっかりなのが特徴ですが、これが癖になりますね！
マトリョーシカのように中から順に値を取り出して処理が進んでいくのです。そう考えると、データの流れがとても分かりやすい言語ですよね。
プログラムは結局データの流れを記述しているわけですから、Lispは非常に優れた言語であるという根強い人気の理由がわかった気がしました。

# 参考
[CLISP](https://ja.wikipedia.org/wiki/CLISP)

[M.Hiroi's Home Page / Common Lisp Programming](http://www.nct9.ne.jp/m_hiroi/clisp/index.html#abc)

[Common lisp by examples](http://csci.viu.ca/~wesselsd/courses/csci330/code/lisp/)

[Lispって何？[Lisp入門の入門] - Qiita](https://qiita.com/kikikaikai12/items/f146009b403ed9395fe0)

[いまから始めるCommon Lisp - Qiita](https://qiita.com/t-sin/items/054c2ff315ec3b9d3bdc)