AI言語は、LispとPrologに決まってるやろ〜 というあたくし。
Pythonって、なんや。遅いインタープリタ、ナメてんのか…
だが、Pythonって、ライブラリ呼ぶだけでイロイロできてしまう…
ライブラリの呼び出し方は、ググってコピペでOK\(^^;/
でも、やっぱり Lisp 使うぜ。
ここで軟弱な Pythonで書かれたLispを使おうかなと…
「Hy」 という軟弱 Lisp
Ubuntu 18.04.5 LTSでは、
$ sudo apt install python3-hy
で、インストールできました。
$ hy
で起動。
なんと、setq が無くて、代わりが setv。
マクロはある。
setqを defmacro するしか…
「〜」がCommon Lispの「,」にあたるようだ。
=> (defmacro setq [var val]
... `(setv ~var ~val))
=> (setq a 'asd)
=> a
'asd'
=> (setq a '(q w e))
=> a
('q' 'w' 'e')
関数でも defun するか…
あれ、defun じゃなくて、「defn」 か
=> (defn fact [x]
... (if (<= x 0) 1
... (* x (fact (- x 1)))))
=> (fact 3)
6
=> (fact 6)
720
よーし、テールリカーシブな実装になってるか、調べたろ…
=>(defn aho []
... (aho))
=> (aho)
Traceback (most recent call last):
File "/usr/lib/python3.6/code.py", line 91, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
File "<input>", line 2, in aho
File "<input>", line 2, in aho
File "<input>", line 2, in aho
[Previous line repeated 988 more times]
RecursionError: maximum recursion depth exceeded
=>
あ、アカン、素朴すぎる… \(^^;/
fnで無名関数は作れる。
でも、クロージャは作れないようだ…アカンやん。
公式ドキュメントを「closure」でサーチしても、出てこないから、無いんだろう…
=> (setv xxxx
(do(setv lll ())
(fn [x]
(if (= x 0) (setv lll ())
(setv lll(cons lll x)) (print lll)))))
... ... ... ... => => (xxxx 0)
[]
=> (xxxx 2)
Traceback (most recent call last):
File "/usr/lib/python3.6/code.py", line 91, in runcode
exec(code, self.locals)
File ">input>", line 1, in
File ">input>", line 5, in xxxx
UnboundLocalError: local variable 'lll' referenced before assignment
=>
上は、Common Lispならば こう書くやつ (if 0は省略)
(setq xxxx
(let((lll ()))
(lambda (x)
(setq lll (cons x lll)))))
* (funcall xxxx 'q)
(Q)
* (funcall xxxx 'q)
(Q Q)
* (funcall xxxx 'q)
(Q Q Q)
hyでは、setvはバインドを行う。
doは Common Lispの prog と同等らしい。
ちなみに、バインドを起こさず、set のみ行うプリミティブは、hyには無さそうなのだが…
あと、Hy のリテラルは下の表の通り、Pythonのものと対応している。
あたくしは、Python は辞書がなければ使い物にならないと考えており…
Hy の世界でPython 辞書が扱えるのは、なかなかよろしい。
だがっ! 記号(Symbol) が無いではないか。
すべてストリングかよっ。Lispなのに記号が無い。記号処理言語なのに記号が無い…
うーん、虚しい…
多分、自分でオブジェクトを独自に作ると、GCが面倒くさくなると考えたんじゃないかな…虚しい…
この表は
https://docs.hylang.org/en/master/tutorial.htmlからコピーしました。
--
Here’s an example of Hy code for each type and the Python equivalent.
Hy | Python | Type |
---|---|---|
1 | 1 | int |
1.2 | 1.2 | float |
4j | 4j | complex |
True | True | bool |
None | None | NoneType |
"hy" | 'hy' | str |
b"hy" | b'hy' | bytes |
(, 1 2 3) | (1, 2, 3) | tuple |
[1 2 3] | [1, 2, 3] | list |
#{1 2 3} | {1, 2, 3} | set |
{1 2 3 4} | {1: 2, 3: 4} | dict |
--
Python の関数を呼び出す。
オブジェクトは、Pythonのネイティブのままだから、Python関数呼び出しは楽でいい。
標準的なライブラリを呼び出す。
=> (import datetime)
=> (setv ttt (datetime.datetime.now))
=> ttt
datetime.datetime(2020, 12, 22, 20, 48, 31, 987827)
自作のPython関数。 "aho.py"ファイルとして下記を作る。
# aho.py
def aho1(d):
print('a')
for k in d:
print('key='+ str(k) +', value=' + str(d[k]))
## aho1({1:11, 2:22, 3:33})
そしてhy から呼び出し。
=> (import aho)
=> (setv dd {'a 'asd 'b 'qwe 'c 'zxc})
=> dd
{'a': 'asd', 'b': 'qwe', 'c': 'zxc'}
=> (.aho1 aho dd)
a
key=a, value=asd
key=b, value=qwe
key=c, value=zxc
=> (setv dd1 {'a 1111 'b 222 'c 333})
=> dd1
{'a': 1111, 'b': 222, 'c': 333}
=> (.aho1 aho dd1)
a
key=a, value=1111
key=b, value=222
key=c, value=333
まぁまぁいいね。
以上。