EnglischFranzösischSpanisch

Ad


OnWorks-Favicon

hy – Online in der Cloud

Führen Sie hy beim kostenlosen Hosting-Anbieter OnWorks über Ubuntu Online, Fedora Online, den Windows-Online-Emulator oder den MAC OS-Online-Emulator aus

Dies ist der Befehl hy, der beim kostenlosen Hosting-Anbieter OnWorks mit einer unserer zahlreichen kostenlosen Online-Workstations wie Ubuntu Online, Fedora Online, dem Windows-Online-Emulator oder dem MAC OS-Online-Emulator ausgeführt werden kann

PROGRAMM:

NAME/FUNKTION


hy - hy-Dokumentation [Bild: Hy] [Bild]

MIT DER INTELLIGENTEN SCHADENKALKULATION VON Hy https://try-hy.appspot.com

PyPI https://pypi.python.org/pypi/hy

Quelle https://github.com/hylang/hy

Liste hylang-diskutieren

IRC #hy auf Freenode

Bauen Status
Travis CI.UNINDENT

Hy ist ein wunderbarer Lisp-Dialekt, der in Python eingebettet ist.

Da Hy seinen Lisp-Code in den Python Abstract Syntax Tree umwandelt, haben Sie dies getan
Die ganze schöne Welt von Python steht Ihnen in Lisp-Form zur Verfügung!

Inhaltsübersicht:

SCHNELLSTART


[Bild: Karen Rustard's Cuddles] [Bild]

(Danke an Karen Rustad für Kuscheln!)

WIE TO BESTELLE HY REAL FAST:

1. Ein ... kreieren Assistent Python Arbeitsumfeld.

2. Aktivieren Sie Ihre virtuelle Python-Umgebung.

3. Installieren hy für PyPI mit Pip installieren hy.

4. Starten Sie eine REPL mit hy.

5. Geben Sie stuff in die REPL ein:

=> (drucken Sie „Hy!“)
Hy!
=> (defn salutationsnm [name] (print (+ "Hy " name "!")))
=> (salutationsnm „IhrName“)
Hy YourName!

etc

6. Drücken Sie STRG-D, wenn Sie fertig sind.

OMG! Das ist tolle! I wollen zu schreiben a Hy

7. Öffnen Sie einen Elite-Programmiereditor und geben Sie Folgendes ein:

(Drucken Sie „Ich wollte in Python-Syntax programmieren, aber dann bekam ich Hy.“)

8. Speichern unter großartig.hy.

9. Und führen Sie Ihr erstes Hy-Programm aus:

hy großartig.hy

10
Atmen Sie tief ein, um nicht zu hyperventilieren.

11
Lächle bösartig, schleiche dich in dein Versteck und tue unaussprechliche Dinge.

TUTORIAL


Willkommen zum Hy-Tutorial!

Kurz gesagt, Hy ist ein Lisp-Dialekt, der seine Struktur jedoch in Python umwandelt ...
buchstäblich eine Konvertierung in den abstrakten Syntaxbaum von Python! (Oder um es grober auszudrücken
Begrifflich ist Hy ein Lisp-Stick auf einem Python!)

Das ist ziemlich cool, weil es bedeutet, dass Hy mehrere Dinge ist:

· Ein Lisp, das sich sehr pythonisch anfühlt

· Für Lispers eine großartige Möglichkeit, Lisps verrückte Kräfte zu nutzen, aber in der weiten Welt von Python
Bibliotheken (warum ja, Sie können jetzt eine Django-Anwendung in Lisp schreiben!)

· Für Pythonisten eine großartige Möglichkeit, Lisp bequem von Python aus zu erkunden!

· Für alle: eine angenehme Sprache mit vielen tollen Ideen!

Basic Intro zu Lispeln für Pythonisten
Okay, vielleicht haben Sie Lisp noch nie verwendet, aber Sie haben Python verwendet!

Ein „Hallo Welt“-Programm in Hy ist eigentlich supereinfach. Lass es uns versuchen:

(drucken Sie „Hallo Welt“)

Sehen? Einfach! Wie Sie vielleicht vermutet haben, ist dies dasselbe wie die Python-Version von:

Drucken Sie „Hallo Welt“

Um eine supereinfache Mathematik zusammenzufassen, könnten wir Folgendes tun:

(+1)

Das würde 4 zurückgeben und wäre das Äquivalent von:

1 + 3

Sie werden feststellen, dass das erste Element in der Liste die aufgerufene Funktion und die ist
Bei den restlichen Argumenten handelt es sich um die Argumente, die übergeben werden. Tatsächlich gilt in Hy (wie bei den meisten).
Lisps) können wir mehrere Argumente an den Plus-Operator übergeben:

(+ 1 3 55)

Was 59 zurückgeben würde.

Vielleicht haben Sie schon einmal von Lisp gehört, wissen aber nicht viel darüber. Lisp ist nicht so schwer wie du
könnte man denken, und Hy erbt von Python, also ist Hy eine großartige Möglichkeit, mit dem Erlernen von Lisp zu beginnen.
Das Wichtigste an Lisp ist, dass es viele Klammern gibt. Das könnte
Scheint zunächst verwirrend, ist aber nicht so schwer. Schauen wir uns ein paar einfache mathematische Formeln an
eingepackt in eine Reihe von Klammern, die wir in den Hy-Interpreter eingeben können:

(setv-Ergebnis (- (/ (+ 1 3 88) 2) 8))

Dies würde 38 zurückgeben. Aber warum? Nun, wir könnten uns den entsprechenden Ausdruck in ansehen
Python:

Ergebnis = ((1 + 3 + 88) / 2) - 8

Wenn Sie versuchen würden, herauszufinden, wie das oben Gesagte in Python funktionieren würde, würden Sie das natürlich tun
Finden Sie die Ergebnisse heraus, indem Sie jede innere Klammer lösen. Das ist die gleiche Grundidee
Hy. Versuchen wir diese Übung zunächst in Python:

Ergebnis = ((1 + 3 + 88) / 2) - 8
# vereinfacht zu...
Ergebnis = (92 / 2) - 8
# vereinfacht zu...
Ergebnis = 46 - 8
# vereinfacht zu...
Ergebnis = 38

Versuchen wir nun dasselbe in Hy:

(setv-Ergebnis (- (/ (+ 1 3 88) 2) 8))
; vereinfacht zu...
(setv-Ergebnis (- (/ 92 2) 8))
; vereinfacht zu...
(setv-Ergebnis (- 46 8))
; vereinfacht zu...
(Setv-Ergebnis 38)

Wie Sie wahrscheinlich erraten haben, ist dieser letzte Ausdruck mit setv bedeutet, die Variable zuzuweisen
„Ergebnis“ auf 38.

Sehen? Nicht zu schwer!

Dies ist die Grundvoraussetzung von Lisp. Lisp steht für „Listenverarbeitung“; das bedeutet, dass die
Die Struktur des Programms besteht eigentlich aus Listen von Listen. (Wenn Sie mit Python vertraut sind
Stellen Sie sich für Listen die gleiche Struktur wie oben vor, jedoch mit eckigen Klammern, beliebig
Sie können die obige Struktur sowohl als Programm als auch als Datenstruktur sehen.) Dies ist
mit mehr Beispielen leichter zu verstehen, also schreiben wir ein einfaches Python-Programm, testen es,
und zeigen Sie dann das entsprechende Hy-Programm:

def simple_conversation():
print „Hallo! Ich würde dich gerne kennenlernen. Erzähl mir etwas über dich!“
name = raw_input("Wie ist Ihr Name?")
age = raw_input("Wie alt bist du?")
print „Hallo“ + Name + „! Ich sehe, du bist „ + Alter + „ Jahre alt.“

simple_conversation()

Wenn wir dieses Programm ausführen würden, könnte es so aussehen:

Hallo! Ich würde dich gerne kennen lernen. Erzähl mir von dir!
Wie heißt du? Gary
Wie alt bist du? 38
Hallo Gary! Wie ich sehe, sind Sie 38 Jahre alt.

Schauen wir uns nun das entsprechende Hy-Programm an:

(defn simple-conversation []
(Drucken Sie „Hallo! Ich würde Sie gerne kennenlernen. Erzählen Sie mir etwas über sich!“)
(setv name (raw-input „Wie ist Ihr Name?“))
(setv age (raw-input „Wie alt bist du?“))
(drucken (+ "Hallo " Name "! Ich sehe, du bist "
Alter " Jahre alt.")))

(einfache Konversation)

Wenn Sie sich das obige Programm ansehen, denken Sie daran, dass jeweils das erste Element darin enthalten ist
Die Liste des Programms enthält die Funktion (oder das Makro ... dazu kommen wir später), das aufgerufen wird
und dass der Rest die Argumente sind, ist es ziemlich einfach herauszufinden, was das alles bedeutet.
(Wie Sie wahrscheinlich auch erraten haben, definiere ist die Hy-Methode zum Definieren von Methoden.)

Dennoch finden viele Leute das zunächst verwirrend, weil es so viele Klammern gibt.
Aber es gibt viele Dinge, die dies einfacher machen können: Halten Sie die Einrückung schön und schön
Verwenden Sie einen Editor mit Klammervergleich (dies hilft Ihnen herauszufinden, was die einzelnen Elemente sind).
Klammerpaare mit) und die Dinge werden sich angenehm anfühlen.

Eine Codestruktur, die eigentlich aus sehr einfachen Daten besteht, bietet einige Vorteile
Struktur, auf der der Kern von Lisp basiert. Zum einen bedeutet es, dass Ihre Programme es sind
leicht zu analysieren ist und die gesamte tatsächliche Struktur des Programms sehr klar dargestellt wird
zu dir. (In hy gibt es einen zusätzlichen Schritt, bei dem die Struktur, die Sie sehen, in die von Python konvertiert wird
eigene Darstellungen ... in „reineren“ Lisps wie Common Lisp oder Emacs Lisp die Daten
Die Struktur, die Sie im Code sehen, und die Datenstruktur, die ausgeführt wird, sind viel mehr
im wahrsten Sinne des Wortes nah.)

Eine weitere Auswirkung davon sind Makros: Wenn die Struktur eines Programms aus einfachen Daten besteht
Struktur, das bedeutet, dass Sie Code schreiben können, der sehr einfach Code schreiben kann, das heißt
Die Implementierung völlig neuer Sprachfunktionen kann sehr schnell erfolgen. Vor Hy war das nicht der Fall
für Python-Programmierer sehr gut möglich ... jetzt können auch Sie das Unglaubliche von Makros nutzen
Kraft (achten Sie nur darauf, dass Sie sie nicht nach unten richten)!

Hy is a Lisp-Geschmack Python
Hy konvertiert in Pythons eigenen abstrakten Syntaxbaum, sodass Sie bald alles finden werden
Die vertraute Leistungsfähigkeit von Python steht Ihnen zur Verfügung.

Sie haben vollen Zugriff auf die Datentypen und die Standardbibliothek von Python in Hy. Lasst uns experimentieren
damit im hy-Interpreter:

=> [1 2 3]
[1, 2, 3]
=> {"Hund" "bellen"
... „Katze“ „miau“}
...
{'dog': 'bark', 'cat': 'miau'}
=> (, 1 2 3)
(1, 2, 3)

Wenn Sie mit anderen Lisps vertraut sind, könnte es Sie interessieren, dass Hy Common unterstützt
Lisp-Zitiermethode:

=> '(1 2 3)
(1L 2L 3L)

Sie haben auch Zugriff auf alle netten Methoden der integrierten Typen:

=> (.strip „fooooo“)
„fooooo“

Was ist das? Ja, das ist in der Tat genau das Gleiche wie:

" fooooo ".strip()

Das ist richtig – Lisp mit Punktnotation! Wenn wir diese Zeichenfolge als Variable zugewiesen haben, werden wir
kann auch Folgendes tun:

(setv this-string „fooooo“)
(dieser-string.strip)

Was ist mit Bedingungen?:

(wenn (etwas ausprobieren)
(drucken Sie „das ist, wenn wahr“)
(drucken Sie „das ist, wenn falsch“)

Wie Sie oben sehen können, ist das erste Argument if ist ein Wahrheitstest, das zweite Argument ist
Der Körper ist wahr, und das dritte Argument (optional!) ist falsch (d. h. sonst).

Wenn Sie komplexere Bedingungen ausführen müssen, werden Sie feststellen, dass dies nicht der Fall ist elif
erhältlich in Hy. Stattdessen sollten Sie etwas namens verwenden cond. In Python könnten Sie das tun
so etwas wie:

somevar = 33
wenn somevar > 50:
print „Diese Variable ist zu groß!“
elif somevar < 10:
print „Diese Variable ist zu klein!“
sonst:
print „Diese Variable ist genau richtig!“

In Hy würden Sie Folgendes tun:

(Kond
[(> etwa 50)
(Drucken Sie „Diese Variable ist zu groß!“)]
[(< somevar 10)
(drucken Sie „Diese Variable ist zu klein!“)]
[WAHR
(Drucken Sie „Diese Variable ist genau richtig!“)])

Das wird Ihnen auffallen cond schaltet zwischen einer ausgeführten Anweisung und ab
Bedingt überprüft, ob wahr oder falsch, und dann ein bisschen Code, der ausgeführt werden soll, wenn es sich ändert
sich als wahr erwiesen. Sie werden auch feststellen, dass die sonst wird am Ende einfach durch umgesetzt
Überprüfung auf was immer dies auch sein sollte. -- das ist, weil was immer dies auch sein sollte. wird immer wahr sein. Wenn wir also so weit kommen, werden wir es tun
Lass das immer laufen!

Möglicherweise fällt Ihnen das oben auf, wenn Sie Code wie den folgenden haben:

(falls vorhanden)
(Körper-wenn-wahr)
(Körper-wenn-falsch))

Aber warte! Was ist, wenn Sie mehr als eine Anweisung im Hauptteil einer davon ausführen möchten?
diese?

Sie können Folgendes tun:

(wenn (etwas ausprobieren)
(von
(drucken Sie „das ist, wenn wahr“)
(drucken Sie „und warum nicht, reden wir weiter darüber, wie wahr es ist!)“)
(drucken Sie „das hier ist einfach immer noch falsch“))

Sie können sehen, dass wir verwendet haben do um mehrere Anweisungen einzuschließen. Wenn Sie mit anderen vertraut sind
Lisps, das ist das Äquivalent von prognost anderswo.

Kommentare beginnen mit Semikolons:

(drucken Sie „das wird ausgeführt“)
; (drucken Sie „aber das wird nicht“)
(+ 1 2 3) ; Wir werden die Addition ausführen, aber nicht diesen Kommentar!

Looping ist nicht schwer, hat aber eine besondere Struktur. In Python könnten wir Folgendes tun:

denn ich bin Angebot(10):
print "'i' ist jetzt bei " + str(i)

Das Äquivalent in Hy wäre:

(für [i (Bereich 10)]
(print (+ "'i' ist jetzt bei " (str i))))

Sie können auch verschiedene Python-Bibliotheken importieren und nutzen. Zum Beispiel:

(Betriebssystem importieren)

(if (os.path.isdir „/tmp/somedir“)
(os.mkdir „/tmp/somedir/anotherdir“)
(drucken Sie „Hey, diesen Weg gibt es nicht!“))

Pythons Kontextmanager (mit Anweisungen) werden wie folgt verwendet:

(mit [[f (open "/tmp/data.in")]]
(drucken (.read f)))

was äquivalent ist zu:

mit open("/tmp/data.in") als f:
print f.read()

Und ja, wir haben Listenverständnis! In Python könnten Sie Folgendes tun:

odds_squared = [
pow(num, 2)
für num in Angebot(100)
wenn Anzahl % 2 == 1]

In Hy könnten Sie Folgendes tun:

(setv Quoten im Quadrat
(Listenkomp
(Leistungszahl 2)
(Anzahl (Bereich 100))
(= (% num 2) 1)))

; Und ein Beispiel, das schamlos von einer Clojure-Seite gestohlen wurde:
; Lassen Sie uns alle Blöcke eines Schachbretts auflisten:

