これは、Ubuntu Online、Fedora Online、Windows オンライン エミュレーター、または MAC OS オンライン エミュレーターなどの複数の無料オンライン ワークステーションの XNUMX つを使用して、OnWorks 無料ホスティング プロバイダーで実行できるコマンド hy です。
プログラム:
NAME
hy - hy ドキュメント [画像: Hy] [画像]
意図に基づいて、適切なメッセージを適切なユーザーに適切なタイミングで Hy https://try-hy.appspot.com
PyPI https://pypi.python.org/pypi/hy
ソース https://github.com/hylang/hy
リスト ハイランディスカッション
IRC #ハイ フリーノード上
建設 status
トラビス CI.インデントなし
Hy は、Python に組み込まれた Lisp の素晴らしい方言です。
Hy はその Lisp コードを Python 抽象構文ツリーに変換するので、次のようになります。
Python の美しい世界全体を Lisp 形式ですぐに利用できます。
内容:
クイックスタート
[画像: カレン・ラスタードの抱擁] [画像]
(抱っこしてくれたカレン・ラスタッドに感謝!)
HOW に GET HY リアル スピーディー:
1。 作成する バーチャル Python 環境.
2. 仮想 Python 環境をアクティブ化します。
3。 インストール hy from PyPI ピップ install hy.
4. REPL を開始します。 hy.
5. REPL に次のように入力します。
=> (「やあ!」と出力)
やあ!
=> (defn salutationsnm [名前] (print (+ "Hy " name "!")))
=> (挨拶文「あなたの名前」)
こんにちは、あなたの名前です!
等
6. 完了したら、CTRL-D を押します。
ああ、神様! それです 素晴らしいです! I 欲しいです 〜へ 書きます a Hy プログラム。
7. エリート プログラミング エディターを開き、次のように入力します。
(print "Python 構文でコーディングするつもりでしたが、Hy になりました。")
8.名前を付けて保存 すごい.hy.
9. そして、最初の Hy プログラムを実行します。
やあすごい。
10.
過呼吸にならないように深呼吸しましょう。
11.
悪人のように微笑んで隠れ家にこっそり行って、言葉では言い表せないようなことをしてください。
チュートリアル
Hy チュートリアルへようこそ!
一言で言えば、Hy は Lisp の方言ですが、その構造を Python に変換するものです。
文字通り、Python の抽象構文ツリーへの変換です。 (もっと大雑把に言うと、
つまり、Hy は Python で舌足らずな人間なのです!)
これは、Hy がいくつかのことを意味しているので、非常にクールです。
· 非常にPython的だと感じるLisp
· Lispers にとっては、Lisp のクレイジーな能力を使用する素晴らしい方法ですが、Python の広い世界でも使用できます。
ライブラリ (そうです、Lisp で Django アプリケーションを作成できるようになりました!)
· Pythonista にとって、快適な Python から Lisp の探索を始める素晴らしい方法です。
· 誰にとっても: 素敵なアイデアがたくさん詰まった楽しい言語です。
Basic intro 〜へ リスプ for パイソンニスタ
さて、あなたはこれまで Lisp を使ったことはないかもしれませんが、Python は使ったことがあるでしょう。
Hy の「hello world」プログラムは、実際には非常に単純です。 試してみよう:
(「Hello World」を印刷)
見る? 簡単! ご想像のとおり、これは次の Python バージョンと同じです。
「ハローワールド」を印刷する
非常に単純な計算を加えると、次のようになります。
(+1 3)
これは 4 を返し、次と同等になります。
1 + 3
リストの最初の項目が呼び出される関数であり、
残りの引数は渡される引数です。実際、Hy では (ほとんどの場合と同様)
Lisp) 複数の引数を plus 演算子に渡すことができます。
(+1 3 55)
これは 59 を返します。
おそらく、Lisp について聞いたことはあっても、それについてはあまり知らないかもしれません。 Lispはあなたほど難しくありません
Hy は Python から継承しているため、Hy は Lisp の学習を始めるのに最適な方法です。
Lisp に関して明らかな主な点は、括弧がたくさんあるということです。 これはもしかしたら
最初は戸惑うように思えますが、それほど難しいことではありません。 簡単な数学を見てみましょう。
Hy インタープリタに入力できる括弧の束で囲まれています。
(setv 結果 (- (/ (+ 1 3 88) 2) 8))
これは 38 を返します。しかし、なぜでしょうか? さて、同等の式を次のように見ることができます。
パイソン:
結果 = ((1 + 3 + 88) / 2) - 8
上記が Python でどのように機能するかを理解しようとすると、もちろん次のようになります。
それぞれの内側の括弧を解くことで結果を導き出します。 それは同じ基本的な考え方です
やあ。 まずは Python でこの演習を試してみましょう。
結果 = ((1 + 3 + 88) / 2) - 8
# 簡略化すると...
結果 = (92 / 2) - 8
# 簡略化すると...
結果 = 46 - 8
# 簡略化すると...
結果= 38
次に、Hy で同じことを試してみましょう。
(setv 結果 (- (/ (+ 1 3 88) 2) 8))
; 簡略化すると...
(setv結果(-(/92)2))
; 簡略化すると...
(setv結果(-46))
; 簡略化すると...
(setv結果38)
おそらくご想像のとおり、この最後の表現は セット 変数を代入することを意味します
「結果」は38まで。
見る? あまり大変ではありません!
これは Lisp の基本前提です。 Lisp は「リスト処理」の略です。 これは、
プログラムの構造は実際にはリストのリストです。 (Pythonに詳しい方なら
リストの場合、上記と同じ構造を想像してください。ただし、代わりに角かっこが使用されています。
上記の構造をプログラムとデータ構造の両方として見ることができます)。
より多くの例を使用すると理解しやすいので、簡単な Python プログラムを作成してテストしてみましょう。
次に、同等の Hy プログラムを表示します。
def simple_conversation():
print 「こんにちは!あなたのことを知りたいのですが、あなた自身について教えてください。」
name = raw_input("あなたの名前は何ですか?")
age = raw_input("あなたの年齢は何歳ですか? ")
print "こんにちは " + 名前 + "! あなたは " + 年齢 + " 歳ですね。"
simple_conversation()
このプログラムを実行すると、次のようになります。
こんにちは! あなたと知り合いになりたいです。 自己紹介をお願いします!
名前はなんですか? ゲイリー
あなたは何歳ですか? 38
こんにちは、ゲイリー! 38歳だそうですね。
次に、同等の Hy プログラムを見てみましょう。
(defn 簡単な会話 []
(「こんにちは!あなたのことを知りたいです。あなた自身について教えてください!」を印刷)
(setv name (生入力「あなたの名前は何ですか?」))
(setv age (生入力「あなたの年齢は何ですか?」))
(print (+ "こんにちは " name "! あなたは "
年齢 " 歳。")))
(簡単な会話)
上記のプログラムを見ると、それぞれの最初の要素が
プログラムのリストは呼び出される関数 (またはマクロ...後で説明します) です。
残りが引数であると考えれば、これが何を意味するのかを理解するのは非常に簡単です。
(あなたもおそらくご想像のとおり、 定義 メソッドを定義する Hy メソッドです)。
それでも、かっこが多すぎるため、最初は混乱する人が多いです。
しかし、これを簡単にするために役立つものがたくさんあります。インデントを適切に保つことと、
括弧を一致させてエディタを使用します (これは、それぞれが何を意味するかを理解するのに役立ちます)
括弧は) と組み合わせると、快適に感じられるようになります。
実際には非常に単純なデータであるコード構造を持つことにはいくつかの利点があります
Lisp のコアとなる構造が基づいています。 まず、それはあなたのプログラムが
解析が簡単で、プログラムの実際の構造全体が非常に明確に露出されます。
あなたへ。 (hy には、表示されている構造が Python の構造に変換される追加のステップがあります。
独自の表現 ... Common Lisp や Emacs Lisp などの「より純粋な」Lisp では、データ
コード内に表示される構造と、実行されるデータ構造はさらに複雑です。
文字通り近いです。)
これのもう XNUMX つの意味はマクロです。プログラムの構造が単純なデータの場合
つまり、非常に簡単にコードを記述できるコードを作成できるということです。
まったく新しい言語機能を非常に迅速に実装できます。 Hy の前はそうではありませんでした
Python プログラマーにとっては非常に可能です...これであなたもマクロの驚異的な機能を利用できるようになります
力を入れてください(足元に向けないように注意してください)!
Hy is a Lisp風味 Python
Hy は Python 独自の抽象構文ツリーに変換するため、すぐにすべてのことが分かるでしょう。
おなじみの Python のパワーをすぐに利用できます。
Hy の Python のデータ型と標準ライブラリに完全にアクセスできます。 実験してみましょう
hy インタプリタでは次のようになります。
=> [1 2 3]
[1、2、3]
=> {「犬」「吠える」
...「猫」「ニャー」}
...
{'犬': '鳴き声', '猫': 'ニャー'}
=> (, 1 2 3)
(1、2、3)
他の Lisp に精通している場合は、Hy が Common Lisp をサポートしていることに興味があるかもしれません。
Lisp による引用方法:
=> '(1 2 3)
(1L 2L 3L)
すべての組み込み型の便利なメソッドにもアクセスできます。
=> (.strip " fooooo ")
「ふおおお」
これは何ですか? はい、確かに、これは次とまったく同じです。
" ふぉおお ".strip()
そう、ドット記法を使ったLispなのです! この文字列を変数として割り当てた場合、
次のこともできます。
(setv this-string " fooooo ")
(この文字列.ストリップ)
条件文についてはどうですか?:
(if (何かを試してみる)
(「これが true の場合」を出力)
(「これが false の場合」を出力))
上でわかるように、最初の引数は if は真実テスト、XNUMX 番目の引数は
true の場合は本文、false の場合は XNUMX 番目の引数 (オプション!) です。 ほかに).
より複雑な条件を実行する必要がある場合は、次のものがないことがわかります。 elif
ハイで利用可能です。 代わりに、と呼ばれるものを使用する必要があります。 条件。 Python では、次のようにすることができます
何かのようなもの:
サムバー = 33
somevar > 50の場合:
print "その変数は大きすぎます!"
elif somevar < 10:
print "その変数は小さすぎます!"
その他:
print "その変数はまさに正しいです!"
Hy では、次のようにします。
(条件
[(> somevar 50)
(print "その変数は大きすぎます!")]
[(< somevar 10)
(print "その変数は小さすぎます!")]
[真実
(print "その変数はまさに正しい!")])
あなたが気づくことは、 条件 実行されるステートメントとステートメントの間でスイッチをオフにします。
真か偽かを条件付きでチェックし、結果が変わった場合に実行する少しのコード
それは真実です。 また、 ほかに 最後に単に次のように実装されます
のチェック true -- それはなぜですか true は常に true になるので、ここまで到達したら、
常にそれを実行してください!
次のようなコードがある場合、上記のことに気づくかもしれません。
(何らかの条件がある場合
(trueの場合の本体)
(偽の場合の本体))
ちょっと待って! 次のいずれかの本文で複数のステートメントを実行したい場合はどうすればよいですか?
これらは?
次のことができます。
(if (何かを試してみる)
(から
(「これが true の場合」を出力)
(print "そしてなぜそうではないのか、それがいかに真実であるかについて話し続けましょう!))
(「これはまだ単に偽です」と表示します))
使用したことがわかります do 複数のステートメントをラップします。 他に詳しいなら
Lisp、これは次のものと同等です 突起 他の場所。
コメントはセミコロンで始まります。
(「これは実行されます」と印刷)
; (「しかし、これはそうではありません」と印刷)
(+ 1 2 3) ; 追加は実行しますが、このコメントは実行しません。
ループ処理は難しいことではありませんが、ある種の特別な構造を持っています。 Python では、次のようにします。
私のために 範囲(10):
print "'i' は現在 " + str(i) にあります
Hy では次のようになります。
([i (範囲 10)] の場合
(print (+ "'i' は現在 " (str i)) にあります))
さまざまな Python ライブラリをインポートして使用することもできます。 例えば:
(OSをインポート)
(if (os.path.isdir "/tmp/somedir")
(os.mkdir "/tmp/somedir/anotherdir")
(「おい、その道はないよ!」と印刷))
Python のコンテキスト マネージャー ( ステートメント) は次のように使用されます。
([[f ("/tmp/data.in" を開く)]] を使用
(print (.read f)))
これは次と同等です:
open("/tmp/data.in") を f として使用:
print f.read()
そしてはい、リスト内包表記があります。 Python では次のようにすることができます。
オッズ二乗 = [
pow(num, 2)
番号入力用 範囲(100)
if num % 2 == 1]
Hy では、次のように実行できます。
(setv オッズ二乗
(リスト-コンプ
(パワー番号 2)
(数値(範囲100))
(= (% num 2) 1)))
; そして、例は Clojure ページから恥知らずにも盗まれました:
; チェス盤のすべてのブロックをリストしてみましょう。
(リスト-コンプ
(、xy)
(x (範囲 8)
y "ABCDEFGH"))
; [(0, 'A'), (0, 'B'), (0, 'C'), (0, 'D'), (0, 'E'), (0, 'F'), ( 0, 'G')、(0, 'H')、
; (1, 'A')、(1, 'B')、(1, 'C')、(1, 'D')、(1, 'E')、(1, 'F')、(1 、'G')、(1、'H')、
; (2, 'A')、(2, 'B')、(2, 'C')、(2, 'D')、(2, 'E')、(2, 'F')、(2 、'G')、(2、'H')、
; (3, 'A')、(3, 'B')、(3, 'C')、(3, 'D')、(3, 'E')、(3, 'F')、(3 、'G')、(3、'H')、
; (4, 'A')、(4, 'B')、(4, 'C')、(4, 'D')、(4, 'E')、(4, 'F')、(4 、'G')、(4、'H')、
; (5, 'A')、(5, 'B')、(5, 'C')、(5, 'D')、(5, 'E')、(5, 'F')、(5 、'G')、(5、'H')、
; (6, 'A')、(6, 'B')、(6, 'C')、(6, 'D')、(6, 'E')、(6, 'F')、(6 、'G')、(6、'H')、
; (7, 'A')、(7, 'B')、(7, 'C')、(7, 'D')、(7, 'E')、(7, 'F')、(7 、'G')、(7、'H')]
Python は、さまざまな派手な引数とキーワード引数をサポートしています。 Python では次のようになります。
見る:
>>> defOptional_arg(pos1, pos2, キーワード 1=なし, キーワード 2=42):
... return [pos1, pos2, キーワード1, キーワード2]
...
>>> オプション引数(1, 2)
[1、2、なし、42]
>>> オプション引数(1, 2, 3, 4)
[1、2、3、4]
>>> オプション引数(キーワード 1=1、位置 2=2、位置 1=3、キーワード 2=4)
[3、2、1、4]
Hyでも同じこと:
=> (defn オプション引数 [pos1 pos2 &オプションのキーワード 1 [キーワード 2 42]]
... [pos1 pos2 キーワード1 キーワード2])
=> (オプションの引数 1 2)
[1 2 なし 42]
=> (オプションの引数 1 2 3 4)
[1 2 3 4]
Hy の 0.10.1 以降のバージョン (例: git master) を実行している場合は、新しい便利な機能もあります。
キーワード引数の構文:
=> (オプションの引数:キーワード1 1
... :pos2 2
... :pos1 3
... :キーワード2 4)
[3、2、1、4]
それ以外の場合は、いつでも使用できます 適用する。 しかし、何ですか 適用する?
通過することに慣れていますか * args と ** kwargs Python で?:
>>> 引数 = [1 2]
>>> kwargs = {"キーワード2": 3
... "キーワード1": 4}
>>>Optional_arg(*args, **kwargs)
これを再現できるのは、 適用する:
=> (setv args [1 2])
=> (setv kwargs {"キーワード2" 3
... "キーワード 1" 4})
=> (optional-arg args kwargs を適用)
[1、2、4、3]
次のような辞書スタイルのキーワード引数の構造もあります。
(defn 別のスタイル [&key {"key1" "val1" "key2" "val2"}]
[キー1 キー2])
ここでの違いは、これは辞書であるため、特定の用語に依存できないことです。
引数の順序付け。
Hyもサポートします * args と ** kwargs。 Pythonの場合:
def some_func(foo, bar, *args, **kwargs):
印刷物をインポートする
pprint.pprint((foo, bar, args, kwargs))
Hy に相当するもの:
(defn some-func [foo bar &rest args &kwargs kwargs]
(印刷物をインポート)
(pprint.pprint (, foo bar args kwargs)))
最後に、もちろん授業が必要です。 Python では、次のようなクラスが考えられます。
クラスFooBar(オブジェクト):
「」 "
さらに別のクラスの例
「」 "
def __init__(self, x):
self.x = x
def get_x(self):
「」 "
x のコピーを返します
「」 "
self.x を返す
ハイでは:
(defclass FooBar [オブジェクト]
「さらに別のクラス例」
[[ - 初期化 -
(fn [自分自身 x]
(setv self.xx)
; __init__ には None が必要なため、現在 --init-- に必要です
; これがなくなることを願っています:)
なし)]
[取得-x
(fn [自分自身]
「x のコピーを返してください」
self.x)]])
クラスレベルの属性を実行することもできます。 Python の場合:
クラス顧客(models.Model):
名前 = モデル.CharField(max_length=255)
アドレス = モデル.TextField()
メモ = models.TextField()
ハイでは:
(defclass Customer [models.Model]
[[名前 (models.CharField :最大長 255})]
[アドレス(models.TextField)]
[メモ (models.TextField)]])
Hy <-> Python 相互運用
Hy をインポートすると、Python から直接 Hy を使用できるようになります。
以下を保存すると ご挨拶.hy:
(defngreet [名前] (print "hello from hy," name))
その後、モジュールをインポートする前に hy をインポートすることで、Python から直接使用できます。 の
Python:
インポートハイ
挨拶文をインポートする
挨拶.greet("フー")
Python で関数 (またはクラス!) を宣言し、それを Hy! で使用することもできます。
以下を保存すると 挨拶.py Pythonの場合:
デフォルトの挨拶(名前):
print("こんにちは、%s" % (名前))
Hy で使用できます。
(挨拶をインポート)
(.挨拶「ふー」)
キーワード引数を使用するには、次のように使用できます。 挨拶.py:
def 挨拶(名前、タイトル = "先生"):
print("こんにちは、%s %s" % (タイトル,名前))
(挨拶をインポート)
(「フー」と挨拶)
(.挨拶「フー」「ダース」)
(適用 (. 挨拶 挨拶) ["Foo"] {"title" "Lord"})
どちらが出力されますか:
こんにちは、フー卿
こんにちは、ダース・フー
こんにちは、フー様
ヒント!
Hy には、「スレッド マクロ」として知られる機能もあります。これは、Hy の非常に優れた機能です。
クロージュアさん。 「スレッドマクロ」(次のように記述されます) ->) は、深いネストを避けるために使用されます。
式。
スレッド マクロは、各式を次の式の最初の引数に挿入します。
場所。
古典的なものを取り上げてみましょう。
(ループ (print (eval (read))))
このように書くのではなく、次のように書くこともできます。
(-> (読み取り) (評価) (印刷) (ループ))
今、を使用して Python-sh、スレッドマクロがどのように実行されるかを示すことができます(python-shのセットアップのため)
パイプのように使用できます。
=> (インポート [sh [cat grep wc]])
=> (-> (cat "/usr/share/dict/words") (grep "-E" "^hy") (wc "-l"))
210
もちろん、これは次のように拡張されます。
(wc (grep (cat "/usr/share/dict/words") "-E" "^hy") "-l")
はるかに読みやすくなりましたね? スレッドマクロを使ってみよう!
HY スタイル ガイド
「ご存知のように、大臣、私は多くの点でダンブルドアの考えに同意しません…しかし、彼がそうであることを否定することはできません。
スタイルがある…」 — フィニアス・ナイジェラス・ブラック、 ハリー ポッター と 注文 of フェニックス
Hy スタイル ガイドは、Hyve (そう、Hy コミュニティ) の一連の基本ルールとなることを目的としています。
すべてに Hy を追加して慣用的な Hy コードを記述することに誇りを持っています。 Hy は多くのことをもたらします
Clojure と Common Lisp からの移行を実現しながら、Python の相互運用性を常に維持します。
前奏曲
この 道 of Hy
雲門は住職に「何のお経を説いているのですか?」と尋ねました。
「涅槃経」。
「涅槃経には四徳がありますね」
「それはあります。」
ウンモンはカップを手に取りながら尋ねた、「これにはいくつの徳があるの?」
「何もありません」と僧侶は言いました。
「でも古代の人たちはそうだったって言ってたよね?」 ウンモンは言った。
「彼らが言ったことについてどう思いますか?」
ウンモンはカップをたたき、「分かりましたか?」と尋ねた。
「いいえ」と僧侶は言いました。
「それでは、お経の講義を続けたほうがいいでしょう」とウンモンは言いました。
— (公案) マクロ
以下に、作成にあたり行われた設計上の決定事項の簡単なリストを示します。
HY。
· Lisp のように見えます。 DTRT を使用すると (例: ダッシュがアンダースコアに変わり、イヤーマフが
すべて大文字)。
· 私たちはまだ Python です。 ほとんどの内部は 1:1 で Python 内部に変換されます。
· あらゆる場所で Unicode を使用します。
· 可能な場合は、Python 2 の誤った決定を修正します (「 true_division).
· 疑問がある場合は、Python を使用してください。
· それでも不明な場合は、Clojure を参照してください。
· さらに確信が持てない場合は、Common Lisp を参照してください。
· 私たちは Clojure ではないことに留意してください。 私たちはCommon Lispではありません。 私たちはホモイコニック Python です。
意味のある余分なビット。
レイアウト & インデント
· 末尾のスペースは避けてください。 最悪だ!
· インデントは 2 スペース(ハードタブなし)とする。ただし、インデントが一致する場合を除く。
前の行。
;; 良い(そして好ましい)
(defn fib [n]
(if (<= n 2)
n
(+ (fib (- n 1)) (fib (- n 2))))
;; まだ大丈夫
(defn fib [n]
(if (<= n 2) n (+ (fib (- n 1)) (fib (- n 2))))
;; まだ大丈夫
(defn fib [n]
(if (<= n 2)
n
(+ (fib (- n 1)) (fib (- n 2))))
;; ヒステリックにばかばかしい
(defn fib [n]
(if (<= n 2)
ん;; はい、スペースキーをランダムに押すのが大好きです
(+ (fib (- n 1)) (fib (- n 2))))
· 括弧は必須です 決して 一人で取り残され、悲しくて孤独です。
;; 良い(そして好ましい)
(defn fib [n]
(if (<= n 2)
n
(+ (fib (- n 1)) (fib (- n 2))))
;; ヒステリックにばかばかしい
(defn fib [n]
(if (<= n 2)
n
(+ (fib (- n 1)) (fib (- n 2)))
)
) ; ああ、火で燃やしてしまえ
・縦に揃える う ブロック。
(let [[foo (bar)]
[qux(バズ)]]
(フークックス))
· インライン コメントはコードの末尾から XNUMX つのスペースでなければなりません。 彼らは常に
コメント文字とコメントの先頭の間のスペース。 また、そうしないようにしてください。
明らかなことをコメントします。
;; 良い
(setv ind (dec x)) ; インデックスは 0 から始まります
;; スタイルに準拠しているが、明白なことだけを述べている
(setv ind (dec x)) ; インデックスを x-1 に設定します
;; 悪い
(setv ind (dec x));楽しみのために単語を入力する
コーディング 形式
· 慣例として、使用しないようにしてください。 def グローバル変数以外の場合。 使用 セット
関数やループなどの内部。
;; 良い(そして好ましい)
(デフォルト *制限* 400000)
(定義 fibs [ab]
(本当ですが
(収量a)
(setv (, ab) (, b (+ ab))))
;; 悪い(そして好ましくない)
(定義 fibs [ab]
(本当ですが
(収量a)
(def (, ab) (, b (+ ab))))
· ベクトル構文が意図されている場所では、s 式構文を使用しないでください。 たとえば、事実
これら XNUMX つの例のうち前者が機能するのは、コンパイラが過度に機能していないだけです。
厳しい。 実際には、このような場所での正しい構文は後者です。
;; 悪い(そして邪悪)
(defn foo (x) (print x))
(foo1)
;; 良い(そして好ましい)
(defn foo [x] (print x))
(foo1)
· 深くネストされたマクロが発生した場合は、スレッド マクロまたはスレッド テール マクロを使用します。
S 式。 ただし、使用するときは慎重にしてください。 明確な場合にはそれらを使用してください。
可読性が向上します。 複雑で理解しにくい式を作成しないでください。
;; 好ましい
(def *名前*
([f (「names.txt」を開く)] 付き)
(-> (.read f) (.strip) (.replace "\"" "") (.split ",") (sorted)))
;; あまりよくない
(def *名前*
([f (「names.txt」を開く)] 付き)
(ソート済み (.split "," (.replace "\"" "" (.strip (.read f))))))
;; おそらく良いアイデアではないでしょう
(定義平方? [x]
(->> 2 (pow (int (sqrt x))) (= x)))
· Clojure スタイルのドット表記法は、オブジェクトのメソッドを直接呼び出すよりも優先されます。
ただし、どちらも引き続きサポートされます。
;; 良い
([fd (開く "/etc/passwd")]
(print (.readlines fd)))
;; あまりよくない
([fd (開く "/etc/passwd")]
(print (fd.readlines)))
まとめ
「ファッションは消えますが、スタイルは永遠です」 - イヴ・サンローラン
このガイドは単なるコミュニティ ガイドラインのセットであり、明らかにコミュニティ ガイドラインは次のことを行います。
活発なコミュニティがなければ意味がありません。 貢献は大歓迎です。 #hy in で参加しましょう
freenode についてブログを書いたり、ツイートしたり、そして最も重要なこととして、Hy を楽しんでください。
感謝
· このガイドは、以下から多大な影響を受けています。 @ポールタグ さんのブログ投稿 Hy 生存 ガイド
・ Clojureの 形式 ガイド
マニュアル INDEX
内容:
Command LINE インタフェース
hy
Command LINE オプション
-c
Hy コードを実行します。 command.
$ hy -c "(print (+ 2 2))"
4
-i
Hy コードを実行します。 command、その後はREPLに留まります。
-m
Hy コードを実行します。 モジュール含みます 定義する 定義されている場合。
この -m フラグはオプション リストを終了し、その後のすべての引数が終了します。 モジュール 名
のモジュールに渡されます sys.argv.
バージョン 0.10.2 の新機能。
- スパイ 実行前に同等の Python コードを出力します。 例えば:
=> (defn salutationsnm [名前] (print (+ "Hy " name "!")))
def salutationsnm(名前):
return print(((u'Hy ' + 名前) + u'!'))
=> (挨拶文「あなたの名前」)
salutationsnm(u'あなたの名前')
こんにちは、あなたの名前です!
=>
バージョン 0.9.11 の新機能。
--show-トレースバック
Hy 例外の拡張トレースバックを出力します。
バージョン 0.9.12 の新機能。
-v Hy のバージョン番号を出力して終了します。
やあ
Command LINE オプション
ファイル[、 ファイルN]
Hy コードを Python バイトコードにコンパイルします。 たとえば、次のコードを次のように保存します。
ハイネーム.hy:
(defn hy-hy [名前]
(print (+ "名前"!")))
(ハイハイ「アフロマン」)
次に、
$ hyc hyname.hy
$ python hyname.pyc
やあアフロマン!
hy2py
バージョン 0.10.1 の新機能。
Command LINE オプション
-s
--ソース付き
解析されたソース構造を表示します。
-a
--ast 付き
生成されたASTを表示します。
-np
--Python なし
AST から生成された Python コードは表示しません。
Hy ( 言語)
警告:
これは不完全です。 文書化作業への貢献を検討してください。
理論 of Hy
Hy は、何よりも Python との双方向で 100% の互換性を維持します。
自体。 すべての Hy コードは、いくつかの簡単なルールに従います。 これは入ってくるので覚えておいてください
ハンディ。
これらのルールは、Hy コードが慣用的であり、両方の言語でインターフェイス可能であることを保証するのに役立ちます。
· イヤーマフ内の記号は、その文字列の大文字バージョンに変換されます。 ために
例、 foo になります FOO.
· UTF-8 エンティティは次を使用してエンコードされます。 Punycode そして接頭辞が やあ。 例えば、 ⚘
になります hy_w7h, ♥ になります hy_g6h, i♥u になります hy_iu_t0x.
· ダッシュを含む記号はアンダースコアに置き換えられます。 例えば、
レンダリングテンプレート になります レンダーテンプレート。 つまり、ダッシュ付きの記号は
相当するアンダースコアをシャドウイングし、その逆も同様です。
ビルトイン
Hy には、正しい Python AST を生成するために使用される特別なフォームが多数備わっています。
以下は「特別な」形式であり、一部では予期しない動作をする可能性があります。
いくつかの状況。
.
バージョン 0.10.0 の新機能。
. オブジェクトの属性アクセスを実行するために使用されます。 小規模な DSL を使用して、迅速な処理を可能にします。
ネストされたデータ構造内の属性と項目へのアクセス。
例えば、
(.foo bar baz [(+ 1 2)] フロブ)
コンパイルすると次のようになります。
foo.bar.baz[1 + 2].frob
. 最初の引数をコンパイルします (例では、 foo) を実行するオブジェクトとして
属性の逆参照。 アクセスするための属性として裸のシンボルを使用します (例では、 バー,
バズ, フロブ)、リストの内容をコンパイルします (例では、 [(+ 1 2)]) インデックス作成用。
他の引数はコンパイル エラーをスローします。
不明な属性にアクセスすると、 属性エラー。 不明なキーにアクセスすると、
インデックスエラー (リストおよびタプル上) または キーエラー (辞書に載っています)。
->
-> (または スレッディング マクロ) は、式のネストを避けるために使用されます。 スレッドマクロ
各式を次の式の最初の引数の場所に挿入します。 以下
コードはこれを示しています:
=> (defn 出力 [ab] (print ab))
=> (-> (+ 4 6) (出力 5))
10 5
->>
->> (または スレッディング tail マクロ) に似ています スレッディング マクロ、しかし代わりに
各式を次の式の最初の引数に挿入すると、それが
最後の引数。 次のコードはこれを示しています。
=> (defn 出力 [ab] (print ab))
=> (->> (+ 4 6) (出力 5))
5 10
適用する
適用する 引数のオプションのリストと kwargs のオプションの辞書を適用するために使用されます。
関数に。
使用法: (申し込み fn-name [引数] [クワーグス])
例:
(定義サンク []
「こんにちは」)
(サンクを適用)
;=> 「こんにちは」
(定義合計購入額 [価格金額 & オプション [手数料 1.05] [付加価値税 1.1]]
(*価格・金額・手数料・消費税))
(合計購入額[10 15]を適用)
;=> 173.25
(合計購入額 [10 15] {"vat" 1.05} を適用)
;=> 165.375
(apply total-purchase [] {"price" 10 "amount" 15 "vat" 1.05})
;=> 165.375
と
と 論理式で使用されます。 少なくとも XNUMX つのパラメータが必要です。 すべてのパラメータの場合
評価する ◯、最後のパラメータが返されます。 それ以外の場合は、最初の false 値
返されます。 使用例:
=> (そして真偽)
×
=> (そして真、真)
◯
=> (そして真 1)
1
=> (および True [] False True)
[]
注:
と 最初の false が返されるとすぐにパラメータの評価をショートして停止します。
遭遇した。
=> (および False (「hello」を出力))
×
アサート
アサート プログラムの実行中に条件を確認するために使用されます。 条件が整っていない場合
会った、 アサーション エラー 上げられます。 アサート XNUMX つまたは XNUMX つのパラメータを取ることができます。 最初
パラメータはチェックする条件であり、次のいずれかに評価される必要があります。 ◯ or ×を選択します。
XNUMX 番目のパラメータはオプションで、アサートのラベルであり、
と一緒に育てられた アサーション エラー 例えば:
(assert(=変数期待値))
(偽を主張)
; アサーション エラー
(アサート (= 1 2) 「XNUMX は XNUMX に等しいはずです」)
; AssertionError: XNUMX は XNUMX に等しい必要があります
連想
連想 キーを辞書内の値に関連付けたり、リストのインデックスを設定したりするために使用されます。
値に。 少なくとも XNUMX つのパラメータを取ります。 データ 構造 変更される、 キー
or index、と 値。 XNUMX つ以上のパラメータが使用される場合、ペアで関連付けられます。
使用例:
=>(let [[コレクション {}]]
... (アソシエイトコレクション「犬」「樹皮」)
... (版画集))
{u'犬': u'吠える'}
=>(let [[コレクション {}]]
... (アソシエイトコレクション「犬」「鳴き声」「猫」「ニャー」)
... (版画集))
{u'猫': u'ニャー'、u'犬': u'吠える'}
=>(let [[コレクション [1 2 3 4]]]
... (関連コレクション 2 なし)
... (版画集))
[1、2、なし、4]
注:
連想 データ構造を適切に変更して返します。 なし.
破る
破る ループから抜け出すために使用します。 ループは直ちに終了します。 以下
例には無限があります while ユーザーが入力するとすぐに終了するループ k.
(while True (if (= "k" (生の入力 "? "))
(壊す)
(「もう一度試してください」と印刷します)))
条件
条件 ネストされた構築に使用できます if 発言。 次の例は、
マクロとその展開の関係:
(cond [条件-1 結果-1]
[条件-2 結果-2])
(if 条件-1 結果-1
(if 条件-2 結果-2))
以下に示すように、最初に一致した結果ブロックのみが実行されます。
=> (defn チェック値 [値]
... (cond [(< value 5) (print "値が 5 より小さい")]
... [(= 値 5) (print "値は 5 に等しい")]
... [(> 値 5) (print "値は 5 より大きい")]
... [True (print "値は、あるべきではないものです")]))
=> (チェック値 6)
値が 5 より大きい
続ける
続ける 実行をループの先頭に戻します。 次の例では、
(副作用1) 反復ごとに呼び出されます。 (副作用2)ただし、呼び出されるのは
リスト内の XNUMX つおきの値。
;; (side-effect1) と (side-effect2) が関数であると仮定し、
;; コレクションは数値のリストです
([x コレクション] の場合)
(から
(副作用1 x)
(if (% x 2)
(続く))
(副作用2 x)))
dict-comp
dict-comp 辞書の作成に使用されます。 XNUMX つまたは XNUMX つのパラメータを取ります。 最初
XNUMX つのパラメータは戻り値 (キーと値のペア) を制御するためのもので、XNUMX つ目は
シーケンスから項目を選択するために使用されます。 XNUMX 番目のオプションのパラメータは、次の目的で使用できます。
条件式に基づいてシーケンス内の一部の項目をフィルターで除外します。
=> (dict-comp x (* x 2) [x (範囲 10)] (奇数? x))
{1:2、3:6、9:18、5:10、7:14}
do / 突起
do と 突起 は、それぞれの引数を評価し、最後の引数を返すために使用されます。 戻る
最後の引数以外のすべての引数の値は破棄されます。 で使用できます ラムダ or
リストコンプ 次のいずれかの例に示すように、より複雑なロジックを実行します。
使用例:
=> (true の場合
... (実行してください (「副作用はロックです!」と印刷します)
... (「はい、本当に!」と印刷します)))
副作用はすごい!
あぁ本当!
;; (副作用) がそれぞれに対して呼び出したい関数であると仮定します。
;; リスト内のすべての値ですが、その戻り値は気にしません
=> (list-comp (do (副作用 x)
... (if (< x 5) (* 2 x)
... (* 4 x)))
... (x (範囲 10)))
[0、2、4、6、8、20、24、28、32、36]
do 1 から n までの任意の数の引数を受け入れることができます。
def / セット
def と セット 値、オブジェクト、または関数をシンボルにバインドするために使用されます。 例えば:
=> (デフォルト名 ["アリス" "ボブ" "チャーリー"])
=> (名前を印刷)
[u'アリス'、u'ボブ'、u'チャーリー']
=> (setv counter (fn [コレクション項目] (.count コレクション項目)))
=> (カウンター [1 2 3 4 5 2 3] 2)
2
デフクラス
新しいクラスは次のように宣言されます デフクラス。 XNUMX つのオプションのパラメータを取ることができます: ベクトル
可能なスーパークラスと、新しいクラスの属性を含む別のベクトルを定義します。
クラスを XNUMX つの項目ベクトルとして扱います。
(defclass クラス名 [スーパークラス-1 スーパークラス-2]
[[属性値]])
以下の例に示すように、値と関数の両方を新しいクラスにバインドできます。
=> (defclass Cat []
... [[年齢なし]
... [カラー「ホワイト」]
... [話す (fn [self] (print "ニャー"))]])
=> (デフォルトスポット(猫))
=> (setv Spot.colour "ブラック")
'黒'
=> (.スピークスポット)
ニャー
定義 / デファン
定義 と デファン マクロは関数を定義するために使用されます。 これらは XNUMX つのパラメータを取ります。 名
定義する関数のベクトル、 パラメータ、 そしてその ボディ 関数の:
(定義名 [パラメータ] 本体)
パラメータの前に次のキーワードを付けることができます。
オプション(&オプション)
パラメータはオプションです。 パラメータは XNUMX つの項目リストとして指定できます。
最初の要素はパラメータ名で、XNUMX 番目の要素はデフォルト値です。 パラメータ
単一の項目として指定することもできます。その場合のデフォルト値は次のとおりです。 なし.
=> (defn 合計値 [値 &オプション [付加価値税 10]]
... (+ (/ (* 付加価値税額) 100) 値))
=> (合計値100)
110.0
=> (合計値 100 1)
101.0
&鍵
クワーグス(&K)
パラメータには 0 個以上のキーワード引数が含まれます。
次のコード例では、すべてのキーワードを出力する関数を定義しています。
引数とその値。
=> (defn print-parameters [&kwargs kwargs]
... (for [(, kv) (.items kwargs)] (print kv)))
=> (印刷パラメータを適用 [] {"パラメータ-1" 1 "パラメータ-2" 2})
パラメータ-2 2
パラメータ-1 1
&休み パラメータには 0 個以上の位置引数が含まれます。 他にポジションはありません
この引数の後に引数を指定できます。
次のコード例では、0 ~ n の数値を与えることができる関数を定義しています。
パラメーター。 次に、すべての奇数を合計し、すべての偶数を減算します。
=> (defn ジグザグサム [&残りの数字]
(let [[奇数 (list-comp x [x 数値] (奇数? x))]
[偶数 (list-comp x [x 数値] (偶数? x))]]
(- (奇数の合計) (偶数の合計))))
=> (ジグザグサム)
0
=> (ジグザグ和 3 9 4)
8
=> (ジグザグ和 1 2 3 4 5 6)
-3
定義エイリアス / デファンエイリアス
バージョン 0.10.0 の新機能。
この 定義エイリアス と デファンエイリアス マクロはよく似ています 定義、という区別付きで、
単一の名前で関数を定義する代わりに、エイリアスを定義することもできます。 他の
最初のパラメータとして関数名のシンボルのリストを取得するのではなく、 定義エイリアス と
デファンエイリアス と違いはありません 定義 と デファン.
=> (defn-alias [メイン名のエイリアス] []
... (「こんにちは!」と印刷))
=> (メイン名)
"こんにちは!"
=> (エイリアス)
"こんにちは!"
定義する
バージョン 0.10.1 の新機能。
この 定義する マクロは、すぐに呼び出される main 関数を定義します。 sys.argv as
このファイルがスクリプトとして実行されている場合に限り、引数を指定します。 つまり、これは次のとおりです。
(defmain [&rest args]
(引数で何かをする))
は以下と同等です:
def main(*args):
do_something_with(args)
0を返す
__name__ == "__main__"の場合:
インポートシステム
retval = main(*sys.arg)
if isinstance(retval, int):
sys.exit(retval)
上でわかるように、この関数から整数を返す場合、これは次のようになります。
スクリプトの終了ステータスとして使用されます。 (そうでない場合、Python はデフォルトでステータス 0 を終了します。
つまり、すべてが大丈夫です!)
(以来 (sys.exit 0) から非整数が返された場合には明示的に実行されません。
定義する、と置くと良いでしょう。 (デフォルト) ファイルの最後のコードとして。)
デフマクロ
デフマクロ マクロを定義するために使用されます。 一般的な形式は次のとおりです (デフマクロ 名 [パラメーター]
expr).
次の例では、コード内の要素の順序を交換するために使用できるマクロを定義します。
ユーザーが中置記法でコードを記述できるようにします。演算子は
オペランド。
=> (defmacro infix [コード]
... (準引用 (
... (引用符を外します (コード 1 を取得))
... (引用符を外します (コード 0 を取得))
... (引用符を外します (コード 2 を取得))))
=> (中置 (1 + 1))
2
defmacro エイリアス
defmacro エイリアス 複数の名前 (エイリアス) を持つマクロを定義するために使用されます。 一般的な形式
is (defmacro-alias [名前] [パラメーター] expr)。 同じ内容で複数のマクロを作成します
指定された名前のリストの下にあるパラメーターのリストと本体。
次の例では XNUMX つのマクロを定義しており、どちらのマクロでもユーザーはコードを記述できます。
中置記法。
=> (defmacro-alias [infix infi] [コード]
... (準引用 (
... (引用符を外します (コード 1 を取得))
... (引用符を外します (コード 0 を取得))
... (引用符を外します (コード 2 を取得))))
=> (中置 (1 + 1))
2
=> (infi (1 + 1))
2
デフマクロ/g!
バージョン 0.9.12 の新機能。
デフマクロ/g! の特別バージョンです デフマクロ 自動的に生成するために使用されます ゲンシム
で始まる記号の場合 g!.
たとえば、 が! になる (gensym 「あ」).
関連項目 ALSO:
セクション using-gensym
恐怖者
バージョン 0.9.12 の新機能。
恐怖者 リーダー マクロを定義し、構文を再構築または変更できるようにします。
=> (defreader ^ [expr] (print expr))
=> #^(1 2 3 4)
(1 2 3 4)
=> #^「こんにちは」
"こんにちは"
関連項目 ALSO:
セクションリーダーマクロ
インクルード
バージョン 0.9.12 の新機能。
インクルード 現在の名前空間からオブジェクトを削除します。
=> (setv foo 42)
=> (デルフー)
=> ふー
トレースバック(最後の最後の呼び出し):
ファイル " "、1行目、
NameError: 名前「foo」が定義されていません
インクルード マッピングやリストなどからオブジェクトを削除することもできます。
=> (setv テスト (リスト (範囲 10)))
=> テスト
[0、1、2、3、4、5、6、7、8、9]
=> (del (スライス テスト 2 4)) ;; 除外項目 2 ~ 4 から項目を削除します
=> テスト
[0、1、4、5、6、7、8、9]
=> (setv dic {"foo" "bar"})
=>ディック
{"foo": "バー"}
=> (del (get dic "foo"))
=>ディック
{}
どと
バージョン 0.10.1 の新機能。
どと オブジェクトへの一連のメソッド呼び出しを簡素化するために使用されます。
=> (doto [] (.append 1) (.append 2) .reverse)
[2 1]
=> (setv コレクション [])
=> (.append コレクション 1)
=> (.append コレクション 2)
=> (.reverse コレクション)
=> コレクション
[2 1]
評価する
評価する 引用符で囲まれた式を評価し、値を返します。
=> (eval '(print "Hello World"))
"こんにちは世界"
評価してコンパイルする
コンパイル時の評価
最初の / 自動車
最初の と 自動車 コレクションの最初の要素にアクセスするためのマクロです。
=> (最初 (範囲 10))
0
for
for リストまたはベクトル内の各要素の関数を呼び出すために使用されます。 それぞれの結果
コールは破棄され、 for 式は戻ります なし その代わり。 サンプルコードは反復します
が コレクション そしてそれぞれのために 素子 in コレクション その 副作用 と機能する
素子 その引数として:
;; (副作用) が単一のパラメータを取る関数であると仮定します。
([要素コレクション] (副作用要素) の場合)
;; for にはオプションの else ブロックを含めることができます
([要素コレクション] の場合 (副作用要素)
(else (副作用-2)))
オプション ほかに ブロックは、次の場合にのみ実行されます。 for ループは正常に終了します。 もし
実行は次のように停止されます 破る ほかに ブロックは実行されません。
=> (for [要素 [1 2 3]] (if (< 要素 3)
... (印刷要素)
... (壊す))
... (else ("ループが終了しました" を出力)))
1
2
=> (for [要素 [1 2 3]] (if (< 要素 4)
... (印刷要素)
... (壊す))
... (else ("ループが終了しました" を出力)))
1
2
3
ループが終了しました
ジェネクスパー
ジェネクスパー ジェネレータ式を作成するために使用されます。 XNUMX つまたは XNUMX つのパラメータを取ります。 の
最初のパラメータは戻り値を制御する式であり、XNUMX 番目のパラメータは使用されます。
リストから項目を選択します。 XNUMX 番目のオプションのパラメータは、フィルタリングで除外するために使用できます。
リスト内の一部の項目は条件式に基づいています。 ジェネクスパー に似ています
リストコンプただし、値を XNUMX つずつ評価する反復可能オブジェクトを返す点が異なります。
すぐに評価します。
=> (def コレクション (範囲 10))
=> (def フィルター済み (genexpr x [x コレクション] (even? x)))
=> (フィルタリングされたリスト)
[0、2、4、6、8]
ゲンシム
バージョン 0.9.12 の新機能。
ゲンシム を使用せずにマクロを記述できるようにする固有のシンボルを生成するために使用されます。
変数名が偶然に衝突してしまう。
=> (gensym)
u':G_1235'
=> (gensym "x")
u':x_1236'
関連項目 ALSO:
セクション using-gensym
取得する
取得する リストおよび辞書内の単一要素にアクセスするために使用されます。 取得する 次の XNUMX つのパラメータを取ります。
データ 構造 と index or キー アイテムの。 対応するものを返します
辞書またはリストからの値。 使用例:
=> (let [[動物 {"犬" "吠える" "猫" "ニャー"}]
... [数字 [「ゼロ」「一」「二」「三」]]]
... (印刷 (動物「犬」を取得))
... (印刷 (数値 2 を取得)))
樹皮
2
注:
取得する 存在しないキーに対して辞書が照会された場合、KeyError が発生します。
注:
取得する 範囲外のインデックスに対してリストまたはタプルがクエリされた場合、IndexError が発生します。
境界。
全体的な
全体的な シンボルをグローバルとしてマークするために使用できます。 これにより、プログラマは、
値をグローバルシンボルに設定します。 グローバル シンボルの読み取りには、 全体的な キーワード --
代入するだけです。
次の例は、グローバル シンボルがどのように使用されるかを示しています。 a 関数内で値が割り当てられ、
後で別の関数で出力されます。 なしで 全体的な キーワード、XNUMX 番目の関数
を投げただろう 名前エラー.
(defn set-a [値]
(グローバルa)
(値を設定))
(defn print-a []
(a)を印刷)
(セット-a 5)
(印刷-a)
if / ない場合
バージョン 0.10.0 の新機能: if-not
if 実行するコードを条件付きで選択するために使用されます。 条件を含める必要があります
ブロックと、条件ブロックが次のように評価された場合に実行されるブロック ◯。 オプションで、
条件の評価が次の場合に実行される最終ブロックが含まれる場合があります。
×.
ない場合 同様ですが、条件が失敗すると XNUMX 番目のブロックが実行されます。
XNUMX 番目と最後のブロックは、テストが成功すると実行されます。これは逆の順序です。 if.
使用例:
(if (お金が残っている? アカウント)
(「買い物に行こう」を印刷)
(「仕事に行きましょう」と印刷))
(そうでない場合 (お金が残っている? アカウント)
(「仕事に行きましょう」を印刷)
(「買い物に行こう」と印刷))
Python の真実性が尊重されます。 なし, ×、任意の数値型のゼロ、空のシーケンス、
および空の辞書が考慮されます ×; 他のすべてが考慮されます ◯.
Lisp-if / LIF と Lisp-if-not / ライフノット
バージョン 0.10.0 の新機能。
バージョン 0.10.2 の新機能: lisp-if-not / lif-not
より Lispy を好む人向け if 条項、我々は持っています Lisp-ifまたは LIF。 この の 考慮する
なし / ゼロ 嘘であること! 他の「偽っぽい」Python 値はすべて true とみなされます。
逆に、私たちは Lisp-if-not と ライフノット と並行して if と ない場合 逆転するのは
比較。
=> (lisp-if True "true" "false")
"真"
=> (lisp-if False "true" "false")
"真"
=> (lisp-if 0 "true" "false")
"真"
=> (lisp-if nil "true" "false")
"NS"
=> (lisp-if None "true" "false")
"NS"
=> (lisp-if-not nil "true" "false")
"真"
=> (lisp-if-not None "true" "false")
"真"
=> (lisp-if-not False "true" "false")
"NS"
; 同等だが短い
=> (lif True "true" "false")
"真"
=> (lif nil "true" "false")
"NS"
=> (lif-not None "true" "false")
"真"
import
import Python のようにモジュールをインポートするために使用されます。 いくつかの方法があります import できる
利用される。
;; これらの各モジュールをインポートします
;;
;; パイソン:
;; インポートシステム
;; OS.パスをインポートする
(sys os.pathをインポート)
;; モジュールからインポートする
;;
;; Python: os.path からインポートが存在します、isdir、isfile
(インポート [os.path [isists isdir isfile]])
;; エイリアスを使用してインポートする
;;
;; Python: sys を systest としてインポートします
(インポート [sys :as systest])
;; さまざまなタイプのインポートを好きなだけリストできます。
(インポート [tests.resources [kwtest function-with-a-dash]]
[os.path [isdir isfile が存在します]]
[sys :as systest])
;; すべてのモジュール関数を現在の名前空間にインポートします
(インポート [sys [*]])
ラムダ / fn
ラムダ と fn 無名関数を定義するために使用できます。 パラメータは次のようになります
定義: 最初のパラメータはパラメータのベクトルで、残りはパラメータの本体です。
機能。 ラムダ 新しい関数を返します。 次の例では、無名関数
が定義され、出力をフィルタリングするために別の関数に渡されます。
=> (def people [{:name "アリス" :年齢 20}
... {:名前「ボブ」:年齢 25}
... {:名前「チャーリー」:50歳}
... {:名前 "デイブ" :5 歳}])
=> (defn display-people [人物フィルター]
... (for [person people] (if (filter person) (print (:name person))))
=> (表示-人 人 (fn [人] (< (:年齢の人) 25)))
アリス
デイブ
通常の関数定義と同様に、本体の最初の要素が文字列の場合、
docstring として機能します。 これは、クラス メソッドに docstring を与える場合に便利です。
=> (setv の XNUMX 倍
... (fn [x]
... 「入力を XNUMX で乗算し、結果を返します。」
... (* x 3)))
これは Python の組み込み関数で確認できます。 助けます 関数:
=> (ヘルプ×XNUMX)
関数 times_three のヘルプ:
回_三(x)
入力を XNUMX で乗算し、結果を返します
(終わり)
last
バージョン 0.10.2 の新機能。
last コレクションの最後の要素にアクセスするために使用できます。
=> (最後 [2 4 6])
6
う
う 字句スコープの変数を作成するために使用されます。 それらは最初に作成されます。
う 形成され、形成された後は存在しなくなります。 次の例はこれを示しています
行動:
=> (let [[x 5]] (x を出力)
... ([[x 6]] にしてみます (x を出力します))
... (x)を印刷)
5
6
5
この う マクロは XNUMX つのパラメータを取ります: ベクトルを定義する variables と ボディ どれが得ますか
実行されました。 variables 各要素が単一の変数またはベクトルであるベクトルです。
変数値のペアを定義します。 単一変数の場合、値が代入されます。
なし; それ以外の場合は、指定された値が使用されます。
=> (let [x [y 5]] (xy を出力))
なし5
リストコンプ
リストコンプ リスト内包表記を実行します。 XNUMX つまたは XNUMX つのパラメータを取ります。 最初
パラメータは戻り値を制御する式であり、XNUMX 番目のパラメータは次の目的で使用されます。
リストから項目を選択します。 XNUMX 番目のオプションのパラメーターは、一部のフィルターを除外するために使用できます。
条件式に基づいてリスト内の項目の数を決定します。 いくつかの例:
=> (def コレクション (範囲 10))
=> (リスト-コンプ x [x コレクション])
[0、1、2、3、4、5、6、7、8、9]
=> (リスト-comp (* x 2) [x コレクション])
[0、2、4、6、8、10、12、14、16、18]
=> (リスト-comp (* x 2) [x コレクション] (< x 5))
[0、2、4、6、8]
論理式で使用されます。 単一のパラメータを受け取り、反転した値を返します。
真理値。 もしも ◯ パラメータとして与えられる、 × が返されますし、その逆も同様です。
使用例:
=> (真実ではありません)
×
=> (偽ではない)
◯
=> (なしではありません)
◯
or
or 論理式で使用されます。 少なくとも XNUMX つのパラメータが必要です。 返されます
最初の非 false パラメータ。 そのような値が存在しない場合は、最後のパラメータが返されます。
=> (または真偽)
◯
=> (そして偽偽)
×
=> (および偽 1 真偽)
1
注:
or 最初の真の値が検出されるとすぐに、パラメーターの評価をショートして停止します。
遭遇した。
=> (または True ("hello" を出力))
◯
印刷
印刷 画面上に出力するために使用されます。 使用例:
(「Hello world!」を印刷)
注:
印刷 常に戻ります なし.
準引用
準引用 フォームを引用できるだけでなく、式を選択的に評価することもできます。
内の式 準引用 を使用して選択的に評価できます 引用終わり (~)。 ザ
評価されたフォームは、次を使用して接合することもできます。 引用符を外してスプライスする (~@)。 準引用も可能です
逆引用符を使用して記述されます (`)シンボル。
;; `qux' を値を持つ変数にします (bar baz)
`(ふぉ~ククス)
; '(foo (bar baz)) と同等
`(foo ~@qux)
; '(foo bar baz) と同等
率
率 渡されたフォームを評価せずに返します。 率 あるいは、
アポストロフィー (')シンボル。
=> (setv x '(print "Hello World"))
; 変数 x は式に設定されていますが、評価されていません
=> ×
(u'print' u'Hello World')
=> (評価 x)
こんにちは世界
必要とする
必要とする 特定のモジュールからマクロをインポートするために使用されます。 少なくとも XNUMX つのパラメータが必要です
どのマクロをインポートする必要があるモジュールを指定します。 複数のモジュールをインポート可能
シングルで 必要とする.
次の例では、マクロをインポートします。 モジュール1 と モジュール2:
(モジュール-1 モジュール-2 が必要)
残り / cdr
残り と cdr 最初の要素なしで引数として渡されたコレクションを返します。
=> (残り(範囲10))
[1、2、3、4、5、6、7、8、9]
セットコンプ
セットコンプ セットを作成するために使用されます。 XNUMX つまたは XNUMX つのパラメータを取ります。 最初のパラメータは
XNUMX 番目は戻り値を制御するために使用され、XNUMX 番目は項目から項目を選択するために使用されます。
順序。 XNUMX 番目のオプションのパラメータは、次の項目の一部をフィルタリングするために使用できます。
条件式に基づくシーケンス。
=> (setv データ [1 2 3 4 5 2 3 4 5 3 4 5])
=> (set-comp x [x データ] (奇数? x))
{1、3、5}
スライス
スライス リストのサブセットを取得し、そこから新しいリストを作成するために使用できます。 フォーム
スライスするリストを指定するパラメータを少なくとも XNUMX つ受け取ります。 XNUMX つのオプションのパラメータを指定できます。
サブセットの開始位置と終了位置を与えるために使用されます。 これらが供給されていない場合、
のデフォルト値 なし 代わりに使用されます。 XNUMX 番目のオプションのパラメータは次の目的で使用されます。
要素間のステップを制御します。
スライス Python の対応物と同じルールに従います。 負のインデックスもカウントされます
リストの最後から始めます。 使用例:
=> (def コレクション (範囲 10))
=> (スライスコレクション)
[0、1、2、3、4、5、6、7、8、9]
=> (スライスコレクション 5)
[5、6、7、8、9]
=> (スライスコレクション 2 8)
[2、3、4、5、6、7]
=> (スライスコレクション 2 8 2)
[2、4、6]
=> (スライスコレクション -4 -2)
[6、7]
投げる / 上げる
この 投げる or 上げる フォームを使用して、 例外 実行時。 使用例:
(投げる)
; 最後の例外を再発生させます
(IOError をスロー)
; IOError をスローする
(スロー (IOError "foobar"))
; IOError("foobar") をスローする
投げる 単一の引数 ( 例外 クラスまたはインスタンス)、または引数がない場合
最後をリレイズする 例外.
試します
この 試します フォームは開始するために使用されます 試します / キャッチ ブロック。 フォームは次のように使用されます。
(やってみて
(エラーが発生しやすい関数)
(catch [e ZeroDivisionError] (print "ゼロ除算"))
(else (「エラーなし」を出力))
(最後に (「すべて完了」と出力)))
試します 少なくともXNUMXつ含まれている必要があります キャッチ ブロックであり、オプションで ほかに or 最後に
ブロック。 の実行中に一致する catch ブロックでエラーが発生した場合
エラーが発生しやすい関数、その キャッチ ブロックが実行されます。 エラーが発生しない場合、 ほかに
ブロックが実行されます。 の 最後に ブロックは、実行されるかどうかに関係なく、最後に実行されます。
エラーが発生しました。
ない限り、
この ない限り、 マクロは、 if 指定されたかどうかをチェックするステートメント
条件付きです ×。 このマクロの展開を以下に示します。
(条件文を除く)
(条件付きの場合
なし
(do ステートメント))
引用終わり
準引用符で囲まれた形式内では、 引用終わり シンボルの評価を強制します。 引用終わり エイリアスは
チルダ (~)シンボル。
(デフォルト名は「抱擁」)
(quasiquote (= name (unquote name)))
;=> (u'=' u'name' u'抱っこ')
`(= 名前 ~名前)
;=> (u'=' u'name' u'抱っこ')
引用符を外してスプライスする
引用符を外してスプライスする のように、準引用符で囲まれた形式内のシンボルの評価を強制します。
引用終わり. 引用符を外してスプライスする 引用符で囲まれていないシンボルに
反復可能な値。反復可能な値を準引用符で囲まれた形式に「結合」します。 引用符を外してスプライスする is
別名 ~@ シンボル。
(def nums [1 2 3 4])
(quasiquote (+ (unquote-splice nums)))
;=> (u'+' 1L 2L 3L 4L)
`(+ ~@nums)
;=> (u'+' 1L 2L 3L 4L)
いつ
いつ に似ています ない限り、ただし、指定された条件が次の場合にテストすることを除きます。 ◯。 そうではない
持つことが可能 ほかに でブロック いつ 大きい。 以下に展開を示します。
マクロ。
(条件文の場合)
(if 条件付き (do ステートメント))
while
while 条件が満たされる限り、XNUMX つ以上のブロックを実行するために使用されます。 次の
例では、「Hello world!」が出力されます。 無限に画面に表示されます:
(True の場合 (「Hello world!」を出力))
コンテキスト マネージャー内でブロックの実行をラップするために使用されます。 コンテキスト
その後、管理者はローカル システムをセットアップし、制御された方法でそれを破棄できます。 の
典型的な使用例 ファイルを処理するときです。 コンテキストを
引数を指定するか、以下に示すように完全に無視します。
([[arg (expr)]] ブロックを使用)
([[(expr)]] ブロックあり)
([[arg (expr)] [(expr)]] ブロックを使用)
次の例では、 ニュース ファイルを開き、その内容を画面に出力します。 の
ファイルは処理後に自動的に閉じられます。
(with [[f (open "NEWS")]] (print (.read f)))
デコレータ付き
デコレータ付き 関数を別の関数でラップするために使用されます。 を実行する関数
装飾は単一の値、つまり装飾される関数を受け入れ、新しい値を返す必要があります。
機能。 デコレータ付き 少なくとも XNUMX つのパラメータを取ります: 実行する関数
装飾と装飾される機能。 複数のデコレータ関数を使用できます
適用済み; それらは、最も外側から最も内側に向かって順番に適用されます。 最初
デコレータは最も外側のデコレータになります。 引数を持つデコレータは単に呼び出されます
関数呼び出しのようなもの。
(デコレータ付きデコレータ-楽しい
(defn some-function [] ...)
(デコレータ付き デコレータ1 デコレータ2 ...
(defn some-function [] ...)
(with-decorator (decorator arg) ..
(defn some-function [] ...)
次の例では、 デコレーター株式会社 関数を装飾するために使用されます 添加 また、
XNUMX つのパラメータを受け取り、次の値を使用して装飾された関数を呼び出す関数。
1 ずつ増加します。 添加 値 1 および 1 で呼び出され、終了
結果は 4 になります (1 + 1 + 1 + 1).
=> (defn inc-decorator [関数]
... (fn [値-1 値-2] (func (+ 値-1 1) (+ 値-2 1)))
=> (defn inc2-decorator [関数]
... (fn [値-1 値-2] (func (+ 値-1 2) (+ 値-2 2)))
=> (with-decorator inc-decorator (defn 加算 [ab] (+ ab)))
=> (追加 1 1)
4
=> (with-decorator inc2-decorator inc-decorator
... (定義加算 [ab] (+ ab)))
=> (追加 1 1)
8
とgensyms
バージョン 0.9.12 の新機能。
とgensym のセットを生成するために使用されます ゲンシム マクロで使用します。 次のコード:
(gensonyms [abc] 付き)
...)
次のように展開されます:
([[a (gensym)
[b (gensym)
[c (gensym)]]
...)
関連項目 ALSO:
セクション using-gensym
産出
産出 XNUMX つ以上の値を返すジェネレーター オブジェクトを作成するために使用されます。 発電機
反復可能であるため、ループ、リスト内包表記などで使用できます。
構成します。
関数 乱数 ジェネレーターを使用して無限級数を生成する方法を示します
無限のメモリを消費することなく。
=> (defn 乗算 [基本係数]
... (for [[(, ベース係数) (zip ベース係数)]]
... (収量 (* 基本係数))))
=> (乗算 (範囲 5) (範囲 5))
=> (リスト-演算値 [値 (乗算 (範囲 10) (範囲 10))])
[0、1、4、9、16、25、36、49、64、81]
=> (ランダムにインポート)
=> (定義 乱数 [低 高]
... (while True (yield (.randint ランダム低高))))
=> (list-comp x [x (take 15 (random-numbers 1 50))])])
[7、41、6、22、32、17、5、38、18、38、17、14、23、23、19]
利回りから
バージョン 0.9.13 の新機能。
パイソン 3.3 そして UP ONLY!
利回りから サブジェネレーターを呼び出すために使用されます。 これは、コルーチンを次のようにしたい場合に便利です。
たとえば、次のような派手なものを使用する場合、そのプロセスを別のコルーチンに委任できます。
非同期.
Hy 基本
基本 機能
最後に
使用法: (でも最後に コル)
最後の項目を除くすべての項目のイテレータを返します。 コル.
=> (リスト (最後 (範囲 10)))
[0、1、2、3、4、5、6、7、8]
=> (リスト (最後 [1]))
[]
=> (リスト (最後まで []))
[]
=> (itertools をインポート)
=> (リスト (take 5 (butlast (itertools.count 10))))
[10、11、12、13、14]
コル?
バージョン 0.10.0 の新機能。
使用法: (コル? x)
返品 ◯ if x 反復可能であり、文字列ではありません。
=> (収集? [1 2 3 4])
◯
=> (coll? {"a" 1 "b" 2})
◯
=> (コレ? "abc")
×
短所
バージョン 0.10.0 の新機能。
使用法: (短所 a b)
car を含む新しい cons セルを返します a とcdr b.
=> (setv a (cons 'hd 'tl))
=> (= 'hd (車 a))
◯
=> (= 'tl (cdr a))
◯
短所?
バージョン 0.10.0 の新機能。
使用法: (短所? ふー)
かどうかを確認します foo はコンセルです。
=> (setv a (cons 'hd 'tl))
=> (短所? a)
◯
=> (短所?なし)
×
=> (短所? [1 2 3])
×
12月
使用法: (XNUMX月 x)
XNUMX つ小さい値を返します x。 に相当 (- x 1)。 レイズ タイプエラー if (会員登録はお済みでしょうか? (数字? バツ)).
=> (3月XNUMX日)
2
=> (0月XNUMX日)
-1
=> (12.3月XNUMX日)
11.3
分解する
バージョン 0.10.0 の新機能。
使用法: (分解する ツリー オプション(&オプション) [コードジェン 間違い])
指定された Hy の Python AST をダンプします。 ツリー 標準出力に。 もし コード生成 is ◯、 関数
代わりに Python コードを出力します。
=> (逆アセンブル '(print "Hello World!"))
モジュール(
本文=[
Expr(value=Call(func=Name(id='print'), args=[Str(s='Hello World!')], キーワード=[], starargs=None, kwargs=None))])
=> (逆アセンブル '(print "Hello World!") true)
print('Hello World!')
空?
使用法: (空の? コル)
返品 ◯ if コル 空です。 に相当 (= 0 (レン 集めてください)).
=> (空? [])
◯
=> (空ですか? "")
◯
=> (空? (, 1 2))
×
毎?
バージョン 0.10.0 の新機能。
使用法: (毎? 捕食 コル)
返品 ◯ if (プレド x) は論理的に真です x in コル、そうでなければ ×。 戻る ◯
if コル 空です。
=> (毎?偶数?[2 4 6])
◯
=> (毎?偶数?[1 3 5])
×
=> (毎?偶数?[2 4 5])
×
=> (毎?均等? [])
◯
浮く?
使用法: (浮く? x)
返品 ◯ if x フロートです。
=> (浮動小数点? 3.2)
◯
=> (浮動小数点? -2)
×
平?
使用法: (平? x)
返品 ◯ if x は均等です。 レイズ タイプエラー if (会員登録はお済みでしょうか? (数字? バツ)).
=> (偶数? 2)
◯
=> (偶数? 13)
×
=> (偶数? 0)
◯
アイデンティティ
使用法: (身元 x)
関数に指定された引数を返します。
=> (アイデンティティ 4)
4
=> (リスト (マップ ID [1 2 3 4]))
[1 2 3 4]
株式会社
使用法: (含む x)
より XNUMX つ多い値を返します x。 に相当 (+ x 1)。 レイズ タイプエラー if (会員登録はお済みでしょうか? (数字? バツ)).
=> (3 を含む)
4
=> (0 を含む)
1
=> (12.3 を含む)
13.3
インスタンス?
使用法: (実例? class x)
返品 ◯ if x のインスタンスです class.
=> (インスタンス? float 1.0)
◯
=> (インスタンス? int 7)
◯
=> (インスタンス? str (str "foo"))
◯
=> (defclass TestClass [オブジェクト])
=> (setv inst (TestClass))
=> (インスタンス? TestClass inst)
◯
整数?
使用法: (整数? x)
返品 ◯ if x は整数です。 Python 2 の場合、これは次のいずれかです int型 or 長い。 Python 3 の場合、
これは int型.
=> (整数? 3)
◯
=> (整数? -2.4)
×
間を空ける
バージョン 0.10.1 の新機能。
使用法: (間を空ける seq1 seq2 ...)
各シーケンスの最初の項目、次に XNUMX 番目の項目などの反復可能項目を返します。
=> (リスト (インターリーブ (範囲 5) (範囲 100 105)))
[0、100、1、101、2、102、3、103、4、104]
=> (リスト (インターリーブ (範囲 1000000) "abc"))
[0、'a'、1、'b'、2、'c']
介入する
バージョン 0.10.1 の新機能。
使用法: (間に挟む 項目 続く)
項目で区切られたシーケンスの要素の反復可能値を返します。
=> (リスト (「!」「abcd」を挟む))
['あいうえお']
=> (リスト (-1 (範囲 5) を挿入))
[0、-1、1、-1、2、-1、3、-1、4]
反復可能ですか?
使用法: (反復可能? x)
返品 ◯ if x 反復可能です。 反復可能なオブジェクトは、次の場合に新しい反復子を返します。 (イター x) is
と呼ばれた。 と対比してください イテレータ?.
=> ;; 文字列に対して機能します
=> (反復可能? (str "abcde"))
◯
=> ;; リストに対して機能します
=> (反復可能? [1 2 3 4 5])
◯
=> ;; タプルで動作します
=> (反復可能? (, 1 2 3))
◯
=> ;; 辞書で動作します
=> (反復可能? {:a 1 :b 2 :c 3})
◯
=> ;; イテレータ/ジェネレータで動作します
=> (反復可能? (3 回繰り返します))
◯
イテレータ?
使用法: (反復子? x)
返品 ◯ if x イテレータです。 イテレータは、それ自身を
イテレータのとき (イター x) と呼ばれます。 と対比してください 反復可能ですか?.
=> ;; リストでは機能しません
=> (反復子? [1 2 3 4 5])
×
=> ;; ただし、リストから iter を取得できます
=> (反復子? (iter [1 2 3 4 5]))
◯
=> ;; 辞書では機能しません
=> (反復子? {:a 1 :b 2 :c 3})
×
=> ;; dictからイテレータを作成する
=> (反復子? (反復子 {:a 1 :b 2 :c 3}))
◯
リスト*
使用法: (リスト* &休み しっぽ)
引数を含む入れ子になった cons セルのチェーン (点線のリスト) を生成します。 もし
引数リストには要素が XNUMX つしかないので、それを返します。
=> (リスト* 1 2 3 4)
(1 2 3 . 4)
=> (リスト* 1 2 3 [4])
[1、2、3、4]
=> (リスト*1)
1
=> (短所? (リスト* 1 2 3 4))
◯
マクロ展開
バージョン 0.10.0 の新機能。
使用法: (マクロ展開 形)
の完全なマクロ展開を返します。 フォーム.
=> (マクロ展開 '(-> (ab) (xy)))
(u'x' (u'a' u'b') u'y')
=> (マクロ展開 '(-> (ab) (-> (cd) (ef))))
(u'e' (u'c' (u'a' u'b') u'd') u'f')
マクロエキスパンド-1
バージョン 0.10.0 の新機能。
使用法: (マクロエキスパンド-1 形)
次の単一ステップのマクロ展開を返します。 フォーム.
=> (macroexpand-1 '(-> (ab) (-> (cd) (ef))))
(u'_>' (u'a' u'b') (u'c' u'd') (u'e' u'f'))
と合併
バージョン 0.10.1 の新機能。
使用法: (と合併 f &休み 地図)
最初に結合された残りのマップで構成されるマップを返します。 キーが発生した場合
複数のマップがある場合、後者のマッピング (左から右) が結合されます。
呼び出しによる結果のマッピング (f 結果の値 後者のヴァル).
=> (マージウィズ (fn [xy] (+ xy)) {"a" 10 "b" 20} {"a" 1 "c" 30})
{u'a': 11L、u'c': 30L、u'b': 20L}
否定ですか?
使用法: (いや? x)
返品 ◯ if x はゼロ未満です。 レイズ タイプエラー if (会員登録はお済みでしょうか? (数字? バツ)).
=> (否定? -2)
◯
=> (否定? 3)
×
=> (否定? 0)
×
ゼロ?
使用法: (なし? x)
返品 ◯ if x is ゼロ / なし.
=> (なし? なし)
◯
=> (なし?なし)
◯
=> (nil? 0)
×
=> (setf x nil)
=> (nil?x)
◯
=> ;; list.append は常に None を返します
=> (nil? (.append [1 2 3] 4))
◯
無し?
使用法: (なし? x)
返品 ◯ if x is なし.
=> (なし? なし)
◯
=> (なし? 0)
×
=> (setf x なし)
=> (なし?×)
◯
=> ;; list.append は常に None を返します
=> (なし? (.append [1 2 3] 4))
◯
n番目の
使用法: (n番目 コル n オプション(&オプション) [ディフォルト なし])
を返します nコレクション内の 0 番目の項目。デフォルト値を返します。 ゼロ、もし
範囲外です(別途指定がない限り)。 レイズ 値エラー if n 負です。
=> (n番目 [1 2 4 7] 1)
2
=> (n番目 [1 2 4 7] 3)
7
=> (nil? (nth [1 2 4 7] 5))
◯
=> (nth [1 2 4 7] 5 "デフォルト")
'ディフォルト'
=> (nth (take 3 (drop 2 [1 2 3 4 5 6])) 2))
5
=> (n番目 [1 2 4 7] -1)
トレースバック(最後の最後の呼び出し):
...
ValueError: islice() のインデックスは None または整数: 0 <= x <= sys.maxsize である必要があります。
数値的な?
使用法: (数字? x)
返品 ◯ if x Python で定義されている数値です。 数字.数字 とに提供されます。
=> (数値? -2)
◯
=> (数値? 3.2)
◯
=> (数値? "foo")
×
奇数?
使用法: (奇数? x)
返品 ◯ if x 奇数です。 レイズ タイプエラー if (会員登録はお済みでしょうか? (数字? バツ)).
=> (奇数? 13)
◯
=> (奇数? 2)
×
=> (奇数? 0)
×
そうですか?
使用法: (そうですか? x)
返品 ◯ if x はゼロより大きいです。 レイズ タイプエラー if (会員登録はお済みでしょうか? (数字? バツ)).
=> (位置? 3)
◯
=> (位置? -2)
×
=> (位置? 0)
×
2番目の
使用法: (XNUMX番 コル)
の XNUMX 番目のメンバーを返します コル。 に相当 (取得する コル 1).
=> (0 番目の [1 2 XNUMX])
1
一部
バージョン 0.10.0 の新機能。
使用法: (いくつか 捕食 コル)
最初の論理的に真の値を返します。 (プレド x) いずれかの x in コル、そうでなければ ゼロ.
返品 ゼロ if コル 空です。
=> (一部は偶数ですか? [2 4 6])
◯
=> (nil? (偶数もある? [1 3 5]))
◯
=> (nil? (何らかのアイデンティティ [0 "" []]))
◯
=> (何らかのアイデンティティ [0 "空でない文字列" []])
'空でない文字列'
=> (nil? (場合によっては? []))
◯
ストリング?
使用法: (弦? x)
返品 ◯ if x 文字列です。
=> (文字列? "foo")
◯
=> (文字列? -2)
×
シンボル?
使用法: (シンボル? x)
返品 ◯ if x は記号です。
=> (シンボル? 'foo)
◯
=> (記号? '[abc])
×
零?
使用法: (ゼロ? x)
返品 ◯ if x ゼロです。
=> (ゼロ? 3)
×
=> (ゼロ? -2)
×
=> (ゼロ? 0)
◯
シーケンス 機能
シーケンス関数は、潜在的に無限のシーケンスを作成したり操作したりできます。
シーケンスがリストまたは同様のコンテナ内で完全に実現される必要があります。 彼らはこれを次のようにして行います
Python イテレータを返します。
使用方法の例として、正準無限フィボナッチ数ジェネレーターを使用できます。
これらの機能の一部。
(定義 fib []
(セットTV a 0)
(セットテレビ b 1)
(本当ですが
(収量a)
(setv (, ab) (, b (+ ab))))
注意してください (その間 true ...) ループ。 これを REPL で実行すると、
=> (フィブ)
関数を呼び出すとイテレータが返されるだけですが、それを使用するまでは機能しません。
このようなことを試みることは、無限ループが実行されるまで実行されるため、お勧めできません。
利用可能な RAM をすべて消費するか、この場合は強制終了するまで消費します。
=> (リスト(fib))
[1] 91474 人が死亡
最初の 10 個のフィボナッチ数を取得するには、次を使用します。 取る。 ご了承ください 取る ジェネレーターも返します。
それでそこからリストを作成します。
=> (リスト (テイク 10 (fib)))
[0、1、1、2、3、5、8、13、21、34]
インデックス 9 のフィボナッチ数を取得するには (0 から開始):
=> (n番目(fib) 9)
34
サイクル
使用法: (サイクル コル)
coll のメンバーの無限イテレータを返します。
=> (リスト (テイク 7 (サイクル [1 2 3])))
[1、2、3、1、2、3、1]
=> (リスト (テイク 2 (サイクル [1 2 3])))
[1、2]
明確な
使用法: (明確な コル)
一意のメンバーのみを含むイテレータを返します。 コル.
=> (リスト (distinct [ 1 2 3 4 3 5 2 ]))
[1、2、3、4、5]
=> (リスト (個別の []))
[]
=> (リスト (distinct (iter [ 1 2 3 4 3 5 2 ])))
[1、2、3、4、5]
ドロップ
使用法: (落とす n コル)
最初のイテレータをスキップしてイテレータを返します。 n のメンバー コル。 レイズ 値エラー if n is
負。
=> (リスト (ドロップ 2 [1 2 3 4 5]))
[3、4、5]
=> (リスト (ドロップ 4 [1 2 3 4 5]))
【5]
=> (リスト (ドロップ 0 [1 2 3 4 5]))
[1、2、3、4、5]
=> (リスト (ドロップ 6 [1 2 3 4 5]))
[]
ドロップラスト
使用法: (ドロップラスト n コル)
最後を除くすべての反復子を返します。 n のアイテム コル。 レイズ 値エラー if n is
負。
=> (リスト (最後の 5 をドロップ (範囲 10 20)))
[10、11、12、13、14]
=> (リスト (ドロップ-最後の 0 (範囲 5)))
[0、1、2、3、4]
=> (リスト (ドロップ-最後の 100 (範囲 100)))
[]
=> (itertools をインポート)
=> (リスト (take 5 (drop-last 100 (itertools.count 10))))
[10、11、12、13、14]
ドロップしながら
使用法: (ドロップしながら 捕食 コル)
のメンバーをスキップしてイテレータを返します。 コル まで 捕食 is ×.
=> (リスト (偶数ドロップ中? [2 4 7 8 9]))
[7、8、9]
=> (list (drop-while numeric? [1 2 3 None "a"])))
[何もない、うわー]
=> (リスト (ドロップ中の位置? [2 4 7 8 9]))
[]
filter
使用法: (フィルター 捕食 コル)
内のすべての項目のイテレータを返します。 コル 述語を渡すもの 捕食.
参照 削除します.
=> (リスト (フィルター位置? [1 2 3 -4 5 -7]))
[1、2、3、5]
=> (リスト (フィルタ偶数? [1 2 3 -4 5 -7]))
[2、-4]
平らにする
バージョン 0.9.12 の新機能。
使用法: (平らにする コル)
すべての項目の単一のリストを返します。 コル含まれるすべてのリストを平坦化することによって、および/または
タプル。
=> (平坦化 [1 2 [3 4] 5])
[1、2、3、4、5]
=> (平坦化 ["foo" (, 1 2) [1 [2 3] 4] "bar"])
['foo', 1, 2, 1, 2, 3, 4, 'bar']
反復する
使用法: (反復 fn x)
次のイテレータを返します。 x, fn(x), fn(fn(x)), etc.
=> (リスト (take 5 (iterate inc 5)))
[5、6、7、8、9]
=> (リスト (take 5 (iterate (fn [x] (* xx)) 5)))
[5、25、625、390625、152587890625]
read
使用法: (読む オプション(&オプション) [ファイルから [eof])
次の Hy 式を読み取ります。 ファイルから (デフォルトでは システム標準入力)、を取得できます
EOF として単一バイト (デフォルトは空の文字列)。 レイズ EOFエラー if ファイルから 前に終わる
完全な式を解析できます。
=> (読む)
(+2 2)
('+' 2 2)
=> (評価(読み取り))
(+2 2)
4
=> (インポートIO)
=> (def バッファ (io.StringIO "(+ 2 2)\n(- 2 1)"))
=> (eval (apply read [] {"from_file" バッファ}))
4
=> (eval (apply read [] {"from_file" バッファ}))
1
=> ; 「example.hy」に次の内容が含まれていると仮定します。
=> ; (「こんにちは」を印刷)
=> ; (「ハイフレンズ!」と印刷してください)
=> (with [[f (open "example.hy")]]
... (試す
... (本当ですが
... (let [[exp (read f)]]
... (する
... (「OHY」expを印刷)
... (評価式))))
... (キャッチ [e EOFError]
... (「EOF!」を印刷))))
OHY (「印刷」「こんにちは」)
こんにちは
OHY (「印刷」「ハイフレンズ!」)
ハイフレンズ!
終了!
削除します
使用法: (取り除く 捕食 コル)
からイテレータを返します。 コル 述語を渡す要素の場合、 捕食、削除されました。
参照 filter .
=> (リスト (奇数を削除? [1 2 3 4 5 6 7]))
[2、4、6]
=> (リスト (位置を削除しますか? [1 2 3 4 5 6 7]))
[]
=> (リスト (neg を削除しますか? [1 2 3 4 5 6 7]))
[1、2、3、4、5、6、7]
繰り返す
使用法: (繰り返す x)
次の反復子 (無限) を返します。 x.
=> (リスト (テイク 6 (「s」を繰り返す)))
[あなた、あなた、あなた、あなた、あなた、あなた]
繰り返し
使用法: (繰り返し fn)
呼び出してイテレータを返します fn 繰り返す。
=> (インポート [ランダム [randint]])
=> (list (take 5 (繰り返し (fn [] (randint 0 10)))))
[6、2、0、6、7]
取る
使用法: (取った n コル)
最初の要素を含む反復子を返します。 n のメンバー コル。 レイズ 値エラー if n is
負。
=> (リスト (テイク 3 [1 2 3 4 5]))
[1、2、3]
=> (リスト (テイク 4 (「s」を繰り返す)))
[あなた、あなた、あなた、あなた]
=> (リスト (テイク 0 (「s」を繰り返す)))
[]
取る
使用法: (n番目を取る n コル)
すべてを含む反復子を返します。 n- 番目のメンバー コル.
=> (リスト (take-nth 2 [1 2 3 4 5 6 7]))
[1、3、5、7]
=> (リスト (take-nth 3 [1 2 3 4 5 6 7]))
[1、4、7]
=> (リスト (take-nth 4 [1 2 3 4 5 6 7]))
[1、5]
=> (リスト (take-nth 10 [1 2 3 4 5 6 7]))
【1]
しばらくの間
使用法: (しばらくの間 捕食 コル)
からイテレータを返します。 コル 限り 捕食 収益 ◯.
=> (リスト (テイク中の位置? [ 1 2 3 -4 5]))
[1、2、3]
=> (リスト (take-while neg? [ -4 -3 1 2 5]))
[-4、-3]
=> (リスト (take-while neg? [ 1 2 3 -4 5]))
[]
ジップウィズ
バージョン 0.9.13 の新機能。
使用法: (ジッパー付き fn コル ...)
に相当 ZIPですが、タプルを作成する代わりに複数引数関数を使用します。 もし
ジップウィズ N 個のコレクションで呼び出されると、 fn N 個の引数を受け入れる必要があります。
=> (インポート演算子)
=> (リスト (zipwith 演算子.add [1 2 3] [4 5 6]))
[5、7、9]
リーダー マクロ
Reader マクロは、Lisp に構文をその場で変更および変更する機能を与えます。 欲しくないですよね
ポーランド語表記? リーダー マクロを使用すると、それを簡単に行うことができます。 Clojure のような方法が必要です
正規表現? Reader マクロでもこれを簡単に行うことができます。
構文
=> (defreader ^ [expr] (print expr))
=> #^(1 2 3 4)
(1 2 3 4)
=> #^「こんにちは」
"こんにちは"
=> #^1+2+3+4+3+2
1+2+3+4+3+2
Hy にはタプルのリテラルがありません。 嫌いだと言ってみましょう (, ...) そして何か他のものが欲しいです。 これ
これはリーダーマクロがうまく解決できる問題です。
=> (defreader t [expr] `(, ~@expr))
=> #t(1 2 3)
(1、2、3)
Clojure のように正規表現のリテラルを使用することもできます。
=> (インポート再)
=> (defreader r [expr] `(re.compile ~expr))
=> #r".*"
<_sre.SRE_Pattern オブジェクト (0xcv7713ph15#)>
製品の導入
恐怖者 リーダー マクロのシンボル名として XNUMX 文字を受け取ります。 もう何でも
エラーが返されます。 実装に関しては、 恐怖者 で覆われたラムダに展開します。
デコレーター。 このデコレーターは、ラムダをそのモジュール名とともに辞書に保存します。
シンボル。
=> (defreader ^ [expr] (print expr))
;=> (with_decorator (hy.macros.reader ^) (fn [expr] (print expr)))
# に拡大します (dispatch_reader_macro ...) シンボルと式が渡される場所
正しい機能。
=> #^()
;=> (dispatch_reader_macro ^ ())
=> #^「こんにちは」
"こんにちは"
警告:
Hy のレクサーとパーサーの制限により、リーダー マクロは定義されたマクロを再定義できません
のような構文 ()[]{}。 この問題は将来的に解決される可能性が高くなります。
内部 Hy ドキュメント
注:
これらのビットは主に Hy 自体をハッキングする人にとって役立ちますが、次の目的にも使用できます。
マクロプログラミングをさらに深く掘り下げる人。
Hy Models
概要 〜へ Hy Models
Hy モデルは通常の Python オブジェクトの上にある非常に薄い層であり、Hy ソースを表します
データとしてのコード。 モデルはソースの位置情報のみを追加し、いくつかのメソッドを追加します。
Hy ソース コードのクリーンな操作 (マクロなど) をサポートします。 それを達成するために
目標として、Hy モデルは基本 Python クラスのミックスインであり、 HyObject.
HyObject
hy.models.HyObject Hy モデルの基本クラスです。 実装するメソッドは XNUMX つだけです。 replace,
これは、現在のオブジェクトのソース位置を引数として渡されたものに置き換えます。
これにより、変更された式の元の位置を追跡できるようになります。
マクロは、コンパイラ内であっても、純粋な hy マクロ内であっても。
HyObject Hy モデルをインスタンス化するために直接使用することを目的としたものではなく、ミックスインとしてのみ使用することを目的としています。
他のクラスの場合。
Models
括弧で囲まれたリストと括弧で囲まれたリストは、Hy パーサーによって複合モデルとして解析されます。
ハイリスト
hy.models.list.HyList 「反復可能な」Hy モデルの基本クラスです。 その基本的な使い方は、
括弧で囲まれたものを表す [] リスト。トップレベルの式として使用すると、次のように変換されます。
コンパイル段階での Python リスト リテラル。
HyList を別の反復可能なオブジェクトに追加すると、左側のオブジェクトのクラスが再利用されます。
これは、マクロ内で Hy オブジェクトを連結する場合などに便利な動作です。
ハイ式
hy.models.expression.HyExpression 受け継ぐ ハイリスト 括弧付きの () 表現。 の
これらの式のコンパイル結果は、リストの最初の要素によって異なります。
コンパイラは、コンパイラの特殊形式、ユーザー定義マクロ、およびコンパイラ間で式をディスパッチします。
通常の Python 関数呼び出し。
ハイディクト
hy.models.dict.HyDict 受け継ぐ ハイリスト 中括弧の場合 {} コンパイルする式
Python 辞書リテラルまで。
辞書の代わりにリストを基底クラスとして使用する決定 ハイディクト より簡単にできます
マクロでの辞書の操作、複合式を許可するという追加の利点
dict キーとして (たとえば、 ハイ式 Python クラスはハッシュ可能ではありません)。
アトミック Models
入力ストリームでは、文字列の Python 表記法に従って二重引用符で囲まれた文字列が、
単一のトークンとして解析され、 ハイストリング.
スペース、括弧、引用符、二重引用符を除く、連続した文字列
とコメントは識別子として解析されます。
識別子は、解析フェーズ中に次の順序でアトミック モデルに解決されます。
· HyInteger
· ハイフロート
· ハイコンプレックス (原子が裸でない場合 j)
· ハイキーワード (原子が次で始まる場合 :)
· ハイシンボル
ハイストリング
hy.models.string.HyString 文字列と同等の Hy モデルの基本クラスです。 また
二重引用符で囲まれた文字列リテラルを表します。 ""、Unicode文字列にコンパイルされます。
Python のリテラル。 ハイストリングス Python 2 では Unicode オブジェクトを継承し、Python XNUMX では文字列オブジェクトを継承します。
Python 3 (したがってエンコードに依存しません)。
ハイストリング ベースのモデルは不変です。
Hy リテラル文字列は複数行にまたがることができ、パーサーによって XNUMX つの文字列としてみなされます。
Unicode 文字列の Python エスケープを考慮したユニット。
数値の Models
hy.models.integer.HyInteger 整数リテラルを表します ( 長い Python 2 で入力します。
と int型 Python 3 上)。
hy.models.float.HyFloat 浮動小数点リテラルを表します。
hy.models.complex.HyComplex 複雑なリテラルを表します。
数値モデルは、対応する Python ルーチンと有効な数値 Python を使用して解析されます。
リテラルは対応する Hy に変換されます。
ハイシンボル
hy.models.symbol.HySymbol Hy 言語でシンボルを表現するために使用されるモデルです。 それ
受け継ぐ ハイストリング.
ハイシンボル Python の相互運用性を高めるために、オブジェクトは解析フェーズで破壊されます。
・アスタリスクで囲まれた記号(*) は大文字に変換されます。
· ダッシュ (-) はアンダースコア (_);
· 末尾に疑問符が XNUMX つ (?) が先頭に変わります は_.
注意: マングリングは解析フェーズ中に行われるため、次のことが可能です。
Hy ソース コードでは生成できない HySymbol をプログラムで生成します。 そんな
このメカニズムは、gensym によって「インターンされていない」シンボルを生成するために使用されます。
ハイキーワード
hy.models.keyword.HyKeyword Hyのキーワードを表します。 キーワードは、で始まる記号です。
a :。 クラスは継承します ハイストリング.
区別するために ハイキーワード from HySymbols、(非自発的)可能性なし
クラッシュ、私用 Unicode 文字 「\uFDD0」 キーワードリテラルの先頭に付加されます
保管前。
デメリット 細胞
hy.models.cons.HyCons は Python フレンドリーの表現です 短所 細胞。 コンスセルは、
Scheme や Common などの「通常の」LISP バリアントの機能を模倣するのに特に便利です
舌足らずの発音。
コンス セルは 2 項目のオブジェクトであり、 自動車 (頭)と cdr (しっぽ)。 一部のLispでは
バリアントでは、コンス セルが基本的な構成要素であり、S 式は実際には
コンスセルのリンクされたリストとして表されます。 いつものように、Hyではそうではありません
式は Python リストでラップされて構成されます。 ハイ式。 しかし、 ハイコンズ
このように、「通常の」Lisp バリアントの動作を模倣します。
· (短所 何か なし) is (HyExpression [何か])
· (短所 何か いくつかのリスト) is ((タイプ いくつかのリスト) (+ [何か] いくつかのリスト)) (if
いくつかのリスト から継承 リスト).
· (取得する (短所 a b) 0) is a
· (スライス (短所 a b) 1) is b
Hy はドット付きリスト構文をサポートしています。 '(a . b) 手段 (短所 'a 'b) と '(a b . c) 手段
(短所 'a (短所 'b 'c))。 コンパイラがトップレベルで cons セルに遭遇すると、
コンパイルエラー。
ハイコンズ 渡された引数 (car と cdr) を Hy 型でラップし、操作を容易にします。
マクロコンテキストの cons セル。
Hy 内部 理論
概要
Hy の内部は Python バイトコードのフロントエンドとして機能するため、Hy 自体は
Python バイトコードにコンパイルされ、未変更の Python ランタイムで Hy コードを実行できるようになります。
気づかずに。
これを行う方法は、Hy を内部 Python AST データ構造に変換することです。
Python 標準のモジュールを使用して、その AST を Python バイトコードに構築します
これにより、Python 内部のすべての作業をすべてのライブラリで複製する必要がなくなります。
単一の Python リリース。
Hy は XNUMX つの段階で機能します。 次のセクションでは、ソースからソースまでの Hy の各ステップについて説明します。
ランタイム。
ステップ 1 と 2: トークン化 と 解析
Hy をコンパイルする最初の段階は、ソースを処理できるトークンに変換することです。 私たちは
rply というプロジェクトを使用します。これは、サブセットで書かれた非常に優れた (そして高速な) パーサーです。
rpython と呼ばれる Python の。
字句解析コードはすべて次のように定義されています。 hy.lex.lexer。 このコードはほとんどが Hy を定義しているだけです
文法であり、実際の難しい部分はすべて rply によって処理されます -- 定義するだけです
rply の「コールバック」 hy.lex.パーサー、生成されたトークンを受け取り、
こんにちはモデルたち。
Hy モデルは Hy の「AST」と考えることができ、マクロはこれを操作します。
(直接)、コンパイラが Hy をコンパイルするときに使用するものです。
関連項目 ALSO:
セクション Hy Models Hy モデルとその意味の詳細については、こちらをご覧ください。
手順 3: Hy 編集 〜へ Python AST
Hy の魔法のほとんどがここで起こります。 ここで Hy AST (モデル) を取り上げます。
そしてそれらを Python AST にコンパイルします。 いくつかのファンキーな出来事がここで起こります。
AST の問題を解決し、コンパイラでの作業は私たちが行う最も重要な作業の XNUMX つです。
持ってる。
コンパイラは少し複雑なので、最初は理解できなくても心配する必要はありません。
正しくなるには少し時間がかかるかもしれません。
コンパイラへの主なエントリポイントは次のとおりです。 HyASTCompiler.compile。 このメソッドが呼び出されると、
クラス上の唯一の実際の「パブリック」メソッド (つまり、実際には、
そのメソッドを超える API)。
実際、内部的にさえ、直接再帰することはほとんどなく、ほとんどの場合強制的に再帰します。
ハイツリースルー コンパイル、式のサブ要素でこれを行うことがよくあります。
我々が持っていること。 サブ要素を適切にディスパッチできるかどうかは、Type ベースのディスパッチャ次第です。
コンパイルを実行するすべてのメソッドには、 @builds() デコレーター。 あなたはできる
コンパイルする Hy モデルのクラスを渡すか、文字列を使用できます。
表現。 これはすぐに解決します。
名 ステージ タイプディスパッチ
から始めましょう コンパイル 方法。 最初に行うことは、オブジェクトのタイプを確認することです
私たちは構築しています。 を構築できる方法があるかどうかを調べます。 タイプ() 我々
を持っており、それを処理できるメソッドにディスパッチします。 それができる方法がない場合は、
その型を構築すると、内部で 例外.
たとえば、 ハイストリング、Hy AST から Python へのほぼ 1 対 1 のマッピングがあります。
AST。 の コンパイル文字列 メソッドは ハイストリング、およびを返します ast.Str()
正しい行番号と内容が入力されます。
マクロ展開
を取得したら ハイ式、これが既知のマクロかどうかを確認し、プッシュします。
を呼び出すことで拡張されました hy.macros.macroexpand、結果を にプッシュして戻します。
HyASTCompiler.compile.
秒 ステージ 式のディスパッチ
唯一の特殊なケースは、 ハイ式に応じて異なるASTを作成する必要があるため、
問題の特別なフォームについて。 たとえば、何かを打ったとき、 (if true true 間違い)、我々
を生成する必要があります ast.If、サブノードを適切にコンパイルします。 ここは、 @builds()
引数として文字列を指定した場合。
コンパイル式 (これは @builds(HyExpression))発送します
最初の引数の文字列に基づきます。 何らかの理由で最初の引数がそうでない場合は、
文字列の場合、その場合も適切に処理します (おそらく、 例外).
文字列が Hy に知られていない場合、デフォルトで ast.Call、しようとします
ランタイム呼び出しを実行します (Python では次のようなもの) foo()).
問題 ヒット Python AST
Python AST は優れています。 そのおかげで、このような強力なプロジェクトを構築できるようになりました。
Python とあまり激しく戦う必要がなくなります。 他のものと同じように、私たちは
ここでは、遭遇する可能性のある一般的な問題の短いリストを示します。
Python 差別化する の間に ステートメント と 式.
これは大したことではないように聞こえるかもしれません。実際、ほとんどの Python プログラマーにとって、これは次のとおりです。
すぐに「そうですね」の瞬間になります。
Python では、次のようなことを行います。
印刷 for x in 範囲(10): パス、理由 印刷 式を出力し、 for ではありません
式、これは制御フロー ステートメントです。 のようなもの 1 + 1 そのままの式です ラムダ
x: 1 + x、ただし、次のような他の言語機能 if, forまたは while ステートメントです。
これらには Python にとって「価値」がないため、何かを行うため、Hy での作業が難しくなります。
ような (印刷 (if true true 間違い)) それは一般的なだけでなく、予想されることです。
その結果、私たちは、 結果 オブジェクト、私たちはあらゆるものを提供します ast.stmt
実行する必要があるものと、単一の ast.expr 何かの値を取得するために使用できます
ちょうど実行されました。 Hy は、実行中に強制的に何かを割り当てることでこれを実現します。
例として、Hy:
(print (true true false の場合))
次のようになります:
真であれば:
_mangled_name_here = True
その他:
_mangled_name_here = False
_mangled_name_here を印刷
OK、それは少し嘘でした。なぜなら、このステートメントを実際に次のように変換するからです。
print True の場合は True、それ以外の場合は False
物事を無理やり押し込むことで、 ast.expr できれば可能ですが、一般的な考え方は当てはまります。
手順 4: Python バイトコード 出力 と ランタイム
Python AST ツリーが完成したら、それを Python にコンパイルしてみます。
バイトコードをプッシュスルーして 評価する。 ここから先は、私たちはもうコントロールできなくなり、
Python がすべてを処理します。 これが、Python トレースバック、pdb、
ジャンゴアプリは動作します。
Hy マクロ
使い方 ゲンシム for より安全な マクロ
マクロを作成するときは、外部変数をキャプチャしたり、マクロを使用したりしないように注意する必要があります。
ユーザーコードと競合する可能性のある変数名。
マクロの例を使用します nif (参照してください
http://letoverlambda.com/index.cl/guest/chap3.html#sec_5 より完全な説明については。)
nif は例であり、数値のようなものです if、式に基づいて、次のいずれかが
式が正、ゼロ、または負であるかどうかに応じて、3 つの形式が呼び出されます。
最初のパスは次のようになります。
(defmacro nif [expr pos-form XNUMX-form neg-form]
`(let [[obscure-name ~expr]]
(cond [(pos? obscure-name) ~pos-form]
[(ゼロ?あいまいな名前) ~ゼロの形式]
[(neg?あいまいな名前) ~neg-form])))
コラボレー あいまいな名前 他の変数と競合しないように変数名を選択する試みです。
コード。 しかし、もちろん、善意ではありますが、これが保証されるわけではありません。
メソッド gensym は、まさにそのような場合に新しい一意のシンボルを生成するように設計されています。
より優れたバージョンの nif だろう:
(defmacro nif [expr pos-form XNUMX-form neg-form]
(let [[g (gensym)]]
`(let [[~g ~expr]]
(cond [(pos? ~g) ~pos-form]
[(ゼロ? ~g) ~ゼロ形式]
[(neg? ~g) ~neg-form]))))
シンボルが XNUMX つしかないため、これは簡単なケースです。 ただし、複数必要な場合は、
gensym には、基本的に一連の う
文:
(gensonyms [abc] 付き)
...)
次のように展開されます:
([[a (gensym)
[b (gensym)
[c (gensym)]]
...)
それで私たちが書き直した nif 次のようになります:
(defmacro nif [expr pos-form XNUMX-form neg-form]
(gensonym 付き [g]
`(let [[~g ~expr]]
(cond [(pos? ~g) ~pos-form]
[(ゼロ? ~g) ~ゼロ形式]
[(neg? ~g) ~neg-form]))))
最後に、これらすべてを実行する新しいマクロを作成できます。 デフマクロ/g! とる
で始まるすべての記号 g! そして自動的に電話をかけます ゲンシム 残りの部分で
シンボル。 それで が! になる (gensym 「あ」).
私たちの最終バージョンは、 nif、で構築 デフマクロ/g! になります:
(defmacro/g! nif [expr pos-form XNUMX-form neg-form]
`(let [[~g!res ~expr]]
(cond [(pos? ~g!res) ~pos-form]
[(ゼロ? ~g!res) ~ゼロ形式]
[(neg? ~g!res) ~neg-form]))))
チェック マクロ Arguments と 調達 例外
Hy コンパイラ ビルトイン
寄稿者 モジュール INDEX
内容:
アナフォリック マクロ
バージョン 0.9.12 の新機能。
アナフォリック マクロ モジュールにより、Hy での関数型プログラミングが非常に簡潔かつ簡単になります。
読み。
アナフォリック マクロは、何らかの形式を意図的にキャプチャするプログラミング マクロの一種です。
照応 (参照する表現) によって参照される可能性のあるマクロに提供されます。
別のものに)。 — ウィキペディア (http://en.wikipedia.org/wiki/Anaphoric_macro)
マクロ
AP-IF
使用法: (ap-if (ふー) (印刷 それ))
最初の形式の真実性を評価し、それをバインドします。 it 真実と偽りの両方で
枝。
桃
使用法: (桃 [1 2 3 4 5] (印刷 それ))
リスト内の各要素のフォームを評価して副作用を確認します。
毎時毎時
使用法: (ap-each-while リスト 捕食 体)
述語フォームが返す各要素のフォームを評価します。 ◯.
=> (ap-each-while [1 2 3 4 5 6] (< it 4) (print it))
1
2
3
ap マップ
使用法: (APマップ フォーム リスト)
照応形式のマップは、関数ではなく通常のマップと同じように機能します。
オブジェクトは Hy 形式を取ります。 特別な名前 it から現在のオブジェクトにバインドされます。
反復内のリスト。
=> (リスト (ap-map (* it 2) [1 2 3]))
[2、4、6]
ap-map-when
使用法: (ap-map-when 予定 代表 リスト)
述語関数を使用してリスト上のマッピングを評価し、いつ適用するかを決定します。
フォーム。
=> (リスト (ap-map-when奇数? (* it 2) [1 2 3 4]))
[2、2、6、4]
=> (リスト (ap-map-when Even? (* it 2) [1 2 3 4]))
[1、4、3、8]
ap フィルター
使用法: (apフィルター フォーム リスト)
屈折計と同様に、この類の検証は官能評価と並行して行うべきです。一般的に、抽出が進むにつれて高温になる抽出方法は、抽出が成功する確率が低い傾向にあります。 ap マップ 関数の代わりに特別な形式を使用して、要素をフィルタリングします。
リスト。 特別な名前 it 反復内の現在の要素にバインドされます。
=> (list (ap-filter (> (* it 2) 6) [1 2 3 4 5]))
[4、5]
AP拒否
使用法: (ap-拒否 フォーム リスト)
この関数は次の逆のことを行います ap フィルター、を渡す要素を拒否します。
述語 。 特別な名前 it 反復内の現在の要素にバインドされます。
=> (list (ap-reject (> (* it 2) 6) [1 2 3 4 5]))
[1、2、3]
ap-dotimes
使用法 (ap-dotimes n 体)
この関数は本体を評価します n 特殊変数を使用した回 it からバインドされる 0 〜へ
1-N。 副作用に有効です。
=> (setv n [])
=> (ap-dotimes 3 (.append n it))
=> n
[0、1、2]
APファースト
使用法 (ap-first 予定 リスト)
この関数は、述語を渡す最初の要素を返します。 なし、 とともに
特殊変数 it 反復内の現在の要素にバインドされます。
=>(ap-first (> it 5) (範囲 10))
6
ap-last
使用法 (ap-last 予定 リスト)
この関数は、述語を渡す最後の要素を返します。 なし、特別な
変数 it 反復内の現在の要素にバインドされます。
=>(ap-last (> it 5) (範囲 10))
9
apリダクション
使用法 (AP リデュース フォーム リスト オプション(&オプション) 初期値)
この関数は、本文の最初の 2 つの要素にフォームを適用した結果を返します。
リストがなくなるまで結果と 3 番目の要素などを適用します。 オプションで、
初期値を指定できるため、関数が初期値に適用され、
代わりに最初の要素を使用します。 これにより、反復される要素が次のように公開されます。 it と電流
累積値として ACC.
=>(ap-reduce (+ it acc) (範囲 10))
45
ループ/繰り返し
バージョン 0.10.0 の新機能。
この ループ / 再発する マクロを使用すると、プログラマーは末尾呼び出し最適化 (TCO) を簡単に使用できます。
彼らの Hy コードに。
末尾呼び出しは、別のプロシージャ内で最後の呼び出しとして発生するサブルーチン呼び出しです。
アクション; 戻り値を生成する場合があり、その値は呼び出し側によってすぐに返されます。
手順。 サブルーチンが実行する呼び出しの場合、最終的には
この同じサブルーチンが呼び出しチェーンの下で再び呼び出され、末尾の位置にあり、
このようなサブルーチンは末尾再帰的であると言われ、再帰の特殊なケースです。
末尾呼び出しは、新しいスタックを追加せずに実装できるため重要です。
フレームを呼び出しスタックに追加します。 現在の手順のフレームの大部分は必要ありません。
さらに、テールコールのフレームに置き換えることができます。 プログラムはジャンプできるようになります
呼び出されたサブルーチンに。 標準の呼び出しシーケンスの代わりにそのようなコードを生成することは、
末尾呼び出しの削除、または末尾呼び出しの最適化と呼ばれます。 末尾呼び出しの削除が可能
末尾位置でのプロシージャ呼び出しは goto ステートメントと同じくらい効率的に実装されます。
したがって、効率的な構造化プログラミングが可能になります。 — ウィキペディア (‐
http://en.wikipedia.org/wiki/Tail_call)
マクロ
ループ
ループ 再帰ポイントを確立します。 と ループ, 再発する に設定された変数を再バインドします。
再帰ポイントを取得し、コードの実行をその再帰ポイントに送り返します。 もし 再発する で使用されています
末尾以外の位置の場合、例外がスローされます。
使用法: (ループ バインディング &休み 体)
例:
(hy.contrib.loopが必要)
(定義階乗 [n]
(ループ [[in] [acc 1]]
(if (ゼロ? i)
ACC
(recur (dec i) (* acc i))))
(階乗1000)
デフマルチ
バージョン 0.10.0 の新機能。
デフマルチ 指定された数の args および/または kwargs によって関数をアリティ オーバーロードできます。
Clojure の考え方からインスピレーションを得た 定義.
=> (hy.contrib.multiが必要)
=> (デフマルチ楽しい
... ([a] "a")
... ([ab] "ab")
... ([abc] "abc"))
=> (楽しみ1)
「あ」
=> (楽しい 1 2)
「アブ」
=> (楽しい 1 2 3)
「ABC」
HACKING ON HY
加入 私たちの ハイブ!
Hyをハックしに来てください!
ぜひ遊びに来てください #ハイ on irc.freenode.net!
Twitter でこの件について話し合ってください #ハイ ハッシュタグ!
それについてブログに書いてください!
(よく聞かずに)隣の家のフェンスにスプレーペイントしないでください。
ハック!
これを行う:
1。 作成する バーチャル 環境:
$ virtualenv venv
そしてそれをアクティブ化します:
$ 。 venv/bin/アクティブ化
または使用 仮想環境ラッパー 仮想環境を作成および管理するには:
$ mkvirtualenv hy
$ワークオンハイ
2. ソース コードを取得します。
$ git clone https://github.com/hylang/hy.git
またはフォークを使用します。
$ git クローン git@github.com: /hy.git
3. ハッキングのためにインストールします。
$ cd hy/
$ pip install -e 。
4. 他の開発要件をインストールします。
$ pip install -r 要件-dev.txt
5. 素晴らしいことをする。 あなたが成し遂げたことに対して、誰かが喜びや嫌悪感で金切り声を上げます。
テスト!
テストは次の場所にあります テスト/。 を使用しております 鼻.
テストを実行するには:
$ 鼻テスト
テストを書く --- テストは良いものです!
また、サポートされているすべてのプラットフォームと PEP 8 準拠のテストを実行することをお勧めします。
コード。 これを行うには、tox を実行します。
$トックス
書類!
ドキュメントは次の場所にあります docs /。 を使用しております スフィンクス.
HTML でドキュメントを作成するには:
$ cd ドキュメント
$ HTML を作成
ドキュメントを書く --- ドキュメントは良いものです! このドクターも!
貢献
貢献は大歓迎であり、大いに感謝されます。どんな些細なことでも Hy をより良くするのに役立ちます
驚くばかり。
プルリクエストは素晴らしいです! 私たちは彼らを愛しています。 ここにクイックガイドがあります:
· リポジトリをフォークし、機能/修正のトピック ブランチを作成します。 直接変更を加えることは避けてください
マスターブランチ上で。
· すべての新機能にはテストが伴う必要があります。
· PR を送信する前に、テストを実行し、コードがスタイルに照らしてチェックされていることを確認してください。
ガイド。 これらの両方を一度に行うことができます。
$メイクd
· コミットを論理ユニットに作成します。これにより、後で追跡およびナビゲートしやすくなります。 前に
PR を送信する場合は、簡単に戻ってくることができる変更セットにコミットを圧縮してみてください。
後で。 また、変更セット内に偽の空白を残さないようにしてください。 これ
後で空白修正コミットが作成されることを回避します。
· コミット メッセージに関しては、次の点に従うようにしてください。
· Git コミット メッセージの最初の行は 50 文字の制限を守ってください。
· 詳細/説明については、この後に空行を入れて続行してください。
コミットについて詳しく説明します。
· 最後に、自分自身を AUTHORS ファイルに (別のコミットとして) 追加します。あなたにはそうする価値があります :)
· すべての受信変更は、Hylang のコア チームの 2 人の異なるメンバーによって承認される必要があります。
追加のレビューは明らかに歓迎ですが、いずれの場合も少なくとも 2 回の承認が必要です。
変更します。
· コア メンバーが PR を送信する場合は、PR を含まない 2 人のコア メンバーを見つけてください。
PR投稿者。 ここでの考え方は、PR 作成者と協力し、もう XNUMX 人が承認するというものです。
変更セット全体。
· ドキュメントやその他の些細な変更については、XNUMX つの ACK の後にマージするのが適切です。 私たちは持っている
カバレッジが低いので、その障壁を低く保つことが望ましいでしょう。
基本 チーム
Hy のコア開発チームは次の開発者で構成されています。
· ジュリアン 段上
· モーテン リンデルド
· J ケニス 神様です。
· Gergely ナジ
· トゥッカ トゥルト
· カレン ラスタッド
· アビシェーク L
· クリストファー アラン ウェバー
· コンラート ヒンセン
· ウィル カーン・グリーン
· Paul Cairns タリアモンテ
· ニコラス ダンドリモント
· ボブ トルバート
· Berker ペクサグ
· クリントン N. ドライスバッハ
· 彼 セマジ
onworks.net サービスを使用して hy オンラインを使用する