Lispに興味はあるけど、環境構築が面倒で手を出せなかった経験はありませんか?
この記事では、コマンド1つでLispを動かし、Pythonライブラリをそのまま使えるHylangの始め方を紹介します。読み終わる頃には、Lispの基本構文からマクロの活用、shebangによるスクリプト化まで一通り試せるようになります。
Hylangでできること
- PythonのライブラリをLisp構文で利用可能
-
uvx hyでインストール不要、即座に実行 - Lispマクロを使った柔軟なコーディングスタイル
# これだけでLispが動く
echo '(print "hello world")' | uvx hy -
対象読者
- Lispに興味があるが環境構築が面倒で手を出せなかったほう
- Pythonのライブラリを関数型スタイルで使いたいほう
- Lispマクロを体験したいほう
Hylangとは
Hylangは、Python上で動作するLisp方言です。HylangのコードはPythonの抽象構文木(AST)に変換されて実行されるため、Pythonの全機能をそのまま利用できます。
なぜHylangなのか
Pythonのライブラリがそのまま使えます。
NumPy、pandas、requests、TensorFlowなどPyPIの豊富なパッケージをLisp構文で利用可能。環境構築も uvx hy の一発で完了します。
環境
| 項目 | バージョン |
|---|---|
| uv | 0.10.4 |
| Hylang | 1.2.0 |
セットアップ
uvのインストール
uvはPythonパッケージマネージャです。egetでのインストール方法を参照するか、以下のコマンドでインストールできます。
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Homebrew
brew install uv
Hylangのインストールは不要
uvx コマンドはパッケージを一時的にダウンロードして実行するため、Hylangの事前インストールは不要です。
Hylangの基本構文
Hello World
echo '(print "hello world")' | uvx hy -
hello world
ファイルから実行する場合:
(print "hello world")
uvx hy hello.hy
変数と関数
; 変数定義
(setv name "Hylang")
(setv version 1.2)
; 関数定義
(defn greet [n]
(print f"Hello, {n}"))
(greet "World")
Hello, World
リスト操作
echo '(setv nums [1 2 3 4 5])
(print (list (map (fn [x] (* x 2)) nums)))' | uvx hy -
[2, 4, 6, 8, 10]
再帰関数
(defn factorial [n]
(if (<= n 1)
1
(* n (factorial (- n 1)))))
(print (factorial 5))
120
PythonライブラリをLisp構文で呼び出す
HylangからPythonライブラリをそのまま呼び出せます。
JSONの操作
echo '(import json)
(print (json.dumps {"name" "test" "value" 42}))' | uvx hy -
{"name": "test", "value": 42}
HTTPリクエスト
echo '(import requests)
(setv resp (requests.get "https://httpbin.org/get"))
(print resp.status_code)' | uvx --with requests hy -
200
--with オプションで追加のパッケージを指定できます。
hyruleでマクロを使いこなす
hyruleは、Hylang用の便利なマクロ集です。
スレッディングマクロ
-> マクロは、処理を左から右へ連鎖させます。
echo '(require hyrule [->])
(print (-> "hello world" .upper))' | uvx --with hyrule hy -
HELLO WORLD
->> マクロは、各式の最後の引数として前の結果を渡します。
echo '(require hyrule [->>])
(print (->> [1 2 3 4 5]
(filter (fn [x] (> x 2)))
list))' | uvx --with hyrule hy -
[3, 4, 5]
hyruleの主要マクロ
| マクロ | 説明 |
|---|---|
-> |
最初の引数として結果を渡す |
->> |
最後の引数として結果を渡す |
cond |
複数条件分岐 |
unless |
条件が偽のとき実行 |
of |
型アノテーション簡略化 |
構文早見表
| 操作 | Python | Hylang |
|---|---|---|
| 変数定義 | x = 1 |
(setv x 1) |
| 関数定義 | def f(x): ... |
(defn f [x] ...) |
| 条件分岐 | if x: ... else: ... |
(if x ... ...) |
| ループ | for x in xs: ... |
(for [x xs] ...) |
| ラムダ | lambda x: x * 2 |
(fn [x] (* x 2)) |
| インポート | import json |
(import json) |
| メソッド呼出 | "hello".upper() |
(.upper "hello") |
PythonからHylangモジュールをインポートする
PythonからHylangモジュールをインポートできます。
(defn hello [] (print "Hello from Hy"))
import hy
import mymodule
mymodule.hello()
uvx --with hy python main.py
Hello from Hy
import hy を先に実行することで、.hy ファイルを通常のPythonモジュールとしてインポートできます。
依存込みで単一実行ファイルにする
shebangを使えば、依存パッケージ込みで1ファイルに完結できます。
#!/usr/bin/env -S uvx --with hyrule --with rich hy
(require hyrule [->>])
(import rich.console [Console])
(setv console (Console))
(->> ["Hello" "from" "Hylang!"]
(.join " ")
(console.print :style "bold green"))
chmod +x demo.hy
./demo.hy
まとめ
| やりたいこと | コマンド |
|---|---|
| Hylangを実行 | uvx hy script.hy |
| 対話モード | uvx hy |
| パッケージ追加 | uvx --with requests hy script.hy |
| マクロライブラリ使用 | uvx --with hyrule hy script.hy |
Hylangを使えば、Pythonの豊富なエコシステムを活用しながらLispのシンプルな構文とマクロの力を体験できます。uvx hy で今すぐ始められるので、ぜひ試してみてください。