(Listenkomp
(, xy)
(x (Bereich 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 unterstützt verschiedene ausgefallene Argumente und Schlüsselwortargumente. In Python könnten wir das tun
sehen:

>>> def optional_arg(pos1, pos2, keyword1=Keine, keyword2=42):
... return [pos1, pos2, keyword1, keyword2]
...
>>> optional_arg(1, 2)
[1, 2, Keine, 42]
>>> optional_arg(1, 2, 3, 4)
[1, 2, 3, 4]
>>> optional_arg(keyword1=1, pos2=2, pos1=3, keyword2=4)
[3, 2, 1, 4]

Das Gleiche in Hy:

=> (defn optional-arg [pos1 pos2 &optional keyword1 [keyword2 42]]
... [pos1 pos2 keyword1 keyword2])
=> (optional-arg 1 2)
[1 2 Keine 42]
=> (optional-arg 1 2 3 4)
[1 2 3 4]

Wenn Sie eine Hy-Version älter als 0.10.1 verwenden (z. B. Git Master), gibt es auch eine schöne neue Version
Syntax des Schlüsselwortarguments:

=> (optional-arg :keyword1 1
... :pos2 2
... :pos1 3
... :keyword2 4)
[3, 2, 1, 4]

Ansonsten können Sie immer verwenden sich bewerben. Aber was ist sich bewerben?

Kennen Sie sich mit dem Passieren aus? *Argumente und ** kwargs in Python?:

>>> args = [1 2]
>>> kwargs = {"keyword2": 3
... "keyword1": 4}
>>> optional_arg(*args, **kwargs)

Wir können dies mit reproduzieren sich bewerben:

=> (setv args [1 2])
=> (setv kwargs {"keyword2" 3
... „keyword1“ 4})
=> (optional-arg args kwargs anwenden)
[1, 2, 4, 3]

Es gibt auch eine Schlüsselwortargumentkonstruktion im Wörterbuchstil, die wie folgt aussieht:

(defn another-style [&key {"key1" "val1" "key2" "val2"}]
[Schlüssel1 Schlüssel2])

Der Unterschied besteht darin, dass Sie sich nicht auf bestimmte Wörter verlassen können, da es sich um ein Wörterbuch handelt
Reihenfolge der Argumente.

Hy unterstützt auch *Argumente und ** kwargs. In Python:

def some_func(foo, bar, *args, **kwargs):
pprint importieren
pprint.pprint((foo, bar, args, kwargs))

Das Hy-Äquivalent:

(defn some-func [foo bar &rest args &kwargs kwargs]
(Druck importieren)
(pprint.pprint (, foo bar args kwargs)))

Schließlich brauchen wir natürlich Unterricht! In Python könnten wir eine Klasse haben wie:

Klasse FooBar(Objekt):
"" "
Noch eine Beispielklasse
"" "
def __init__(self, x):
self.x = x

def get_x(self):
"" "
Geben Sie unsere Kopie von x zurück
"" "
return self.x

In Hy:

(defclass FooBar [Objekt]
„Noch eine Beispielklasse“
[[--drin--
(fn [selbst x]
(setv self.xx)
; Wird derzeit für --init-- benötigt, da __init__ None benötigt
; Hoffentlich wird das verschwinden :)
Keiner)]

[get-x
(fn [selbst]
„Gib unsere Kopie von x zurück“
self.x)]])

Sie können auch Attribute auf Klassenebene erstellen. In Python:

Klasse Kunde(models.Model):
name = models.CharField(max_length=255)
Adresse = models.TextField()
Notes = models.TextField()

In Hy:

(defclass Kunde [models.Model]
[[Name (models.CharField :max-length 255})]
[Adresse (models.TextField)]
[Anmerkungen (models.TextField)]])

Hy <-> Python interop
Durch den Import von Hy können Sie Hy direkt aus Python verwenden!

Wenn Sie Folgendes speichern: Grüße.hy:

(defn meet [name] (print „hello from hy“, name))

Dann können Sie es direkt aus Python verwenden, indem Sie hy importieren, bevor Sie das Modul importieren. In
Python:

hy importieren
Grüße importieren

Greetings.greet("Foo")

Sie können auch eine Funktion in Python (oder sogar eine Klasse!) deklarieren und sie in Hy verwenden!

Wenn Sie Folgendes speichern: Grüße.py bei Python:

auf jeden Fall grüßen(Name):
print("Hallo, %s" % (Name))

Sie können es in Hy verwenden:

(Grüße importieren)
(.greet Grüße „foo“)

Um Schlüsselwortargumente zu verwenden, können Sie in verwenden Grüße.py:

def meet(name, title="Sir"):
print("Grüße, %s %s" % (title,name))

(Grüße importieren)
(.greet Grüße „Foo“)
(.greet Grüße „Foo“ „Darth“)
(Anwenden (. Grüße grüßen) ["Foo"] {"Titel" "Herr"})

Welches würde ausgeben:

Grüße, Sir Foo

Grüße, Darth Foo

Grüße, Lord Foo

Profi-Tipps!
Hy verfügt auch über das sogenannte „Threading-Makro“, eine wirklich nette Funktion von
Clojures. Das „Threading-Makro“ (geschrieben als ->) wird verwendet, um eine tiefe Verschachtelung von zu vermeiden
Ausdrücke.

Das Threading-Makro fügt jeden Ausdruck in das erste Argument des nächsten Ausdrucks ein
statt.

Nehmen wir den Klassiker:

(loop (print (eval (read)))))

Anstatt es so zu schreiben, können wir es auch wie folgt schreiben:

(-> (lesen) (auswerten) (drucken) (Schleife))

Verwenden Sie jetzt python-sch, wir können zeigen, wie das Threading-Makro (aufgrund des Python-Sh-Setups)
kann wie eine Pfeife verwendet werden:

=> (import [sh [cat grep wc]])
=> (-> (cat „/usr/share/dict/words“) (grep „-E“ „^hy“) (wc „-l“))
210

Was sich natürlich erweitert auf:

(wc (grep (cat „/usr/share/dict/words“) „-E“ „^hy“) „-l“)

Viel besser lesbar, nicht wahr? Benutzen Sie das Threading-Makro!

HY STYLE PROFESSIONELLE


„Wissen Sie, Minister, ich bin in vielerlei Hinsicht anderer Meinung als Dumbledore … aber Sie können es nicht leugnen
Habe Stil…“ – Phineas Nigellus Black, Harry Töpfer und Bestellung of Phoenix

Der Hy-Styleguide soll eine Reihe von Grundregeln für die Hyve (ja, die Hy-Community) sein
ist stolz darauf, Hy an alles anzuhängen), um idiomatischen Hy-Code zu schreiben. Hy leitet viel ab
von Clojure & Common Lisp, unter Beibehaltung der Python-Interopabilität.

Auftakt
Das Tao of Hy
Ummon fragte den obersten Mönch: „Über welches Sutra halten Sie Ihren Vortrag?“
„Das Nirvana-Sutra.“
„Das Nirvana-Sutra hat die vier Tugenden, nicht wahr?“
"Es hat."
Ummon fragte und nahm eine Tasse: „Wie viele Tugenden hat das?“
„Überhaupt keine“, sagte der Mönch.
„Aber die alten Leute sagten, es sei so gewesen, nicht wahr?“ sagte Ummon.
„Was halten Sie von dem, was sie gesagt haben?“
Ummon schlug auf die Tasse und fragte: „Verstehst du?“
„Nein“, sagte der Mönch.
„Dann“, sagte Ummon, „fahren Sie besser mit Ihren Vorträgen über das Sutra fort.“
– das (Koan-)Makro

Im Folgenden finden Sie eine kurze Liste der Designentscheidungen, die in die Erstellung einflossen
Hi.

· Sehen Sie aus wie ein Lispel; DTRT damit (z. B. Bindestriche werden zu Unterstrichen, Ohrenschützer werden zu
Großbuchstaben).

· Wir sind immer noch Python. Die meisten Interna werden 1:1 in Python-Interna übersetzt.

· Verwenden Sie überall Unicode.

· Korrigieren Sie die fehlerhaften Entscheidungen in Python 2, wenn wir können (siehe true_division).

· Im Zweifelsfall lieber auf Python zurückgreifen.

· Wenn Sie sich immer noch nicht sicher sind, wenden Sie sich an Clojure.

· Wenn Sie sich noch unsicherer sind, wenden Sie sich lieber an Common Lisp.

· Denken Sie daran, wir sind nicht Clojure. Wir sind kein Common Lisp. Wir sind homoikonische Python, mit
zusätzliche Teile, die Sinn machen.

Layout & Einbuchtung
· Vermeiden Sie nachgestellte Leerzeichen. Sie sind scheiße!

· Die Einrückung muss 2 Leerzeichen betragen (keine festen Tabulatoren), außer bei Übereinstimmung mit der Einrückung von
die vorherige Zeile.

;; Gut (und bevorzugt)
(defn fib [n]
(wenn (<= n 2)
n
(+ (fib (- n 1)) (fib (- n 2)))))

;; Immer noch okay
(defn fib [n]
(if (<= n 2) n (+ (fib (- n 1)) (fib (- n 2)))))

;; Immer noch okay
(defn fib [n]
(wenn (<= n 2)
n
(+ (fib (- n 1)) (fib (- n 2)))))

;; Hysterisch lächerlich
(defn fib [n]
(wenn (<= n 2)
N ;; Ja, ich liebe es, zufällig die Leertaste zu drücken
(+ (fib (- n 1)) (fib (- n 2)))))

· Klammern müssen hört niemals allein, traurig und einsam auf ihrer eigenen Linie zurückgelassen werden.

;; Gut (und bevorzugt)
(defn fib [n]
(wenn (<= n 2)
n
(+ (fib (- n 1)) (fib (- n 2)))))

;; Hysterisch lächerlich
(defn fib [n]
(wenn (<= n 2)
n
(+ (fib (- n 1)) (fib (- n 2)))
)
); GAH, VERBRENNE ES MIT FEUER

· Vertikal ausrichten lassen Blöcke

(lass [[foo (bar)]
[qux (baz)]]
(foo qux))

· Inline-Kommentare müssen zwei Leerzeichen vom Ende des Codes entfernt sein. Sie müssen immer eine haben
Leerzeichen zwischen dem Kommentarzeichen und dem Anfang des Kommentars. Versuchen Sie auch, dies nicht zu tun
Kommentieren Sie das Offensichtliche.

;; Gut
(setv ind (dec x)) ; Die Indizierung beginnt bei 0

;; Stilkonform, sagt aber nur das Offensichtliche
(setv ind (dec x)) ; Setzt den Index auf x-1

;; Schlecht
(setv ind (dec x));Wörter zum Spaß eingeben

Programmierung Design
· Versuchen Sie es nicht als Konvention zu verwenden def für alles andere als globale Variablen; verwenden setv
innerhalb von Funktionen, Schleifen usw.

;; Gut (und bevorzugt)
(def. *Limit* 400000)

(defn fibs [ab]
(obwohl wahr
(Ertrag a)
(setv (, ab) (, b (+ ab)))))

;; Schlecht (und nicht bevorzugt)
(defn fibs [ab]
(obwohl wahr
(Ertrag a)
(def (, ab) (, b (+ ab)))))

· Verwenden Sie keine S-Ausdruckssyntax, wenn Vektorsyntax vorgesehen ist. Zum Beispiel die Tatsache
Dass das erstere dieser beiden Beispiele funktioniert, liegt nur daran, dass der Compiler nicht übermäßig funktioniert
strikt. In Wirklichkeit ist die korrekte Syntax an solchen Stellen die letztere.

;; Schlecht (und böse)
(defn foo (x) (print x))
(foo 1)

;; Gut (und bevorzugt)
(defn foo [x] (x drucken))
(foo 1)

· Verwenden Sie das Threading-Makro oder die Threading-Tail-Makros, wenn Sie auf tief verschachtelte Objekte stoßen
S-Ausdrücke. Seien Sie jedoch bei der Verwendung mit Bedacht. Verwenden Sie sie, wenn Klarheit und
die Lesbarkeit verbessert sich; Konstruieren Sie keine komplizierten, schwer verständlichen Ausdrücke.

;; Bevorzugt
(def *Namen*
(mit [f (open „names.txt“)]
(-> (.read f) (.strip) (.replace "\"" "") (.split ",") (sortiert))))

;; Nicht so gut
(def *Namen*
(mit [f (open „names.txt“)]
(sortiert (.split "," (.replace "\"" "" (.strip (.read f)))))))

;; Wahrscheinlich keine gute Idee
(defn Quadrat? [x]
(->> 2 (pow (int (sqrt x))) (= x)))

· Die Punktnotation im Clojure-Stil wird dem direkten Aufruf der Methode des Objekts vorgezogen.
Beide werden jedoch weiterhin unterstützt.

;; Gut
(mit [fd (öffnen "/ etc / passwd")]
(print (.readlines fd)))

;; Nicht so gut
(mit [fd (öffnen "/ etc / passwd")]
(drucken (fd.readlines)))

Zusammenfassung
„Mode verblasst, Stil ist ewig“ – Yves Saint Laurent

Bei diesem Leitfaden handelt es sich lediglich um eine Reihe von Community-Richtlinien, und Community-Richtlinien tun dies natürlich auch
Ohne eine aktive Community macht es keinen Sinn. Beiträge sind willkommen. Besuchen Sie uns bei #hy in
freenode, darüber bloggen, twittern und vor allem Spaß mit Hy haben.

Vielen Dank
· Dieser Leitfaden ist stark inspiriert von @paultag 's Blogbeitrag Hy Survival - Überleben Guide

· Das Clojure Design Guide

DOKUMENTATION INDEX


Inhaltsübersicht:

Befehl Line Schnittstelle
hy
Befehl Line Optionen
-c
Führen Sie den Hy-Code aus Befehl.

$ hy -c "(print (+ 2 2))"
4

-i
Führen Sie den Hy-Code aus Befehl, dann bleib in REPL.

-m
Führen Sie den Hy-Code aus Moduleneinschließlich defmain falls definiert.

Das -m Flag beendet die Optionsliste, sodass alle Argumente nach dem Modulen Name
werden an das Modul übergeben sys.argv.

Neu in Version 0.10.2.

--Spion Drucken Sie vor der Ausführung den entsprechenden Python-Code aus. Zum Beispiel:

=> (defn salutationsnm [name] (print (+ "Hy " name "!")))
def salutationsnm(name):
return print(((u'Hy ' + name) + u'!'))
=> (salutationsnm „IhrName“)
salutationsnm(u'YourName')
Hy YourName!
=>

Neu in Version 0.9.11.

--show-tracebacks
Drucken Sie erweiterte Tracebacks für Hy-Ausnahmen.

Neu in Version 0.9.12.

-v Drucken Sie die Hy-Versionsnummer aus und beenden Sie den Vorgang.

hyc
Befehl Line Optionen
Datei[, DateiN]
Kompilieren Sie Hy-Code in Python-Bytecode. Speichern Sie beispielsweise den folgenden Code unter
hyname.hy:

(defn hy-hy [Name]
(drucken (+ „Hy „ Name „!“)))

(hy-hy „Afroman“)

Dann renne:

$ hyc hyname.hy
$ python hyname.pyc
Hy Afroman!

hy2py
Neu in Version 0.10.1.

Befehl Line Optionen
-s

--with-source
Zeigen Sie die analysierte Quellstruktur an.

-a

--mit-ast
Zeigen Sie den generierten AST an.

-np

--without-python
Zeigen Sie nicht den vom AST generierten Python-Code an.

Hy (Das Sprache)
WARNUNG:
Das ist unvollständig; Bitte erwägen Sie, zum Dokumentationsaufwand beizutragen.

TheorieXNUMX Tauchgänge (XNUMX Tage) of Hy
Hy sorgt vor allem für eine 100-prozentige Kompatibilität in beide Richtungen mit Python
selbst. Der gesamte Hy-Code folgt ein paar einfachen Regeln. Merken Sie sich das, denn es kommt herein
praktisch.

Diese Regeln tragen dazu bei, dass der Hy-Code in beiden Sprachen idiomatisch und schnittstellenfähig ist.

· Symbole in Ohrenschützern werden in die großgeschriebene Version dieser Zeichenfolge übersetzt. Für
Beispiel foo wird werden FOO.

· UTF-8-Entitäten werden mit codiert Punycode und vorangestellt mit hy_. Beispielsweise,
wird werden hy_w7h, wird werden hy_g6h und i♥u wird werden hy_iu_t0x.

