hylang (hyrule)のマクロ
hylangの各種マクロの動作を一々調べるのも億劫なので備忘。
使ったものしか反映しないので網羅性はないです。
hylang: https://docs.hylang.org/en/master/api.html?highlight=match
hyrule: https://hyrule.readthedocs.io/en/master/
hylangは1.0+a4から0.24にバージョンアップし、構文がいくつか変更されました。
- タプルが
(, x)
から#(x)
になった。 -
if test a b
が必ずTrue
の場合とFalse
の場合の値を与えなければならなくなった。 -
cond [x y]
がcond a b
になった。 - タグマクロは廃止され、リーダーマクロとその定義マクロ
defreader
が追加された。- リーダーマクロは
(require hyrule :readers [%])
のように:readers
の後にシンボルのリストかキーワード*
によって導入する。
- リーダーマクロは
もしかしたらごちゃごちゃになっているかもしれませんがご容赦ください。
. #* args
hylangのマクロ
args
のもつメソッドやプロパティに逐次的にアクセスする。
例えばPythonで下のように書ける場合、
text = " Hello World "
text.strip().split()
['Hello', 'World']
hylangでは.
を利用して、
(setv text " Hello World ")
(. text (strip) (split))
['Hello', 'World']
と書ける。
いわゆるメソッドチェーン。
評価後の値を次の評価に使うので、状態変化後に値を返さない(Noneが返る)メソッドはこれを使った連続は行えない。
-> head #* body
hyruleのマクロ
head
を最初にとってbody
の第一引数に入れ...を繰り返す。
hylangではメソッド呼び出しを関数と同様の語順で書けるので、.
を関数呼び出しに対応させたような感じ。
上記の(. text (strip) (split))
を最終的にprint
するように書き直す。
(setv text " Hello World ")
(-> text (.strip) (.split) (print))
['Hello', 'World']
->
では次に来る値が必ず第一引数になるので、それまでの操作を任意の場所に入れるにはas->
を用いる。
as-> head name #* rest
hyruleのマクロ
name
に今持っている結果の値を入れていく。
(require hyrule ["as->"])
(setv text " Hello World ")
(as-> text it
(.strip it)
(.split it)
(print "this code returned" it))
this code returned ['Hello' 'World']
ncut seq key1 #* keys
hyruleのマクロ
複数のスライスを一度に渡すことのできるマクロ。
例えばnumpyの多次元配列の一部をスライスで取るとき、スライスを2つ渡す。
import numpy as np
m = np.arange(9).reshape(3,3)
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
m[1:3, 1:3]
array([[4, 5],
[7, 8]])
ところがcut
はこのような操作を行うことができない。
(import numpy :as np)
(require hyrule [->])
(setv m (. (np.arange 9) (reshape 3 3)))
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
(-> m (cut 1 3) (cut 1 3))
array([[6, 7, 8]])
# m[1:3][1:3] と等価
これを解決したいときにncut
をつかう。
(ncut m 1:3 (: 1 3))
array([[4, 5],
[7, 8]])
アクセスする引数にはスライス・タプル・単なる値が使える。
ap-when test-form #* body
hyruleのマクロ
test-form
をキーワードit
で呼び出せる
(ap-when 1
f"ok {it}")
"ok 1"
doto form #* expressions
hyruleのマクロ
form
の評価値を各expressions
の第一引数に入れてexpressions
を順次実行する。
form
を返す。
(require hyrule [doto])
(setv a (doto [1 2 3]
(.append 4)
(print "is inter")
(.extend [5 6])))
(print "a:" a)
[1, 2, 3, 4] is inter
a: [1, 2, 3, 4, 5, 6]
pythonにありがちな状態変更メソッドをまとめるのに便利。
%
hyruleのリーダーマクロ
次のシンボルにある%n
をその位置に引数を入れる関数に変更する。
n
は数値。
#% (a %1 b)
は、
(fn [n1] (a n1 b))
と等価。
n
は歯抜けでもよく、その場合抜かされた値は使われない。
%n
がなくても関数オブジェクトになるので、threading.Thread
のような関数オブジェクトを引数に取るものに式を渡すのにも使える。
py string
hylangのマクロ。
pythonの式であるstring
をhyのコンパイル時に埋め込む。
式の値が返ってくる
状態を持つような場合はpys
を使う。
pys
は中身に関わらずNoneを返す