EnglezăFrancezăSpaniolă

Ad


Favicon OnWorks

hy - Online în cloud

Rulați hy în furnizorul de găzduire gratuit OnWorks prin Ubuntu Online, Fedora Online, emulator online Windows sau emulator online MAC OS

Aceasta este comanda hy care poate fi rulată în furnizorul de găzduire gratuit OnWorks folosind una dintre multiplele noastre stații de lucru online gratuite, cum ar fi Ubuntu Online, Fedora Online, emulator online Windows sau emulator online MAC OS

PROGRAM:

NUME


hy - hy Documentație [imagine: Hy] [image]

Încerca Hy https://try-hy.appspot.com

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

Sursă https://github.com/hylang/hy

Listă hylang-discută

IRC #hy pe Freenode

Construi Starea
Travis CI.NEINDENT

Hy este un dialect minunat al Lisp care este încorporat în Python.

Deoarece Hy își transformă codul Lisp în Arborele de sintaxă abstractă Python, aveți
întreaga lume frumoasă a lui Python la îndemâna ta, în formă de Lisp!

Cuprins:

PORNIRE RAPIDĂ


[imagine: Grăgălațiile lui Karen Rustard] [imagine]

(Mulțumesc lui Karen Rustad pentru Cuddles!)

CUM LA GET HY REAL FAST:

1. Creeaza o Virtual Piton Mediu inconjurator.

2. Activați mediul virtual Python.

3. Instala hy din PyPI cu țâfnă instala hy.

4. Începeți un REPL cu hy.

5. Introduceți lucruri în REPL:

=> (tipărește „Hy!”)
Hy!
=> (defn salutationsnm [nume] (tipărit (+ „Nume „Hy „!”)))
=> (salutationsnm „Numele tău”)
Bună numele tău!

etc

6. Apăsați CTRL-D când ați terminat.

OMG! asta- uimitor! I vrea la scrie a Hy programul.

7. Deschideți un editor de programare de elită și tastați:

(printați „Voiam să codific în sintaxa Python, dar apoi am primit Hy.”)

8. Salvați ca minunat.hy.

9. Și rulați primul program Hy:

hy minunat.hy

10.
Respirați adânc pentru a nu hiperventila.

11.
Zâmbește răutăcios și furișează-te în casa ta și fă lucruri de nespus.

TUTORIAL


Bun venit la tutorialul Hy!

Pe scurt, Hy este un dialect Lisp, dar unul care își convertește structura în Python...
literalmente o conversie în arborele de sintaxă abstractă al lui Python! (Sau pentru a o pune în mai brut
termeni, Hy este lisp-stick pe un Python!)

Acest lucru este destul de grozav pentru că înseamnă că Hy este mai multe lucruri:

· Un Lisp care se simte foarte Pythonic

· Pentru Lispers, o modalitate grozavă de a folosi puterile nebunești ale lui Lisp, dar în lumea largă a lui Python
biblioteci (de ce da, acum puteți scrie o aplicație Django în Lisp!)

· Pentru Pythonisti, o modalitate excelentă de a începe să explorezi Lisp, din confortul lui Python!

· Pentru toată lumea: un limbaj plăcut, care are o mulțime de idei îngrijite!

pachet de bază introducere la Foșnet pentru Pythonisti
Bine, poate că nu ai mai folosit niciodată Lisp, dar ai folosit Python!

Un program „hello world” în Hy este de fapt super simplu. Hai sa incercam:

(tipărește „bună lume”)

Vedea? Uşor! După cum probabil ați ghicit, aceasta este aceeași cu versiunea Python a:

tipăriți „bună lume”

Pentru a adăuga niște matematici super simple, am putea face:

(+ 1 3)

Care ar returna 4 și ar fi echivalentul cu:

1 + 3

Ceea ce veți observa este că primul element din listă este funcția apelată și
restul argumentelor sunt argumentele transmise. De fapt, în Hy (ca și în cazul celor mai multe
Lisps) putem transmite mai multe argumente operatorului plus:

(+ 1 3 55)

Care ar returna 59.

Poate ai mai auzit de Lisp, dar nu știi prea multe despre el. Lisp nu este la fel de dur ca tine
s-ar putea gândi, iar Hy moștenește de la Python, așa că Hy este o modalitate excelentă de a începe să învețe Lisp.
Principalul lucru care este evident despre Lisp este că există o mulțime de paranteze. Asta ar putea
pare confuz la început, dar nu este atât de greu. Să ne uităm la o matematică simplă
înfășurat într-o grămadă de paranteze pe care le-am putea introduce în interpretul Hy:

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

Aceasta ar reveni 38. Dar de ce? Ei bine, am putea privi expresia echivalentă în
piton:

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

Dacă ar fi să încerci să-ți dai seama cum ar funcționa cele de mai sus în python, bineînțeles ai face-o
aflați rezultatele rezolvând fiecare paranteză interioară. Aceasta este aceeași idee de bază în
Hy. Să încercăm mai întâi acest exercițiu în Python:

rezultat = ((1 + 3 + 88) / 2) - 8
# simplificat în...
rezultat = (92 / 2) - 8
# simplificat în...
rezultat = 46 - 8
# simplificat în...
rezultat = 38

Acum să încercăm același lucru în Hy:

(rezultat setv (- (/ (+ 1 3 88) 2) 8))
; simplificat la...
(rezultat setv (- (/ 92 2) 8))
; simplificat la...
(rezultat setv (- 46 8))
; simplificat la...
(rezultat setv 38)

După cum probabil ați ghicit, această ultimă expresie cu setv înseamnă a atribui variabila
„rezultat” la 38.

Vedea? Nu prea greu!

Aceasta este premisa de bază a Lisp. Lisp înseamnă „procesarea listei”; aceasta înseamnă că
structura programului este de fapt liste de liste. (Dacă sunteți familiarizat cu Python
liste, imaginați-vă întreaga structură ca mai sus, dar cu paranteze pătrate în schimb, oricare
veți putea vedea structura de mai sus atât ca program, cât și ca structură de date.) Aceasta este
mai ușor de înțeles cu mai multe exemple, așa că haideți să scriem un program Python simplu, să-l testăm,
și apoi arată programul Hy echivalent:

def simple_conversation():
print "Bună ziua! Aș dori să te cunosc. Povestește-mi despre tine!"
name = raw_input ("Care este numele tău?")
age = raw_input("Ce vârstă ai?")
tipăriți „Bună ziua „ + nume + „! Văd că aveți „ + vârstă + „ ani.”

simple_conversation()

Dacă am rula acest program, ar putea merge astfel:

Salut! Mi-ar placea sa te cunosc. Spune-mi despre tine!
Cum te numești? Gary
Ce vârstă ai? 38
Salut Gary! Văd că ai 38 de ani.

Acum să ne uităm la programul Hy echivalent:

(defn simplă-conversație []
(tipărește „Bună ziua! Aș dori să te cunosc. Povestește-mi despre tine!”)
(numele setv (intrare brută „Care este numele tău?”))
(setv age (intrare brută „Care ai vârsta ta?”))
(tipărește (+ „Bună „nume „! Văd că ești”
vârsta „ani.”)))

(simplu-conversatie)

Dacă vă uitați la programul de mai sus, atâta timp cât vă amintiți că primul element din fiecare
lista programului este funcția (sau macro-ul... vom ajunge la acestea mai târziu) care este apelată
și că restul sunt argumentele, este destul de ușor să-ți dai seama ce înseamnă toate acestea.
(După cum probabil ați ghicit și dvs., defn este metoda Hy de definire a metodelor.)

Totuși, mulți oameni consideră acest lucru confuz la început, deoarece există atât de multe paranteze,
dar există o mulțime de lucruri care pot ajuta să ușureze acest lucru: păstrați indentarea plăcută și
utilizați un editor cu potrivire între paranteze (acest lucru vă va ajuta să aflați ce anume
paranteza se face pereche cu) și lucrurile vor începe să se simtă confortabil.

Există câteva avantaje în a avea o structură de cod care este de fapt o dată foarte simplă
structura pe care se bazează nucleul Lisp. În primul rând, înseamnă că programele tale sunt
ușor de analizat și că întreaga structură reală a programului este foarte clar expusă
pentru tine. (Există un pas suplimentar în hy în care structura pe care o vedeți este convertită în cea a lui Python
propriile reprezentări... în Lisps „mai pur” precum Common Lisp sau Emacs Lisp, datele
structura pe care o vedeți în cod și structura de date care este executată este mult mai mult
literalmente aproape.)

O altă implicație a acestui lucru este macrocomenzile: dacă structura unui program este o simplă date
structură, asta înseamnă că poți scrie cod care poate scrie cod foarte ușor, adică
implementarea caracteristicilor de limbă complet noi poate fi foarte rapidă. Înainte de Hy, asta nu era
foarte posibil pentru programatorii Python... acum și tu poți folosi macrocomenzile incredibile
putere (ai grijă să nu-i îndrepti spre picioare)!

Hy is a Aromă de lisp Piton
Hy se convertește la propriul arbore de sintaxă abstractă al lui Python, așa că în curând vei începe să descoperi că toate
puterea familiară a pitonului este la îndemâna ta.

Aveți acces complet la tipurile de date Python și la biblioteca standard în Hy. Să experimentăm
cu asta în interpretul hy:

=> [1 2 3]
[1, 2, 3]
=> {"câine" "latră"
... „pisica” „miau”}
...
{„câine”: „latră”, „pisica”: „miau”}
=> (, 1 2 3)
(1, 2, 3)

Dacă ești familiarizat cu alți Lisps, s-ar putea să fii interesat de faptul că Hy acceptă Commonul
Metoda Lisp de a cita:

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

De asemenea, aveți acces la metodele frumoase ale tuturor tipurilor încorporate:

=> (.strip " fooooo ")
"fooooo"

Ce este asta? Da, într-adevăr, acesta este exact același cu:

„fooooo“.strip()

Așa este --- Lisp cu notație punct! Dacă avem acest șir atribuit ca variabilă, noi
mai poate face următoarele:

(setv acest șir „fooooo”)
(this-string.strip)

Dar condiționalele?:

(dacă (încearcă-ceva)
(tipăriți „acest lucru este adevărat”)
(tipăriți „acest lucru este fals”)

După cum puteți spune mai sus, primul argument pentru if este un test de adevăr, al doilea argument este
corpul dacă este adevărat, iar al treilea argument (opțional!) este fals (adică. altfel).

Dacă trebuie să faci condiționale mai complexe, vei descoperi că nu ai Elif
disponibil în Hy. În schimb, ar trebui să folosești ceva numit Cond. În Python, s-ar putea să faci
ceva asemănător cu:

somevar = 33
dacă cevavar > 50:
print "Acea variabilă este prea mare!"
elif somevar < 10:
print "Acea variabilă este prea mică!"
altceva:
print "Acea variabilă este corectă!"

În Hy, ai face:

(cond
[(> oarecare 50)
(tipăriți „Acea variabilă este prea mare!”)]
[(< somevar 10)
(tipăriți „Acea variabilă este prea mică!”)]
[Adevărat
(tipăriți „Acea variabilă este corectă!”)])

Ceea ce vei observa este că Cond se oprește între o instrucțiune some care este executată și
verificat condiționat pentru adevărat sau falsitate și apoi un pic de cod de executat dacă se întoarce
să fie adevărat. Veți observa, de asemenea, că altfel este implementat la sfârșit pur și simplu de
verificarea pentru adevărat -- asta-i pentru că adevărat va fi întotdeauna adevărat, așa că dacă ajungem până aici, vom ajunge
rulează-l mereu!

S-ar putea să observați că mai sus dacă aveți cod precum:

(dacă există vreo condiție
(corp-dacă-adevărat)
(corp-dacă-fals))

Dar asteapta! Ce se întâmplă dacă doriți să executați mai multe instrucțiuni în corpul uneia dintre
aceste?

Puteți face următoarele:

(dacă (încearcă-ceva)
(de
(tipăriți „acest lucru este adevărat”)
(printați „și de ce nu, să vorbim în continuare despre cât de adevărat este!))
(tipăriți „acesta este încă pur și simplu fals”))

Puteți vedea că am folosit do pentru a încheia mai multe declarații. Dacă ești familiarizat cu altele
Lisps, acesta este echivalentul progn în altă parte.

Comentariile încep cu punct și virgulă:

(tipărește „aceasta va rula”)
; (tipărește „dar asta nu”)
(+ 1 2 3); vom executa adăugarea, dar nu acest comentariu!

Loopingul nu este greu, dar are un fel de structură specială. În Python, am putea face:

pentru eu in gamă(10):
print „„i” este acum la „ + str(i)

Echivalentul în Hy ar fi:

(pentru [i (interval 10)]
(tipărește (+ „„i” este acum la „ (str i))))

De asemenea, puteți importa și utiliza diverse biblioteci Python. De exemplu:

(import OS)

(dacă (os.path.isdir "/tmp/somedir")
(os.mkdir "/tmp/somedir/anotherdir")
(tipăriți „Hei, calea aia nu este acolo!”))

Managerii de context Python (cu declarații) sunt folosite astfel:

(cu [[f (deschideți „/tmp/data.in”)]]
(tipărește (.citește f)))

care este echivalent cu:

cu open("/tmp/data.in") ca f:
print f.read()

Și da, avem liste de înțelegeri! În Python ați putea face:

odds_squared = [
pow(num, 2)
pentru num in gamă(100)
dacă num % 2 == 1]

În Hy, ai putea face acestea precum:

(setv cote pătrate
(lista-comp
(pow nr 2)
(număr (interval 100))
(= (% num 2) 1)))

; Și, un exemplu furat fără rușine dintr-o pagină Clojure:
; Să enumerăm toate blocurile unei table de șah:

(lista-comp
(, X y)
(x (interval 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 are suport pentru diverse argumente fanteziste și argumente cheie. În Python am putea
vedea:

>>> def optional_arg(pos1, pos2, keyword1=None, keyword2=42):
... return [pos1, pos2, keyword1, keyword2]
...
>>> optional_arg(1, 2)
[1, 2, Niciunul, 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]

Același lucru în Hy:

=> (defn optional-arg [pos1 pos2 &optional keyword1 [keyword2 42]]
... [pos1 pos2 cuvânt cheie1 cuvânt cheie2])
=> (opțional-arg 1 2)
[1 2 Nici unul 42]
=> (opțional-arg 1 2 3 4)
[1 2 3 4]

Dacă rulați o versiune de Hy trecută de 0.10.1 (de exemplu, git master), există și o nouă
sintaxa argumentului cuvântului cheie:

=> (optional-arg :keyword1 1
... :pos2 2
... :pos1 3
... :cuvânt cheie2 4)
[3, 2, 1, 4]

În caz contrar, puteți utiliza întotdeauna aplica. Dar ce este aplica?

Ești familiarizat cu trecerea *args și ** kwargs în Python?:

>>> args = [1 2]
>>> kwargs = {"keyword2": 3
... „cuvânt cheie1”: 4}
>>> optional_arg(*args, **kwargs)

Putem reproduce asta cu aplica:

=> (setv args [1 2])
=> (setv kwargs {"keyword2" 3
... „cuvânt cheie1” 4})
=> (aplica opțional-arg args kwargs)
[1, 2, 4, 3]

Există, de asemenea, o construcție a argumentelor de cuvinte cheie în stil dicționar care arată astfel:

(defn alt stil [&key {"key1" "val1" "key2" "val2"}]
[tasta 1 tasta 2])

Diferența aici este că, deoarece este un dicționar, nu te poți baza pe niciun anume
ordonand la argumente.

Hy sprijină, de asemenea *args și ** kwargs. În Python:

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

Echivalentul Hy:

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

În sfârșit, bineînțeles că avem nevoie de cursuri! În Python, am putea avea o clasă ca:

clasa FooBar(obiect):
"" "
Un alt exemplu de clasă
"" "
def __init__(self, x):
sine.x = x

def get_x(self):
"" "
Returnează copia noastră a lui x
"" "
return self.x

În Hy:

(defclass FooBar [obiect]
„Încă un exemplu de clasă”
[[--init--
(fn [self x]
(setv self.xx)
; Momentan necesar pentru --init-- deoarece __init__ nu are nevoie
; Sper ca asta va disparea :)
Nici unul)]

[obține-x
(fn [auto]
„Returnați copia noastră de x”
self.x)]])

De asemenea, puteți face atribute la nivel de clasă. În Python:

clasă Client (modele.Model):
nume = modele.CharField(max_length=255)
adresa = modele.TextField()
note = modele.TextField()

În Hy:

(defclass Client [modele.Model]
[[nume (models.CharField:max-length 255})]
[adresă (modele.TextField)]
[note (modele.TextField)]])

Hy <-> Piton interop
Importând Hy, puteți folosi Hy direct din Python!

Dacă salvați următoarele în salutări.hy:

(defn salut [nume] (tipărește „bună ziua de la hy,” nume))

Apoi îl puteți folosi direct din python, importând hy înainte de a importa modulul. În
Piton:

import hy
import salutări

greetings.greet("Foo")

Puteți, de asemenea, să declarați o funcție în python (sau chiar o clasă!) și să o utilizați în Hy!

Dacă salvați următoarele în salutări.py în Python:

def salut(nume):
print("bună ziua, %s" % (nume))

Îl poți folosi în Hy:

(import salutări)
(.salut salutari "foo")

Pentru a utiliza argumente ale cuvintelor cheie, puteți utiliza in salutări.py:

def greet(nume, titlu="Domnule"):
print(„Salut, %s %s” % (titlu,nume))

(import salutări)
(. salutări „Foo”)
(. salutări „Foo” „Darth”)
(aplicați (. salutări, salut) ["Foo"] {"titlu" "Lord"})

Care ar scoate:

Salutări, Sir Foo

Salutări, Darth Foo

Salutări, Lord Foo

Sfaturi!
Hy prezintă, de asemenea, ceva cunoscut sub numele de „macro de threading”, o caracteristică foarte bună a
ale lui Clojure. „Macronologia de threading” (scrisă ca ->) este folosit pentru a evita cuibărirea adâncă a
expresii.

Macrocomanda de threading inserează fiecare expresie în primul argument al expresiei următoare
loc.

Să luăm clasicul:

(buclă (tipărire (evaluare (citire))))

În loc să o scriem așa, o putem scrie după cum urmează:

(-> (citește) (eval) (tipărește) (buclă))

Acum, folosind python-sh, putem arăta cum macrocomanda de threading (din cauza configurării lui python-sh)
poate fi folosit ca o țeavă:

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

Care, desigur, se extinde la:

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

Mult mai lizibil, nu? Utilizați macrocomanda de threading!

HY STYLE GHID


„Știi, domnule ministru, nu sunt de acord cu Dumbledore din multe puncte de vedere... dar nu poți nega că este
am primit stil...” – Phineas Nigellus Black, Harry Olar și il comandă of il Fenix

Ghidul de stil Hy intenționează să fie un set de reguli de bază pentru Hyve (da, comunitatea Hy
se mândrește că atașează Hy la orice) să scrie cod idiomatic Hy. Hy derivă mult
de la Clojure & Common Lisp, menținând întotdeauna interoperabilitatea Python.

Preludiu
Tao of Hy
Ummon l-a întrebat pe călugărul șef: „Despre ce sutra predai?”
„Sutra Nirvana”.
„Sutra Nirvana are cele Patru Virtuți, nu-i așa?”
"Are."
Ummon întrebă, luând o ceașcă: — Câte virtuți are asta?
— Deloc, spuse călugărul.
„Dar oamenii din vechime au spus că a fost, nu-i așa? spuse Ummon.
— Ce părere ai despre ce au spus ei?
Ummon a lovit ceașca și a întrebat: — Înțelegi?
— Nu, spuse călugărul.
„Atunci”, a spus Ummon, „mai bine ai continua cu prelegerile tale despre sutra”.
— macroul (koan).

Următoarele ilustrează o listă scurtă a deciziilor de proiectare care au fost luate în considerare
Hy.

· Arată ca un Lisp; DTRT cu el (de exemplu, liniuțele se transformă în caractere de subliniere, căștile pentru urechi se transformă în
cu majuscule).

· Suntem încă Python. Majoritatea elementelor interne se traduc 1:1 în elementele interne Python.

· Folosiți Unicode peste tot.

· Remediați deciziile proaste în Python 2 când putem (vezi adevărata_diviziune).

· Când aveți îndoieli, amânați-vă la Python.

· Dacă încă nu sunteți sigur, treceți la Clojure.

· Dacă sunteți și mai nesigur, treceți la Common Lisp.

· Ține minte că nu suntem Clojure. Nu suntem Common Lisp. Suntem Homoiconic Python, cu
biți în plus care au sens.

Aspect & zimțuire
· Evitați spațiile în urmă. Ei naibii!

· Indentarea trebuie să fie de 2 spații (fără file dure), cu excepția cazului în care se potrivește indentarea
linia anterioară.

;; Bun (și preferat)
(defn fib [n]
(dacă (<= n 2)
n
(+ (fib (- n 1)) (fib (- n 2)))))

;; Încă bine
(defn fib [n]
(dacă (<= n 2) n (+ (fib (- n 1)) (fib (- n 2)))))

;; Încă bine
(defn fib [n]
(dacă (<= n 2)
n
(+ (fib (- n 1)) (fib (- n 2)))))

;; Isteric ridicol
(defn fib [n]
(dacă (<= n 2)
n ;; da, îmi place să apese la întâmplare tasta spațiu
(+ (fib (- n 1)) (fib (- n 2)))))

· Parantezele trebuie nu să fie lăsați singuri, triști și singuri pe propria linie.

;; Bun (și preferat)
(defn fib [n]
(dacă (<= n 2)
n
(+ (fib (- n 1)) (fib (- n 2)))))

;; Isteric ridicol
(defn fib [n]
(dacă (<= n 2)
n
(+ (fib (- n 1)) (fib (- n 2)))
)
) ; GAH, ARDE-L CU FOC

· Aliniați vertical lăsa blocuri.

(lasă [[foo (bar)]
[qux (baz)]]
(foo qux))

· Comentariile inline vor fi la două spații de la sfârșitul codului; trebuie să aibă întotdeauna o
spațiu între caracterul de comentariu și începutul comentariului. De asemenea, încearcă să nu
comentează ceea ce este evident.

;; Bun
(setv ind (dec x)) ; indexarea începe de la 0

;; Conform stilului, dar doar afirmă ceea ce este evident
(setv ind (dec x)) ; setează indicele la x-1

;; Rău
(setv ind (dec x)); tastarea cuvintelor pentru distracție

Codificare Stil
· Ca convenție, încercați să nu utilizați Def pentru orice altceva decât variabile globale; utilizare setv
funcții din interior, bucle etc.

;; Bun (și preferat)
(def. *limită* 400000)

(defn fibs [ab]
(deși este adevărat
(randament a)
(setv (, ab) (, b (+ ab)))))

;; Rău (și nu este preferat)
(defn fibs [ab]
(deși este adevărat
(randament a)
(def (, ab) (, b (+ ab)))))

· Nu utilizați sintaxa expresiei s acolo unde este intenționată sintaxa vectorială. De exemplu, faptul
că primul dintre aceste două exemple funcționează doar pentru că compilatorul nu este excesiv
strict. În realitate, sintaxa corectă în locuri ca acesta este cea din urmă.

;; Rău (și rău)
(defn foo (x) (tipărește x))
(foo 1)

;; Bun (și preferat)
(defn foo [x] (tipărește x))
(foo 1)

· Folosiți macrocomenzile de filetare sau macrocomenzile de coadă de filetare atunci când întâlniți un imbricat adânc
expresii s. Cu toate acestea, fiți prudent când le utilizați. Folosiți-le când claritate și
se îmbunătățește lizibilitatea; nu construiți expresii complicate, greu de înțeles.

;; Preferat
(def. *nume*
(cu [f (deschideți „names.txt”)]
(-> (.citește f) (.strip) (.înlocuiește "\"" "") (.split ",") (sortat))))

;; Nu asa de bine
(def. *nume*
(cu [f (deschideți „names.txt”)]
(sortat (.split "," (.înlocuiește "\"" "" (.strip (.read f)))))))

;; Probabil că nu este o idee bună
(pătrat definit? [x]
(->> 2 (pow (int (sqrt x))) (= x)))

· Notația cu puncte în stil Clojure este preferată față de apelul direct al metodei obiectului,
deși ambele vor continua să fie susținute.

;; Bun
(cu [fd (deschidere "/ Etc / passwd")]
(printare (.readlines fd)))

;; Nu asa de bine
(cu [fd (deschidere "/ Etc / passwd")]
(printare (fd.readlines)))

Concluzie
„Modele se estompează, stilul este etern” – Yves Saint Laurent

Acest ghid este doar un set de reguli ale comunității și, evident, regulile comunității fac
nu are sens fără o comunitate activă. Contribuțiile sunt binevenite. Alăturați-vă nouă la #hy in
freenode, blog despre asta, tweet despre asta și, cel mai important, distrează-te cu Hy.

mulțumesc
· Acest ghid este puternic inspirat din @paultag postarea pe blog a lui Hy Supravieţuire Ghid

· Clojure Stil Ghid

DOCUMENTAȚIE INDEX


Cuprins:

Comandă Linie interfaţă
hy
Comandă Linie Opţiuni
-c
Executați codul Hy în comandă.

$ hy -c "(tipărește (+ 2 2))"
4

-i
Executați codul Hy în comandă, apoi rămâneți în REPL.

-m
Executați codul Hy în modul, inclusiv defmain dacă este definit.

-m flag termină lista de opțiuni astfel încât toate argumentele de după modul nume
sunt transmise la modulul în sys.argv.

Nou în versiunea 0.10.2.

--spion Imprimați codul Python echivalent înainte de executare. De exemplu:

=> (defn salutationsnm [nume] (tipărit (+ „Nume „Hy „!”)))
def salutationsnm(nume):
return print(((u'Hy ' + nume) + u'!'))
=> (salutationsnm „Numele tău”)
salutationsnm(u'Numele tău')
Bună numele tău!
=>

Nou în versiunea 0.9.11.

--show-tracebacks
Tipăriți urmăriri extinse pentru excepțiile Hy.

Nou în versiunea 0.9.12.

-v Tipăriți numărul versiunii Hy și ieșiți.

hyc
Comandă Linie Opţiuni
fişier[, fisierN]
Compilați codul Hy în codul de octeți Python. De exemplu, salvați următorul cod ca
hyname.hy:

(defn hy-hy [nume]
(Tipărește (+ „Nume „Hy” „!”)))

(hy-hy „afroman”)

Apoi rulați:

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

hy2py
Nou în versiunea 0.10.1.

Comandă Linie Opţiuni
-s

--cu-sursa
Afișați structura sursei analizată.

-a

--cu-ast
Afișați AST generat.

-np

--fără-python
Nu afișați codul Python generat din AST.

Hy ( limba)
AVERTISMENT:
Aceasta este incompletă; vă rugăm să luați în considerare contribuția la efortul de documentare.

Teorie of Hy
Hy menține, peste orice altceva, compatibilitatea 100% în ambele direcții cu Python
în sine. Toate codurile Hy urmează câteva reguli simple. Memorează asta, deoarece va intra
telefon.

Aceste reguli ajută la asigurarea faptului că codul Hy este idiomatic și interfațăbil în ambele limbi.

· Simbolurile din căștile pentru urechi vor fi traduse în versiunea cu majuscule a acelui șir. Pentru
exemplu, foo va deveni FOO.

· Entitățile UTF-8 vor fi codificate folosind punycode și prefixat cu hy_. De exemplu,
va deveni hy_w7h, va deveni hy_g6h, și eu ♥u va deveni hy_iu_t0x.

· Simbolurile care conțin liniuțe le vor înlocui cu liniuțe de subliniere. De exemplu,
șablon de randare va deveni șablon de randare. Aceasta înseamnă că simbolurile cu liniuțe vor
umbriți echivalentele lor subliniere și invers.

Încorporate
Hy prezintă o serie de forme speciale care sunt folosite pentru a ajuta la generarea corectă a Python AST.
Următoarele sunt forme „speciale”, care pot avea un comportament ușor neașteptat
unele situatii.

.
Nou în versiunea 0.10.0.

. este utilizat pentru a efectua accesul la atribute pe obiecte. Utilizează un mic DSL pentru a permite rapid
acces la atribute și articole dintr-o structură de date imbricată.

De exemplu,

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

Compilează până la:

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

. compilează primul argument (în exemplu, foo) ca obiect pe care să se facă
dereferire de atribute. Folosește simboluri goale ca atribute de acces (în exemplu, bar,
Baz, frob), și compilează conținutul listelor (în exemplu, [(+ 1 2)]) pentru indexare.
Alte argumente aruncă o eroare de compilare.

Accesul la atribute necunoscute aruncă un AttributeError. Accesul la chei necunoscute aruncă un
IndexError (pe liste și tupluri) sau a KeyError (pe dicționare).

->
-> (Sau filetat macro) este folosit pentru a evita imbricarea expresiilor. Macro-ul de threading
inserează fiecare expresie în locul primului argument al expresiei următoare. Următoarele
codul demonstrează asta:

=> (defn output [ab] (print ab))
=> (-> (+ 4 6) (ieșire 5))
10 5

- >>
- >> (Sau filetat coadă macro) este similară cu filetat macro, dar în loc de
inserând fiecare expresie în primul argument al expresiei următoare, o adaugă ca
ultimul argument. Următorul cod demonstrează acest lucru:

=> (defn output [ab] (print ab))
=> (->> (+ 4 6) (ieșire 5))
5 10

aplica
aplica este folosit pentru a aplica o listă opțională de argumente și un dicționar opțional de kwargs
la o funcție.

Utilizare: (aplica fn-nume [args] [kwargs])

Exemple:

(defn thunk []
„acolo”)

(aplica thunk)
; => „acolo”

(defn total-cumpărare [suma prețului și opțional [taxe 1.05] [tva 1.1]]
(* preț suma taxe tva))

(aplicați achiziția totală [10 15])
; => 173.25

(aplicați achiziția totală [10 15] {„vat” 1.05})
; => 165.375

(aplicați total-cumpărare [] {"preț" 10 "suma" 15 "tva" 1.05})
; => 165.375

și
și este folosit în expresii logice. Este nevoie de cel puțin doi parametri. Dacă toți parametrii
evaluează la Adevărat, ultimul parametru este returnat. În orice alt caz, prima valoare falsă
va fi returnat. Exemplu de utilizare:

=> (și Adevărat Fals)
Fals

=> (și adevărat adevărat)
Adevărat

=> (și adevărat 1)
1

=> (și Adevărat [] Fals Adevărat)
[]

NOTĂ:
și scurtcircuitează și oprește evaluarea parametrilor de îndată ce primul este fals
întâlnite.

=> (și False (tipărește „bună ziua”))
Fals

afirma
afirma este folosit pentru a verifica condițiile în timp ce programul rulează. Dacă condiția nu este
întâlnit, an AssertionError este crescut. afirma poate lua unul sau doi parametri. Primul
parametrul este condiția de verificat și ar trebui să se evalueze la oricare Adevărat or Fals.
al doilea parametru, opțional, este o etichetă pentru afirmație și este șirul care va fi
crescut cu AssertionError. De exemplu:

(afirma (= variabila valoare-așteptată))

(afirmă fals)
; AssertionError

(afirmați (= 1 2) „unul ar trebui să fie egal cu doi”)
; AssertionError: unu ar trebui să fie egal cu doi

conf. univ
conf. univ este folosit pentru a asocia o cheie cu o valoare dintr-un dicționar sau pentru a seta un index al unei liste
la o valoare. Este nevoie de cel puțin trei parametri: the de date structura a fi modificat, a cheie
or index, Precum și o valoare. Dacă sunt utilizați mai mult de trei parametri, se va asocia în perechi.

Exemple de utilizare:

=>(lasă [[colecția {}]]
... (colecția conf. „Câine” „Lătrat”)
... (colecție tipărită))
{u'Dog': u'Bark'}

=>(lasă [[colecția {}]]
... (colecția conf. „Câine” „Lătrat” „Pisică” „Miau”)
... (colecție tipărită))
{u'Cat': u'Meow', u'Dog': u'Bark'}

=>(să [[colecția [1 2 3 4]]]
... (asoc colectia 2 Niciuna)
... (colecție tipărită))
[1, 2, Niciunul, 4]

NOTĂ:
conf. univ modifică structura de date în loc și returnează Nici unul.

rupe
rupe este folosit pentru a ieși dintr-o buclă. Se încheie imediat bucla. Următoarele
exemplul are un infinit în timp ce buclă care se încheie imediat ce utilizatorul intră k.

(în timp ce este adevărat (dacă (= "k" (input brut "? "))
(pauză)
(printați „Încercați din nou”)))

Cond
Cond poate fi folosit pentru a construi imbricat if declarații. Următorul exemplu arată
relația dintre macro și extinderea sa:

(cond [condiție-1 rezultat-1]
[condiție-2 rezultat-2])

(dacă condiția-1 rezultatul-1
(dacă condiția-2 rezultat-2))

După cum se arată mai jos, este executat doar primul bloc de rezultate potrivit.

=> (defn verificare-valoare [valoare]
... (cond [(< valoarea 5) (printați „valoarea este mai mică decât 5”)]
... [(= valoarea 5) (printați „valoarea este egală cu 5”)]
... [(> valoarea 5) (printați „valoarea este mai mare decât 5”)]
... [Adevărat (tipăriți „valoarea este ceva ce nu ar trebui să fie”)]))

=> (verificare-valoare 6)
valoarea este mai mare decat 5

continua
continua returnează execuția la începutul unei bucle. În exemplul următor,
(efect secundar 1) este chemat pentru fiecare iterație. (efect secundar 2), cu toate acestea, este doar apelat
orice altă valoare din listă.

;; presupunând că (efectul secundar1) și (efectul secundar2) sunt funcții și
;; colecția este o listă de valori numerice

(pentru [x colecție]
(de
(efect secundar 1 x)
(dacă (% x 2)
(continua))
(efect secundar2 x)))

dict-comp
dict-comp este folosit pentru a crea dicționare. Este nevoie de trei sau patru parametri. Primul
doi parametri sunt pentru controlul valorii returnate (perechea cheie-valoare), în timp ce al treilea este
folosit pentru a selecta elemente dintr-o secvență. Al patrulea parametru și opțional poate fi folosit pentru
filtrați unele dintre elementele din secvență pe baza unei expresii condiționate.

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

do / progn
do și progn sunt folosite pentru a evalua fiecare dintre argumentele lor și a returna ultimul. Întoarcere
valorile din oricare altul decât ultimul argument sunt eliminate. Poate fi folosit în lambda or
list-comp pentru a efectua o logică mai complexă, așa cum se arată în unul dintre exemplele următoare.

Câteva exemple de utilizare:

=> (dacă este adevărat
... (face (tipărește „Efecte secundare rock!”)
... (tipărește „Da, într-adevăr!”)))
Efecte secundare rock!
Da, într-adevăr!

;; presupunând că (efectul secundar) este o funcție pe care dorim să o apelăm pentru fiecare
;; și fiecare valoare din listă, dar a cărei valoare de returnare nu ne pasă
=> (list-comp (a face (efect secundar x)
... (dacă (< x 5) (* 2 x)
... (* 4 x)))
... (x (interval 10)))
[0, 2, 4, 6, 8, 20, 24, 28, 32, 36]

do poate accepta orice număr de argumente, de la 1 la n.

Def / setv
Def și setv sunt folosite pentru a lega o valoare, un obiect sau o funcție la un simbol. De exemplu:

=> (nume definite ["Alice" "Bob" "Charlie"])
=> (nume tipărite)
[u'Alice', u'Bob', u'Charlie']

=> (contor setv (fn [articol de colecție] (articol de colecție .count)))
=> (contor [1 2 3 4 5 2 3] 2)
2

defclass
Sunt declarate clase noi cu defclass. Poate lua doi parametri opționali: un vector
definirea unei posibile super clase și a unui alt vector care conține atribute ale noului
clasa ca doi vectori de elemente.

(defclass class-name [super-clasa-1 super-clasa-2]
[[valoarea atributului]])

Atât valorile, cât și funcțiile pot fi legate la noua clasă, așa cum se arată în exemplul de mai jos:

=> (defclass Cat []
... [[varsta Niciuna]
... [culoarea „alb”]
... [vorbește (fn [self] (tipărește „Miau”)]])

=> (loc de def (pisica))
=> (setv spot.colour „Negru”)
'Negru'
=> (.robește loc)
miau

defn / defun
defn și defun macrocomenzile sunt folosite pentru a defini funcțiile. Ei iau trei parametri: the nume
a funcției de definit, un vector de parametrii, Şi corp a functiei:

(nume definit [params] body)

Parametrii pot avea următoarele cuvinte cheie în fața lor:

&opțional
Parametrul este opțional. Parametrul poate fi dat ca o listă cu două elemente, unde
primul element este numele parametrului, iar al doilea este valoarea implicită. Parametrul
poate fi dat și ca un singur articol, caz în care valoarea implicită este Nici unul.

=> (valoare-totală definită [valoare &opțional [taxa pe valoarea adăugată 10]]
... (+ (/ (* valoarea-taxa pe valoarea adăugată) 100) valoare))

=> (valoare-totală 100)
110.0

=> (valoare-totală 100 1)
101.0

&cheie

&kwargs
Parametrul va conține 0 sau mai multe argumente de cuvinte cheie.

Următoarele exemple de cod definesc o funcție care va imprima toate cuvintele cheie
argumentele și valorile acestora.

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

=> (aplicați parametrii de tipărire [] {"parameter-1" 1 "parameter-2" 2})
parametrul-2 2
parametrul-1 1

&odihnă Parametrul va conține 0 sau mai multe argumente poziționale. Nicio altă poziție
argumentele pot fi specificate după aceasta.

Următorul exemplu de cod definește o funcție care poate fi dată de la 0 la n numeric
parametrii. Apoi însumează fiecare număr impar și scade fiecare număr par.

=> (defn zig-zag-sum [&restul numere]
(fie [[numere-impare (list-comp x [x numere] (impare? x))]
[numere-pare (list-comp x [x numere] (pare? x))]]
(- (suma numere impare) (suma numere pare))))

=> (suma-zig-zag)
0
=> (zig-zag-sumă 3 9 4)
8
=> (zig-zag-sumă 1 2 3 4 5 6)
-3

defn-alias / defun-alias
Nou în versiunea 0.10.0.

defn-alias și defun-alias macrourile seamănă mult defn, cu distincţia că
în loc să definească o funcție cu un singur nume, acestea pot defini și aliasuri. Alte
decât să luăm ca prim parametru o listă de simboluri pentru numele funcțiilor, defn-alias și
defun-alias nu sunt diferite de defn și defun.

=> (defn-alias [alias-nume principal] []
... (tipărește „Bună ziua!”))
=> (nume-principal)
"Buna ziua!"
=> (alias)
"Buna ziua!"

defmain
Nou în versiunea 0.10.1.

defmain macro definește o funcție principală care este apelată imediat cu sys.argv as
argumente dacă și numai dacă acest fișier este executat ca script. Cu alte cuvinte, aceasta:

(defmain [&rest args]
(fa-ceva-cu argumente))

este echivalentul cu:

def main(*args):
face_ceva_cu(args)
returnați 0

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

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

Rețineți că, după cum puteți vedea mai sus, dacă returnați un număr întreg din această funcție, acesta va fi
folosit ca stare de ieșire pentru scriptul dvs. (Python iese implicit din starea 0 în caz contrar,
ceea ce înseamnă că totul este în regulă!)

(De cand (sys.exit 0) nu este rulat în mod explicit în cazul unei returnări non-întregi de la
defmain, este o idee bună să puneți (defmain) ca ultima bucată de cod din fișierul dvs.)

defmacro
defmacro este folosit pentru a defini macrocomenzi. Formatul general este (defmacro nume [parametri]
expr).

Următorul exemplu definește o macrocomandă care poate fi utilizată pentru a schimba ordinea elementelor din cod,
permițând utilizatorului să scrie cod în notație infixă, unde operatorul se află între
operanzi.

=> (defmacro infix [cod]
... (cvasighiliț (
... (descotați (obțineți codul 1))
... (descotați (obțineți codul 0))
... (descotați (obțineți codul 2)))))

=> (infix (1 + 1))
2

defmacro-alias
defmacro-alias este folosit pentru a defini macrocomenzi cu mai multe nume (alias-uri). Formatul general
is (defmacro-alias [nume] [parametri] expr). Creează mai multe macrocomenzi cu același lucru
lista parametrilor și corpul, sub lista specificată de nume.

Următorul exemplu definește două macrocomenzi, ambele permitând utilizatorului să scrie cod
notație infixă.

=> (defmacro-alias [infix infi] [cod]
... (cvasighiliț (
... (descotați (obțineți codul 1))
... (descotați (obțineți codul 0))
... (descotați (obțineți codul 2)))))

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

defmacro/g!
Nou în versiunea 0.9.12.

defmacro/g! este o versiune specială a defmacro care este folosit pentru a genera automat gensym
pentru orice simbol care începe cu g!.

De exemplu, g!a ar deveni (gensim "A").

VEZI DE ASEMENEA:
Secțiunea folosind-gensym

degenerator
Nou în versiunea 0.9.12.

degenerator definește o macrocomandă de cititor, permițându-vă să restructurați sau să modificați sintaxa.

=> (degenerator ^ [expr] (print expr))
=> #^(1 2 3 4)
(1)
=> #^"Bună ziua"
"Buna"

VEZI DE ASEMENEA:
Macro-uri din cititorul de secțiuni

del
Nou în versiunea 0.9.12.

del elimină un obiect din spațiul de nume curent.

=> (setv foo 42)
=> (del foo)
=> foo
Traceback (ultimul apel cel mai recent):
Fișierul " ", rândul 1, în
NameError: numele „foo” nu este definit

del poate elimina, de asemenea, obiecte din mapări, liste și multe altele.

=> (test setv (lista (interval 10)))
=> test
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
=> (del (test slice 2 4)) ;; elimina articolele de la 2 la 4 excluse
=> test
[0, 1, 4, 5, 6, 7, 8, 9]
=> (setv dic {"foo" "bar"})
=> dic
{"foo": "bar"}
=> (del (obține dic "foo"))
=> dic
{}

la
Nou în versiunea 0.10.1.

la este folosit pentru a simplifica o secvență de apeluri de metodă către un obiect.

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

=> (colecția setv [])
=> (.adăugați colecția 1)
=> (.adăugați colecția 2)
=> (.colectare inversă)
=> colectare
[2 1]

eval
eval evaluează o expresie citată și returnează valoarea.

=> (eval '(tipăreşte "Bună ziua"))
„Bonjour Monde”

eval-si-compilează
eval-când-compilare
primul / mașină
primul și mașină sunt macrocomenzi pentru accesarea primului element al unei colecții:

=> (primul (interval 10))
0

pentru
pentru este folosit pentru a apela o funcție pentru fiecare element dintr-o listă sau vector. Rezultatele fiecăruia
apel sunt renunțate și pentru expresia revine Nici unul in schimb. Exemplul de cod se repetă
peste colectare și pentru fiecare element in colectare apelează efect secundar funcționează cu
element ca argument:

;; presupunând că (efectul secundar) este o funcție care preia un singur parametru
(pentru [colecția de elemente] (element cu efect secundar))

;; for poate avea un bloc opțional else
(pentru [colecția de elemente] (element cu efect secundar)
(altfel (efect secundar-2)))

Opțional altfel blocul este executat numai dacă pentru bucla se termină normal. Dacă
execuția este oprită cu rupe, altfel blocul nu se execută.

=> (pentru [element [1 2 3]] (dacă (< element 3)
... (element de imprimare)
... (pauză))
... (altfel (tipărește „bucla terminată”)))
1
2

=> (pentru [element [1 2 3]] (dacă (< element 4)
... (element de imprimare)
... (pauză))
... (altfel (tipărește „bucla terminată”)))
1
2
3
bucla terminată

genexpr
genexpr este folosit pentru a crea expresii generatoare. Este nevoie de doi sau trei parametri. The
primul parametru este expresia care controlează valoarea returnată, în timp ce al doilea este utilizat
pentru a selecta elemente dintr-o listă. Al treilea parametru și opțional poate fi folosit pentru a filtra
unele dintre elementele din listă bazate pe o expresie condiționată. genexpr este similar cu
list-comp, cu excepția faptului că returnează un iterabil care evaluează valorile unul câte unul în loc de
evaluându-le imediat.

=> (colecție def (interval 10))
=> (def filtrat (genexpr x [x colecție] (chiar? x)))
=> (lista filtrată)
[0, 2, 4, 6, 8]

gensym
Nou în versiunea 0.9.12.

gensym este folosit pentru a genera un simbol unic care permite scrierea fără macrocomenzi
ciocniri accidentale de nume de variabile.

=> (gensym)
u':G_1235'

=> (gensym "x")
u':x_1236'

VEZI DE ASEMENEA:
Secțiunea folosind-gensym

obține
obține este folosit pentru a accesa elemente individuale din liste și dicționare. obține ia doi parametri:
il de date structura si index or cheie a articolului. Apoi va returna corespunzătoare
valoare din dicționar sau din listă. Exemplu de utilizare:

=> (lasă [[animalele {"câine" "latră" "pisica" "miau"}]
... [numerele [„zero” „unu” „două” „trei”]]]
... (imprimați (obțineți animale „câine”))
... (tipărește (obține numerele 2)))
scoarţă
Două

NOTĂ:
obține generează o KeyError dacă un dicționar este interogat pentru o cheie inexistentă.

NOTĂ:
obține generează o IndexError dacă o listă sau un tuplu este interogat pentru un index care este în afara
limite.

global
global poate fi folosit pentru a marca un simbol ca global. Acest lucru permite programatorului să atribuie un
valoare la un simbol global. Citirea unui simbol global nu necesită global cuvânt cheie --
doar atribuirea o face.

Următorul exemplu arată cum simbolul global a i se atribuie o valoare într-o funcție și
este imprimat ulterior într-o altă funcție. Fara global cuvânt cheie, a doua funcție
ar fi aruncat o NameErrore.

(defn set-a [valoare]
(a globala)
(setv o valoare))

(defn print-a []
(tipărește a))

(set-a 5)
(tipărește-a)

if / dacă nu
Nou în versiunea 0.10.0: dacă nu

if este folosit pentru a selecta condiționat codul care urmează să fie executat. Trebuie să conțină o condiție
bloc și blocul care urmează să fie executat dacă blocul de condiție evaluează la Adevărat. Opțional,
poate conţine un bloc final care se execută în cazul în care evaluarea condiţiei este
Fals.

dacă nu este similar, dar al doilea bloc va fi executat când condiția eșuează în timp ce
al treilea și ultimul bloc este executat când testul reușește -- în ordinea opusă a if.

Exemplu de utilizare:

(dacă (bani au rămas? cont)
(tipărește „hai să mergem la cumpărături”)
(tipărește „să mergem să lucrăm”)

(dacă nu (bani rămase? cont)
(tipărește „să mergem să lucrăm”)
(tipărește „hai să mergem la cumpărături”)

Adevărul Python este respectat. Nici unul, Fals, zero de orice tip numeric, o secvență goală,
și se consideră un dicționar gol Fals; totul este luat în considerare Adevărat.

lisp-dacă / fibră și cioială-dacă-nu / da-nu
Nou în versiunea 0.10.0.

Nou în versiunea 0.10.2: lisp-if-not / lif-not

Pentru cei care preferă un Lispy if clauză, avem lisp-dacă, Sau fibră. Acest afară consideră
Nici unul / zero a fi fals! Toate celelalte valori Python „false” sunt considerate adevărate.
Invers, avem cioială-dacă-nu și da-nu în paralel cu if și dacă nu care se inversează
comparatia.

=> (lisp-dacă Adevărat „adevărat” „fals”)
"Adevărat"
=> (lisp-if False „adevărat” „fals”)
"Adevărat"
=> (lisp-dacă 0 „adevărat” „fals”)
"Adevărat"
=> (lisp-dacă nul „adevărat” „fals”)
"fals"
=> (lisp-if Niciunul „adevărat” „fals”)
"fals"
=> (lip-dacă-nu nul „adevărat” „fals”)
"Adevărat"
=> (lip-dacă-nu Niciunul „adevărat” „fals”)
"Adevărat"
=> (lip-dacă-nu Fals „adevărat” „fals”)
"fals"

; Echivalent, dar mai scurt
=> (dacă Adevărat „adevărat” „fals”)
"Adevărat"
=> (lif nil „adevărat” „fals”)
"fals"
=> (lif-nut Niciunul „adevărat” „fals”)
"Adevărat"

import
import este folosit pentru a importa module, ca în Python. Există mai multe moduri prin care import poate să
fi folosit.

;; Importă fiecare dintre aceste module
;;
;; Piton:
;; import sys
;; import os.path
(import sys os.path)

;; Importați dintr-un modul
;;
;; Python: din os.path importul există, isdir, isfile
(import [os.path [există isdir isfile]])

;; Import cu un alias
;;
;; Python: import sys ca systest
(import [sys :as systest])

;; Puteți enumera câte importuri doriți de diferite tipuri.
(import [tests.resources [funcție kwtest-cu-liniuță]]
[os.path [există isdir isfile]]
[sys :as systest])

;; Importați toate funcțiile modulului în spațiul de nume curent
(import [sys [*]])

lambda / fn
lambda și fn poate fi folosit pentru a defini o funcție anonimă. Parametrii sunt similari cu
defn: primul parametru este vector de parametri, iar restul este corpul
Funcția. lambda returnează o nouă funcție. În exemplul următor, o funcție anonimă
este definită și transmisă unei alte funcții pentru filtrarea ieșirii.

=> (def oameni [{:nume „Alice” :age 20}
... {:nume „Bob” : vârstă 25}
... {:nume „Charlie” : vârstă 50}
... {:numele „Dave” : vârsta 5}])

=> (defn display-people [filtru de persoane]
... (pentru [persoană persoane] (dacă (persoană de filtrare) (tipărește (:nume persoană)))))

=> (afișare-oameni (fn [persoană] (< (:persoană de vârstă) 25)))
Alice
Dave

La fel ca în definițiile normale ale funcției, dacă primul element al corpului este un șir, acesta
servește ca docstring. Acest lucru este util pentru a da docstrings metodelor de clasă.

=> (setv ori-trei
... (fn [x]
... "Înmulțiește intrarea cu trei și returnează rezultatul."
... (* x 3)))

Acest lucru poate fi confirmat prin intermediul Python încorporat ajutor funcţie:

=> (ajutor ori-trei)
Ajutor pentru funcția times_three:

ori_trei(x)
Înmulțește intrarea cu trei și returnează rezultatul
(SFÂRȘIT)

ultimul
Nou în versiunea 0.10.2.

ultimul poate fi folosit pentru accesarea ultimului element al unei colecții:

=> (ultimul [2 4 6])
6

lăsa
lăsa este folosit pentru a crea variabile cu scop lexical. Ele sunt create la începutul
lăsa formă și încetează să existe după formă. Următorul exemplu arată acest lucru
comportament:

=> (lasă [[x 5]] (tipărește x)
... (lasă [[x 6]] (tipărește x))
... (tipărește x))
5
6
5

lăsa macro ia doi parametri: un vector definitoriu variabile si corp care devine
executat. variabile este un vector în care fiecare element este fie o singură variabilă, fie un vector
definirea unei perechi valori variabile. În cazul unei singure variabile, i se atribuie valoare
Nici unul; în caz contrar, se utilizează valoarea furnizată.

=> (lasă [x [y 5]] (printează xy))
Niciuna 5

list-comp
list-comp efectuează liste de înțelegeri. Este nevoie de doi sau trei parametri. Primul
parametrul este expresia care controlează valoarea returnată, în timp ce al doilea este folosit pentru
selectați articole dintr-o listă. Al treilea parametru și opțional poate fi folosit pentru a filtra unele dintre ele
a elementelor din listă pe baza unei expresii condiționale. Cateva exemple:

=> (colecție def (interval 10))
=> (list-comp x [x colecție])
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

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

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

nu
nu este folosit în expresii logice. Ia un singur parametru și returnează un parametru invers
valoare de adevăr. Dacă Adevărat este dat ca parametru, Fals vor fi returnate și invers.
Exemplu de utilizare:

=> (nu este adevărat)
Fals

=> (nu fals)
Adevărat

=> (nu Niciunul)
Adevărat

or
or este folosit în expresii logice. Este nevoie de cel puțin doi parametri. Acesta va returna
primul parametru non-fals. Dacă nu există o astfel de valoare, va fi returnat ultimul parametru.

=> (sau Adevărat Fals)
Adevărat

=> (și fals fals)
Fals

=> (și Fals 1 Adevărat Fals)
1

NOTĂ:
or scurtcircuitează și oprește evaluarea parametrilor de îndată ce este prima valoare adevărată
întâlnite.

=> (sau Adevărat (tipăriți „bună ziua”))
Adevărat

imprima
imprima este folosit pentru a ieși pe ecran. Exemplu de utilizare:

(tipărește „Bună lume!”)

NOTĂ:
imprima se intoarce mereu Nici unul.

cvasi-citate
cvasi-citate vă permite să citați un formular, dar și să evaluați selectiv expresii.
Expresii în interiorul a cvasi-citate pot fi evaluate selectiv folosind încheiat citatul (~).
forma evaluată poate fi, de asemenea, îmbinată folosind unquote-splicing (~@). Quasiquote poate fi, de asemenea
scris folosind ghilimele din spate (`) simbol.

;; fie `qux' o variabilă cu valoare (bar baz)
`(foo ~qux)
; echivalent cu '(foo (bar baz))
`(foo ~@qux)
; echivalent cu '(foo bar baz)

cita
cita returnează formularul transmis fără a-l evalua. cita poate fi alternativ
scris folosind apostroful (') simbol.

=> (setv x '(tipărește „Hello World”))
; variabila x este setată la expresie și nu este evaluată
=> x
(tipăriți și Bună lume)
=> (eval x)
Salut Lume

necesita
necesita este folosit pentru a importa macrocomenzi dintr-un anumit modul. Este nevoie de cel puțin un parametru
specificând modulul care macrocomenzi ar trebui importate. Pot fi importate mai multe module
cu un singur necesita.

Următorul exemplu va importa macrocomenzi din modulul 1 și modulul 2:

(necesită modul-1 modul-2)

odihnă / cdr
odihnă și cdr returnează colecția transmisă ca argument fără primul element:

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

set-comp
set-comp este folosit pentru a crea seturi. Este nevoie de doi sau trei parametri. Primul parametru este
pentru controlul valorii returnate, în timp ce al doilea este folosit pentru a selecta articole din a
secvenţă. Al treilea parametru și opțional poate fi folosit pentru a filtra unele dintre elemente
secvența bazată pe o expresie condiționată.

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

felie
felie poate fi folosit pentru a lua un subset al unei liste și a crea o nouă listă din aceasta. Forma
ia cel puțin un parametru care specifică lista de tăiat. Doi parametri opționali pot fi
folosit pentru a da poziția de început și de sfârșit a submulțimii. Dacă acestea nu sunt furnizate,
valoarea implicită a Nici unul va fi folosit în schimb. Al treilea parametru opțional este folosit pentru
pas de control între elemente.

felie urmează aceleași reguli ca și omologul său Python. Se numără indici negativi
începând de la sfârşitul listei. Câteva exemple de utilizare:

=> (colecție def (interval 10))

=> (colecție de felii)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

=> (colecția felii 5)
[5, 6, 7, 8, 9]

=> (colecția de felii 2 8)
[2, 3, 4, 5, 6, 7]

=> (colecția felii 2 8 2)
[2, 4, 6]

=> (colecția felii -4 -2)
[6, 7]

arunca / ridica
arunca or ridica formele pot fi folosite pentru a ridica o Excepție în timpul rulării. Exemplu de utilizare:

(arunca)
; resterge ultima excepție

(aruncă IOError)
; Aruncă o IOError

(aruncă (IOError „foobar”))
; Aruncă o IOError ("foobar")

arunca poate accepta un singur argument (an Excepție clasă sau instanță) sau fără argumente pentru
ridică din nou ultimul Excepție.

încerca
încerca formularul este folosit pentru a începe a încerca / captură bloc. Formularul este utilizat după cum urmează:

(încerca
(funcție predispusă la erori)
(prindeți [e ZeroDivisionError] (printați „Diviziunea la zero”))
(altfel (printați „fără erori”)
(în sfârșit (tipărește „totul gata”)))

încerca trebuie să conțină cel puțin unul captură bloc și poate include opțional un altfel or in cele din urma
bloc. Dacă apare o eroare cu un bloc catch potrivit în timpul execuției
funcția predispusă la erori, Că captură blocul va fi executat. Dacă nu apar erori, altfel
blocul este executat. The in cele din urma blocul va fi executat ultimul, indiferent dacă un
eroare a fost ridicată.

dacă nu
dacă nu macro este o prescurtare pentru scrierea unui if declarație care verifică dacă este dat
conditionata este Fals. Următoarele arată extinderea acestei macrocomenzi.

(cu excepția cazului în care declarația condiționată)

(dacă este condiționat
Nici unul
(fă declarația))

încheiat citatul
Într-o formă cvasicitată, încheiat citatul forțează evaluarea unui simbol. încheiat citatul este alias la
tilde (~) simbol.

(nume definit „Cuddles”)
(cvasighitele (= nume (numele fără ghilimele)))
;=> (u'=' u'nume' u'Cuddles')

`(= nume ~nume)
;=> (u'=' u'nume' u'Cuddles')

unquote-splicing
unquote-splicing forțează evaluarea unui simbol într-o formă cvasi-citată, la fel ca
încheiat citatul. unquote-splicing poate fi folosit numai atunci când simbolul necotat conține un
valoare iterabilă, deoarece „împletește” acel iterabil în forma cvasicitată. unquote-splicing is
alias la ~@ simbol.

(numere definite [1 2 3 4])
(cvasighime (+ (numere fără ghilimele)))
;=> (u'+' 1L 2L 3L 4L)

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

cand
cand este similar cu dacă nu, cu excepția faptului că testează când condiționalul dat este Adevărat. Nu este
posibil să aibă o altfel bloc în a cand macro. Următoarele arată extinderea
macro.

(când declarația condiționată)

(dacă este condiționat (a face declarația))

în timp ce
în timp ce este folosit pentru a executa unul sau mai multe blocuri atâta timp cât o condiție este îndeplinită. Următoarele
exemplu va afișa „Hello world!” pe ecran pe termen nelimitat:

(în timp ce este Adevărat (tipărește „Bună lume!”))

cu
cu este folosit pentru a încheia execuția unui bloc într-un manager de context. Contextul
managerul poate configura apoi sistemul local și îl poate demola într-un mod controlat. The
exemplu arhetipic de utilizare cu este la procesarea fișierelor. cu poate lega contextul unui
argumentați sau ignorați-l complet, așa cum se arată mai jos:

(cu bloc [[arg (expr)]])

(cu bloc [[(expr)]])

(cu bloc [[arg (expr)] [(expr)]])

Următorul exemplu va deschide ȘTIRI fișier și imprimați conținutul acestuia pe ecran. The
fișierul este închis automat după ce a fost procesat.

(cu [[f (deschideți „ȘTIRI”)]] (tipărește (.citește f)))

cu-decorator
cu-decorator este folosit pentru a încheia o funcție cu alta. Funcția care îndeplinește
decorarea ar trebui să accepte o singură valoare: funcția care este decorată și să returneze o valoare nouă
Funcția. cu-decorator ia minimum doi parametri: funcția care îndeplinește
decor și funcția fiind decorată. Mai mult de o funcție de decorator poate fi
aplicat; acestea vor fi aplicate în ordine de la cel mai exterior la cel mai interior, adică. primul
decoratorul va fi cel mai exterior și așa mai departe. Decoratorii cu argumente sunt numiți justi
ca un apel de funcție.

(cu-decorator decorator-distracție
(definiți o anumită funcție [] ...)

(cu-decorator decorator1 decorator2 ...
(definiți o anumită funcție [] ...)

(cu-decorator (decorator arg) ..
(definiți o anumită funcție [] ...)

În exemplul următor, inc-decorator este folosit pentru a decora funcția plus cu
funcție care ia doi parametri și apelează funcția decorată cu valori care sunt
incrementat cu 1. Când este decorat plus se numește cu valorile 1 și 1, sfârșitul
rezultatul va fi 4 (1 + 1 + 1 + 1).

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

=> (cu-decorator inc-decorator (defn addition [ab] (+ ab)))
=> (adăugare 1 1)
4
=> (cu-decorator inc2-decorator inc-decorator
... (defn addition [ab] (+ ab)))
=> (adăugare 1 1)
8

cu-gensyms
Nou în versiunea 0.9.12.

cu-gensim este folosit pentru a genera un set de gensym pentru utilizare într-o macro. Urmatorul cod:

(cu-gensyms [abc]
...)

se extinde la:

(să [[a (gensym)
[b (gensym)
[c (gensym)]]
...)

VEZI DE ASEMENEA:
Secțiunea folosind-gensym

Randament
Randament este folosit pentru a crea un obiect generator care returnează una sau mai multe valori. Generatorul
este iterabil și, prin urmare, poate fi folosit în bucle, liste de înțelegere și altele similare
constructe.

Funcția numere-aleatoare arată cum pot fi utilizate generatoarele pentru a genera serii infinite
fără a consuma o cantitate infinită de memorie.

=> (înmulțire definită [coeficienți de bază]
... (pentru [[(, coeficient de bază) (coeficienți baze de zip)]]
... (randament (* coeficient de bază))))

=> (înmulțire (interval 5) (interval 5))


=> (valoare list-comp [valoare (înmulțire (interval 10) (interval 10))])
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

=> (import aleator)
=> (defn numere aleatoare [scăzut mare]
... (în timp ce este Adevărat (randament (.randint aleatoriu scăzut mare))))
=> (list-comp x [x (luați 15 (numere aleatoare 1 50))])])
[7, 41, 6, 22, 32, 17, 5, 38, 18, 38, 17, 14, 23, 23, 19]

randament-din
Nou în versiunea 0.9.13.

PITON 3.3 AND UP NUMAI!

randament-din este folosit pentru a apela un subgenerator. Acest lucru este util dacă doriți ca corutina dvs
să fie capabil să-și delege procesele unei alte corutine, de exemplu, dacă folosești ceva de genul fantezist
asincio.

Hy Nucleu
Nucleu funcţii
dar în ultimul rând
Utilizare: (în sfârșit coll)

Returnează un iterator pentru toate, cu excepția ultimului element din coll.

=> (lista (finalul (interval 10)))
[0, 1, 2, 3, 4, 5, 6, 7, 8]

=> (lista (final [1]))
[]

=> (lista (ultima []))
[]

=> (import iertools)
=> (lista (luați 5 (butlast (itertools.count 10))))
[10, 11, 12, 13, 14]

coll?
Nou în versiunea 0.10.0.

Utilizare: (coll? x)

Returnări Adevărat if x este iterabil și nu un șir.

=> (col? [1 2 3 4])
Adevărat

=> (coll? {"a" 1 "b" 2})
Adevărat

=> (coll? „abc”)
Fals

contra
Nou în versiunea 0.10.0.

Utilizare: (contra a b)

Returnează o celulă proaspătă contra cu mașina a si cdr b.

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

=> (= 'hd (masina a))
Adevărat

=> (= 'tl (cdr a))
Adevărat

idioti?
Nou în versiunea 0.10.0.

Utilizare: (contra? foo)

Verifică dacă foo este o celulă contra.

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

=> (contra? a)
Adevărat

=> (contra? nul)
Fals

=> (contra? [1 2 3])
Fals

dec
Utilizare: (dec x)

Returnează unul mai puțin decât x. Echivalentă cu (- x 1). Creșteri Eroare de scris if (nu (numeric? X)).

=> (3 dec.)
2

=> (0 dec.)
-1

=> (12.3 dec.)
11.3

demonta
Nou în versiunea 0.10.0.

Utilizare: (dezasamblați copac &opțional [codegen fals])

Eliminați Python AST pentru Hy dat copac la ieșirea standard. Dacă codegen is Adevărat, functia
în schimb, tipărește codul Python.

=> (dezasamblați „(tipărește „Hello World!”))
Modul(
body=[
Expr(valoare=Apel(func=Nume(id='printare'), args=[Str(s='Bună ziua!')], cuvinte cheie=[], starargs=Niciuna, kwargs=Niciuna))])

=> (dezasamblați „(printați „Hello World!”) adevărat)
print('Bună lume!')

gol?
Utilizare: (gol? coll)

Returnări Adevărat if coll este gol. Echivalentă cu (= 0 (numai col)).

=> (gol? [])
Adevărat

=> (gol? "")
Adevărat

=> (gol? (, 1 2))
Fals

fiecare?
Nou în versiunea 0.10.0.

Utilizare: (fiecare? inainte de coll)

Returnări Adevărat if (pred x) este logic adevărat pentru fiecare x in coll, Altfel Fals. Întoarcere Adevărat
if coll este gol.

=> (fiecare? chiar? [2 4 6])
Adevărat

=> (fiecare? chiar? [1 3 5])
Fals

=> (fiecare? chiar? [2 4 5])
Fals

=> (fiecare? chiar? [])
Adevărat

pluti?
Utilizare: (pluti? x)

Returnări Adevărat if x este un plutitor.

=> (plutitor? 3.2)
Adevărat

=> (plutește? -2)
Fals

chiar?
Utilizare: (chiar? x)

Returnări Adevărat if x este chiar. Creșteri Eroare de scris if (nu (numeric? X)).

=> (chiar? 2)
Adevărat

=> (chiar? 13)
Fals

=> (chiar? 0)
Adevărat

identitate
Utilizare: (identitate x)

Returnează argumentul furnizat funcției.

=> (identitate 4)
4

=> (lista (identitatea hărții [1 2 3 4]))
[1 2 3 4]

inc
Utilizare: (inc x)

Returnează unul mai mult decât x. Echivalentă cu (+ x 1). Creșteri Eroare de scris if (nu (numeric? X)).

=> (inc. 3)
4

=> (inc. 0)
1

=> (inc. 12.3)
13.3

instanță?
Utilizare: (instanță? clasă x)

Returnări Adevărat if x este un exemplu de clasă.

=> (instanță? float 1.0)
Adevărat

=> (instanță? int 7)
Adevărat

=> (instanță? str (str „foo”))
Adevărat

=> (defclass TestClass [obiect])
=> (setv inst (TestClass))
=> (instanță? TestClass inst)
Adevărat

întreg?
Utilizare: (întreg? x)

Returnări Adevărat if x este un număr întreg. Pentru Python 2, acesta este fie int or lung. Pentru Python 3,
aceasta este int.

=> (întreg? 3)
Adevărat

=> (întreg? -2.4)
Fals

intercalează
Nou în versiunea 0.10.1.

Utilizare: (intercalare secv1 secv2 ...)

Returnează un iterabil al primului element din fiecare dintre secvențe, apoi al doilea etc.

=> (lista (intercalare (interval 5) (interval 100 105)))
[0, 100, 1, 101, 2, 102, 3, 103, 4, 104]

=> (lista (intercalare (interval 1000000) „abc”))
[0, „a”, 1, „b”, 2, „c”]

interpune
Nou în versiunea 0.10.1.

Utilizare: (interpune articol secv.)

Returnează un iterabil al elementelor secvenței separate de element.

=> (lista (interpune „!” „abcd”))
['a', '!', 'b', '!', 'c', '!', 'd']

=> (lista (interpune -1 (interval 5)))
[0, -1, 1, -1, 2, -1, 3, -1, 4]

iterabil?
Utilizare: (iterabil? x)

Returnări Adevărat if x este iterabil. Obiectele iterabile returnează un nou iterator când (iter x) is
numit. Contrast cu iterator?.

=> ;; funcționează pentru șiruri
=> (iterabil? (str "abcde"))
Adevărat

=> ;; funcționează pentru liste
=> (iterabil? [1 2 3 4 5])
Adevărat

=> ;; funcționează pentru tupluri
=> (iterabil? (, 1 2 3))
Adevărat

=> ;; lucrează pentru dict
=> (iterabil? {:a 1 :b 2 :c 3})
Adevărat

=> ;; funcționează pentru iteratoare/generatoare
=> (iterabil? (repetare 3))
Adevărat

iterator?
Utilizare: (iterator? x)

Returnări Adevărat if x este un iterator. Iteratorii sunt obiecte care se întorc ca un
iterator când (iter x) se numește. Contrast cu iterabil?.

=> ;; nu funcționează pentru o listă
=> (iterator? [1 2 3 4 5])
Fals

=> ;; dar putem obține un iter din listă
=> (iterator? (iter [1 2 3 4 5]))
Adevărat

=> ;; nu merge pentru dict
=> (iterator? {:a 1 :b 2 :c 3})
Fals

=> ;; creați un iterator din dict
=> (iterator? (iter {:a 1 :b 2 :c 3}))
Adevărat

listă*
Utilizare: (listă* cap &odihnă coadă)

Generează un lanț de celule contra imbricate (o listă punctată) care conține argumentele. Dacă
lista de argumente are un singur element, returnați-l.

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

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

=> (lista* 1)
1

=> (contra? (lista* 1 2 3 4))
Adevărat

macroexpand
Nou în versiunea 0.10.0.

Utilizare: (macroexpand formă)

Returnează extinderea completă a macrocomenzii formă.

=> (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')

macroexpand-1
Nou în versiunea 0.10.0.

Utilizare: (macroexpand-1 formă)

Returnează extinderea macro într-un singur pas a formă.

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

îmbina-cu
Nou în versiunea 0.10.1.

Utilizare: (contopire cu f &odihnă hărți)

Returnează o hartă care constă din restul hărților conectate mai întâi. Dacă apare o cheie în
mai mult de o hartă, cartografiile de la aceasta din urmă (de la stânga la dreapta) vor fi combinate cu
maparea în rezultat prin apelare (f val-in-rezultat val-in-ultim).

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

neg?
Utilizare: (neg? x)

Returnări Adevărat if x este mai mică decât zero. Creșteri Eroare de scris if (nu (numeric? X)).

=> (neg? -2)
Adevărat

=> (neg? 3)
Fals

=> (neg? 0)
Fals

zero?
Utilizare: (zero? x)

Returnări Adevărat if x is zero / Nici unul.

=> (nul? nul)
Adevărat

=> (niciun? Nici unul)
Adevărat

=> (nul? 0)
Fals

=> (setf x nil)
=> (nul? x)
Adevărat

=> ;; list.append returnează întotdeauna Nimic
=> (nul? (.adăugați [1 2 3] 4))
Adevărat

nici unul?
Utilizare: (nici unul? x)

Returnări Adevărat if x is Nici unul.

=> (niciunul? Nici unul)
Adevărat

=> (nici unul? 0)
Fals

=> (setf x Niciunul)
=> (nici unul? x)
Adevărat

=> ;; list.append returnează întotdeauna Nimic
=> (nici unul? (.adăugați [1 2 3] 4))
Adevărat

a n-
Utilizare: (al al-lea coll n &opțional [Mod implicit zero])

Returnează n-al-lea articol dintr-o colecție, numărând de la 0. Returnează valoarea implicită, zero, dacă
în afara limitelor (dacă nu se specifică altfel). Creșteri ValueError if n este negativ.

=> (al-lea [1 2 4 7] 1)
2

=> (al-lea [1 2 4 7] 3)
7

=> (nul? (n-a [1 2 4 7] 5))
Adevărat

=> (nth [1 2 4 7] 5 "implicit")
'Mod implicit'

=> (al-lea (luați 3 (picătură 2 [1 2 3 4 5 6])) 2))
5

=> (n-a [1 2 4 7] -1)
Traceback (ultimul apel cel mai recent):
...
ValueError: Indicii pentru islice() trebuie să fie None sau un număr întreg: 0 <= x <= sys.maxsize.

numeric?
Utilizare: (numeric? x)

Returnări Adevărat if x este o valoare numerică, așa cum este definită în Python numere.Număr clasă.

=> (numerice? -2)
Adevărat

=> (numeric? 3.2)
Adevărat

=> (numeric? „foo”)
Fals

odd?
Utilizare: (ciudat? x)

Returnări Adevărat if x este ciudat. Creșteri Eroare de scris if (nu (numeric? X)).

=> (impar? 13)
Adevărat

=> (impar? 2)
Fals

=> (impar? 0)
Fals

pos?
Utilizare: (poz? x)

Returnări Adevărat if x este mai mare decât zero. Creșteri Eroare de scris if (nu (numeric? X)).

=> (poz. 3)
Adevărat

=> (poz? -2)
Fals

=> (poz. 0)
Fals

al doilea
Utilizare: (al doilea coll)

Returnează al doilea membru al coll. Echivalentă cu (obține coll 1).

=> (al doilea [0 1 2])
1

unele
Nou în versiunea 0.10.0.

Utilizare: (niste inainte de coll)

Returnează prima valoare logic adevărată a (pred x) pentru orice x in coll, Altfel zero.
Retur zero if coll este gol.

=> (unele chiar? [2 4 6])
Adevărat

=> (nul? (unele chiar? [1 3 5]))
Adevărat

=> (nul? (o anumită identitate [0 "" []]))
Adevărat

=> (oarecare identitate [0 "non-empty-string" []])
„șir-non-vide”

=> (nul? (unele chiar? []))
Adevărat

şir?
Utilizare: (şir? x)

Returnări Adevărat if x este o sfoară.

=> (șir? „foo”)
Adevărat

=> (șir? -2)
Fals

simbol?
Utilizare: (simbol? x)

Returnări Adevărat if x este un simbol.

=> (simbol? 'foo)
Adevărat

=> (simbol? '[abc])
Fals

zero?
Utilizare: (zero? x)

Returnări Adevărat if x este zero.

=> (zero? 3)
Fals

=> (zero? -2)
Fals

=> (zero? 0)
Adevărat

Secvenţă funcţii
Funcțiile de secvență pot fie să creeze, fie să opereze pe o secvență potențial infinită fără
impunând ca secvența să fie realizată în totalitate într-o listă sau un container similar. Ei fac asta prin
returnând un iterator Python.

Putem folosi generatorul canonic infinit de numere Fibonacci ca exemplu de utilizare
unele dintre aceste funcţii.

(defn fib []
(setv a 0)
(setv b 1)
(deși este adevărat
(randament a)
(setv (, ab) (, b (+ ab)))))

Rețineți (in timp ce adevărat ...) buclă. Dacă rulăm acest lucru în REPL,

=> (fib)


Apelarea funcției returnează doar un iterator, dar nu funcționează până când îl consumăm.
Încercarea de așa ceva nu este recomandată, deoarece bucla infinită va rula până la aceasta
consumă toată memoria RAM disponibilă sau, în acest caz, până l-am ucis.

=> (lista (fib))
[1] 91474 ucis hy

Pentru a obține primele 10 numere Fibonacci, utilizați lua. Rețineți că lua returnează și un generator,
asa ca creez o lista din ea.

=> (lista (luați 10 (fib)))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Pentru a obține numărul Fibonacci la indicele 9, (începând de la 0):

=> (al-lea (fib) 9)
34

ciclu
Utilizare: (ciclu coll)

Returnează un iterator infinit al membrilor coll.

=> (lista (luați 7 (ciclu [1 2 3])))
[1, 2, 3, 1, 2, 3, 1]

=> (lista (luați 2 (ciclu [1 2 3])))
[1, 2]

distinct
Utilizare: (distinct coll)

Returnează un iterator care conține numai membrii unici în coll.

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

=> (lista (distinct []))
[]

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

picătură
Utilizare: (cădere brusca n coll)

Returnează un iterator, sărind peste primul n membrii ai coll. Creșteri ValueError if n is
negativ.

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

=> (lista (scris 4 [1 2 3 4 5]))
[5]

=> (lista (scris 0 [1 2 3 4 5]))
[1, 2, 3, 4, 5]

=> (lista (scris 6 [1 2 3 4 5]))
[]

picătură-ultimul
Utilizare: (picătură-ultimul n coll)

Returnează un iterator pentru toate, cu excepția ultimului n articole din coll. Creșteri ValueError if n is
negativ.

=> (listă (eliminare-ultimele 5 (interval 10 20)))
[10, 11, 12, 13, 14]

=> (listă (pentru ultimul 0 (interval 5)))
[0, 1, 2, 3, 4]

=> (listă (pentru ultimul 100 (interval 100)))
[]

=> (import iertools)
=> (lista (luați 5 (scăpare-ultimele 100 (itertools.numărați 10))))
[10, 11, 12, 13, 14]

drop-while
Utilizare: (scădere în timp ce inainte de coll)

Returnează un iterator, ignorând membrii coll până la inainte de is Fals.

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

=> (listă (număr cu drop-while? [1 2 3 Nici unul „a”])))
[Nimeni, u'a']

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

filtru
Utilizare: (filtru inainte de coll)

Returnează un iterator pentru toate elementele din coll care trec predicatul inainte de.

Vezi si scoate.

=> (lista (poziție filtru? [1 2 3 -4 5 -7]))
[1, 2, 3, 5]

=> (listă (filtrează par? [1 2 3 -4 5 -7]))
[2, -4]

aplatiza
Nou în versiunea 0.9.12.

Utilizare: (aplatiza coll)

Returnează o singură listă cu toate elementele din coll, prin aplatizarea tuturor listelor conținute și/sau
tupluri.

=> (aplatizați [1 2 [3 4] 5])
[1, 2, 3, 4, 5]

=> (aplatiza ["foo" (, 1 2) [1 [2 3] 4] "bar"])
[„foo”, 1, 2, 1, 2, 3, 4, „bar”]

repeta
Utilizare: (repeta fn x)

Returnează un iterator de x, fn(x), fn(fn(x)), Etc

=> (listă (luați 5 (iterați inc 5)))
[5, 6, 7, 8, 9]

=> (lista (luați 5 (iterați (fn [x] (* xx)) 5)))
[5, 25, 625, 390625, 152587890625]

citit
Utilizare: (citit &opțional [din fisier eof])

Citește următoarea expresie Hy din din fisier (implicit la sys.stdin), și poate lua a
un singur octet ca EOF (implicit la un șir gol). Creșteri EOFEroare if din fisier se termină înainte
o expresie completă poate fi analizată.

=> (citește)
(+ 2 2)
('+' 2 2)
=> (eval (citește))
(+ 2 2)
4

=> (import io)
=> (def buffer (io.StringIO "(+ 2 2)\n(- 2 1)"))
=> (eval (aplicați citire [] {"from_file" buffer}))
4
=> (eval (aplicați citire [] {"from_file" buffer}))
1

=> ; presupunând că „example.hy” conține:
=> ; (tipărește „bună ziua”)
=> ; (tipărește „prieteni!”)
=> (cu [[f (deschide „example.hy”)]]
... (încerca
... (deși este adevărat
... (să [[exp (citește f)]]
... (fa
... (tipărește „OHY” exp)
... (eval exp))))
... (prindeți [e EOFError]
... (tipărește „EOF!”))))
OHY („printare” „bună ziua”)
Alo
OHY („printează” „prieteni!”)
prietenii!
EOF!

scoate
Utilizare: (elimina inainte de coll)

Returnează un iterator de la coll cu elemente care trec predicatul, inainte de, îndepărtat.

Vezi si filtru.

=> (lista (eliminați impar? [1 2 3 4 5 6 7]))
[2, 4, 6]

=> (lista (elimina pozitia? [1 2 3 4 5 6 7]))
[]

=> (lista (elimină neg? [1 2 3 4 5 6 7]))
[1, 2, 3, 4, 5, 6, 7]

repeta
Utilizare: (repeta x)

Returnează un iterator (infinit) de x.

=> (lista (luați 6 (repetați „s”)))
[u', u's', u's', u's', u's', u's]

repetat
Utilizare: (repetat fn)

Returnează un iterator prin apelare fn repetat.

=> (import [aleatoriu [randint]])

=> (lista (luați 5 (în mod repetat (fn [] (randint 0 10)))))
[6, 2, 0, 6, 7]

lua
Utilizare: (lua n coll)

Returnează un iterator care conține primul n membrii ai coll. Creșteri ValueError if n is
negativ.

=> (lista (luați 3 [1 2 3 4 5]))
[1, 2, 3]

=> (lista (luați 4 (repetați „s”)))
[u', u's', u's', u's']

=> (lista (luați 0 (repetați „s”)))
[]

ia-n-a
Utilizare: (lua-n-a n coll)

Returnează un iterator care conține fiecare n-al-lea membru al coll.

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

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

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

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

ia-timp
Utilizare: (luați-n timp inainte de coll)

Returnează un iterator de la coll atâta timp cât inainte de Returnează Adevărat.

=> (listă (luați în timp ce poziția? [ 1 2 3 -4 5]))
[1, 2, 3]

=> (lista (luați-în timp ce neg? [ -4 -3 1 2 5]))
[-4, -3]

=> (lista (luați-în timp ce neg? [ 1 2 3 -4 5]))
[]

zipwith
Nou în versiunea 0.9.13.

Utilizare: (zipwith fn coll ...)

Echivalentă cu zip, dar folosește o funcție cu mai multe argumente în loc să creeze un tuplu. Dacă
zipwith se numește cu N colecții, atunci fn trebuie să accepte N argumente.

=> (operator de import)
=> (listă (zipwith operator.add [1 2 3] [4 5 6]))
[5, 7, 9]

Cititor Macrocomenzi
Macrocomenzile cititorului îi oferă lui Lisp puterea de a modifica și modifica sintaxa din mers. Nu vrei
Notație poloneză? O macrocomandă de cititor poate face cu ușurință exact asta. Vrei modul lui Clojure de a avea o
regex? Macrocomenzile cititorului pot face acest lucru cu ușurință.

Sintaxă
=> (degenerator ^ [expr] (print expr))
=> #^(1 2 3 4)
(1)
=> #^"Bună ziua"
"Buna"
=> #^1+2+3+4+3+2
1+2+3+4+3+2

Hy nu are literal pentru tupluri. Să spunem că nu-ți place (, ...) si vrei altceva. Acest
este un cititor de probleme macrocomenzile sunt capabile să o rezolve într-un mod ordonat.

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

Ai putea chiar să o faci ca Clojure și să ai un literal pentru expresiile regulate!

=> (import re)
=> (degenerator r [expr] `(re.compilați ~expr))
=> #r".*"
<_sre.SRE_Pattern obiect la 0xcv7713ph15#>

Punerea în aplicare
degenerator ia un singur caracter ca nume de simbol pentru macro-ul cititorului; orice mai mult
va returna o eroare. Din punct de vedere al implementării, degenerator se extinde într-o lambda acoperită cu a
decorator. Acest decorator salvează lambda într-un dicționar cu numele său de modul și
simbol.

=> (degenerator ^ [expr] (print expr))
;=> (cu_decorator (hy.macros.reader ^) (fn [expr] (print expr)))

# se extinde în (dispatch_reader_macro ...) unde se transmite simbolul și expresia
functia corecta.

=> #^()
;=> (dispatch_reader_macro ^ ())
=> #^"Bună ziua"
"Buna"

AVERTISMENT:
Din cauza unei limitări în lexerul și analizatorul lui Hy, macrocomenzile cititorului nu pot redefini definite
sintaxă precum ()[]{}. Cel mai probabil, acest lucru va fi abordat în viitor.

Intern Hy Documentație
NOTĂ:
Acești biți sunt în principal folositori pentru cei care pirata pe Hy în sine, dar pot fi folosiți și pentru
cei care aprofundează în programarea macro.

Hy modele
Introducere la Hy modele
Modelele Hy sunt un strat foarte subțire deasupra obiectelor obișnuite Python, reprezentând sursa Hy
cod ca date. Modelele adaugă doar informații despre poziția sursă și o mână de metode
acceptă manipularea curată a codului sursă Hy, de exemplu în macrocomenzi. Pentru a realiza asta
obiectiv, modelele Hy sunt mixuri ale unei clase de bază Python și HyObject.

HyObject
hy.modele.HyObject este clasa de bază a modelelor Hy. Implementează o singură metodă, înlocui,
care înlocuiește poziția sursă a obiectului curent cu cea trecută ca argument.
Acest lucru ne permite să urmărim poziția inițială a expresiilor care sunt modificate de
macrocomenzi, fie că sunt în compilator sau în macrocomenzi pure hy.

HyObject nu este destinat să fie utilizat direct pentru a instanția modele Hy, ci doar ca mixin
pentru alte clase.

Compus modele
Listele între paranteze și între paranteze sunt analizate ca modele compuse de parserul Hy.

HyList
hy.modele.listă.HyList este clasa de bază a modelelor Hy „iterabile”. Utilizarea sa de bază este să
reprezintă între paranteze [] liste, care, atunci când sunt utilizate ca expresie de nivel superior, se traduc în
Python listă literale în faza de compilare.

Adăugarea unei HyList la un alt obiect iterabil reutilizează clasa obiectului din partea stângă,
un comportament util atunci când doriți să concatenați obiecte Hy într-o macrocomandă, de exemplu.

HyExpression
hy.modele.expresie.HyExpression moștenește HyList pentru parantezat () expresii. The
rezultatul compilarii acelor expresii depinde de primul element al listei: the
compilatorul trimite expresii între formularele speciale ale compilatorului, macro-urile definite de utilizator și
apeluri regulate de funcții Python.

HyDict
hy.modele.dict.HyDict moștenește HyList pentru curly-bracketed {} expresii, care se compilează
până la un dicționar Python literal.

Decizia de a folosi o listă în loc de un dict ca clasă de bază pentru HyDict permite mai usor
manipularea dictelor în macro-uri, cu avantajul suplimentar de a permite expresii compuse
ca taste dict (cum ar fi, de exemplu, HyExpression Clasa Python nu este hashabilă).

Atomic modele
În fluxul de intrare, șiruri de caractere duble, respectând notația Python pentru șiruri,
sunt analizate ca un singur token, care este analizat direct ca a HyString.

Un șir neîntrerupt de caractere, excluzând spații, paranteze, ghilimele, ghilimele duble
și comentarii, este analizat ca un identificator.

Identificatorii sunt rezolvați în modele atomice în timpul fazei de analiză, în următoarea ordine:

· HyInteger

· HyFloat

· HyComplex (dacă atomul nu este gol j)

· HyKeyword (dacă atomul începe cu :)

· HySymbol

HyString
hy.models.string.HyString este clasa de bază a modelelor Hy echivalente cu șiruri. De asemenea
reprezintă literali șir de ghilimele duble, "", care se compilează până la un șir unicode
literali în Python. HyStrings moștenește obiecte Unicode în Python 2 și obiecte șir în
Python 3 (și, prin urmare, nu sunt dependente de codificare).

HyString modelele bazate sunt imuabile.

Șirurile literale Hy se pot întinde pe mai multe linii și sunt considerate de analizator ca fiind un singur
unitate, respectând evadările Python pentru șirurile Unicode.

Numeric modele
hy.modele.integer.HyInteger reprezintă literali întregi (folosind codul lung tastați pe Python 2,
și int pe Python 3).

hy.modele.float.HyFloat reprezintă literali în virgulă mobilă.

hy.models.complex.HyComplex reprezintă literale complexe.

Modelele numerice sunt analizate folosind rutina Python corespunzătoare și python numeric valid
literalii vor fi transformați în omologul lor Hy.

HySymbol
hy.modele.simbol.HySymbol este modelul folosit pentru a reprezenta simboluri în limbajul Hy. Aceasta
moștenește HyString.

HySymbol obiectele sunt alterate în faza de analiză, pentru a ajuta interoperabilitatea Python:

· Simboluri înconjurate de asteriscuri (*) sunt transformate în majuscule;

· liniuțe (-) sunt transformate în subliniere (_);

· Un semn de întrebare final (?) este transformat într-un lider este_.

Avertisment: deoarece manipularea se face în timpul fazei de analizare, este posibil
generați prin programare HySymbols care nu pot fi generate cu codul sursă Hy. Un astfel de
mecanismul este folosit de gensym pentru a genera simboluri „neinternate”.

HyKeyword
hy.models.keyword.HyKeyword reprezintă cuvinte cheie în Hy. Cuvintele cheie sunt simboluri care încep cu
a :. Clasa moștenește HyString.

A distinge HyKeywords din HySymbols, fără posibilitatea de (involuntar)
ciocniri, caracterul Unicode de uz privat „\uFDD0” se adaugă cuvântului cheie literal
înainte de depozitare.

Contra Celule
hy.models.cons.HyCons este o reprezentare a Python-friendly contra celulele. Celulele contra sunt
util în special pentru a imita caracteristicile variantelor LISP „obișnuite”, cum ar fi Scheme sau Common
Lisp.

O celulă contra este un obiect cu 2 elemente, care conține a mașină (capul) și a cdr (coadă). În unele Lisp
variante, celula contra este elementul fundamental, iar expresiile S sunt de fapt
reprezentate ca liste legate de celule contra. Nu este cazul în Hy, ca de obicei
expresiile sunt făcute din liste Python împachetate în a HyExpression. Însă HyCons
imită comportamentul variantelor „obișnuite” Lisp astfel:

· (contra ceva zero) is (HyExpression [ceva])

· (contra ceva o listă) is ((tip o listă) (+ [ceva] unele-lista)) (dacă
unele-listă moștenește din listă).

· (obține (contra a b) 0) is a

· (felie (contra a b) 1) is b

Hy acceptă o sintaxă cu listă punctată, unde '(A . b) mijloace (contra 'a 'b) și '(A b . c) mijloace
(contra 'a (contra 'b 'c)). Dacă compilatorul întâlnește o celulă contra la nivelul superior, se ridică
o eroare de compilare.

HyCons împachetează argumentele transmise (mașină și cdr) în tipuri Hy, pentru a ușura manipularea
celulele contra într-un context macro.

Hy Intern Teorie
Descriere
Elementele interne Hy funcționează ca un front-end la bytecode Python, astfel încât Hy însuși
se compilează până la Python Bytecode, permițând unui runtime Python nemodificat să ruleze codul Hy,
fără măcar să-l observe.

Modul în care facem acest lucru este prin traducerea Hy într-o structură de date Python AST internă și
construind acel AST în codul de octeți Python folosind module din standardul Python
bibliotecă, astfel încât să nu fie nevoie să duplicăm toată munca componentelor interne Python pentru fiecare
o singură lansare Python.

Hy lucrează în patru etape. Următoarele secțiuni vor acoperi fiecare pas al Hy de la sursă la
timpul de rulare.

paşi 1 și 2: tokenizing și Analizare
Prima etapă a compilării Hy este de a lexa sursa în token-uri cu care ne putem ocupa. Noi
utilizați un proiect numit rply, care este un parser foarte frumos (și rapid), scris într-un subset
din Python numit rpython.

Codul de lexing este definit în totalitate hy.lex.lexer. Acest cod definește în mare parte Hy
gramatică și toate părțile grele reale sunt îngrijite de rply -- doar definim
„callbacks” pentru rply in hy.lex.parser, care preia jetoanele generate și returnează
Hy modele.

Vă puteți gândi la modelele Hy ca fiind „AST” pentru Hy, pe care funcționează Macro-urile
(direct) și este ceea ce folosește compilatorul când compilează Hy down.

VEZI DE ASEMENEA:
Secțiune Hy modele pentru mai multe informații despre modelele Hy și ce înseamnă acestea.

Pas 3: Hy Compilation la Piton AST
Aici are loc cea mai mare parte a magiei din Hy. Aici luăm Hy AST (modelele),
și compilați-le în Python AST. Câteva lucruri ciudate se întâmplă aici pentru a funcționa dincolo de câteva
probleme în AST, iar lucrul în compilator este una dintre cele mai importante lucrări pe care le facem
avea.

Compilatorul este puțin complex, așa că nu vă simțiți prost dacă nu îl înțelegi la prima fotografie,
poate dura ceva timp pentru a ajunge corect.

Principalul punct de intrare în compilator este HyASTCompiler.compile. Această metodă este invocată și
singura metodă „publică” reală din clasă (adică nu promitem cu adevărat că
API dincolo de această metodă).

De fapt, chiar și pe plan intern, nu recurgem direct aproape niciodată, aproape întotdeauna forțăm
arborele Hy prin compila, și va face adesea acest lucru cu sub-elemente ale unei expresii
asta avem. Este la latitudinea dispecerului bazat pe tip să trimită corect subelementele.

Toate metodele care formează o compilație sunt marcate cu @builds() decorator. Puteți
fie treceți clasa modelului Hy pe care îl compilează, fie puteți utiliza un șir pentru care
expresii. O să clarific asta într-o secundă.

First Etapă Tip-Expediere
Să începem în compila metodă. Primul lucru pe care îl facem este să verificăm Tipul obiectului
construim. Ne uităm în sus pentru a vedea dacă avem o metodă care poate construi tip() că noi
au și trimiteți la metoda care o poate gestiona. Dacă nu avem nicio metodă care să poată
construim acel tip, ridicăm un intern Excepție.

De exemplu, dacă avem un HyString, avem o mapare aproape 1-la-1 a Hy AST la Python
AST. The șir_compilare metoda ia HyString, și returnează un ast.Str() asta e
populate cu numerele de rând și conținutul corect.

Macro-Extindere
Dacă primim un HyExpression, vom încerca să vedem dacă aceasta este o macrocomandă cunoscută și vom încerca să avem
s-a extins prin invocare hy.macros.macroexpand, apoi împingeți rezultatul înapoi în
HyASTCompiler.compile.

Al doilea Etapă Expresie-Expediere
Singurul caz special este HyExpression, deoarece trebuie să creăm diferite AST în funcție
pe formularul special în cauză. De exemplu, când lovim un (dacă adevărat adevărat fals), Ne-
trebuie să genereze o ast.Dacăși compilați corect sub-nodurile. Aici este locul @builds()
cu un șir ca argument intră.

Pentru expresie_compilare (care este definită cu un @builds(HyExpression)) va expedia
pe baza șirului primului argument. Dacă, dintr-un motiv oarecare, primul argument nu este
un șir, va gestiona corect și acel caz (cel mai probabil prin ridicarea unui Excepție).

Dacă șirul nu este cunoscut de Hy, va crea implicit un ast.Apel, care va încerca
faceți un apel de rulare (în Python, ceva de genul foo()).

Probleme Lovit cu Piton AST
Python AST este grozav; este ceea ce ne-a permis să scriem un proiect atât de puternic
Python fără a fi nevoit să lupți prea tare cu Python. La fel ca orice, am avut partea noastră bună
probleme și iată o listă scurtă a celor obișnuite cu care ați putea întâlni.

Piton se diferențiază între Declaratii și Expresii.

Acest lucru s-ar putea să nu sune mare lucru -- de fapt, pentru majoritatea programatorilor Python, acest lucru va fi
în scurt timp devin un moment „Ei bine, da”.

În Python, făcând ceva de genul:

imprima pentru x in gamă(10): trece, Deoarece imprima imprimă expresii și pentru nu este un
expresie, este o declarație de flux de control. Lucruri ca 1 + 1 sunt expresii, așa cum sunt lambda
x: 1 + x, dar alte caracteristici ale limbii, cum ar fi if, pentru, Sau în timp ce sunt afirmatii.

Deoarece nu au nicio „valoare” pentru Python, lucrul în Hy este greu, deoarece face ceva
ca (imprimare (dacă adevărat adevărat fals)) nu este doar comun, este de așteptat.

Drept urmare, stricam automat lucrurile folosind a Rezultat obiect, unde oferim orice ast.stmt
care trebuie să fugă și un singur ast.expr care poate fi folosit pentru a obține valoarea oricăror
tocmai a fost alergat. Hy face acest lucru forțând alocarea unor lucruri în timp ce rulează.

De exemplu, Hy:

(tipărește (dacă este adevărat, adevărat fals))

Se va transforma in:

daca e adevarat:
_mangled_name_here = Adevărat
altceva:
_mangled_name_here = False

imprimați _mangled_name_aici

OK, asta a fost puțin o minciună, pentru că de fapt transformăm acea afirmație în:

tipăriți Adevărat dacă Adevărat altfel Fals

Forțând lucrurile într-un ast.expr dacă putem, dar ideea generală este valabilă.

Pas 4: Piton Cod octet producție și Runtime
După ce avem un arbore Python AST care este complet, putem încerca să-l compilam în Python
bytecode împingându-l eval. De aici încolo, nu mai avem controlul și
Python are grijă de tot. Acesta este motivul pentru care lucruri precum Python tracebacks, pdb și
aplicațiile django funcționează.

Hy Macrocomenzi
Utilizarea gensym pentru mai sigur Macrocomenzi
Când scrieți macrocomenzi, trebuie să aveți grijă să evitați capturarea sau utilizarea variabilelor externe
nume de variabile care ar putea intra în conflict cu codul utilizatorului.

Vom folosi un exemplu de macrocomandă nÎn (A se vedea
http://letoverlambda.com/index.cl/guest/chap3.html#sec_5 pentru o descriere mai completa.)
nÎn este un exemplu, ceva de genul numeric if, unde pe baza expresiei, unul dintre
3 forme se numesc in functie de daca expresia este pozitiva, zero sau negativa.

O primă trecere ar putea fi ceva de genul:

(defmacro nif [expr pos-form zero-form neg-form]
`(lasă [[obscure-name ~expr]]
(cond [(poz? nume-obscur) ~pos-form]
[(zero? nume-obscur) ~zero-form]
[(neg? obscure-name) ~neg-form])))

Unde obsure-nume este o încercare de a alege un nume de variabilă pentru a nu intra în conflict cu altele
cod. Dar, desigur, deși bine intenționat, aceasta nu este o garanție.

Metoda gensym este concepută pentru a genera un simbol nou, unic tocmai pentru o astfel de ocazie.
O versiune mult mai bună a nÎn va fi:

(defmacro nif [expr pos-form zero-form neg-form]
(să fie [[g (gensym)]]
`(lasă [[~g ~expr]]
(cond [(pos? ~g) ~pos-form]
[(zero? ~g) ~zero-form]
[(neg? ~g) ~neg-form]))))

Acesta este un caz ușor, deoarece există un singur simbol. Dar dacă este nevoie de mai multe
gensym există o a doua macro cu gensyms care practic se extinde la o serie de lăsa
declarații:

(cu-gensyms [abc]
...)

se extinde la:

(să [[a (gensym)
[b (gensym)
[c (gensym)]]
...)

deci rescrisul nostru nÎn ar arata ca:

(defmacro nif [expr pos-form zero-form neg-form]
(cu-gensyms [g]
`(lasă [[~g ~expr]]
(cond [(pos? ~g) ~pos-form]
[(zero? ~g) ~zero-form]
[(neg? ~g) ~neg-form]))))

În cele din urmă, deși putem face o nouă macrocomandă care face toate acestea pentru noi. defmacro/g! va lua
toate simbolurile care încep cu g! și sună automat gensym cu restul de
simbol. Asa de g!a ar deveni (gensim "A").

Versiunea noastră finală a nÎn, construit cu defmacro/g! devine:

(defmacro/g! nif [expr pos-form zero-form neg-form]
`(lasă [[~g!res ~expr]]
(cond [(pos? ~g!res) ~pos-form]
[(zero? ~g!res) ~zero-form]
[(neg? ~g!res) ~neg-form]))))

Control Macro Argumente și ridicare excepţii de
Hy compilator Încorporate

CONTRIBUITOR MODULE INDEX


Cuprins:

Anaforic Macrocomenzi
Nou în versiunea 0.9.12.

Modulul de macro-uri anaforice face ca programarea funcțională în Hy să fie foarte concisă și ușor de utilizat
citire.
O macrocomandă anaforică este un tip de macrocomandă de programare care captează în mod deliberat o formă
furnizate macro-ului la care se poate face referire printr-o anaforă (o expresie care se referă
altcuiva). — Wikipedia (http://en.wikipedia.org/wiki/Anaphoric_macro)

Macrocomenzi
ap-dacă
Utilizare: (ap-dacă (foo) (imprimare aceasta))

Evaluează prima formă pentru adevăr și se leagă de aceasta it atât în ​​adevărat cât și în fals
ramuri.

o piersica
Utilizare: (o piersica [1 2 3 4 5] (imprimare aceasta))

Evaluați formularul pentru fiecare element din listă pentru efecte secundare.

ap-fiecare-timp
Utilizare: (ap-fiecare-timp listă inainte de corp)

Evaluați forma pentru fiecare element în care se întoarce forma predicat Adevărat.

=> (ap-each-while [1 2 3 4 5 6] (< it 4) (tipărește-l))
1
2
3

ap-hartă
Utilizare: (ap-harta formă listă)

Forma anaforică a hărții funcționează la fel ca o hartă obișnuită, cu excepția faptului că în loc de o funcție
obiect ia forma Hy. Numele special it este legat de obiectul curent din
lista în iterație.

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

ap-hartă-când
Utilizare: (ap-hartă-când predfn reprezentant listă)

Evaluați o mapare peste listă folosind o funcție de predicat pentru a determina când să aplicați
formular.

=> (listă (ap-hartă-când impar? (* it 2) [1 2 3 4]))
[2, 2, 6, 4]

=> (listă (ap-hartă-când chiar? (* it 2) [1 2 3 4]))
[1, 4, 3, 8]

ap-filtru
Utilizare: (filtru ap formă listă)

Ca și în cazul ap-hartă luăm o formă specială în loc de o funcție pentru a filtra elementele
listă. Numele special it este legat de elementul curent în iterație.

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

ap-respinge
Utilizare: (ap-resping formă listă)

Această funcție face opusul ap-filtru, respinge elementele care trec pe
predicat . Numele special it este legat de elementul curent în iterație.

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

ap-dotimes
Folosire (ap-dotimes n corp)

Această funcție evaluează corpul n ori, cu variabila specială it legat din 0 la
1-n. Este util pentru efecte secundare.

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

ap-întâi
Folosire (ap-întâi predfn listă)

Această funcție returnează primul element care trece predicatul sau Nici unul, Cu
variabilă specială it legat de elementul curent în iterație.

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

ap-ultimul
Folosire (ap-ultimul predfn listă)

Această funcție returnează ultimul element care trece predicatul sau Nici unul, cu specialul
variabil it legat de elementul curent în iterație.

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

ap-reduce
Folosire (ap-reduce formă listă &opțional valoarea initiala)

Această funcție returnează rezultatul aplicării formei la primele 2 elemente din corp și
aplicând rezultatul și al 3-lea element etc până la epuizarea listei. Opțional un
valoarea inițială poate fi furnizată, astfel încât funcția va fi aplicată la valoarea inițială și la
primul element în schimb. Acest lucru expune elementul care este iterat ca it și curentul
valoare acumulată ca ACC.

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

buclă/recură
Nou în versiunea 0.10.0.

buclă / reapărea macro le oferă programatorilor o modalitate simplă de a utiliza optimizarea apelului final (TCO)
în codul lor Hy.
Un apel de coadă este un apel de subrutină care are loc în interiorul unei alte proceduri ca final
acțiune; poate produce o valoare returnată care este imediat returnată de apelare
procedură. Dacă vreun apel pe care îl efectuează o subrutină, astfel încât acesta ar putea duce în cele din urmă
la aceeași subrutină fiind apelată din nou în lanțul de apeluri, este în poziție de coadă,
o astfel de subrutină se spune că este recursiv la coadă, ceea ce este un caz special de recursivitate.
Apelurile de coadă sunt semnificative deoarece pot fi implementate fără a adăuga o nouă stivă
cadru la stiva de apeluri. Majoritatea cadrului procedurii actuale nu este necesar
mai mult și poate fi înlocuit cu cadrul apelului de coadă. Programul poate sări apoi
la subrutina numită. Producerea unui astfel de cod în loc de o secvență de apel standard este
numită eliminare a apelului de coadă sau optimizare a apelului de coadă. Eliminarea apelului de coadă permite
apelurile de procedură în poziție de coadă pentru a fi implementate la fel de eficient ca instrucțiunile goto,
permiţând astfel o programare structurată eficientă. — Wikipedia (‐
http://en.wikipedia.org/wiki/Tail_call)

Macrocomenzi
buclă
buclă stabilește un punct de recursivitate. Cu buclă, reapărea relegă variabilele stabilite în
punct de recursivitate și trimite execuția codului înapoi la acel punct de recursivitate. Dacă reapărea este utilizat în
o poziție non-coadă, se aruncă o excepție.

Utilizare: (buclă legături &odihnă corp)

Exemplu:

(necesită hy.contrib.loop)

(defn factorial [n]
(buclă [[in] [acc 1]]
(dacă (zero? i)
ACC
(recură (dec i) (* acc i)))))

(factorial 1000)

defmulti
Nou în versiunea 0.10.0.

defmulti vă permite să supraîncărcați cu arity o funcție cu numărul dat de argumente și/sau kwarg.
Inspirat de interpretarea lui Clojure defn.

=> (necesită hy.contrib.multi)
=> (defmulti distracție
... ([a] „a”)
... ([ab] „ab”)
... ([abc] „abc”))
=> (distracție 1)
"A"
=> (distracție 1 2)
"ab"
=> (distracție 1 2 3)
"abc"

HACKING ON HY


Alatura-te al nostru Hyve!
Te rog, haide-l pe Hy!

Vă rugăm să veniți cu noi #hy on irc.freenode.net!

Vă rugăm să vorbiți despre asta pe Twitter cu #hy hashtag!

Vă rugăm să blog despre asta!

Vă rog să nu o vopsiți cu spray pe gardul vecinului (fără să întrebați frumos)!

Hack!
Fa asta:

1. Creeaza o virtual mediu inconjurator:

$ virtualenv venv

și activează-l:

$ . venv/bin/activate

sau utilizare virtualenvwrapper pentru a crea și gestiona mediul tău virtual:

$ mkvirtualenv hy
$ workon hy

2. Obțineți codul sursă:

$ git clona https://github.com/hylang/hy.git

sau folosește furculița:

$ git clona [e-mail protejat]: /hy.git

3. Instalați pentru hacking:

$ cd hy/
$ pip install -e .

4. Instalați alte cerințe de dezvoltare:

$ pip install -r requirements-dev.txt

5. Faceți lucruri minunate; fă pe cineva să țipe de încântare/dezgust pentru ceea ce ai făcut.

Test!
Testele sunt situate în teste/. Folosim nas.

Pentru a rula testele:

$ teste nasului

Scrie teste --- testele sunt bune!

De asemenea, este bine să rulați testele pentru toate platformele suportate și pentru compatibil PEP 8
cod. Puteți face acest lucru rulând tox:

$tox

Document!
Documentația se află în documente /. Folosim Sfinx.

Pentru a construi documentele în HTML:

$ documente cd
$ face html

Scrieți documente --- documentele sunt bune! Chiar și acest document!

Contribuind
Contribuțiile sunt binevenite și foarte apreciate, fiecare pic ajută la creșterea Hy
minunat.

Solicitările de tragere sunt grozave! Ii iubim; iată un ghid rapid:

· Furnizați repo și creați o ramură de subiect pentru o caracteristică/remediere. Evitați să faceți modificări direct
pe ramura maestru.

· Toate funcțiile primite ar trebui să fie însoțite de teste.

· Înainte de a trimite un PR, rulați testele și verificați codul în raport cu stilul
ghid. Puteți face ambele aceste lucruri simultan:

$ face d

· Faceți comite în unități logice, astfel încât să fie mai ușor de urmărit și navigat mai târziu. Inainte de
trimiteți un PR, încercați să strângeți commit-urile în seturi de modificări la care sunt ușor de revenit
mai tarziu. De asemenea, asigurați-vă că nu lăsați spații albe false în seturile de modificări; acest
evită crearea ulterioară a comenzilor de remediere a spațiilor albe.

· În ceea ce privește mesajele de confirmare, încercați să respectați următoarele:

· Încercați să respectați limita de 50 de caractere pentru prima linie a mesajelor de confirmare Git.

· Pentru mai multe detalii/explicații, continuați cu o linie goală și continuați
descriind comiterea în detaliu.

· În cele din urmă, adăugați-vă la fișierul AUTHORS (ca un commit separat): îl meriți :)

· Toate modificările primite trebuie acceptate de 2 membri diferiți ai echipei de bază a lui Hylang.
O revizuire suplimentară este în mod clar binevenită, dar avem nevoie de minimum 2 avize pentru oricare
schimba.

· Dacă un membru de bază trimite un PR, vă rugăm să găsiți 2 membri de bază care nu includ
Remitent PR. Ideea aici este că se poate lucra cu autorul de PR, iar un al doilea ack
întregul set de modificări.

· Pentru documentație și alte modificări banale, este bine să unim după un ACK. Noi avem
acoperire scăzută, așa că ar fi grozav să mențineți acea barieră scăzută.

Nucleu Echipa PGC
Echipa de bază de dezvoltare a Hy este formată din următorii dezvoltatori:

· Julien Danjou

· Morten Linderud

· J Kenneth Rege

· Gergely Nagy

· Tuukka Turto

· Karen Ruginit

· Abhishek L

· Christopher Allan Webber

· Konrad Hinsen

· Va Kahn-Greene

· Paul Tagliamonte

· Nicolas Dandrimont

· Bob Tolbert

· Berker Peksag

· Clinton N. Dreisbach

· Han semaj

Folosiți-vă online folosind serviciile onworks.net


Servere și stații de lucru gratuite

Descărcați aplicații Windows și Linux

  • 1
    NSIS: Nullsoft Scriptable Install System
    NSIS: Nullsoft Scriptable Install System
    NSIS (Nullsoft Scriptable Install
    System) este o sursă deschisă profesională
    sistem pentru a crea programe de instalare Windows. Aceasta
    este conceput pentru a fi cât mai mic și flexibil
    cat posibil...
    Descărcați NSIS: Nullsoft Scriptable Install System
  • 2
    authpass
    authpass
    AuthPass este o parolă open source
    manager cu sprijin pentru popular şi
    Keepass dovedit (kdbx 3.x ȘI kdbx 4.x...
    Descărcați authpass
  • 3
    Zabbix
    Zabbix
    Zabbix este o companie deschisă de clasă enterprise
    soluție de monitorizare distribuită la sursă
    conceput pentru a monitoriza și urmări
    performanța și disponibilitatea rețelei
    servere, dispozitive...
    Descărcați Zabbix
  • 4
    KDiff3
    KDiff3
    Acest depozit nu mai este întreținut
    și se păstrează în scop de arhivă. Vedea
    https://invent.kde.org/sdk/kdiff3 for
    cel mai nou cod și
    https://download.kde.o...
    Descărcați KDiff3
  • 5
    USBLoaderGX
    USBLoaderGX
    USBLoaderGX este o interfață grafică pentru
    Încărcătorul USB al lui Waninkoko, bazat pe
    libwiigui. Permite listarea și
    lansarea de jocuri Wii, jocuri Gamecube și
    homebrew pe Wii și WiiU...
    Descărcați USBLoaderGX
  • 6
    Firebird
    Firebird
    Firebird RDBMS oferă caracteristici ANSI SQL
    și rulează pe Linux, Windows și
    mai multe platforme Unix. Caracteristici
    concurență și performanță excelente
    & putere...
    Descărcați Firebird
  • Mai mult »

Comenzi Linux

Ad