· Symbole, die Bindestriche enthalten, werden durch Unterstriche ersetzt. Zum Beispiel,
Render-Vorlage wird werden render_template. Dies bedeutet, dass Symbole mit Bindestrichen angezeigt werden
schattieren ihre Unterstrich-Äquivalente und umgekehrt.

Einbauten
Hy verfügt über eine Reihe spezieller Formulare, die zur Generierung korrekter Python-ASTs verwendet werden.
Im Folgenden sind „besondere“ Formulare aufgeführt, deren Verhalten möglicherweise etwas unerwartet ist
einige Situationen.

.
Neu in Version 0.10.0.

. wird verwendet, um den Attributzugriff auf Objekte durchzuführen. Es verwendet ein kleines DSL, um eine schnelle Verbindung zu ermöglichen
Zugriff auf Attribute und Elemente in einer verschachtelten Datenstruktur.

Zum Beispiel

(. foo bar baz [(+ 1 2)] frob)

Zusammengefasst zu:

foo.bar.baz[1 + 2].frob

. kompiliert sein erstes Argument (im Beispiel foo) als das Objekt, auf dem das ausgeführt werden soll
Attribut-Dereferenzierung. Es verwendet bloße Symbole als Attribute für den Zugriff (im Beispiel Bar,
baz, frob) und stellt den Inhalt von Listen zusammen (im Beispiel [(+ 1 2)]) zur Indexierung.
Andere Argumente lösen einen Kompilierungsfehler aus.

Der Zugriff auf unbekannte Attribute löst eine aus Attributfehler. Der Zugriff auf unbekannte Schlüssel löst eine aus
IndexFehler (auf Listen und Tupeln) oder a Schlüsselfehler (zu Wörterbüchern).

->
-> (Oder die einfädeln Makro) wird verwendet, um eine Verschachtelung von Ausdrücken zu vermeiden. Das Threading-Makro
fügt jeden Ausdruck an der ersten Argumentstelle des nächsten Ausdrucks ein. Die folgende
Code demonstriert dies:

=> (defn-Ausgabe [ab] (print ab))
=> (-> (+ 4 6) (Ausgabe 5))
10 5

- >>
- >> (Oder die einfädeln Schwanz Makro) ist ähnlich wie die einfädeln Makro, aber statt
Indem es jeden Ausdruck in das erste Argument des nächsten Ausdrucks einfügt, wird es als angehängt
letztes Argument. Der folgende Code demonstriert dies:

=> (defn-Ausgabe [ab] (print ab))
=> (->> (+ 4 6) (Ausgabe 5))
5 10

sich bewerben
sich bewerben wird verwendet, um eine optionale Liste von Argumenten und ein optionales Wörterbuch von Kwargs anzuwenden
zu einer Funktion.

Verwendung: (sich bewerben fn-name [Argumente] [Kwargs])

Beispiele:

(defn thunk []
„Hallo“)

(Thunk anwenden)
;=> „Hallo“

(defn total-purchase [Preisbetrag &optional [Gebühren 1.05] [Mehrwertsteuer 1.1]]
(*Preis Betrag Gebühren MwSt.))

(Gesamtkaufpreis anwenden [10 15])
;=> 173.25

(Gesamtkaufpreis anwenden [10 15] {"Mehrwertsteuer" 1.05})
;=> 165.375

(Gesamtkauf [] {"Preis" 10 "Betrag" 15 "Mehrwertsteuer" 1.05} anwenden)
;=> 165.375

und
und wird in logischen Ausdrücken verwendet. Es sind mindestens zwei Parameter erforderlich. Wenn alle Parameter
bewerten zu Wahre, der letzte Parameter wird zurückgegeben. In allen anderen Fällen der erste falsche Wert
Wird zurückgegeben. Beispielverwendung:

=> (und wahr falsch)
falsch

=> (und wahr wahr)
Wahre

=> (und Wahr 1)
1

=> (und True [] False True)
[]

Anmerkungen:
und schließt kurz und stoppt die Parameterauswertung, sobald der erste Fehler auftritt
angetroffen.

=> (und False (print „hello“))
falsch

behaupten
behaupten wird verwendet, um Bedingungen zu überprüfen, während das Programm ausgeführt wird. Wenn die Bedingung nicht zutrifft
traf, ein Behauptungsfehler angehoben wird. behaupten kann einen oder zwei Parameter annehmen. Der erste
Der Parameter ist die zu prüfende Bedingung und sollte als Ergebnis ausgewertet werden Wahre or falschdem „Vermischten Geschmack“. Seine
Der zweite optionale Parameter ist eine Bezeichnung für die Behauptung und die Zeichenfolge, die es sein wird
aufgewachsen mit dem Behauptungsfehler. Zum Beispiel:

(assert (= variabler erwarteter Wert))

(Bestätigen Sie Falsch)
; Behauptungsfehler

(behaupten (= 1 2) „eins sollte gleich zwei sein“)
; AssertionError: Eins sollte gleich zwei sein

Assoc
Assoc wird verwendet, um einen Schlüssel einem Wert in einem Wörterbuch zuzuordnen oder einen Index einer Liste festzulegen
auf einen Wert. Es benötigt mindestens drei Parameter: den technische Daten Struktur geändert werden, a Schlüssel
or IndexUnd eine Wert. Wenn mehr als drei Parameter verwendet werden, erfolgt die Zuordnung paarweise.

Anwendungsbeispiele:

=>(let [[collection {}]]
... (assoziierte Sammlung „Dog“ „Bark“)
... (Drucksammlung))
{u'Dog': u'Bark'}

=>(let [[collection {}]]
... (assoziierte Sammlung „Hund“, „Bark“, „Katze“, „Miau“)
... (Drucksammlung))
{u'Cat': u'Meow', u'Dog': u'Bark'}

=>(let [[collection [1 2 3 4]]]
... (assoziierte Sammlung 2 Keine)
... (Drucksammlung))
[1, 2, Keine, 4]

Anmerkungen:
Assoc Ändert die vorhandene Datenstruktur und gibt sie zurück Andere.

brechen
brechen wird verwendet, um aus einer Schleife auszubrechen. Es beendet die Schleife sofort. Die folgende
Beispiel hat ein Unendliches während Schleife, die beendet wird, sobald der Benutzer eintritt k.

(while True (if (= „k“ (raw-input „?“))
(brechen)
(drucken Sie „Erneut versuchen“)))

cond
cond kann verwendet werden, um verschachtelt zu bauen if Aussagen. Das folgende Beispiel zeigt die
Beziehung zwischen dem Makro und seiner Erweiterung:

(Bedingung [Bedingung-1 Ergebnis-1]
[Bedingung-2 Ergebnis-2])

(Wenn Bedingung-1 Ergebnis-1
(wenn Bedingung-2 Ergebnis-2))

Wie unten gezeigt, wird nur der erste passende Ergebnisblock ausgeführt.

=> (definierter Prüfwert [Wert]
... (cond [(< Wert 5) (print „Wert ist kleiner als 5“)]
... [(= Wert 5) (print „Wert ist gleich 5“)]
... [(> Wert 5) (Druck „Wert ist größer als 5“)]
... [Wahr (drucken Sie „Wert ist etwas, was er nicht sein sollte“)]))

=> (Prüfwert 6)
Wert ist größer als 5

fortsetzen
fortsetzen Gibt die Ausführung an den Anfang einer Schleife zurück. Im folgenden Beispiel:
(Nebenwirkung1) wird für jede Iteration aufgerufen. (Nebenwirkung2), wird jedoch nur aufgerufen
jeder andere Wert in der Liste.

;; unter der Annahme, dass (Nebenwirkung1) und (Nebenwirkung2) Funktionen und sind
;; Die Sammlung ist eine Liste numerischer Werte

(für [x Sammlung]
(von
(Nebenwirkung1 x)
(wenn (% x 2)
(weitermachen))
(Nebenwirkung2 x)))

dict-comp
dict-comp wird zum Erstellen von Wörterbüchern verwendet. Es benötigt drei oder vier Parameter. Der erste
Zwei Parameter dienen zur Steuerung des Rückgabewerts (Schlüssel-Wert-Paar), der dritte dient dazu
Wird verwendet, um Elemente aus einer Sequenz auszuwählen. Der vierte und optionale Parameter kann dazu verwendet werden
Filtern Sie einige Elemente in der Sequenz basierend auf einem bedingten Ausdruck heraus.

=> (dict-comp x (* x 2) [x (Bereich 10)] (ungerade? x))
{1: 2, 3: 6, 9: 18, 5: 10, 7: 14}

do / prognost
do und prognost werden verwendet, um jedes ihrer Argumente auszuwerten und das letzte zurückzugeben. Zurückkehren
Werte von jedem anderen als dem letzten Argument werden verworfen. Es kann in verwendet werden Lambda or
Listenkomp um komplexere Logik auszuführen, wie in einem der folgenden Beispiele gezeigt.

Einige Anwendungsbeispiele:

=> (falls wahr
... (tun (drucken Sie „Nebenwirkungen rocken!“)
... (drucken Sie „Ja, wirklich!“)))
Nebenwirkungen rocken!
Ja wirklich!

;; vorausgesetzt, dass (Nebeneffekt) eine Funktion ist, die wir für jeden aufrufen möchten
;; und jeder Wert in der Liste, dessen Rückgabewert uns jedoch egal ist
=> (list-comp (do (Nebeneffekt x)
... (wenn (< x 5) (* 2 x)
... (* 4 x)))
... (x (Bereich 10)))
[0, 2, 4, 6, 8, 20, 24, 28, 32, 36]

do kann eine beliebige Anzahl von Argumenten akzeptieren, von 1 bis n.

def / setv
def und setv werden verwendet, um einen Wert, ein Objekt oder eine Funktion an ein Symbol zu binden. Zum Beispiel:

=> (def-Namen [„Alice“ „Bob“ „Charlie“])
=> (Namen drucken)
[u'Alice', u'Bob', u'Charlie']

=> (setv counter (fn [Sammlungselement] (.count Sammlungselement)))
=> (Zähler [1 2 3 4 5 2 3] 2)
2

deklassieren
Neue Klassen werden mit deklariert deklassieren. Es kann zwei optionale Parameter annehmen: einen Vektor
Definieren einer möglichen Superklasse und eines weiteren Vektors, der Attribute der neuen enthält
Klasse als zwei Elementvektoren.

(defclass Klassenname [Superklasse-1 Superklasse-2]
[[Attributwert]])

Sowohl Werte als auch Funktionen können an die neue Klasse gebunden werden, wie im folgenden Beispiel gezeigt:

=> (defclass Cat []
... [[Alter Keine]
... [Farbe „weiß“]
... [sprechen (fn [self] (print „Meow“))]])

=> (def spot (Cat))
=> (setv spot.color „Schwarz“)
'Schwarz'
=> (.speak spot)
Miau

definiere / defin
definiere und defin Makros werden zum Definieren von Funktionen verwendet. Sie nehmen drei Parameter an: den Name
der zu definierenden Funktion, ein Vektor von Parameterund der Körper der Funktion:

(definierter Name [Parameter] Körper)

Parametern können die folgenden Schlüsselwörter vorangestellt sein:

&Optional
Parameter ist optional. Der Parameter kann als Liste mit zwei Elementen angegeben werden, wobei die
Das erste Element ist der Parametername und das zweite der Standardwert. Der Parameter
kann auch als einzelnes Element angegeben werden. In diesem Fall lautet der Standardwert Andere.

=> (defn Gesamtwert [Wert &optional [Mehrwertsteuer 10]]
... (+ (/ (*Wert-Mehrwertsteuer) 100) Wert))

=> (Gesamtwert 100)
110.0

=> (Gesamtwert 100 1)
101.0

&Schlüssel

&kwargs
Der Parameter enthält 0 oder mehr Schlüsselwortargumente.

Die folgenden Codebeispiele definieren eine Funktion, die alle Schlüsselwörter ausgibt
Argumente und ihre Werte.

=> (defn print-parameters [&kwargs kwargs]
... (für [(, kv) (.items kwargs)] (print kv)))

=> (print-parameters anwenden [] {"parameter-1" 1 "parameter-2" 2})
Parameter-2 2
Parameter-1 1

&Rest Der Parameter enthält 0 oder mehr Positionsargumente. Keine andere Position
Nach diesem Argument können Argumente angegeben werden.

Das folgende Codebeispiel definiert eine Funktion, der 0 bis n numerische Werte zugewiesen werden können
Parameter. Anschließend wird jede ungerade Zahl summiert und jede gerade Zahl subtrahiert.

=> (defn zig-zag-sum [&rest zahlen]
(let [[odd-numbers (list-comp x [x zahlen] (ungerade? x))]
[gerade Zahlen (list-comp x [x Zahlen] (gerade? x))]]
(- (Summe der ungeraden Zahlen) (Summe der geraden Zahlen))))

=> (Zick-Zack-Summe)
0
=> (Zick-Zack-Summe 3 9 4)
8
=> (Zick-Zack-Summe 1 2 3 4 5 6)
-3

defn-alias / defun-alias
Neu in Version 0.10.0.

Das defn-alias und defun-alias Makros sind ähnlich definiere, mit der Unterscheidung, dass
Anstatt eine Funktion mit einem einzelnen Namen zu definieren, können diese auch Aliase definieren. Andere
als eine Liste von Symbolen für Funktionsnamen als ersten Parameter zu nehmen, defn-alias und
defun-alias unterscheiden sich nicht von definiere und defin.

=> (defn-alias [Hauptname-Alias] []
... (drucken Sie „Hallo!“))
=> (Hauptname)
"Hallo!"
=> (Alias)
"Hallo!"

defmain
Neu in Version 0.10.1.

Das defmain Makro definiert eine Hauptfunktion, die sofort mit aufgerufen wird sys.argv as
Argumente genau dann, wenn diese Datei als Skript ausgeführt wird. Mit anderen Worten, dies:

(defmain [&rest args]
(etwas mit Argumenten machen))

ist das Äquivalent von:

def main(*args):
do_something_with(args)
0 zurückgeben

if __name__ == "__main__":
sys importieren
retval = main(*sys.arg)

if isinstance(retval, int):
sys.exit(retval)

Beachten Sie, dass, wie Sie oben sehen können, dies der Fall ist, wenn Sie von dieser Funktion eine Ganzzahl zurückgeben
Wird als Exit-Status für Ihr Skript verwendet. (Python beendet standardmäßig den Status 0, andernfalls
was bedeutet, dass alles in Ordnung ist!)

(Seit (sys.exit 0) wird im Falle einer nicht ganzzahligen Rückgabe von nicht explizit ausgeführt
defmain, es ist eine gute Idee zu sagen (defmain) als letztes Codestück in Ihrer Datei.)

defmakro
defmakro wird zum Definieren von Makros verwendet. Das allgemeine Format ist (defmacro Name [Parameter]
Ausdruck).

Das folgende Beispiel definiert ein Makro, das zum Vertauschen der Reihenfolge von Elementen im Code verwendet werden kann.
Erlaubt dem Benutzer, Code in Infix-Notation zu schreiben, wobei sich der Operator dazwischen befindet
Operanden.

=> (defmacro Infix [Code]
... (Quasiquote (
... (Zitat aufheben (Code 1 abrufen))
... (Zitat aufheben (Code 0 abrufen))
... (Anführungszeichen entfernen (Code 2 abrufen)))))

=> (Infix (1 + 1))
2

defmacro-alias
defmacro-alias wird verwendet, um Makros mit mehreren Namen (Aliase) zu definieren. Das allgemeine Format
is (defmacro-alias [Namen] [Parameter] Ausdruck). Es erstellt mehrere Makros mit demselben
Parameterliste und Textkörper unter der angegebenen Namensliste.

Das folgende Beispiel definiert zwei Makros, die dem Benutzer beide das Schreiben von Code ermöglichen
Infix-Notation.

=> (defmacro-alias [infix infi] [code]
... (Quasiquote (
... (Zitat aufheben (Code 1 abrufen))
... (Zitat aufheben (Code 0 abrufen))
... (Anführungszeichen entfernen (Code 2 abrufen)))))

=> (Infix (1 + 1))
2
=> (infi (1 + 1))
2

defmacro/g!
Neu in Version 0.9.12.

defmacro/g! ist eine spezielle Version von defmakro das zur automatischen Generierung verwendet wird Gensym
für jedes Symbol, das mit beginnt g!.

