Dies ist der Artikel zum 7. Tag von iRidge Adventskalender.
Dieser Artikel stellt Hy vor, einen in Python implementierten Lisp-Dialekt.
Ich bin tanaka.lisp, ein serverseitiger Ingenieur von Iridge Co., Ltd. Ich möchte die Welt des Webs und von Python sehen und arbeite für die Python-Firma Iridge.
Plötzlich ist die Sprache, die ich so sehr liebe, Common Lisp. In meinem Geschäft lese und schreibe ich ausschließlich Python, aber da Python nicht Lisp ist, bin ich der automatischen Einrückung und "if pred1 und pred2: ..." bis "if (und pred1 pred2): ... ausgeliefert. Ich kämpfe ständig darum, zu schreiben. Entzugssymptome, die Lisper eigen sind, können auftreten. Ich begann über S-Ausdrücke nachzudenken, googelte mit "Hyperspec Funktionsname
" und begann, S-Ausdrücke in Emacs einzugeben. Am Ende ist es eine mysteriöse Idee, dass __Python zu Lisp wird, was mir während der Geschäftszeiten über den Kopf geht.
Oh, wenn Python ein S-Ausdruck wäre. Wenn Sie einen S-Ausdruck schreiben könnten, während Sie auf der riesigen Standardbibliotheksgruppe von Python wie Where's Language fahren. Oh, oh.
Aber da ist. So eine verträumte, coole Sprache.
Hy
Hy ist ein in Python geschriebener Lisp-Dialekt.
Es hat eine Syntax, die stark von Clojure beeinflusst wird. Wenn Sie sich im Hy Style Guide verlaufen, lautet die Reihenfolge "Python> Clojure> Common Lisp". Folgen Sie also den Gepflogenheiten dieser Sprache.
Darüber hinaus ist es möglich, mit Python wie Clojure zu interagieren, und es scheint, dass Django-App in Hy geschrieben werden kann. Oh, ist das nicht gut für Hy? ??
Übrigens Haskell ist berühmt als Tintenfischsprache, aber Hys Maskottchen scheint Tintenfisch zu sein. Du bist Tintenfisch. Die Dokumentation Drei-Minuten-Tutorial ist die interessanteste und ich empfehle Ihnen, sie zu lesen. Ich war damit umgehauen.
Lassen Sie es uns installieren. Installieren Sie es hier in der virtualenv-Umgebung [^ 1].
[^ 1]: Übrigens scheint es im apt-Repository von Ubuntu unter dem Namen "python-hy" registriert zu sein.
Erstellen Sie zunächst eine venv-Umgebung.
$ virtualenv venv
# ...Viel Ausgabe
$ cd venv
$ source ./venv/bin/activate
Dann vom Github mit Pip installieren.
(venv) $ pip install git+https://github.com/hylang/hy.git
# ...Viel Ausgabe
Hallo, um die REPL zu starten ist nach.
(venv) $ hy
hy 0.11.0+320.g5b87932 using CPython(default) 2.7.12 on Linux
=> (print "Hy!")
Hy!
=>
Es ist einfach, oder?
Mal sehen, was für eine Sprache es ist.
;;;Numerischer Wert und Wahrheitswert
=> 42
42L
=> False
False
;;;String
=> "forty two"
u'forty two'
Erstens kann die Datenstruktur, die in Python verwendet werden kann, fast so verwendet werden, wie sie ist. Es scheint jedoch, dass das Schreiben von "," oder ":" oder "Begrenzung" verboten ist.
;;;aufführen. `,`Schreibe nicht
=> ["life" "universe" "everything"]
[u'life', u'universe', u'everything']
;;;Wörterbuch.Dies erfordert auch keine Abgrenzung
=> {"arthor" "dent" "ford" "prefect"}
{u'arthor': u'dent', u'ford': u'prefect'}
Und hier sind die Datentypen, die Lisp eigen sind. Es fühlt sich seltsam an, dass die Symbolanzeige eine Unicode-Zeichenfolge ist.
;;;Symbol.Die Anzeige ist eine Zeichenfolge, aber der Typ ist ein richtiges Symbol
=> 'marvin
u'marvin'
=> (type 'marvin)
<class 'hy.models.symbol.HySymbol'>
;;Stichwort
=> :deep-thought
u'\ufdd0:deep-thought'
;;Symbole, die anderen immer ungleich sind
=> (gensym)
u':G_1236'
Und wie, es gibt kein Null! Ah, Gott, wie schreibe ich eine leere Liste?
;;;nein null!
=> nil
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'nil' is not defined
Gott "Du solltest ()
! "
Ich "Ich verstehe!"
=> ()
[]
Tatsächlich scheint es, dass sogar Lisps traditionelle Listennotation ** manchmal zu einer Python-Liste ** wird.
=> '(a b c)
(u'a' u'b' u'c')
=> (cons 'googolplex (cons 'star (cons 'thinker ())))
[u'googolplex', u'star', u'thinker']
Und Nachteile. Es scheint, dass Lisps Vater John McCarthy es Corns aussprach.
=> (cons 'arther 'dent)
(u'arther' . u'dent')
;;;Es ist in Ordnung, in Punktpaaren und Zitaten zu schreiben
=> '(arther . dent)
(u'arther' . u'dent')
Da Hy eine Lisp-Sprache ist, werden Funktionsaufrufe in polnischer Notation geschrieben.
;;;String-Verkettung
=> (+ "forty" " " "two")
u'forty two'
;;;Vier Regeln
=> (+ 1 (* 5 8) 1)
42L
Die Funktionsdefinition sieht wie folgt aus: Clojure. Es ist das übliche Gefühl, wenn ich einfach "defun" tippe und verwirrt bin.
=> (defn factorial [n]
... (if (<= n 0)
... 1
... (* n (factorial (- n 1)))))
=> (factorial 10)
3628800L
Die Liste ist übrigens die zuckerbeschichtete Syntax von Cons. Der Lisp-Code wird in eine Liste geschrieben. Sie sollten also in der Lage sein, den Code in Nachteile zu schreiben. Selbst wenn Sie in Common Lisp ein Programm mit Punktpaaren schreiben, wird es richtig gelesen, aber ...
=> (print . ("forty" . ("two" . ())))
forty two
Oh! Ich werde es tun! Dies ebnete den Weg für die Verschleierung.
Versuchen Sie als Beispiel für die Verwendung der umfangreichen Standardbibliothek von Python Beispiele für die Kommunikation mit httplib mit Hy.
;;;importieren.von kann auch importiert werden
=> (import httplib)
=> (setv conn (httplib.HTTPSConnection "www.python.org"))
=> (conn.request "GET" "/")
=> (setv res (conn.getresponse))
=> (print res.status res.reason)
200 OK
Lesen Sie es einfach als S-Formel und fertig. Dies ist Ihre Chance, ein in Python geschriebenes Skript nach Hy zu verschieben.
Stellen Sie jetzt sicher, dass Hy nicht nur mit Python vertraut ist, sondern auch ein Lisp-Begleiter. Für diejenigen, die nicht Lisper sind, sind Makros hier keine C-Makros, sondern diejenigen, die abstrakte Syntaxbäume manipulieren. Rust, Nim, Scala usw. haben diese Funktion. Übrigens hat Hy [bereits ein anaphorisches Makro] als Contributor-Modul (http://docs.hylang.org/en/latest/contrib/anaphoric.html).
Zum Beispiel dachte ich vorerst, dass anaphorische Makros angemessen sind, weil die Vorteile leicht zu verstehen sind. Mit einem anaphorischen Makro können Sie beispielsweise auf den Wert des Ausdrucks im bedingten Teil der if-Anweisung von hinten verweisen. Weitere Informationen finden Sie unter [Entsprechendes Kapitel von On Lisp](http: //www.asahi-net). Bitte lesen Sie auch or.jp/~kc7k-nd/onlispjhtml/anaphoricMacros.html).
Vorerst werde ich es implementieren, indem ich es aus On Lisp kopiere und versuche, es zu verwenden.
=> (defmacro aif [test-form then-form &optional else-form]
... `(let [it ~test-form]
... (if it ~then-form ,else-form)))
=> (aif (+ 1 2)
... (print 'cheese it it))
cheese 3 3
Sie können mit "it" auf das Bewertungsergebnis des bedingten Ausdrucks des if-Ausdrucks (hier "aif") verweisen. Mal sehen, wie der Ausdruck konvertiert wird
;;;Die Ausgabe ist für eine einfache Anzeige handformatiert
=> (macroexpand '(aif (+ 1 2)
... (print 'cheese it it)))
((u'fn' [](u'setv' u'it' (u'+' 1L 2L))
(u'if' u'it'
(u'print' (u'quote' u'cheese') u'it' u'it')
u',else_form')))
Das Symbol wird als Unicode-Zeichenfolge angezeigt, was umständlich ist, aber gut aussieht.
Was mich darüber glücklich macht
Das ist ein schöner Punkt.
Betrachten Sie als Beispiel den Fall, in dem ein bedingter Ausdruck ein Ausdruck ist, der viel Zeit in Anspruch nimmt.
=> (reduce (fn [a b](+ a b)) (range 1 1000000000))
499999999500000000
Ich habe vorerst versucht, diese Formel zu treffen ** REPL schwieg ungefähr eine Minute lang: schluchzen: **. Wenn Sie dieses Ergebnis mehrmals verwenden möchten
(aif (reduce (fn [a b](+ a b)) (range 1 1000000000))
(print (+ it it))
Diese Dimension kann mehrere Berechnungen vermeiden. Es ist eine Geschichte, die Sie einer lokalen Variablen zuweisen sollten. Wenn Sie jedoch ein anaphorisches Makro schreiben, erfolgt die Erstellung und Zuweisung der lokalen Variablen automatisch hinter den Kulissen.
Schließlich. Sie können Hy-Code in Python-Code konvertieren. Auf diese Weise können Sie die Gefahr von Hy beseitigen, die REPL ~ ~ bei der Entwicklung birgt, in Hy schreiben und beim Festschreiben ~ ~ in Python konvertieren.
Wenn Sie es versuchen, wird der Aufwand für das eigentliche Parsen verringert, oder es tritt keine Verzögerung auf, bis das Ergebnis zurückgegeben wird.
(venv) $ cat upto.hy
(defn up-to-n [n]
(list-comp n (n (range n)) (= (% n 2) 0)))
(print (up-to-n (integer (raw-input "input number: "))))
# upto.Konvertieren Sie hy
(venv) $ hy2py upto.hy > upto.py
#Konvertierungsergebnis
(venv) $ cat upto.py
from hy.core.language import integer, range
def up_to_n(n):
return [n for n in range(n) if ((n % 2L) == 0L)]
print(up_to_n(integer(raw_input(u'input number: '))))
(venv) $ python upto.py
input number: 10
[0, 2, 4, 6, 8]
Einführung des in Python geschriebenen Lisp-Dialekts Hy.
pip
einfachEs ist ein Eindruck, den ich berührt und geschrieben habe, dass es eine ziemlich gut gemachte Sprache ist.
Dieser Artikel sollte ursprünglich vor einem Jahr veröffentlicht werden [^ 2]. Als ich jedoch die Welt von Python kennenlernte und sie dann berührte, konnte ich den Hintergrund erraten, wie Hy gemacht wurde. Es kann sein, dass jetzt der richtige Zeitpunkt ist, sich an Python zu gewöhnen.
[^ 2]: Ich habe darüber nachgedacht, es im internen LT anzukündigen, aber es scheint schwierig, dies in diesem Artikel LT zu tun ...
Ich denke, Hy selbst ist eine ziemlich gute Sprache, daher erwägen Lisper-Brüder, die in der Python-Branche tätig sind, sie einzuführen, wenn sie sagen: "Ich muss Python verwenden, aber die Syntax ist nicht im S-Stil." Wie wäre es, es zu versuchen?
Recommended Posts