Cooles Lisp geschrieben in Python: Hy

Dies ist der Artikel zum 7. Tag von iRidge Adventskalender.

Dieser Artikel stellt Hy vor, einen in Python implementierten Lisp-Dialekt.

Motivation

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.

Hy Installation

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?

Hy Hitomi Tour

Mal sehen, was für eine Sprache es ist.

Grundlegende Syntax

Datenstruktur

;;;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')

Funktion

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.

Greifen Sie auf Python-Funktionen zu

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.

Makro

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.

Greifen Sie von Hy auf Python zu

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]

Zusammenfassung

Einführung des in Python geschriebenen Lisp-Dialekts Hy.

Es 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

Cooles Lisp geschrieben in Python: Hy
Gacha geschrieben in Python -BOX Gacha-
Kompatibilitätsdiagnoseprogramm in Python geschrieben
Einfache Gacha-Logik in Python geschrieben
In Python geschriebener Fourier-Serien-Verifizierungscode
Stresstest mit Locust in Python geschrieben
Übergangswahrscheinlichkeit der in Python geschriebenen Markov-Kette
Quadtree in Python --2
Python in der Optimierung
CURL in Python
Metaprogrammierung mit Python
Python 3.3 mit Anaconda
Geokodierung in Python
SendKeys in Python
Metaanalyse in Python
Unittest in Python
Epoche in Python
Zwietracht in Python
Deutsch in Python
DCI in Python
Quicksort in Python
nCr in Python
N-Gramm in Python
Programmieren mit Python
Plink in Python
Konstante in Python
FizzBuzz in Python
SQLite in Python
Schritt AIC in Python
LINE-Bot [0] in Python
CSV in Python
Reverse Assembler mit Python
Reflexion in Python
Konstante in Python
nCr in Python.
Format in Python
Scons in Python 3
Puyopuyo in Python
Python in Virtualenv
PPAP in Python
Quad-Tree in Python
Reflexion in Python
Chemie mit Python
Hashbar in Python
DirectLiNGAM in Python
LiNGAM in Python
In Python reduzieren
In Python flach drücken
Einführung in die Überprüfung der Wirksamkeit Kapitel 3 in Python geschrieben
Einführung in die Überprüfung der Wirksamkeit Kapitel 2 in Python geschrieben
Sortierte Liste in Python
Täglicher AtCoder # 36 mit Python
AtCoder # 2 jeden Tag mit Python
Täglicher AtCoder # 32 in Python
Täglicher AtCoder # 18 in Python
Bearbeiten Sie Schriftarten in Python
Singleton-Muster in Python
Dateioperationen in Python