Zum Beispiel, g!a würde werden (gensym "A").

SEHEN EBENFALLS:
Abschnitt using-gensym

Defreader
Neu in Version 0.9.12.

Defreader Definiert ein Reader-Makro, mit dem Sie die Syntax umstrukturieren oder ändern können.

=> (defreader ^ [expr] (print expr))
=> #^(1 2 3 4)
(1 2 3 4)
=> #^"Hallo"
"Hallo"

SEHEN EBENFALLS:
Abschnitt Reader-Makros

Restaurants
Neu in Version 0.9.12.

Restaurants Entfernt ein Objekt aus dem aktuellen Namespace.

=> (setv foo 42)
=> (del foo)
=> foo
Traceback (jüngste Aufforderung zuletzt):
Datei " ", Zeile 1, in
NameError: Name „foo“ ist nicht definiert

Restaurants kann auch Objekte aus Zuordnungen, Listen und mehr entfernen.

=> (setv test (Liste (Bereich 10)))
=> testen
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
=> (del (Slice-Test 2 4)) ;; Entfernen Sie die Elemente von 2 bis 4 ausgeschlossen
=> testen
[0, 1, 4, 5, 6, 7, 8, 9]
=> (setv dic {"foo" "bar"})
=> dic
{"foo": "bar"}
=> (del (get dic „foo“))
=> dic
{}

begabtes
Neu in Version 0.10.1.

begabtes wird verwendet, um eine Folge von Methodenaufrufen für ein Objekt zu vereinfachen.

=> (doto [] (.append 1) (.append 2) .reverse)
[2 1]

=> (setv-Sammlung [])
=> (.append Sammlung 1)
=> (.append Sammlung 2)
=> (.reverse Sammlung)
=> Sammlung
[2 1]

eval
eval wertet einen Ausdruck in Anführungszeichen aus und gibt den Wert zurück.

