Python を触っていない Lisper のための Hy 環境構築

この記事は、[Lisp Advent Calendar 2019](https://qiita.com/advent-calendar/2019/lisp) の 15 日目の記事です。

# この記事の要旨

Hy は Python の Virtual Machine 上で動作する Clojure ライクな Lisp 方言です。
Python を触ったことがない Lisper (主にClojurian) 向けに、Hy の環境構築方法に絞って説明していきます。

# 対象読者

* Python を触ったことがない Lisper (主にClojurian)

Hy 自体の入門ドキュメントとしては、公式チュートリアルか先人の記したものを参照していただければと思います。

* [Hy tutorial](http://docs.hylang.org/en/stable/tutorial.html)
* [Hy ショートイントロブック](https://booth.pm/ja/items/1570502)

# 環境構築

## Python をインストールする

### Windows 10 の場合

[python.org](https://www.python.org/) からインストーラをダウンロードしてインストールするのが簡単です。
いきなり罠なのですが、python.org のトップページからダウンロードできる最新版インストーラは 32bit 版です（2019/12時点）。
32bit 環境でない限りはインストールしないように気を付けましょう。

<img width="1920" alt="2019-12-10_22h14_25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543140/8c56e78f-3a53-ce86-9cf1-cdbd736d5ef9.png">

### MacOS の場合

Homebrew をインストールし、```brew``` コマンドでインストールするのが一般的なようです。

```$ brew info python``` でインストール可能なバージョンを確認すると、3.7.5 でした (2019/12/13 時点)。

Homebrew でインストールされる Python 3 (3.7.5) の場所

```
/usr/local/bin/python3
```

site-packages の場所

```
/usr/local/lib/python3.7/site-packages
```

## 仮想環境の構築

Python 本体の site-packages にサードパーティー製モジュールをインストールしても動作はするのですが、
プロジェクトごとに仮想環境を使い分けると元環境を汚さずに済み、他プロジェクトへの影響を回避できます。
デフォルトで付属している ```venv``` コマンドを使って仮想環境を作る場合、作成したいディレクトリ下で、下記のように実行すると作成されます。

```
$ python -m venv <venv名>
```

もし、仮想環境を使っているうちに後述するサードパーティー製モジュールの依存関係がめちゃくちゃになってしまったら、そのまま捨てて新しく作り直すだけです。

仮想環境の有効・無効を切り替えるには、```activate```・```deactivate``` コマンドを使います。
venv 内にある ```activate``` の場所は Shell や OS によって違うため、[venv --- 仮想環境の作成](https://docs.python.org/ja/3/library/venv.html) 内の「仮想環境を有効化するためのコマンド」を参照ください。


## モジュールのインストール

Python をインストールした段階で、[標準ライブラリ](https://docs.python.org/ja/3/library/index.html) が一緒にインストールされており、それらを Hy から使うことができます。Python はバッテリー内蔵言語のため、標準ライブラリだけでも割といろいろなことができます。

標準ライブラリ以外のサードパーティー製モジュールを使用したい場合は、パッケージ管理ツールの [pip](https://docs.python.org/ja/3/installing/index.html) を使って仮想環境にインストールします。
基本的に、Python のモジュールは（ほとんど）すべて Hy で動作します。
もちろん、Hy で書かれたモジュールも同じバージョンであれば動作します（ほとんど見当たりませんが…）。
Python のサードパーティー製モジュールは [PyPI](https://pypi.org/) で探すとよいでしょう。
たまに、PyPI に登録されていない Python モジュールがありますが、それらのインストール方法も後述します（GitHub リポジトリで管理されているものに関して）。

科学計算用ライブラリ Anaconda をインストールし、```conda``` でモジュール管理をするという手もあります。
```pip``` と併用すると環境が壊れることがあるため、この記事ではインストールしないものとします。

仮想環境を ```activate``` し、```pip install <モジュール名>```でモジュールをインストールします。
一括でインストールしたい場合は、モジュール名を改行で区切った requirements.txt を書き、```pip install -r requirements.txt``` を実行します。慣例として requirements.txt という名前にしていますが、別の名前でも構いません。

```text:requirements.txt
hy
openpyxl
PySide2
```

特定のバージョンを指定することもできます。

```text:requirements.txt
hy==0.17.0
openpyxl==3.0.2
PySide2==5.13.2
```

モジュールが GitHub リポジトリにしかない場合は、

```
pip install git+https://github.com/hoge/fuga.git
```

のようにします。
これを requirements.txt に含めることもできます。

その環境にインストールしたサードパーティー製モジュールの一覧を確認したい場合は、```pip freeze``` を実行します。
```pip freeze > requirements.txt``` のように書き出しておけば、環境が壊れてしまった場合も復帰が楽になります。

## エディタ・IDE

Hy のプラグインがあるエディタ・IDE はまだほとんどありません。私が知る限りでは、下記の三つのみです。

* Emacs
 * [hy-mode](https://melpa.org/#/hy-mode)

* Vim
 * [vim-hy](https://github.com/hylang/vim-hy)

* Visual Studio Code
 * [vscode-hy](https://marketplace.visualstudio.com/items?itemName=xuqinghan.vscode-hy)

# パッケージの作り方

自作のアプリケーションやライブラリを階層化したいときは、パッケージを作成すると管理しやすいです。

```
hy ─┬─ hoge ─┬─ fuga ─┬─ __init__.hy
    .        │        .
    └─ piyo  │        └─ bar.hy
             │
             ├─ __init__.hy
             .
             └─ foo.hy
```

上図で環境変数 [PYTHONPATH](https://docs.python.org/ja/3/using/cmdline.html#envvar-PYTHONPATH) に ```hy``` ディレクトリを追記した場合、
hoge 以下のディレクトリにそれぞれ \_\_init\_\_.hy を置くことで

```hylang:example_import.hy
(import hoge)  ;; hogeの__init__.hy がインポートされる
(import hoge.foo)
(import hoge.fuga)  ;; hoge/fugaの__init__.hy がインポートされる
(import hoge.fuga.bar)
```

のように書くことができます。このパッケージの構造は Python と同様です。

[Python チュートリアル > 6. モジュール > 6.4. パッケージ](https://docs.python.org/ja/3/tutorial/modules.html#packages)

# まとめ
* Hy の環境構築は Python のそれとほとんど同じです。
* 仮想環境を作ると大元の環境が汚されずに済みます。仮想環境が壊れても、捨てて作り直すだけです。
* Hy は、Python の標準ライブラリがデフォルトで使用できます。
* 標準ライブラリになければサードパーティー製モジュールを PyPI などで探して ```pip``` でインストールします。
* requirements.txt を ```pip freeze``` で書き出しておくと保険になります。

それでは、良い Hy ライフを。