=> (eval '(print „Hello World“))
"Hallo Welt"

auswerten und kompilieren
eval-when-compile
zuerst / Auto
zuerst und Auto sind Makros für den Zugriff auf das erste Element einer Sammlung:

=> (erster (Bereich 10))
0

für
für wird verwendet, um eine Funktion für jedes Element in einer Liste oder einem Vektor aufzurufen. Die Ergebnisse von jedem
Anruf werden verworfen und die für Ausdruck kehrt zurück Andere stattdessen. Der Beispielcode iteriert
übrig Sammlung und für jeden Element in Sammlung ruft die Nebenwirkung funktionieren mit
Element als Argument:

;; unter der Annahme, dass (Nebeneffekt) eine Funktion ist, die einen einzelnen Parameter annimmt
(für [Elementsammlung] (Nebeneffektelement))

;; for kann einen optionalen else-Block haben
(für [Elementsammlung] (Nebeneffektelement)
(sonst (Nebenwirkung-2)))

Das optionale sonst Block wird nur ausgeführt, wenn der für Die Schleife wird normal beendet. Wenn die
Die Ausführung wird mit angehalten brechen, der sonst Block wird nicht ausgeführt.

=> (für [Element [1 2 3]] (if (< Element 3)
... (Druckelement)
... (brechen))
... (else (print „Schleife fertig“)))
1
2

=> (für [Element [1 2 3]] (if (< Element 4)
... (Druckelement)
... (brechen))
... (else (print „Schleife fertig“)))
1
2
3
Schleife beendet

genexpr
genexpr wird zum Erstellen von Generatorausdrücken verwendet. Es benötigt zwei oder drei Parameter. Der
Der erste Parameter ist der Ausdruck, der den Rückgabewert steuert, während der zweite verwendet wird
um Elemente aus einer Liste auszuwählen. Der dritte und optionale Parameter kann zum Herausfiltern verwendet werden
Einige der Elemente in der Liste basieren auf einem bedingten Ausdruck. genexpr ähnelt
Listenkomp, außer dass es eine Iterable zurückgibt, die die Werte einzeln auswertet, statt
sie sofort auszuwerten.

=> (def-Sammlung (Bereich 10))
=> (def gefiltert (genexpr x [x Sammlung] (gerade? x)))
=> (Liste gefiltert)
[0, 2, 4, 6, 8]

Gensym
Neu in Version 0.9.12.

Gensym wird verwendet, um ein eindeutiges Symbol zu generieren, das das Schreiben von Makros ermöglicht
versehentliche Konflikte zwischen Variablennamen.

=> (gensym)
u':G_1235'

=> (Gensym „x“)
u':x_1236'

SEHEN EBENFALLS:
Abschnitt using-gensym

bekommen
bekommen wird verwendet, um auf einzelne Elemente in Listen und Wörterbüchern zuzugreifen. bekommen nimmt zwei Parameter an:
technische Daten Struktur und dem Index or Schlüssel des Artikels. Es wird dann das entsprechende zurückgegeben
Wert aus dem Wörterbuch oder der Liste. Beispielverwendung:

=> (lass [[Tiere {"Hund" "bellen" "Katze" "miauen"}]
... [Zahlen [„Null“, „Eins“, „Zwei“, „Drei“]]]
... (drucken (Tiere bekommen „Hund“))
... (drucken (Nummern 2 erhalten)))
Rinde
XNUMX

Anmerkungen:
bekommen löst einen KeyError aus, wenn ein Wörterbuch nach einem nicht vorhandenen Schlüssel abgefragt wird.

Anmerkungen:
bekommen löst einen IndexError aus, wenn eine Liste oder ein Tupel nach einem Index abgefragt wird, der nicht vorhanden ist
Grenzen.

globale
globale kann verwendet werden, um ein Symbol als global zu markieren. Dadurch kann der Programmierer eine zuweisen
Wert zu einem globalen Symbol. Das Lesen eines globalen Symbols erfordert nicht das globale Stichwort --
Nur das Zuweisen reicht aus.

Das folgende Beispiel zeigt, wie das globale Symbol funktioniert a wird in einer Funktion ein Wert zugewiesen und
wird später in einer anderen Funktion gedruckt. Ohne das globale Schlüsselwort, die zweite Funktion
hätte einen geworfen NameFehler.

(defn set-a [Wert]
(global a)
(einen Wert festlegen))

(defn print-a []
(drucken a))

(Satz-a 5)
(print-a)

if / wenn nicht
Neu in Version 0.10.0: if-not

if wird verwendet, um den auszuführenden Code bedingt auszuwählen. Es muss eine Bedingung enthalten
Block und der Block, der ausgeführt werden soll, wenn der Bedingungsblock als ausgewertet wird Wahre. Optional,
Es kann einen letzten Block enthalten, der ausgeführt wird, falls die Bedingung ausgewertet wird
falsch.

wenn nicht ist ähnlich, aber der zweite Block wird ausgeführt, wenn die Bedingung fehlschlägt
Der dritte und letzte Block wird ausgeführt, wenn der Test erfolgreich ist – in umgekehrter Reihenfolge if.

Beispielverwendung:

(wenn (Geld übrig? Konto)
(Aufdruck „Lass uns einkaufen gehen“)
(Drucken Sie „Lass uns gehen und arbeiten“)

(wenn nicht (Geld übrig? Konto)
(Drucken Sie „Lass uns gehen und arbeiten“)
(Aufdruck „Lass uns einkaufen gehen“))

Die Wahrhaftigkeit von Python wird respektiert. Andere, falsch, Null eines beliebigen numerischen Typs, eine leere Sequenz,
und ein leeres Wörterbuch werden berücksichtigt falsch; alles andere wird berücksichtigt Wahre.

Lispel-wenn / lif und Lispeln-wenn-nicht / Leben nicht
Neu in Version 0.10.0.

Neu in Version 0.10.2: lisp-if-not / lif-not

Für diejenigen, die ein Lispy bevorzugen if Klausel, wir haben Lispel-wenn, oder lif. Dies einzige überlegt
Andere / Null falsch sein! Alle anderen „falschen“ Python-Werte werden als wahr betrachtet.
Im Gegenteil, wir haben Lispeln-wenn-nicht und Leben nicht parallel zu if und wenn nicht was sich umkehrt
der Vergleich.

=> (lisp-if True „true“ „false“)
"True"
=> (lisp-if False „true“ „false“)
"True"
=> (lisp-if 0 „true“ „false“)
"True"
=> (lisp-if nil „true“ „false“)
"False"
=> (lisp-if None „true“ „false“)
"False"
=> (lisp-if-not nil „true“ „false“)
"True"
=> (lisp-if-not None „true“ „false“)
"True"
=> (lisp-if-not False „true“ „false“)
"False"

; Äquivalent, aber kürzer
=> (lif True „true“ „false“)
"True"
=> (lif nil „wahr“ „falsch“)
"False"
=> (lif-not None „true“ „false“)
"True"

importieren
importieren wird zum Importieren von Modulen verwendet, wie in Python. Dafür gibt es mehrere Möglichkeiten importieren kann
verwendet werden.

;; Importiert jedes dieser Module
;;
;; Python:
;; Importsystem
;; os.path importieren
(sys os.path importieren)

;; Import aus einem Modul
;;
;; Python: aus os.path import existiert, isdir, isfile
(import [os.path [exists isdir isfile]])

;; Mit einem Alias ​​importieren
;;
;; Python: sys als systest importieren
(importieren [sys :as systest])

;; Sie können beliebig viele Importe unterschiedlicher Art auflisten.
(import [tests.resources [kwtest function-with-a-dash]]
[os.path [exists isdir isfile]]
[sys :as systest])

;; Importieren Sie alle Modulfunktionen in den aktuellen Namespace
(importieren [sys [*]])

Lambda / fn
Lambda und fn kann verwendet werden, um eine anonyme Funktion zu definieren. Die Parameter sind ähnlich
definiere: Der erste Parameter ist ein Parametervektor und der Rest ist der Körper des
Funktion. Lambda gibt eine neue Funktion zurück. Im folgenden Beispiel eine anonyme Funktion
wird definiert und an eine andere Funktion zum Filtern der Ausgabe übergeben.

=> (def Leute [{:Name „Alice“ :Alter 20}“
... {:Name „Bob“ :Alter 25}
... {:Name „Charlie“ :Alter 50}
... {:Name „Dave“ :Alter 5}])

=> (defn display-people [Personenfilter]
... (für [Person Personen] (if (Filter Person) (print (:Name Person)))))

=> (display-people people (fn [person] (< (:age person) 25)))
Alice
Dave

Wenn das erste Element des Körpers wie bei normalen Funktionsdefinitionen eine Zeichenfolge ist, wird es
dient als Dokumentzeichenfolge. Dies ist nützlich, um Klassenmethoden Dokumentzeichenfolgen zu geben.

=> (setv mal-drei
... (fn [x]
... „Multipliziert die Eingabe mit drei und gibt das Ergebnis zurück.“
... (* x 3)))

Dies kann über Pythons integrierte Funktion bestätigt werden Hilfe Funktion:

=> (Hilfe mal drei)
Hilfe zur Funktion times_two:

mal_drei(x)
Multipliziert die Eingabe mit drei und gibt das Ergebnis zurück
(ENDE)

letzte
Neu in Version 0.10.2.

letzte kann für den Zugriff auf das letzte Element einer Sammlung verwendet werden:

=> (letzte [2 4 6])
6

lassen
lassen wird verwendet, um lexikalisch gültige Variablen zu erstellen. Sie werden zu Beginn erstellt
lassen Form und hören nach der Form auf zu existieren. Das folgende Beispiel zeigt dies
Verhalten:

=> (let [[x 5]] (x drucken)
... (let [[x 6]] (print x))
... (drucken x))
5
6
5

Das lassen Das Makro benötigt zwei Parameter: einen Vektor, der definiert Variablen und dem Körper was bekommt
hingerichtet. Variablen ist ein Vektor, bei dem jedes Element entweder eine einzelne Variable oder ein Vektor ist
Definieren eines variablen Wertepaars. Im Falle einer einzelnen Variablen wird ihr ein Wert zugewiesen
Andere; andernfalls wird der angegebene Wert verwendet.

=> (let [x [y 5]] (xy drucken))
Keine 5

Listenkomp
Listenkomp führt Listenverständnisse durch. Es benötigt zwei oder drei Parameter. Der erste
Parameter ist der Ausdruck, der den Rückgabewert steuert, während der zweite dazu verwendet wird
Elemente aus einer Liste auswählen. Mit dem dritten und optionalen Parameter können einige herausgefiltert werden
der Elemente in der Liste basierend auf einem bedingten Ausdruck. Einige Beispiele:

=> (def-Sammlung (Bereich 10))
=> (list-comp x [x Sammlung])
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

=> (list-comp (* x 2) [x Sammlung])
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

=> (list-comp (* x 2) [x Sammlung] (< x 5))
[0, 2, 4, 6, 8]

nicht
nicht wird in logischen Ausdrücken verwendet. Es nimmt einen einzelnen Parameter und gibt einen umgekehrten Wert zurück
Wahrheitswert. Wenn Wahre wird als Parameter angegeben, falsch zurückgegeben werden und umgekehrt.
Beispielverwendung:

=> (nicht wahr)
falsch

=> (nicht falsch)
Wahre

=> (nicht Keine)
Wahre

or
or wird in logischen Ausdrücken verwendet. Es sind mindestens zwei Parameter erforderlich. Es wird das zurückgegeben
erster nicht falscher Parameter. Wenn kein solcher Wert vorhanden ist, wird der letzte Parameter zurückgegeben.

=> (oder Richtig Falsch)
Wahre

=> (und Falsch Falsch)
falsch

=> (und Falsch 1 Wahr Falsch)
1

Anmerkungen:
or schließt kurz und stoppt die Parameterauswertung, sobald der erste wahre Wert vorliegt
angetroffen.

=> (oder True (drucken Sie „Hallo“))
Wahre

drucken
drucken dient der Ausgabe auf dem Bildschirm. Beispielverwendung:

(Drucken Sie „Hallo Welt!“)

Anmerkungen:
drucken kehrt immer zurück Andere.

Quasi-Zitat
Quasi-Zitat ermöglicht das Zitieren eines Formulars, aber auch die gezielte Auswertung von Ausdrücken.
Ausdrücke in a Quasi-Zitat kann gezielt ausgewertet werden Ende des Zitats (~). Die
Die ausgewertete Form kann auch mit gespleißt werden Unquote-Splice (~@). Quasiquote kann auch sein
geschrieben mit dem Backquote (`) Zeichen.

;; sei „qux“ eine Variable mit Wert (bar baz)
`(foo ~qux)
; entspricht '(foo (bar baz))
`(foo ~@qux)
; entspricht '(foo bar baz)

Angebot!
Angebot! gibt das ihm übergebene Formular zurück, ohne es auszuwerten. Angebot! kann alternativ sein
geschrieben mit dem Apostroph (') Zeichen.

=> (setv x '(print „Hello World“))
; Variable x ist auf Ausdruck & gesetzt und wird nicht ausgewertet
=> x
(u'print' u'Hello World')
=> (Auswertung x)
Hallo Welt

erfordern
erfordern wird verwendet, um Makros aus einem bestimmten Modul zu importieren. Es benötigt mindestens einen Parameter
Angabe des Moduls, welche Makros importiert werden sollen. Es können mehrere Module importiert werden
mit einem einzigen erfordern.

Das folgende Beispiel importiert Makros aus Modul-1 und Modul-2:

(erfordert Modul-1 Modul-2)

Ruhe / cdr
Ruhe und cdr Gibt die als Argument übergebene Sammlung ohne das erste Element zurück:

=> (Rest (Bereich 10))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

set-comp
set-comp wird zum Erstellen von Sets verwendet. Es benötigt zwei oder drei Parameter. Der erste Parameter ist
zur Steuerung des Rückgabewerts, während die zweite zur Auswahl von Elementen aus a verwendet wird
Reihenfolge. Der dritte und optionale Parameter kann verwendet werden, um einige der Elemente herauszufiltern
die Sequenz basierend auf einem bedingten Ausdruck.

=> (setv-Daten [1 2 3 4 5 2 3 4 5 3 4 5])
=> (set-comp x [x Daten] (ungerade? x))
{1, 3, 5}

Scheibe
Scheibe kann verwendet werden, um eine Teilmenge einer Liste zu nehmen und daraus eine neue Liste zu erstellen. Die Form
benötigt mindestens einen Parameter, der die aufzuteilende Liste angibt. Zwei optionale Parameter können sein
wird verwendet, um die Start- und Endposition der Teilmenge anzugeben. Wenn sie nicht mitgeliefert werden, wird die
Standardwert von Andere wird stattdessen verwendet. Der dritte optionale Parameter dient dazu
Kontrollschritt zwischen den Elementen.

Scheibe folgt den gleichen Regeln wie sein Python-Gegenstück. Negative Indizes werden gezählt
beginnend am Ende der Liste. Einige Anwendungsbeispiele:

=> (def-Sammlung (Bereich 10))

=> (Slice-Sammlung)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

=> (Slice-Sammlung 5)
[5, 6, 7, 8, 9]

=> (Slice-Sammlung 2 8)
[2, 3, 4, 5, 6, 7]

=> (Slice-Sammlung 2 8 2)
[2, 4, 6]

=> (Slice-Sammlung -4 -2)
[6, 7]

werfen / erhöhen
Das werfen or erhöhen Formulare können verwendet werden, um eine zu erhöhen Exception zur Laufzeit. Beispielverwendung:

(werfen)
; Lösen Sie die letzte Ausnahme erneut aus

(IOError auslösen)
; Wirf einen IOError

(throw (IOError „foobar“))
; Wirf einen IOError("foobar")

werfen kann ein einzelnes Argument akzeptieren (an Exception Klasse oder Instanz) oder keine Argumente für
Erhöhe den letzten erneut Exception.

versuchen
Das versuchen Formular wird verwendet, um a zu starten versuchen / Fang Block. Das Formular wird wie folgt verwendet:

(Versuchen
(fehleranfällige Funktion)
(catch [e ZeroDivisionError] (print „Division by Zero“))
(sonst (drucken Sie „keine Fehler“))
(endlich (drucken Sie „alles erledigt“)))

versuchen muss mindestens einen enthalten Fang Block und kann optional einen enthalten sonst or endlich
Block. Wenn während der Ausführung von ein Fehler mit einem passenden Catch-Block ausgelöst wird
fehleranfällige Funktion, Dass Fang Block wird ausgeführt. Wenn keine Fehler auftreten, wird die sonst
Block wird ausgeführt. Der endlich Der Block wird zuletzt ausgeführt, unabhängig davon, ob ein Block ausgeführt wird oder nicht
Es wurde ein Fehler ausgelöst.

es sei denn
Das es sei denn Makro ist eine Abkürzung für das Schreiben eines if Anweisung, die prüft, ob das Gegebene vorliegt
bedingt ist falsch. Im Folgenden wird die Erweiterung dieses Makros gezeigt.

(es sei denn, bedingte Anweisung)

(falls bedingt
Andere
(Anweisung machen))

Ende des Zitats
Innerhalb einer quasi zitierten Form, Ende des Zitats erzwingt die Auswertung eines Symbols. Ende des Zitats ist alias
die Tilde (~) Zeichen.

(def. Name „Cuddles“)
(Quasiquote (= Name (Name ohne Anführungszeichen)))
;=> (u'=' u'name' u'Cuddles')

`(= Name ~Name)
;=> (u'=' u'name' u'Cuddles')

Unquote-Splice
Unquote-Splice erzwingt die Auswertung eines Symbols innerhalb einer quasi zitierten Form, ähnlich wie
Ende des Zitats. Unquote-Splice kann nur verwendet werden, wenn das nicht in Anführungszeichen gesetzte Symbol ein enthält
iterierbarer Wert, da er den iterierbaren Wert in die Quasi-Anführungszeichenform „zusammenfügt“. Unquote-Splice is
Alias ​​auf die ~@ Symbol.

(def nums [1 2 3 4])
(quasiquote (+ (unquote-splice nums)))
;=> (u'+' 1L 2L 3L 4L)

`(+ ~@nums)
;=> (u'+' 1L 2L 3L 4L)

wann
wann ähnelt es sei denn, außer dass es testet, wann die gegebene Bedingung erfüllt ist Wahre. Es ist nicht
möglich, eine zu haben sonst Block in a wann Makro. Das Folgende zeigt die Erweiterung des
Makro.

(wenn bedingte Anweisung)

(wenn bedingt (do-Anweisung))

während
während wird verwendet, um einen oder mehrere Blöcke auszuführen, solange eine Bedingung erfüllt ist. Die folgende
Beispiel gibt „Hallo Welt!“ aus. auf unbestimmte Zeit auf dem Bildschirm:

(während True (drucken Sie „Hallo Welt!“))

mit
mit wird verwendet, um die Ausführung eines Blocks innerhalb eines Kontextmanagers einzuschließen. Der Kontext
Anschließend kann der Manager das lokale System kontrolliert auf- und wieder abbauen. Der
archetypisches Anwendungsbeispiel mit ist bei der Verarbeitung von Dateien. mit kann Kontext an einen binden
Argument oder ignorieren Sie es vollständig, wie unten gezeigt:

(mit [[arg (expr)]]-Block)

(mit [[(expr)]]-Block)

(mit [[arg (expr)] [(expr)]] Block)

Das folgende Beispiel öffnet die AKTUELLES laden Sie die Datei herunter und geben Sie ihren Inhalt auf dem Bildschirm aus. Der
Die Datei wird nach der Verarbeitung automatisch geschlossen.

(mit [[f (open "NEWS")]] (print (.read f)))

mit Dekorateur
mit Dekorateur wird verwendet, um eine Funktion mit einer anderen zu verpacken. Die Funktion, die Folgendes ausführt
Die Dekoration sollte einen einzelnen Wert akzeptieren: die Funktion, die dekoriert wird, und einen neuen Wert zurückgeben
Funktion. mit Dekorateur benötigt mindestens zwei Parameter: die Funktion, die ausgeführt wird
Dekoration und die zu dekorierende Funktion. Es kann mehr als eine Dekoratorfunktion geben
angewandt; Sie werden in der Reihenfolge von außen nach innen angewendet, d. h. der erste
Der Dekorateur wird der äußerste sein und so weiter. Dekoratoren mit Argumenten werden einfach genannt
wie ein Funktionsaufruf.

(mit-dekorateur-dekorateur-spaß
(defn some-function [] ...)

(mit-Dekorator Dekorator1 Dekorator2 ...
(defn some-function [] ...)

(with-decorator (decorator arg) ..
(defn some-function [] ...)

Im folgenden Beispiel Inc-Dekorateur wird zur Dekoration der Veranstaltung verwendet Zusatz mit
Funktion, die zwei Parameter akzeptiert und die dekorierte Funktion mit Werten aufruft
um 1 erhöht. Wenn die dekoriert ist Zusatz heißt mit den Werten 1 und 1 das Ende
Das Ergebnis wird 4 sein (1+1 + 1+1).

=> (defn inc-decorator [func]
... (fn [Wert-1 Wert-2] (Funktion (+ Wert-1 1) (+ Wert-2 1))))
=> (defn inc2-decorator [func]
... (fn [Wert-1 Wert-2] (Funktion (+ Wert-1 2) (+ Wert-2 2))))

=> (with-decorator inc-decorator (defn Addition [ab] (+ ab)))
=> (Zusatz 1 1)
4
=> (with-decorator inc2-decorator inc-decorator
... (defn Zusatz [ab] (+ ab)))
=> (Zusatz 1 1)
8

mit-gensyms
Neu in Version 0.9.12.

mit-gensym wird verwendet, um eine Reihe von zu generieren Gensym zur Verwendung in einem Makro. Der folgende Code:

(with-gensyms [abc]
...)

erweitert sich zu:

(lass [[a (gensym)
[b (Gensym)
[c (gensym)]]
...)

SEHEN EBENFALLS:
Abschnitt using-gensym

Ausbeute
Ausbeute wird verwendet, um ein Generatorobjekt zu erstellen, das einen oder mehrere Werte zurückgibt. Der Generator
ist iterierbar und kann daher in Schleifen, Listenverständnissen und Ähnlichem verwendet werden
Konstrukte.

Die Funktion zufällige Zahlen zeigt, wie Generatoren zur Erzeugung unendlicher Reihen verwendet werden können
ohne unendlich viel Speicher zu verbrauchen.

=> (defn multiplizieren [Basiskoeffizienten]
... (für [[(, Basiskoeffizient) (Zip-Basiskoeffizienten)]]
... (Rendite (*Basiskoeffizient))))

=> (multiplizieren (Bereich 5) (Bereich 5))


=> (list-comp-Wert [Wert (multiplizieren (Bereich 10) (Bereich 10))])
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

=> (zufällig importieren)
=> (definierte Zufallszahlen [niedrig hoch]
... (while True (yield (.randint random low high))))
=> (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]

Ertrag-aus
Neu in Version 0.9.13.

PYTHON 3.3 UND UP ONLY!

Ertrag-aus wird verwendet, um einen Subgenerator aufzurufen. Dies ist nützlich, wenn Sie möchten, dass Ihre Coroutine dies tut
in der Lage sein, seine Prozesse an eine andere Coroutine zu delegieren, beispielsweise wenn Sie so etwas Ausgefallenes verwenden
Asyncio.

Hy Kernbereich
Kernbereich Funktionen
aberlast
Verwendung: (aberzuletzt Coll)

Gibt einen Iterator aller Elemente bis auf das letzte in zurück coll.

=> (list (butlast (range 10)))
[0, 1, 2, 3, 4, 5, 6, 7, 8]

=> (list (butlast [1]))
[]

=> (list (butlast []))
[]

=> (itertools importieren)
=> (list (take 5 (butlast (itertools.count 10))))
[10, 11, 12, 13, 14]

Coll?
Neu in Version 0.10.0.

Verwendung: (komm? x)

Rücksendungen Wahre if x ist iterierbar und kein String.

=> (ugs? [1 2 3 4])
Wahre

=> (ugs? {"a" 1 "b" 2})
Wahre

=> (ugs? „abc“)
falsch

Nachteile
Neu in Version 0.10.0.

Verwendung: (Nachteile a b)

Gibt eine frische Cons-Zelle mit Auto zurück a und cdr b.

=> (setv a (cons 'hd 'tl))

=> (= 'hd (auto a))
Wahre

=> (= 'tl (cdr a))
Wahre

Nachteile?
Neu in Version 0.10.0.

Verwendung: (Nachteile? foo)

Überprüft, ob foo ist eine Cons-Zelle.

=> (setv a (cons 'hd 'tl))

=> (Nachteile? a)
Wahre

=> (Nachteile? Null)
falsch

=> (Nachteile? [1 2 3])
falsch

Dez
Verwendung: (Dez x)

Gibt eins weniger als zurück x. Gleichwertig (- x 1). Erhöht Typfehler if (Nicht (numerisch? X)).

=> (3. Dez.)
2

=> (0. Dez.)
-1

=> (12.3. Dez.)
11.3

Neueinsteiger
Neu in Version 0.10.0.

Verwendung: (zerlegen Baum &Optional [Codegen FALSCH])

Geben Sie den Python-AST für gegebenes Hy aus Baum zur Standardausgabe. Wenn Codegen is Wahre, die Funktion
gibt stattdessen Python-Code aus.

=> (disassemble '(print „Hello World!“))
Modul(
Körper=[
Expr(value=Call(func=Name(id='print'), args=[Str(s='Hello World!')], keywords=[], starargs=None, kwargs=None))])

=> (disassemble '(print "Hello World!") true)
print('Hallo Welt!')

leer?
Verwendung: (leer? Coll)

Rücksendungen Wahre if coll ist leer. Gleichwertig (= 0 (nur Coll)).

=> (leer? [])
Wahre

=> (leer? "")
Wahre

=> (leer? (, 1 2))
falsch

jeden?
Neu in Version 0.10.0.

Verwendung: (jeden? pred Coll)

Rücksendungen Wahre if (vor x) ist logischerweise für jeden wahr x in coll, Sonst falsch. Rückkehr Wahre
if coll ist leer.

=> (jeder? gerade? [2 4 6])
Wahre

=> (jeder? gerade? [1 3 5])
falsch

=> (jeder? gerade? [2 4 5])
falsch

=> (jeder? gerade? [])
Wahre

schweben?
Verwendung: (schweben? x)

Rücksendungen Wahre if x ist ein Schwimmer.

=> (float? 3.2)
Wahre

=> (float? -2)
falsch

sogar?
Verwendung: (sogar? x)

Rücksendungen Wahre if x ist gerade. Erhöht Typfehler if (Nicht (numerisch? X)).

=> (gerade? 2)
Wahre

=> (gerade? 13)
falsch

=> (gerade? 0)
Wahre

Identität
Verwendung: (Identität x)

Gibt das der Funktion bereitgestellte Argument zurück.

=> (Identität 4)
4

=> (Liste (Kartenidentität [1 2 3 4]))
[1 2 3 4]

inc.
Verwendung: (inkl x)

Gibt eins mehr als zurück x. Gleichwertig (+ x 1). Erhöht Typfehler if (Nicht (numerisch? X)).

=> (inkl. 3)
4

=> (inkl. 0)
1

=> (inkl. 12.3)
13.3

Beispiel?
Verwendung: (Beispiel? Klasse x)

Rücksendungen Wahre if x ist eine Instanz von Klasse.

=> (Instanz? float 1.0)
Wahre

=> (Instanz? int 7)
Wahre

=> (Instanz? str (str "foo"))
Wahre

=> (defclass TestClass [Objekt])
=> (setv inst (TestClass))
=> (Instanz? TestClass inst)
Wahre

ganze Zahl?
Verwendung: (ganze Zahl? x)

Rücksendungen Wahre if x ist eine ganze Zahl. Für Python 2 ist dies entweder int or lange. Für Python 3,
Das ist int.

=> (Ganzzahl? 3)
Wahre

=> (Ganzzahl? -2.4)
falsch

verschachteln
Neu in Version 0.10.1.

Verwendung: (verschachtelt seq1 seq2 ...)

Gibt eine Iterable des ersten Elements in jeder der Sequenzen zurück, dann das zweite usw.

=> (list (interleave (range 5) (range 100 105)))
[0, 100, 1, 101, 2, 102, 3, 103, 4, 104]

=> (list (interleave (range 1000000) „abc“))
[0, 'a', 1, 'b', 2, 'c']

dazwischenlegen
Neu in Version 0.10.1.

Verwendung: (zwischenlegen Artikel seq)

Gibt eine Itable der durch das Element getrennten Elemente der Sequenz zurück.

=> (list (interpose „!“ „abcd“))
['A B C D']

=> (list (interpose -1 (range 5)))
[0, -1, 1, -1, 2, -1, 3, -1, 4]

wiederholbar?
Verwendung: (wiederholbar? x)

Rücksendungen Wahre if x ist iterierbar. Iterierbare Objekte geben einen neuen Iterator zurück, wenn (iter x) is
angerufen. Im Gegensatz zu Iterator?.

=> ;; Funktioniert für Streicher
=> (iterierbar? (str „abcde“))
Wahre

=> ;; Funktioniert für Listen
=> (iterierbar? [1 2 3 4 5])
Wahre

=> ;; Funktioniert für Tupel
=> (iterierbar? (, 1 2 3))
Wahre

=> ;; Funktioniert für Diktate
=> (iterierbar? {:a 1 :b 2 :c 3})
Wahre

=> ;; Funktioniert für Iteratoren/Generatoren
=> (iterierbar? (Wiederholung 3))
Wahre

Iterator?
Verwendung: (Iterator? x)

Rücksendungen Wahre if x ist ein Iterator. Iteratoren sind Objekte, die sich selbst als zurückgeben
Iterator wann (iter x) wird genannt. Im Gegensatz zu wiederholbar?.

=> ;; funktioniert nicht für eine Liste
=> (Iterator? [1 2 3 4 5])
falsch

=> ;; aber wir können einen Iter aus der Liste erhalten
=> (iterator? (iter [1 2 3 4 5]))
Wahre

=> ;; funktioniert nicht für dict
=> (Iterator? {:a 1 :b 2 :c 3})
falsch

=> ;; Erstellen Sie einen Iterator aus dem Diktat
=> (iterator? (iter {:a 1 :b 2 :c 3}))
Wahre

Liste*
Verwendung: (Liste* ganzer &Rest Schwanz)

Erzeugt eine Kette verschachtelter Cons-Zellen (eine gepunktete Liste), die die Argumente enthält. Wenn die
Argumentliste hat nur ein Element, geben Sie es zurück.

=> (Liste* 1 2 3 4)
(1 2 3 . 4)

=> (Liste* 1 2 3 [4])
[1, 2, 3, 4]

=> (Liste* 1)
1

=> (Nachteile? (Liste* 1 2 3 4))
Wahre

Makroexpansion
Neu in Version 0.10.0.

Verwendung: (Makroexpand Form)

Gibt die vollständige Makroerweiterung von zurück unten stehende Formular.

=> (macroexpand '(-> (ab) (xy)))
(u'x' (u'a' u'b') u'y')

=> (macroexpand '(-> (ab) (-> (cd) (ef))))
(u'e' (u'c' (u'a' u'b') u'd') u'f')

Makroexpand-1
Neu in Version 0.10.0.

Verwendung: (Makroexpand-1 Form)

Gibt die Einzelschritt-Makroerweiterung von zurück unten stehende Formular.

=> (macroexpand-1 '(-> (ab) (-> (cd) (ef))))
(u'_>' (u'a' u'b') (u'c' u'd') (u'e' u'f'))

verbinden mit
Neu in Version 0.10.1.

Verwendung: (verbinden mit f &Rest Karten)

Gibt eine Karte zurück, die aus den übrigen zuerst verbundenen Karten besteht. Wenn ein Schlüssel in vorkommt
Bei mehr als einer Karte werden die Zuordnung(en) der letzteren (von links nach rechts) mit kombiniert
die Zuordnung im Ergebnis durch Aufruf (f val-in-result Val-in-Letzteres).

=> (merge-with (fn [xy] (+ xy)) {"a" 10 "b" 20} {"a" 1 "c" 30})
{u'a': 11L, u'c': 30L, u'b': 20L}

neg?
Verwendung: (negativ? x)

Rücksendungen Wahre if x ist kleiner als Null. Erhöht Typfehler if (Nicht (numerisch? X)).

=> (neg? -2)
Wahre

=> (negativ? 3)
falsch

=> (negativ? 0)
falsch

Null?
Verwendung: (Null? x)

Rücksendungen Wahre if x is Null / Andere.

=> (null? null)
Wahre

=> (Null? Keine)
Wahre

=> (null? 0)
falsch

=> (setf x nil)
=> (null? x)
Wahre

=> ;; list.append gibt immer None zurück
=> (nil? (.append [1 2 3] 4))
Wahre

keiner?
Verwendung: (keiner? x)

Rücksendungen Wahre if x is Andere.

=> (keine? Keine)
Wahre

=> (keine? 0)
falsch

=> (setf x Keine)
=> (keine? x)
Wahre

=> ;; list.append gibt immer None zurück
=> (keine? (.append [1 2 3] 4))
Wahre

nth
Verwendung: (nth coll n &Optional [Ursprünglich Null])

Liefert die n-tes Element in einer Sammlung, gezählt von 0. Gibt den Standardwert zurück. NullWenn
außerhalb der Grenzen (sofern nicht anders angegeben). Erhöht WertFehler if n ist negativ.

=> (nth [1 2 4 7] 1)
2

=> (nth [1 2 4 7] 3)
7

=> (nil? (nth [1 2 4 7] 5))
Wahre

=> (nth [1 2 4 7] 5 „Standard“)
'Default'

=> (nth (take 3 (drop 2 [1 2 3 4 5 6])) 2))
5

=> (nth [1 2 4 7] -1)
Traceback (jüngste Aufforderung zuletzt):
...
ValueError: Indizes für islice() müssen None oder eine Ganzzahl sein: 0 <= x <= sys.maxsize.

numerisch?
Verwendung: (numerisch? x)

Rücksendungen Wahre if x ist eine Zahl, wie sie in Python definiert ist Zahlen.Nummer Klasse.

=> (numerisch? -2)
Wahre

=> (numerisch? 3.2)
Wahre

=> (numerisch? „foo“)
falsch

seltsam?
Verwendung: (seltsam? x)

Rücksendungen Wahre if x ist ungerade. Erhöht Typfehler if (Nicht (numerisch? X)).

=> (ungerade? 13)
Wahre

=> (ungerade? 2)
falsch

=> (ungerade? 0)
falsch

pos?
Verwendung: (pos? x)

Rücksendungen Wahre if x ist größer als Null. Erhöht Typfehler if (Nicht (numerisch? X)).

=> (Pos. 3)
Wahre

=> (pos? -2)
falsch

=> (Pos. 0)
falsch

zweite
Verwendung: (Sekunde Coll)

Gibt das zweite Mitglied von zurück coll. Gleichwertig (erhalten coll 1).

=> (zweite [0 1 2])
1

einige
Neu in Version 0.10.0.

Verwendung: (etwas pred Coll)

Gibt den ersten logisch wahren Wert von zurück (vor x) für jede x in coll, Sonst Null.
Return Null if coll ist leer.

=> (einige sogar? [2 4 6])
Wahre

=> (null? (einige sogar? [1 3 5]))
Wahre

=> (nil? (irgendeine Identität [0 "" []]))
Wahre

=> (irgendeine Identität [0 „non-empty-string“ []])
'nicht-leerer-String'

=> (null? (einige sogar? []))
Wahre

Zeichenfolge?
Verwendung: (Zeichenfolge? x)

Rücksendungen Wahre if x ist eine Zeichenfolge.

=> (Zeichenfolge? „foo“)
Wahre

=> (Zeichenfolge? -2)
falsch

Symbol?
Verwendung: (Symbol? x)

Rücksendungen Wahre if x ist ein Symbol.

=> (Symbol? 'foo)
Wahre

=> (Symbol? '[abc])
falsch

Null?
Verwendung: (null? x)

Rücksendungen Wahre if x ist null.

=> (Null? 3)
falsch

=> (Null? -2)
falsch

=> (Null? 0)
Wahre

Reihenfolge Funktionen
Sequenzfunktionen können eine potenziell unendliche Sequenz ohne erstellen oder bearbeiten
Es ist erforderlich, dass die Sequenz vollständig in einer Liste oder einem ähnlichen Container realisiert wird. Sie tun dies durch
Rückgabe eines Python-Iterators.

Als Anwendungsbeispiel können wir den kanonischen unendlichen Fibonacci-Zahlengenerator verwenden
einige dieser Funktionen.

(defn fib []
(setv a 0)
(setv b 1)
(obwohl wahr
(Ertrag a)
(setv (, ab) (, b (+ ab)))))

Beachten Sie das (während was immer dies auch sein sollte. ...) Schleife. Wenn wir dies in der REPL ausführen,

=> (Fib)


Der Aufruf der Funktion gibt nur einen Iterator zurück, funktioniert aber erst, wenn wir ihn konsumieren.
Es wird nicht empfohlen, so etwas auszuprobieren, da die Endlosschleife bis dahin läuft
verbraucht den gesamten verfügbaren RAM, oder in diesem Fall bis ich es beendet habe.

=> (Liste (fib))
[1] 91474 getötete Hy

Um die ersten 10 Fibonacci-Zahlen zu erhalten, verwenden Sie nehmen. Beachten Sie, dass nehmen gibt auch einen Generator zurück,
Also erstelle ich daraus eine Liste.

=> (Liste (nimm 10 (Fib)))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

So erhalten Sie die Fibonacci-Zahl bei Index 9 (beginnend bei 0):

=> (nth (fib) 9)
34

Zyklus
Verwendung: (Kreislauf Coll)

Gibt einen unendlichen Iterator der Mitglieder von coll zurück.

=> (list (take 7 (cycle [1 2 3])))
[1, 2, 3, 1, 2, 3, 1]

=> (list (take 2 (cycle [1 2 3])))
[1, 2]

deutlich
Verwendung: (unterscheidbar Coll)

Gibt einen Iterator zurück, der nur die eindeutigen Mitglieder in enthält coll.

=> (list (distinct [ 1 2 3 4 3 5 2 ]))
[1, 2, 3, 4, 5]

=> (list (distinct []))
[]

=> (list (distinct (iter [ 1 2 3 4 3 5 2 ])))
[1, 2, 3, 4, 5]

fallen lassen
Verwendung: (fallen n Coll)

Gibt einen Iterator zurück und überspringt den ersten n Mitglieder coll. Erhöht WertFehler if n is
Negativ.

=> (list (drop 2 [1 2 3 4 5]))
[3, 4, 5]

=> (list (drop 4 [1 2 3 4 5]))
[5]

=> (list (drop 0 [1 2 3 4 5]))
[1, 2, 3, 4, 5]

=> (list (drop 6 [1 2 3 4 5]))
[]

Drop-Last
Verwendung: (Drop-Last n Coll)

Gibt einen Iterator aller bis auf den letzten zurück n Artikel in coll. Erhöht WertFehler if n is
Negativ.

=> (Liste (Drop-Last 5 (Bereich 10 20)))
[10, 11, 12, 13, 14]

=> (list (drop-last 0 (range 5)))
[0, 1, 2, 3, 4]

=> (list (drop-last 100 (range 100)))
[]

=> (itertools importieren)
=> (list (take 5 (drop-last 100 (itertools.count 10))))
[10, 11, 12, 13, 14]

Drop-While
Verwendung: (drop-while pred Coll)

Gibt einen Iterator zurück und überspringt Mitglieder von coll bis pred is falsch.

=> (list (drop-while even? [2 4 7 8 9]))
[7, 8, 9]

=> (list (drop-while numeric? [1 2 3 None "a"])))
[Keine, u'a']

=> (list (drop-while pos? [2 4 7 8 9]))
[]

Filter
Verwendung: (Filter pred Coll)

Gibt einen Iterator für alle Elemente in zurück coll die das Prädikat übergeben pred.

[VORLÄUFIGE VOLLAUTOMATISCHE TEXTÜBERSETZUNG - muss noch überarbeitet werden. Wir bitten um Ihr Verständnis.] entfernen.

=> (Liste (Filterposition? [1 2 3 -4 5 -7]))
[1, 2, 3, 5]

=> (Liste (Gerade filtern? [1 2 3 -4 5 -7]))
[2, -4]

ebnen
Neu in Version 0.9.12.

Verwendung: (ebnen Coll)

Gibt eine einzelne Liste aller Elemente in zurück coll, indem alle enthaltenen Listen reduziert werden und/oder
Tupel.

=> (abflachen [1 2 [3 4] 5])
[1, 2, 3, 4, 5]

=> (flatten ["foo" (, 1 2) [1 [2 3] 4] "bar"])
['foo', 1, 2, 1, 2, 3, 4, 'bar']

iterieren
Verwendung: (iterieren fn x)

Gibt einen Iterator von zurück x, fn(x), fn(fn(x)), usw.

=> (list (take 5 (iterate inc 5)))
[5, 6, 7, 8, 9]

=> (list (take 5 (iterate (fn [x] (* xx)) 5)))
[5, 25, 625, 390625, 152587890625]

lesen
Verwendung: (lesen &Optional [aus Datei eof])

Liest den nächsten Hy-Ausdruck aus aus Datei (standardmäßig sys.stdin) und kann eine nehmen
einzelnes Byte als EOF (standardmäßig eine leere Zeichenfolge). Erhöht EOFError if aus Datei endet vorher
Ein vollständiger Ausdruck kann analysiert werden.

=> (lesen)
(+2)
('+' 2 2)
=> (auswerten (lesen))
(+2)
4

=> (io importieren)
=> (def buffer (io.StringIO "(+ 2 2)\n(- 2 1)"))
=> (eval (apply read [] {"from_file" buffer}))
4
=> (eval (apply read [] {"from_file" buffer}))
1

=> ; vorausgesetzt, „example.hy“ enthält:
=> ; (Drucken Sie „Hallo“)
=> ; (drucken Sie „hyfriends!“)
=> (mit [[f (open "example.hy")]]
... (versuchen
... (obwohl wahr
... (let [[exp (read f)]]
... (Tun
... (drucken Sie „OHY“ exp)
... (Bewertung exp))))
... (catch [e EOFError]
... (drucken Sie "EOF!"))))
OHY („drucken“ „Hallo“)
HELLO
OHY ('print' 'hyfriends!')
Freunde!
EOF!

entfernen
Verwendung: (entfernen pred Coll)

Gibt einen Iterator von zurück coll mit Elementen, die das Prädikat übergeben, pred, ENTFERNT.

[VORLÄUFIGE VOLLAUTOMATISCHE TEXTÜBERSETZUNG - muss noch überarbeitet werden. Wir bitten um Ihr Verständnis.] Filter.

=> (Liste (ungerade entfernen? [1 2 3 4 5 6 7]))
[2, 4, 6]

=> (list (pos entfernen? [1 2 3 4 5 6 7]))
[]

=> (list (neg entfernen? [1 2 3 4 5 6 7]))
[1, 2, 3, 4, 5, 6, 7]

wiederholen
Verwendung: (wiederholen x)

Gibt einen Iterator (unendlich) von zurück x.

=> (Liste (nehmen Sie 6 (wiederholen Sie „s“)))
[u's', u's', u's', u's', u's', u's']

wiederholt
Verwendung: (wiederholt fn)

Gibt durch Aufruf einen Iterator zurück fn wiederholt.

=> (import [random [randint]])

=> (list (take 5 (repeatedly (fn [] (randint 0 10)))))
[6, 2, 0, 6, 7]

nehmen
Verwendung: (nehmen n Coll)

Gibt einen Iterator zurück, der den ersten enthält n Mitglieder coll. Erhöht WertFehler if n is
Negativ.

=> (Liste (nimm 3 [1 2 3 4 5]))
[1, 2, 3]

=> (Liste (nehmen Sie 4 (wiederholen Sie „s“)))
[u's', u's', u's', u's']

=> (Liste (nehmen Sie 0 (wiederholen Sie „s“)))
[]

nimm-nth
Verwendung: (nehmen-nth n Coll)

Gibt einen Iterator zurück, der alle enthält n-tes Mitglied von coll.

=> (list (take-nth 2 [1 2 3 4 5 6 7]))
[1, 3, 5, 7]

=> (list (take-nth 3 [1 2 3 4 5 6 7]))
[1, 4, 7]

=> (list (take-nth 4 [1 2 3 4 5 6 7]))
[1, 5]

=> (list (take-nth 10 [1 2 3 4 5 6 7]))
[1]

eine Weile dauern
Verwendung: (eine Weile dauern pred Coll)

Gibt einen Iterator von zurück coll solange pred Rückgabe Wahre.

=> (list (take-while pos? [ 1 2 3 -4 5]))
[1, 2, 3]

=> (list (take-while neg? [ -4 -3 1 2 5]))
[-4, -3]

=> (list (take-while neg? [ 1 2 3 -4 5]))
[]

zipwith
Neu in Version 0.9.13.

Verwendung: (zipwith fn coll ...)

Gleichwertig Reißverschluss, verwendet jedoch eine Funktion mit mehreren Argumenten, anstatt ein Tupel zu erstellen. Wenn
zipwith wird dann mit N Sammlungen aufgerufen fn muss N Argumente akzeptieren.

=> (Importoperator)
=> (Liste (zipwith Operator.add [1 2 3] [4 5 6]))
[5, 7, 9]

Leser Makros
Reader-Makros geben Lisp die Möglichkeit, die Syntax im Handumdrehen zu ändern und zu ändern. Du willst nicht
Polnische Schreibweise? Ein Reader-Makro kann genau das leicht tun. Willst du Clojures Art, eine zu haben?
Regex? Auch Reader-Makros können dies problemlos bewerkstelligen.

Syntax
=> (defreader ^ [expr] (print expr))
=> #^(1 2 3 4)
(1 2 3 4)
=> #^"Hallo"
"Hallo"
=> #^1+2+3+4+3+2
1+2+3+4+3+2

Hy hat kein Literal für Tupel. Nehmen wir an, Sie mögen es nicht (, ...) und möchte etwas anderes. Das
ist ein Problem, das Reader-Makros auf nette Weise lösen können.

=> (defreader t [expr] `(, ~@expr))
=> #t(1 2 3)
(1, 2, 3)

Sie könnten es sogar wie Clojure machen und ein Literal für reguläre Ausdrücke haben!

=> (import re)
=> (defreader r [expr] `(re.compile ~expr))
=> #r".*"
<_sre.SRE_Pattern-Objekt bei 0xcv7713ph15#>

Sytemimplementierung
Defreader akzeptiert ein einzelnes Zeichen als Symbolnamen für das Reader-Makro; alles was länger ist
wird einen Fehler zurückgeben. Umsetzungstechnisch, Defreader dehnt sich zu einem mit a bedeckten Lambda aus
Dekorateur. Dieser Dekorateur speichert das Lambda in einem Wörterbuch mit seinem Modulnamen und
Symbol.

=> (defreader ^ [expr] (print expr))
;=> (with_decorator (hy.macros.reader ^) (fn [expr] (print expr)))

# erweitert sich in (dispatch_reader_macro ...) wohin das Symbol und der Ausdruck übergeben werden
die richtige Funktion.

=> #^()
;=> (dispatch_reader_macro ^())
=> #^"Hallo"
"Hallo"

WARNUNG:
Aufgrund einer Einschränkung im Lexer und Parser von Hy können Reader-Makros nicht definiert neu definiert werden
Syntax wie ()[]{}. Dies wird höchstwahrscheinlich in Zukunft behoben.

Intern Hy Dokumentation
Anmerkungen:
Diese Bits sind vor allem für Leute nützlich, die Hy selbst hacken, können aber auch für verwendet werden
diejenigen, die tiefer in die Makroprogrammierung eintauchen.

Hy Modelle
Einleitung zu Hy Modelle
Hy-Modelle sind eine sehr dünne Schicht über regulären Python-Objekten und stellen die Hy-Quelle dar
Code als Daten. Modelle fügen lediglich Quellpositionsinformationen und eine Handvoll Methoden hinzu
unterstützen die saubere Manipulation des Hy-Quellcodes, beispielsweise in Makros. Um das zu erreichen
Ziel: Hy-Modelle sind Mixins einer Basis-Python-Klasse und HyObject.

HyObject
hy.models.HyObject ist die Basisklasse der Hy-Modelle. Es implementiert nur eine Methode, ersetzen,
Dadurch wird die Quellposition des aktuellen Objekts durch die als Argument übergebene Position ersetzt.
Dadurch können wir die ursprüngliche Position von Ausdrücken verfolgen, die von geändert werden
Makros, sei es im Compiler oder in reinen Hy-Makros.

HyObject ist nicht dazu gedacht, Hy-Modelle direkt zu instanziieren, sondern nur als Mixin
für andere Klassen.

Compounds Modelle
Listen in Klammern und Klammern werden vom Hy-Parser als zusammengesetzte Modelle analysiert.

HyList
hy.models.list.HyList ist die Basisklasse „iterierbarer“ Hy-Modelle. Seine grundlegende Verwendung besteht darin,
in Klammern darstellen [] Listen, die, wenn sie als Ausdruck der obersten Ebene verwendet werden, übersetzt werden in
Python-Listenliterale in der Kompilierungsphase.

Durch das Hinzufügen einer HyList zu einem anderen iterierbaren Objekt wird die Klasse des linken Objekts wiederverwendet.
Ein nützliches Verhalten, wenn Sie beispielsweise Hy-Objekte in einem Makro verketten möchten.

HyExpression
hy.models.expression.HyExpression erbt HyList für Klammern () Ausdrücke. Der
Das Kompilierungsergebnis dieser Ausdrücke hängt vom ersten Element der Liste ab: dem
Der Compiler verteilt Ausdrücke zwischen Compiler-Sonderformen, benutzerdefinierten Makros und
reguläre Python-Funktionsaufrufe.

HyDict
hy.models.dict.HyDict erbt HyList für geschweifte Klammern {} Ausdrücke, die kompilieren
bis hin zu einem Python-Wörterbuchliteral.

Die Entscheidung, eine Liste anstelle eines Diktats als Basisklasse für zu verwenden HyDict ermöglicht einfacher
Manipulation von Diktaten in Makros, mit dem zusätzlichen Vorteil, dass zusammengesetzte Ausdrücke möglich sind
als Diktattasten (wie zum Beispiel die HyExpression Die Python-Klasse ist nicht hashbar.

Atom- Modelle
Im Eingabestream werden Zeichenfolgen in doppelte Anführungszeichen gesetzt, unter Berücksichtigung der Python-Notation für Zeichenfolgen,
werden als einzelnes Token geparst, das direkt als a geparst wird HyString.

Eine ununterbrochene Zeichenfolge, ausgenommen Leerzeichen, Klammern, Anführungszeichen und doppelte Anführungszeichen
und Kommentare werden als Bezeichner geparst.

Bezeichner werden während der Analysephase in der folgenden Reihenfolge in atomare Modelle aufgelöst:

· HyInteger

· HyFloat

· HyComplex (Wenn das Atom kein nacktes ist j)

· HyKeyword (Wenn das Atom mit beginnt :)

· HySymbol

HyString
hy.models.string.HyString ist die Basisklasse stringäquivalenter Hy-Modelle. Es auch
stellt String-Literale in doppelten Anführungszeichen dar, "", die bis zur Unicode-Zeichenfolge kompiliert werden
Literale in Python. HyStrings erben Unicode-Objekte in Python 2 und String-Objekte in
Python 3 (und sind daher nicht kodierungsabhängig).

HyString basierte Modelle sind unveränderlich.

Hy-Literalzeichenfolgen können sich über mehrere Zeilen erstrecken und werden vom Parser als eine einzige Zeile betrachtet
Einheit, unter Berücksichtigung der Python-Escapezeichen für Unicode-Strings.

Numerisch Modelle
hy.models.integer.HyInteger stellt ganzzahlige Literale dar (unter Verwendung von lange Geben Sie auf Python 2 ein,
und int auf Python 3).

hy.models.float.HyFloat stellt Gleitkommaliterale dar.

hy.models.complex.HyComplex stellt komplexe Literale dar.

Numerische Modelle werden mit der entsprechenden Python-Routine und einem gültigen numerischen Python analysiert
Literale werden in ihr Hy-Gegenstück umgewandelt.

HySymbol
hy.models.symbol.HySymbol ist das Modell, das zur Darstellung von Symbolen in der Hy-Sprache verwendet wird. Es
erbt HyString.

HySymbol Objekte werden in der Parsing-Phase entstellt, um die Python-Interoperabilität zu verbessern:

· Von Sternchen umgebene Symbole (*) werden in Großbuchstaben umgewandelt;

· Bindestriche (-) werden in Unterstriche umgewandelt (_);

· Ein abschließendes Fragezeichen (?) wird in eine führende umgewandelt Ist_.

Vorsichtsmaßnahme: Da das Mangeln während der Analysephase erfolgt, ist dies möglich
Generieren Sie programmgesteuert HySymbols, die nicht mit Hy-Quellcode generiert werden können. So ein
Der Mechanismus wird von Gensym verwendet, um „uninternierte“ Symbole zu generieren.

HyKeyword
hy.models.keyword.HyKeyword repräsentiert Schlüsselwörter in Hy. Schlüsselwörter sind Symbole, die mit beginnen
a :. Die Klasse erbt HyString.

Zu unterscheiden HyKeywords für HySymbols, ohne die Möglichkeit (unfreiwillig)
kollidiert mit dem privat genutzten Unicode-Zeichen „\uFDD0“ wird dem Schlüsselwortliteral vorangestellt
vor der Lagerung.

Nachteile Die Zellen
hy.models.cons.HyCons ist eine Darstellung von Python-freundlich Nachteile Zellen. Nachteile von Zellen sind
Besonders nützlich, um Funktionen „üblicher“ LISP-Varianten wie Scheme oder Common nachzuahmen
Lispeln.

Eine Cons-Zelle ist ein Objekt mit zwei Elementen, das Folgendes enthält: Auto (Kopf) und a cdr (Schwanz). In etwas Lisp
Varianten ist die Cons-Zelle der grundlegende Baustein, und S-Ausdrücke sind es tatsächlich
dargestellt als verknüpfte Listen von Cons-Zellen. Dies ist in Hy nicht wie üblich der Fall
Ausdrücke bestehen aus Python-Listen, die in a eingeschlossen sind HyExpression. Jedoch die HyCons
ahmt das Verhalten „normaler“ Lisp-Varianten folgendermaßen nach:

· (Nachteile etwas Null) is (HyExpression [etwas])

· (Nachteile etwas einige-Liste) is ((Typ einige-Liste) (+ [etwas] einige-Liste)) (ob
einige-Liste erbt von Liste).

· (erhalten (Nachteile a b) 0) is a

· (Scheibe (Nachteile a b) 1) is b

Hy unterstützt eine gepunktete Listensyntax, wobei '(A . b) Mittel (Nachteile 'a 'B) und '(A b . c) Mittel
(Nachteile 'a (Nachteile 'b 'C)). Wenn der Compiler auf der obersten Ebene auf eine Cons-Zelle stößt, wird er ausgelöst
ein Kompilierungsfehler.

HyCons Umschließt die übergebenen Argumente (car und cdr) in Hy-Typen, um die Manipulation zu erleichtern
Nachteile von Zellen im Makrokontext.

Hy Intern TheorieXNUMX Tauchgänge (XNUMX Tage)
Überblick
Die Hy-Interna fungieren als Front-End für den Python-Bytecode, sodass Hy selbst
kompiliert bis zum Python-Bytecode, sodass eine unveränderte Python-Laufzeitumgebung Hy-Code ausführen kann,
ohne es überhaupt zu merken.

Wir tun dies, indem wir Hy in eine interne Python AST-Datenstruktur übersetzen und
Erstellen Sie diesen AST mithilfe von Modulen aus dem Python-Standard in Python-Bytecode
Bibliothek, sodass wir nicht für jeden die gesamte Arbeit der Python-Interna duplizieren müssen
einzelne Python-Version.

Hy arbeitet in vier Stufen. Die folgenden Abschnitte behandeln jeden Schritt von Hy von der Quelle bis
Laufzeit.

Shritte 1 und 2: Tokenisierung und Parsing
Der erste Schritt beim Kompilieren von Hy besteht darin, die Quelle in Token zu lexifizieren, mit denen wir umgehen können. Wir
Verwenden Sie ein Projekt namens rply, das ein wirklich schöner (und schneller) Parser ist, der in einer Teilmenge geschrieben ist
von Python namens rpython.

Der gesamte Lexing-Code ist in definiert hy.lex.lexer. Dieser Code definiert größtenteils nur das Hy
Die Grammatik und alle eigentlichen schwierigen Teile werden von rply übernommen – wir definieren nur
„Rückrufe“ für die Antwort hy.lex.parser, das die generierten Token übernimmt und die zurückgibt
Hy-Modelle.

Sie können sich die Hy-Modelle als „AST“ für Hy vorstellen, sie sind das, womit Makros arbeiten
(direkt) und es ist das, was der Compiler verwendet, wenn er Hy herunterkompiliert.

SEHEN EBENFALLS:
Abschnitt Hy Modelle Weitere Informationen zu Hy-Modellen und deren Bedeutung finden Sie hier.

Schritt 3: Hy Zusammenstellung zu Python AST
Hier geschieht der größte Teil der Magie in Hy. Hier nehmen wir Hy AST (die Modelle),
und kompilieren Sie sie in Python AST. Hier passieren ein paar seltsame Dinge, die über ein paar hinausgehen
Probleme in AST, und die Arbeit im Compiler gehört zu unseren wichtigsten Aufgaben
haben.

Der Compiler ist etwas komplex, also seien Sie nicht beunruhigt, wenn Sie ihn nicht auf Anhieb verstehen.
Es kann einige Zeit dauern, bis es richtig ist.

Der Haupteinstiegspunkt zum Compiler ist HyASTCompiler.compile. Diese Methode wird aufgerufen und
die einzige echte „öffentliche“ Methode der Klasse (das heißt, wir versprechen das nicht wirklich
API über diese Methode hinaus).

Tatsächlich rekursieren wir selbst intern fast nie direkt, sondern erzwingen fast immer
der Hy-Baum durch kompilieren, und wird dies häufig mit Unterelementen eines Ausdrucks tun
dass wir haben. Es liegt am typbasierten Dispatcher, Unterelemente ordnungsgemäß zu versenden.

Alle Methoden, die eine Kompilierung durchführen, sind mit gekennzeichnet @builds() Dekorateur. Du kannst
Übergeben Sie entweder die Klasse des Hy-Modells, das es kompiliert, oder Sie können eine Zeichenfolge dafür verwenden
Ausdrücke. Ich werde das gleich klären.

Vorname Stufe Typ-Versand
Beginnen wir in der kompilieren Methode. Als Erstes überprüfen wir den Typ der Sache
wir bauen. Wir schauen nach, ob wir eine Methode haben, die das erstellen kann Art() dass wir
haben, und an die Methode senden, die damit umgehen kann. Wenn wir keine Methoden haben, die das können
Wenn wir diesen Typ erstellen, erstellen wir einen internen Exception.

Wenn wir zum Beispiel eine haben HyStringhaben wir eine nahezu 1:1-Zuordnung von Hy AST zu Python
AST. Der kompilieren_string Methode nimmt die HyString, und gibt an . zurück ast.Str()
mit den richtigen Zeilennummern und Inhalten gefüllt.

Makro-Erweitern
Wenn wir eine bekommen HyExpression, werden wir versuchen herauszufinden, ob es sich um ein bekanntes Makro handelt, und darauf drängen, es zu haben
es erweiterte sich durch Anrufung hy.macros.macroexpand, dann schieben Sie das Ergebnis zurück in
HyASTCompiler.compile.

Zweite Stufe Ausdrucksversand
Der einzige Sonderfall ist der HyExpression, da wir abhängig davon unterschiedliche AST erstellen müssen
auf dem jeweiligen Sonderformular. Zum Beispiel, wenn wir einen treffen (ob was immer dies auch sein sollte. was immer dies auch sein sollte. falsch)Wir
müssen eine generieren ast.If, und kompilieren Sie die Unterknoten ordnungsgemäß. Hier ist die @builds()
mit einem String als Argument eingeht.

NB: Kompilierungsausdruck (was mit einem definiert ist @builds(HyExpression)) wird versendet
basierend auf der Zeichenfolge des ersten Arguments. Wenn das erste Argument aus irgendeinem Grund nicht zutrifft
eine Zeichenfolge, wird auch dieser Fall ordnungsgemäß behandelt (höchstwahrscheinlich durch Auslösen von an Exception).

Wenn Hy die Zeichenfolge nicht kennt, wird standardmäßig eine erstellt ast.Anruf, was ich versuchen werde
Führen Sie einen Laufzeitaufruf durch (in Python etwa so). foo ()).

Fragen Hit mit Python AST
Python AST ist großartig; Das hat es uns ermöglicht, darüber hinaus ein so kraftvolles Projekt zu schreiben
Python, ohne zu hart gegen Python kämpfen zu müssen. Wie von allem hatten wir unseren gerechten Anteil
Probleme, und hier ist eine kurze Liste der häufigsten Probleme, auf die Sie stoßen könnten.

Python unterscheidet zwischen Statements und Ausdrücke.

Das klingt vielleicht nicht nach einer großen Sache – für die meisten Python-Programmierer ist dies tatsächlich so
bald zu einem „Na ja“-Moment werden.

Machen Sie in Python so etwas wie:

drucken für x in Angebot(10): passierenDa drucken druckt Ausdrücke und für ist kein
Ausdruck, es ist eine Kontrollflussanweisung. Dinge wie 1 + 1 sind Ausdrücke, so wie sie sind Lambda
x: 1 + x, aber auch andere Sprachfunktionen, wie z if, für, oder während sind Aussagen.

Da sie für Python keinen „Wert“ haben, ist die Arbeit in Hy schwierig, da sie etwas tun
Gefällt mir (drucken (ob was immer dies auch sein sollte. was immer dies auch sein sollte. FALSCH)) ist nicht nur üblich, es wird erwartet.

Infolgedessen verstümmeln wir Dinge automatisch mit a Ergebnis Objekt, wo wir jedes anbieten ast.stmt
das muss gelaufen werden, und ein einziges ast.expr das kann verwendet werden, um den Wert von allem zu ermitteln
wurde gerade ausgeführt. Hy erreicht dies, indem er beim Laufen die Zuweisung zu Dingen erzwingt.

Als Beispiel das Hy:

(drucken (wenn wahr, wahr, falsch))

Wird zu:

Wenn wahr:
_mangled_name_here = Wahr
sonst:
_mangled_name_here = Falsch

print _mangled_name_here

OK, das war ein bisschen gelogen, da wir diese Aussage tatsächlich wie folgt umwandeln:

Gibt True aus, wenn True, sonst False

Indem man Dinge in eine zwingt ast.expr wenn wir können, aber die allgemeine Idee gilt.

Schritt 4: Python Bytecode Output und Laufzeit
Nachdem wir einen vollständigen Python-AST-Baum haben, können wir versuchen, ihn in Python zu kompilieren
Bytecode durch Durchschieben eval. Von hier an haben wir nicht mehr die Kontrolle, und
Python kümmert sich um alles. Aus diesem Grund werden Dinge wie Python-Tracebacks, PDFs und
Django-Apps funktionieren.

Hy Makros
Die richtigen Gensym für Sicherer Makros
Beim Schreiben von Makros muss darauf geachtet werden, dass keine externen Variablen erfasst oder verwendet werden
Variablennamen, die mit dem Benutzercode in Konflikt geraten könnten.

Wir werden ein Beispielmakro verwenden nif (sehen
http://letoverlambda.com/index.cl/guest/chap3.html#sec_5 für eine ausführlichere Beschreibung.)
nif ist ein Beispiel, so etwas wie eine Zahl if, wobei basierend auf dem Ausdruck einer der
3 Formen werden aufgerufen, je nachdem, ob der Ausdruck positiv, null oder negativ ist.

Ein erster Durchgang könnte etwa so aussehen:

(defmacro nif [expr pos-form null-form neg-form]
`(let [[obscure-name ~expr]]
(cond [(pos? obscure-name) ~pos-form]
[(Null? obskurer Name) ~Nullform]
[(neg? obscure-name) ~neg-form])))

woher Obsure-Name ist ein Versuch, einen Variablennamen so auszuwählen, dass er nicht mit anderen in Konflikt gerät
Code. Aber das ist natürlich gut gemeint, aber keine Garantie.

Die Methode gensym soll für genau diesen Anlass ein neues, einzigartiges Symbol generieren.
Eine viel bessere Version von nif wäre:

(defmacro nif [expr pos-form null-form neg-form]
(sei [[g (gensym)]]
`(let [[~g ~expr]]
(cond [(pos? ~g) ~pos-form]
[(Null? ~g) ~Nullform]
[(neg? ~g) ~neg-Form]))))

Dies ist ein einfacher Fall, da es nur ein Symbol gibt. Aber wenn Bedarf besteht, mehrere
Gensyms gibt es ein zweites Makro mit-gensyms, das sich im Grunde zu einer Reihe von erweitert lassen
Aussagen:

(with-gensyms [abc]
...)

erweitert sich zu:

(lass [[a (gensym)
[b (Gensym)
[c (gensym)]]
...)

also unser neu geschrieben nif würde aussehen wie:

(defmacro nif [expr pos-form null-form neg-form]
(with-gensyms [g]
`(let [[~g ~expr]]
(cond [(pos? ~g) ~pos-form]
[(Null? ~g) ~Nullform]
[(neg? ~g) ~neg-Form]))))

Schließlich können wir jedoch ein neues Makro erstellen, das all dies für uns erledigt. defmacro/g! werde nehmen
alle Symbole, die mit beginnen g! und automatisch anrufen Gensym mit dem Rest
Symbol. Also g!a würde werden (gensym "A").

Unsere letzte Version von nifgebaut mit defmacro/g! wird:

(defmacro/g! nif [expr pos-form null-form neg-form]
`(let [[~g!res ~expr]]
(cond [(pos? ~g!res) ~pos-form]
[(null? ~g!res) ~nullform]
[(neg? ~g!res) ~neg-form]))))

Überprüfung Makro Argumente und Erhöhung Ausnahmen
Hy Compiler Einbauten

BEITRAG MODULE INDEX


Inhaltsübersicht:

Anaphorisch Makros
Neu in Version 0.9.12.

Das anaphorische Makromodul macht die funktionale Programmierung in Hy sehr prägnant und einfach
lesen.
Ein anaphorisches Makro ist eine Art Programmiermakro, das bewusst eine Form einfängt
wird dem Makro bereitgestellt, auf das durch eine Anapher (ein verweisender Ausdruck) verwiesen werden kann
zum anderen). — Wikipedia (http://en.wikipedia.org/wiki/Anaphoric_macro)

Makros
ap-wenn
Verwendung: (ap-if (foo) (drucken Es))

Bewertet die erste Form auf Wahrhaftigkeit und bindet sie daran it sowohl im Wahren als auch im Falschen
Geäst.

ein Pfirsich
Verwendung: (ein Pfirsich [1 2 3 4 5] (drucken Es))

Bewerten Sie das Formular für jedes Element in der Liste auf Nebenwirkungen.

ap-each-while
Verwendung: (ap-jedes-während Liste pred Körper)

Werten Sie die Form für jedes Element aus, bei dem die Prädikatform zurückgegeben wird Wahre.

=> (ap-each-while [1 2 3 4 5 6] (< it 4) (drucken))
1
2
3

ap-Karte
Verwendung: (ap-map unten stehende Formular Liste)

Die anaphorische Form der Karte funktioniert genauso wie die normale Karte, außer dass es sich dabei um eine Funktion handelt
Objekt nimmt es eine Hy-Form an. Der besondere Name it ist an das aktuelle Objekt gebunden
Liste in der Iteration.

=> (list (ap-map (* it 2) [1 2 3]))
[2, 4, 6]

ap-map-wann
Verwendung: (ap-map-when predfn Vertreter Liste)

Werten Sie eine Zuordnung über die Liste mithilfe einer Prädikatfunktion aus, um zu bestimmen, wann die angewendet werden soll
Form.

=> (list (ap-map-when odd? (* it 2) [1 2 3 4]))
[2, 2, 6, 4]

=> (list (ap-map-when even? (* it 2) [1 2 3 4]))
[1, 4, 3, 8]

AP-Filter
Verwendung: (ap-filter unten stehende Formular Liste)

Wie bei ap-Karte Wir verwenden eine spezielle Form anstelle einer Funktion, um die Elemente zu filtern
Liste. Der besondere Name it ist an das aktuelle Element in der Iteration gebunden.

=> (list (ap-filter (> (* it 2) 6) [1 2 3 4 5]))
[4, 5]

ap-ablehnen
Verwendung: (ap-ablehnen unten stehende Formular Liste)

Diese Funktion bewirkt das Gegenteil von AP-Filter, lehnt es die Elemente ab, die das passieren
Prädikat. Der besondere Name it ist an das aktuelle Element in der Iteration gebunden.

=> (list (ap-reject (> (* it 2) 6) [1 2 3 4 5]))
[1, 2, 3]

ap-dotimes
Anwendungsbereich (ap-dotimes n Körper)

Diese Funktion wertet den Körper aus n mal, mit der speziellen Variablen it gebunden von 0 zu
1-n. Es ist nützlich bei Nebenwirkungen.

=> (setv n [])
=> (ap-dotimes 3 (.append n it))
=> n
[0, 1, 2]

ap-first
Anwendungsbereich (ap-first predfn Liste)

Diese Funktion gibt das erste Element zurück, das das Prädikat or übergibt Andere, Mit dem
spezielle Variable it an das aktuelle Element in der Iteration gebunden.

=>(ap-first (> it 5) (Bereich 10))
6

ap-last
Anwendungsbereich (ap-last predfn Liste)

Diese Funktion gibt das letzte Element zurück, das das Prädikat or übergibt Anderemit dem besonderen
Variable it an das aktuelle Element in der Iteration gebunden.

=>(ap-last (> it 5) (Bereich 10))
9

ap-reduzieren
Anwendungsbereich (ap-reduzieren unten stehende Formular Liste &Optional Ursprünglicher Wert)

Diese Funktion gibt das Ergebnis der Anwendung der Form auf die ersten beiden Elemente im Körper zurück
Anwenden des Ergebnisses und des 3. Elements usw., bis die Liste erschöpft ist. Optional ein
Der Anfangswert kann angegeben werden, damit die Funktion auf den Anfangswert und den angewendet wird
stattdessen das erste Element. Dadurch wird das Element angezeigt, als das iteriert wird it Und die aktuelle
kumulierter Wert als acc.

=>(ap-reduce (+ it acc) (Bereich 10))
45

Schleife/Wiederholung
Neu in Version 0.10.0.

Das Schleife / wiederkehren Das Makro bietet Programmierern eine einfache Möglichkeit, die Tail-Call-Optimierung (TCO) zu nutzen.
in ihrem Hy-Code.
Ein Tail Call ist ein Unterprogrammaufruf, der innerhalb einer anderen Prozedur als deren Abschluss erfolgt
Aktion; Es kann einen Rückgabewert erzeugen, der dann vom Aufrufer sofort zurückgegeben wird
Verfahren. Wenn ein Unterprogramm einen Aufruf ausführt, kann dies möglicherweise dazu führen, dass dies der Fall ist
zu derselben Unterroutine, die in der Aufrufkette erneut aufgerufen wird, befindet sich in der Endposition,
Eine solche Unterroutine wird als Schwanzrekursion bezeichnet, was einen Sonderfall der Rekursion darstellt.
Tail Calls sind von Bedeutung, da sie ohne das Hinzufügen eines neuen Stacks implementiert werden können
Frame an den Aufrufstapel. Der Großteil des Rahmens des aktuellen Verfahrens wird nicht benötigt
mehr, und es kann durch den Rahmen des Heckrufs ersetzt werden. Das Programm kann dann springen
zum aufgerufenen Unterprogramm. Das Erzeugen eines solchen Codes anstelle einer Standardaufrufsequenz ist
Dies wird als Tail-Call-Eliminierung oder Tail-Call-Optimierung bezeichnet. Tail-Call-Eliminierung ermöglicht
Prozeduraufrufe in der Endposition sollen genauso effizient implementiert werden wie goto-Anweisungen,
Dies ermöglicht eine effiziente strukturierte Programmierung. — Wikipedia (‐
http://en.wikipedia.org/wiki/Tail_call)

Makros
Schleife
Schleife legt einen Rekursionspunkt fest. Mit Schleife, wiederkehren bindet die in der festgelegten Variablen erneut
Rekursionspunkt und sendet die Codeausführung zurück an diesen Rekursionspunkt. Wenn wiederkehren wird in verwendet
Bei einer Nicht-Tail-Position wird eine Ausnahme ausgelöst.

Verwendung: (Schleife Bindungen &Rest Körper)

Beispiel:

(erfordert hy.contrib.loop)

(defn Fakultät [n]
(Schleife [[in] [acc 1]]
(wenn (Null? i)
acc
(recur (dec i) (* acc i)))))

(Fakultät 1000)

defmulti
Neu in Version 0.10.0.

defmulti ermöglicht die Aritätsüberladung einer Funktion mit der angegebenen Anzahl von Argumenten und/oder Kwargs.
Inspiriert von Clojures Interpretation definiere.

=> (erfordert hy.contrib.multi)
=> (auf jeden Fall viel Spaß
... ([a] „a“)
... ([ab] „ab“)
... ([abc] „abc“))
=> (Spaß 1)
"ein"
=> (Spaß 1 2)
„ab“
=> (Spaß 1 2 3)
"ABC"

HACKING ON HY


Registrieren UNSERE Hyve!
Bitte komm vorbei, Hy!

Bitte kommen Sie vorbei und hängen Sie mit uns ab #hy on irc.freenode.net!

Bitte sprechen Sie auf Twitter mit dem darüber #hy Hashtag!

Bitte bloggen Sie darüber!

Bitte sprühen Sie es nicht auf den Zaun Ihres Nachbarn (ohne nett zu fragen)!

Hacken!
Mach das:

1. Ein ... kreieren virtuell Umwelt:

$ virtualenv venv

und aktivieren Sie es:

$ . venv/bin/activate

oder benutzen virtueller Wrapper So erstellen und verwalten Sie Ihre virtuelle Umgebung:

$ mkvirtualenv hy
$ workon hy

2. Holen Sie sich den Quellcode:

$ Git-Klon https://github.com/hylang/hy.git

Oder verwenden Sie Ihre Gabel:

$ git Klon [E-Mail geschützt] : /hy.git

3. Zum Hacken installieren:

$ cd hy/
$ pip install -e .

4. Installieren Sie andere Entwicklungsanforderungen:

$ pip install -r Anforderungen-dev.txt

5. Tue tolle Dinge; jemanden vor Freude/Abscheu über das, was du angerichtet hast, aufschreien lassen.

Test!
Tests befinden sich in Tests /. Wir gebrauchen Nase.

So führen Sie die Tests aus:

$ Nasentests

Schreiben Sie Tests – Tests sind gut!

Außerdem empfiehlt es sich, die Tests für alle unterstützten Plattformen und für PEP 8-Konformität durchzuführen
Code. Sie können dies tun, indem Sie tox ausführen:

$ tox

Dokument!
Die Dokumentation befindet sich in docs /. Wir gebrauchen Sphinx.

So erstellen Sie die Dokumente in HTML:

$ cd-Dokumente
$ HTML erstellen

Schreiben Sie Dokumente – Dokumente sind gut! Sogar dieses Dokument!

Beitrag
Beiträge sind willkommen und werden sehr geschätzt. Jeder kleine Beitrag trägt dazu bei, Hy noch besser zu machen
genial.

Pull-Requests sind großartig! Wir lieben sie; Hier ist eine Kurzanleitung:

· Forken Sie das Repo und erstellen Sie einen Themenzweig für ein Feature/Fix. Vermeiden Sie direkte Änderungen
auf dem Hauptzweig.

· Alle eingehenden Features sollten von Tests begleitet sein.

· Bevor Sie eine PR einreichen, führen Sie bitte die Tests durch und überprüfen Sie Ihren Code anhand des Stils
Führung. Sie können beide Dinge gleichzeitig tun:

$ mache d

· Machen Sie Commits zu logischen Einheiten, damit Sie sie später einfacher verfolgen und navigieren können. Vor
Wenn Sie eine PR einreichen, versuchen Sie, die Commits in Changesets zusammenzufassen, auf die Sie leicht zurückgreifen können
später. Stellen Sie außerdem sicher, dass Sie in den Änderungssätzen keine falschen Leerzeichen hinterlassen. Das
vermeidet die spätere Erstellung von Whitespace-Fix-Commits.

· Was Commit-Nachrichten betrifft, versuchen Sie, Folgendes einzuhalten:

· Versuchen Sie, die Begrenzung auf 50 Zeichen für die erste Zeile von Git-Commit-Nachrichten einzuhalten.

· Für weitere Details/Erklärungen fügen Sie eine Leerzeile ein und fahren Sie fort
den Commit im Detail beschreiben.

· Fügen Sie sich schließlich selbst zur AUTHORS-Datei hinzu (als separates Commit): Sie haben es verdient :)

· Alle eingehenden Änderungen müssen von zwei verschiedenen Mitgliedern des Hylang-Kernteams bestätigt werden.
Eine zusätzliche Überprüfung ist natürlich willkommen, wir benötigen jedoch mindestens zwei Freigaben für jede
zu navigieren.

· Wenn ein Kernmitglied eine PR einsendet, suchen Sie bitte nach zwei Kernmitgliedern, die diese nicht enthalten
PR-Einreicher. Die Idee dabei ist, dass man mit dem PR-Autor zusammenarbeiten kann und ein zweiter acks
das gesamte Änderungsset.

· Für die Dokumentation und andere triviale Änderungen können wir sie gerne nach einer ACK zusammenführen. Wir haben
geringe Abdeckung, daher wäre es großartig, diese Barriere niedrig zu halten.

Kernbereich Team
Das Kernentwicklungsteam von Hy besteht aus folgenden Entwicklern:

· Julien Danjou

· Morten Linderud

· J Kenneth King

· Gergely Nagy

· Tuukka Turto

· Karen Rustad

· Abhishek L

· Friedrich Allan Webber

· Konrad Hinsen

· WERDEN SIE AUS MEINEM SCHUH HERAUSGUCKEN? Kahn-Greene

· Alexander Tagliamonte

· Nicolas Dandrimont

· Bobs Tolbert

· Berker Peksag

· Clinton N. Dreisbach

· er semaj

Nutzen Sie hy online über die Dienste von onworks.net


Kostenlose Server & Workstations

Laden Sie Windows- und Linux-Apps herunter

Linux-Befehle

Ad