англійськафранцузькаіспанська

Ad


Значок OnWorks

hy - Інтернет у хмарі

Запустіть hy у постачальника безкоштовного хостингу OnWorks через Ubuntu Online, Fedora Online, онлайн-емулятор Windows або онлайн-емулятор MAC OS

Це команда hy, яку можна запустити в постачальнику безкоштовного хостингу OnWorks за допомогою однієї з наших численних безкоштовних онлайн-робочих станцій, таких як Ubuntu Online, Fedora Online, онлайн- емулятор Windows або онлайн-емулятор MAC OS

ПРОГРАМА:

ІМ'Я


hy - hy Документація [зображення: Hy] [зображення]

пробувати Hy https://try-hy.appspot.com

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

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

список гіланг-дискусія

IRC #hy на Freenode

Будувати статус
Travis CI.НЕЗАХІДНИЙ

Hy — чудовий діалект Lisp, який вбудований у Python.

Оскільки Hy перетворює свій код Lisp в абстрактне синтаксичне дерево Python, у вас є
весь прекрасний світ Python у вас під рукою, у формі Lisp!

Зміст:

ШВИДКИЙ ПОЧАТОК


[зображення: обійми Карен Рустард] [зображення]

(Спасибі Карен Рустад за обійми!)

ЯК TO GET HY НЕРУХОМІСТЬ ШВИДКО:

1 Створити Віртуальний Python Навколишнє середовище.

2. Активуйте своє віртуальне середовище Python.

3. Встановлювати hy від PyPI з типун встановлювати hy.

4. Почніть REPL з hy.

5. Введіть речі в REPL:

=> (друк "Привіт!")
Hy!
=> (defn salutationsnm [ім'я] (друк (+ "Hy " name "!")
=> (вітання nm "Ваше ім'я")
Хай, твоє ім'я!

і т.д.

6. Коли закінчите, натисніть CTRL-D.

OMG! Це дивовижний! I хотіти до запис a Hy програми.

7. Відкрийте елітний редактор програмування та введіть:

(друк "Я збирався кодувати синтаксис Python, але потім отримав Hy.")

8. Зберегти як awesome.hy.

9. І запустіть свою першу програму Hy:

hy awesome.hy

10.
Зробіть глибокий вдих, щоб не допустити гіпервентиляції.

11.
Посміхайтеся лиходійсько і прокрадайтеся до свого сховища і робіть невимовні речі.

Підручник


Ласкаво просимо до підручника Hy!

Коротше кажучи, Hy - це діалект Лісп, але такий, який перетворює свою структуру на Python ...
буквально перетворення в абстрактне синтаксичне дерево Python! (Або кажучи більш грубим
умовно, Hy — це lisp-stick на Python!)

Це дуже круто, тому що це означає, що Hy має кілька речей:

· Lisp, який виглядає дуже пітонично

· Для Lispers, чудовий спосіб використовувати божевільні здібності Lisp, але в широкому світі Python
бібліотеки (чому так, тепер ви можете написати програму Django на Lisp!)

· Для Pythonista — чудовий спосіб розпочати вивчення Lisp, не виходячи з Python!

· Для всіх: приємна мова, яка має багато акуратних ідей!

базовий Введення до шепелявість та цінності Пітоністи
Гаразд, можливо, ви ніколи раніше не використовували Lisp, але ви використовували Python!

Програма "hello world" в Hy насправді дуже проста. Давайте спробуємо:

(друк "привіт, світ")

Подивитися? Легко! Як ви вже здогадалися, це те саме, що версія Python:

надрукувати "привіт, світ"

Щоб додати дуже просту математику, ми можемо зробити:

(+ 1 3)

Що поверне 4 і буде еквівалентом:

1 + 3

Ви помітите, що першим пунктом у списку є функція, яка викликається, і функція
решта аргументів - це аргументи, які передаються. Насправді, у Hy (як і більшість
Lisps) ми можемо передати кілька аргументів оператору плюс:

(+ 1 3 55)

Що повернуло б 59.

Можливо, ви вже чули про Lisp, але мало знаєте про нього. Шепелявість не така складна, як ти
може подумати, а Hy успадковується від Python, тож Hy — чудовий спосіб почати вивчати Lisp.
Головне, що очевидно в Lisp, це те, що тут багато дужок. Це може
спочатку здається заплутаним, але це не так вже й складно. Давайте подивимося на просту математику
загорнуті в купу дужок, які ми могли б ввести в інтерпретатор Hy:

(результат setv (- (/ (+ 1 3 88) 2) 8))

Це повернуло б 38. Але чому? Ну, ми могли б подивитися на еквівалентний вираз в
python:

результат = ((1 + 3 + 88) / 2) - 8

Якби ви спробували з’ясувати, як наведене вище працюватиме в python, ви, звичайно, це б
з’ясувати результати, розв’язавши кожну внутрішню дужку. Це та сама основна ідея в
Hy. Давайте спочатку спробуємо цю вправу на Python:

результат = ((1 + 3 + 88) / 2) - 8
# спрощено до...
результат = (92 / 2) - 8
# спрощено до...
результат = 46 - 8
# спрощено до...
результат = 38

Тепер давайте спробуємо те ж саме в Hy:

(результат setv (- (/ (+ 1 3 88) 2) 8))
; спрощено до...
(результат setv (- (/ 92 2) 8))
; спрощено до...
(результат setv (- 46 8))
; спрощено до...
(результат setv 38)

Як ви, напевно, здогадалися, цей останній вираз с установка означає призначити змінну
«результат» до 38.

Подивитися? Не дуже важко!

Це основна передумова Lisp. Lisp означає «обробка списку»; це означає, що
Структура програми насправді є списками списків. (Якщо ви знайомі з Python
списки, уявіть собі всю структуру, що й вище, але замість квадратних дужок будь-яку
ви зможете побачити структуру вище як програму та структуру даних.) Це
легше зрозуміти з більшою кількістю прикладів, тому давайте напишемо просту програму на Python, перевіримо її,
а потім показати еквівалентну програму Hy:

def simple_conversation():
print "Привіт! Я хотів би з вами познайомитися. Розкажіть про себе!"
name = raw_input("Як тебе звати?")
age = raw_input("Який твій вік?")
print "Привіт " + ім'я + "! Я бачу, що тобі " + вік + " років."

проста_розмова()

Якби ми запустили цю програму, вона могла б виглядати так:

Привіт! Я хотів би з тобою познайомитись. Розкажіть про себе!
Як вас звати? Гарі
Скільки тобі років? 38
Привіт Гарі! Я бачу, тобі 38 років.

Тепер давайте подивимося на еквівалентну програму Hy:

(defn проста розмова []
(друк «Привіт! Я хотів би з вами познайомитись. Розкажіть про себе!»)
(назва setv (необроблений вхід «Як тебе звати?»)))
(setv age (raw-input "Який твій вік?"))
(друк (+ "Привіт " ім'я "! Я бачу, що ти "
вік "років".)))

(проста розмова)

Якщо ви подивитеся на наведену вище програму, до тих пір, поки ви пам'ятаєте, що перший елемент у кожній
Список програми — це функція (або макрос... ми розповімо про них пізніше).
і що решта є аргументами, досить легко зрозуміти, що це все означає.
(Як ви, напевно, також здогадалися, деф є методом Hy визначення методів.)

Тим не менш, багатьох людей спочатку це збиває з пантелику, тому що тут дуже багато дужок,
але є багато речей, які можуть полегшити це: зберегти відступи та
скористайтеся редактором із узгодженням дужок (це допоможе вам зрозуміти, що кожен
круглі дужки поєднуються з) і все стане комфортним.

Структура коду, яка насправді є дуже простими даними, має деякі переваги
структуру, на якій базується ядро ​​Lisp. З одного боку, це означає, що ваші програми є
легко розібратися, і що вся фактична структура програми дуже чітко виявляється
тобі. (У hy є додатковий крок, коли структура, яку ви бачите, перетворюється на Python
власні уявлення ... в "чистішому" Lisps, наприклад Common Lisp або Emacs Lisp, дані
Структура, яку ви бачите в коді, і структура даних, яка виконується, набагато більше
буквально близько)

Іншим наслідком цього є макроси: якщо структура програми є простими даними
структуру, це означає, що ви можете писати код, який може писати код дуже легко, тобто
впровадження абсолютно нових мовних функцій може бути дуже швидким. До Hy, цього не було
дуже можливо для програмістів Python ... тепер ви також можете неймовірно використовувати макроси
потужність (тільки будьте обережні, щоб не націлити їх у ногу)!

Hy is a Зі смаком шепелявого Python
Hy перетворюється на власне абстрактне синтаксичне дерево Python, тому незабаром ви почнете виявляти, що все
знайома сила Python у вас під рукою.

Ви маєте повний доступ до типів даних Python і стандартної бібліотеки в Hy. Давайте експериментувати
з цим у інтерпретаторі hy:

=> [1 2 3]
[1, 2, 3]
=> {"собака" "гавкає"
... "кіт" "мяу"}
...
{'собака': 'гавкання', 'кіт': 'мяу'}
=> (, 1 2 3)
(1, 2, 3)

Якщо ви знайомі з іншими Lisps, вам може бути цікаво, що Hy підтримує Common
Метод цитування Lisp:

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

Ви також маєте доступ до всіх хороших методів вбудованих типів:

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

Що це? Так, дійсно, це те саме, що:

" fooooo ".strip()

Правильно --- Шепелявка з точковим позначенням! Якщо нам призначено цей рядок як змінну, ми
також можна зробити наступне:

(встановити цей рядок "fooooo")
(цей-рядок.смуга)

А як щодо умовних умов?:

(якщо (спробуй-що-небудь)
(друк "це, якщо правда")
(друкувати "це якщо хибно"))

Як ви можете сказати вище, перший аргумент до if це перевірка істинності, другий аргумент
тіло, якщо істина, а третій аргумент (необов’язковий!), якщо хибний (тобто. ще).

Якщо вам потрібно виконати більш складні умови, ви виявите, що у вас їх немає Еліф
доступний у Hy. Замість цього ви повинні використовувати щось під назвою кондиц. У Python ви можете зробити
щось на зразок:

somevar = 33
якщо somevar > 50:
print "Ця змінна завелика!"
elif somevar < 10:
print "Ця змінна занадто мала!"
ще:
print "Ця змінна jussssst права!"

У Hy ви б зробили:

(пров
[(> somevar 50)
(друк "Ця змінна занадто велика!")]
[(< somevar 10)
(друк "Ця змінна занадто мала!")]
[правда
(надрукуйте "Ця змінна jussssst!")])

Те, що ви помітите, це кондиц вимикається між деяким оператором, який виконується, і
перевіряється умовно на істину чи хибність, а потім фрагмент коду для виконання, якщо він виявиться
виявляється правдою. Ви також помітите, що ще реалізується в кінці просто шляхом
перевірка на правда -- це тому, що правда завжди буде правдою, тож якщо ми зайдемо так далеко, ми дійдемо
завжди запускай це!

Ви можете помітити це вище, якщо у вас є такий код:

(якщо якась умова
(тіло-якщо-правда)
(body-if-false))

Але почекайте! Що робити, якщо ви хочете виконати більше одного оператора в тілі одного з
ці?

Ви можете зробити наступне:

(якщо (спробуй-що-небудь)
(робити
(друк "це, якщо правда")
(друк «а чому б і ні, давайте далі говорити про те, наскільки це правда!))
(надрукуйте "це все ще просто неправда"))

Ви бачите, що ми використовували do щоб обернути кілька операторів. Якщо ви знайомі з іншими
Шепелявець, це еквівалент прогн в іншому місці.

Коментарі починаються з крапки з комою:

(друк "це буде працювати")
; (друк "але цього не буде")
(+ 1 2 3) ; ми виконаємо доповнення, але не цей коментар!

Циклування не складне, але має особливу структуру. У Python ми можемо зробити:

бо я в діапазон(10):
надрукувати "'i' зараз на " + str(i)

Еквівалент у Hy буде:

(для [i (діапазон 10)]
(друк (+ "'i' зараз на " (str i))))

Ви також можете імпортувати та використовувати різні бібліотеки Python. Наприклад:

(імпорт ОС)

(якщо (os.path.isdir "/tmp/somedir")
(os.mkdir "/tmp/somedir/anotherdir")
(друк «Гей, цього шляху немає!»))

Менеджери контексту Python (з твердження) використовуються так:

(за допомогою [[f (відкрити "/tmp/data.in")]]
(друкувати (.читати f)))

що еквівалентно:

з open("/tmp/data.in") як f:
друкувати f.read()

І так, у нас є розуміння списку! У Python ви можете зробити:

коефіцієнт_квадрат = [
pow(число, 2)
для кількості в діапазон(100)
якщо кількість % 2 == 1]

У Hy можна виконати такі дії:

(setv шанси-квадрат
(список-комп
(потужність номер 2)
(кількість (діапазон 100))
(= (% кількість 2) 1)))

; І приклад, безсоромно вкрадений зі сторінки Clojure:
; Давайте перерахуємо всі блоки шахової дошки:

(список-комп
(, xy)
(x (діапазон 8)
y "ABCDEFGH"))

; [(0, 'A'), (0, 'B'), (0, 'C'), (0, 'D'), (0, 'E'), (0, 'F'), ( 0, 'G'), (0, 'H'),
; (1, 'A'), (1, 'B'), (1, 'C'), (1, 'D'), (1, 'E'), (1, 'F'), (1 , 'G'), (1, 'H'),
; (2, 'A'), (2, 'B'), (2, 'C'), (2, 'D'), (2, 'E'), (2, 'F'), (2 , 'G'), (2, 'H'),
; (3, 'A'), (3, 'B'), (3, 'C'), (3, 'D'), (3, 'E'), (3, 'F'), (3 , 'G'), (3, 'H'),
; (4, 'A'), (4, 'B'), (4, 'C'), (4, 'D'), (4, 'E'), (4, 'F'), (4 , 'G'), (4, 'H'),
; (5, 'A'), (5, 'B'), (5, 'C'), (5, 'D'), (5, 'E'), (5, 'F'), (5 , 'G'), (5, 'H'),
; (6, 'A'), (6, 'B'), (6, 'C'), (6, 'D'), (6, 'E'), (6, 'F'), (6 , 'G'), (6, 'H'),
; (7, 'A'), (7, 'B'), (7, 'C'), (7, 'D'), (7, 'E'), (7, 'F'), (7 , 'G'), (7, 'H')]

Python підтримує різні модні аргументи та аргументи ключових слів. У Python ми могли б
побачити:

>>> def optional_arg(pos1, pos2, keyword1=None, keyword2=42):
... повернути [поз1, поз2, ключове слово1, ключове слово2]
...
>>> необов'язковий_аргу(1, 2)
[1, 2, Немає, 42]
>>> необов'язковий_аргумент(1, 2, 3, 4)
[1, 2, 3, 4]
>>> необов'язковий_аргу(ключове слово1=1, поз2=2, поз1=3, ключове слово2=4)
[3, 2, 1, 4]

Те саме в Hy:

=> (defn optional-arg [pos1 pos2 &optional keyword1 [keyword2 42]]
... [поз1 поз2 ключове слово1 ключове слово2])
=> (необов'язковий аргумент 1 2)
[1 2 Немає 42]
=> (необов'язковий аргумент 1 2 3 4)
[1 2 3 4]

Якщо ви використовуєте версію Hy після 0.10.1 (наприклад, git master), є також гарна нова
Синтаксис аргументу ключового слова:

=> (необов'язковий аргумент :ключове слово1 1
... :pos2 2
... :pos1 3
... :ключове слово2 4)
[3, 2, 1, 4]

В іншому випадку ви завжди можете скористатися застосовувати. Але що застосовувати?

Ви знайомі з проходженням *аргументи та ** кварги на Python?:

>>> аргументи = [1 2]
>>> kwargs = {"ключове слово2": 3
... "ключове слово1": 4}
>>> optional_arg(*args, **kwargs)

Ми можемо відтворити це за допомогою застосовувати:

=> (setv args [1 2])
=> (setv kwargs {"keyword2" 3
... "ключове слово1" 4})
=> (застосувати optional-arg args kwargs)
[1, 2, 4, 3]

Існує також конструкція аргументів ключових слів у стилі словника, яка виглядає так:

(defn other-style [&key {"key1" "val1" "key2" "val2"}]
[ключ 1 ключ2])

Різниця тут у тому, що, оскільки це словник, ви не можете покладатися на якийсь конкретний
впорядкування аргументів.

Hy також підтримує *аргументи та ** кварги. У Python:

def some_func(foo, bar, *args, **kwargs):
імпорт pprint
pprint.pprint((foo, bar, args, kwargs))

Еквівалент Hy:

(defn some-func [foo bar &rest args &kwargs kwargs]
(імпорт pprint)
(pprint.pprint (, foo bar args kwargs)))

Нарешті, звичайно, нам потрібні заняття! У Python у нас може бути такий клас:

клас FooBar (об'єкт):
"" "
Ще один приклад класу
"" "
def __init__(self, x):
self.x = x

def get_x(self):
"" "
Поверніть нашу копію x
"" "
повернути self.x

В Hy:

(defclass FooBar [об'єкт]
«Ще один приклад класу»
[[--у цьому--
(fn [я x]
(setv self.xx)
; Наразі потрібний для --init--, оскільки __init__ не потребує
; Сподіваюся, це піде :)
Жодного)]

[отримати-x
(fn [я]
"Поверніть нашу копію x"
себе.x)]])

Ви також можете виконувати атрибути на рівні класу. У Python:

клас Customer(models.Model):
назва = models.CharField(max_length=255)
адреса = models.TextField()
примітки = models.TextField()

В Hy:

(defclass Customer [models.Model]
[[назва (models.CharField :max-length 255})]
[адреса (models.TextField)]
[примітки (models.TextField)]])

Hy <-> Python interop
Імпортуючи Hy, ви можете використовувати Hy безпосередньо з Python!

Якщо ви збережете наступне в greetings.hy:

(defn greet [ім'я] (надрукуйте "привіт від hy", ім'я))

Тоді ви можете використовувати його безпосередньо з python, імпортуючи hy перед імпортуванням модуля. в
python:

імпорт hy
імпортні привітання

greetings.greet("Foo")

Ви також можете оголосити функцію в python (або навіть клас!) і використовувати її в Hy!

Якщо ви збережете наступне в greetings.py у Python:

def привітати (ім'я):
print("привіт, %s" % (ім'я))

Ви можете використовувати його в Hy:

(імпортні привітання)
(.greet привітання "foo")

Щоб використовувати аргументи ключового слова, можна використовувати in greetings.py:

def greet(name, title="Sir"):
print("Вітаємо, %s %s" % (назва, ім'я))

(імпортні привітання)
(.greet привітання "Foo")
(.greet привітання "Foo" "Darth")
(застосувати (. greetings greet) ["Foo"] {"title" "Lord"})

Що виведе:

Вітаю, сер Фу

Вітаю, Дарт Фу

Вітаю, лорд Фу

Підказки!
Hy також має щось відоме як «макрос потоків», дійсно чудова функція
Clojure. "Макрос потоків" (записується як ->) використовується, щоб уникнути глибокого вкладення
вирази.

Макрос потоку вставляє кожен вираз у перший аргумент наступного виразу
місце.

Візьмемо класику:

(цикл (друк (eval (читати))

Замість того, щоб писати це так, ми можемо написати це так:

(-> (читання) (eval) (друк) (цикл))

Тепер, використовуючи python-sh, ми можемо показати, як потоковий макрос (через налаштування python-sh)
можна використовувати як трубу:

=> (імпорт [sh [cat grep wc]])
=> (-> (cat "/usr/share/dict/words") (grep "-E" "^hy") (wc "-l"))
210

Що, звісно, ​​поширюється на:

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

Набагато читабельніше, чи не так? Використовуйте макрос потоку!

HY СТИЛЬ КЕРІВНИЦТВО


«Ви знаєте, міністре, я не згоден з Дамблдором з багатьох пунктів… але ви не можете заперечувати, що він
отримав стиль...» — Фінеас Найгелус Блек, Гаррі Гончар та замовлення of Фінікс

Посібник зі стилю Hy має намір бути набором основних правил для Hyve (так, спільноти Hy
пишається тим, що додає Hy до всього), щоб написати ідіоматичний код Hy. Хай отримує багато
від Clojure і Common Lisp, завжди зберігаючи сумісність із Python.

Прелюдія
Команда Тао of Hy
Уммон запитав старшого ченця: «Про яку сутру ви читаєте лекції?»
«Нірвана-сутра».
«Нірвана-сутра має чотири чесноти, чи не так?»
"Це має."
Уммон спитала, беручи чашку: «Скільки в цьому достоїнств?»
«Зовсім ніякої», — сказав монах.
— Але стародавні люди казали, що так було, чи не так? — сказав Уммон.
— Що ти думаєш про те, що вони сказали?
Уммон вдарив по чашці й запитав: "Ви розумієте?"
— Ні, — сказав монах.
— Тоді, — сказав Уммон, — вам краще продовжити свої лекції про сутру.
— макрос (коан).

Нижче наведено короткий список дизайнерських рішень, які були розроблені
Hy.

· Виглядає як шепелявець; DTRT з ним (наприклад, тире перетворюються на підкреслення, навушники перетворюються на
великі літери).

· Ми все ще Python. Більшість внутрішніх компонентів перекладають 1:1 на внутрішні елементи Python.

· Використовуйте Unicode скрізь.

· Виправити погані рішення в Python 2, коли ми зможемо (див справжній_ділення).

· Якщо ви сумніваєтеся, зверніться до Python.

· Якщо ви все ще не впевнені, зверніться до Clojure.

· Якщо ви ще більше не впевнені, перейдіть до Common Lisp.

· Майте на увазі, що ми не Clojure. Ми не Common Lisp. Ми Homoiconic Python, з
додаткові біти, які мають сенс.

макет & відступ
· Уникайте пробілів. Вони смокчуть!

· Відступ має складатися з 2 пробілів (без жорстких символів табуляції), за винятком випадків збігу відступу
попередній рядок.

;; Добре (і бажано)
(defn fib [n]
(якщо (<= n 2)
n
(+ (фіб (- n 1)) (фіб (- n 2)))))

;; Все ще добре
(defn fib [n]
(якщо (<= n 2) n (+ (fib (- n 1)) (fib (- n 2)))))

;; Все ще добре
(defn fib [n]
(якщо (<= n 2)
n
(+ (фіб (- n 1)) (фіб (- n 2)))))

;; Істерично смішно
(defn fib [n]
(якщо (<= n 2)
n ;; так, я люблю довільно натискати клавішу пробіл
(+ (фіб (- n 1)) (фіб (- n 2)))))

· Дужки обов’язково ніколи залишатися одні, сумні та самотні на своїй лінії.

;; Добре (і бажано)
(defn fib [n]
(якщо (<= n 2)
n
(+ (фіб (- n 1)) (фіб (- n 2)))))

;; Істерично смішно
(defn fib [n]
(якщо (<= n 2)
n
(+ (фіб (- n 1)) (фіб (- n 2)))
)
) ; ГАХ, СПАЛІТЬ ВОГНЕМ

· Вирівняти по вертикалі дозволяти блоки

(нехай [[foo (bar)]
[qux (baz)]]
(фу qux))

· Вбудовані коментарі мають бути за два пробіли від кінця коду; вони завжди повинні мати a
пробіл між символом коментаря та початком коментаря. Також намагайтеся не робити
коментуйте очевидне.

;; добре
(setv ind (dec x)) ; індексація починається з 0

;; Відповідає стилю, але лише констатує очевидне
(setv ind (dec x)) ; встановлює індекс х-1

;; Погано
(setv ind (dec x)); введення слів для розваги

Кодування стиль
· Як умовність, намагайтеся не використовувати захист для будь-чого, крім глобальних змінних; використання установка
внутрішні функції, цикли тощо.

;; Добре (і бажано)
(зазначення *ліміт* 400000)

(defn fibs [ab]
(поки правда
(вихід а)
(setv (, ab) (, b (+ ab)))))

;; Погано (і не бажано)
(defn fibs [ab]
(поки правда
(вихід а)
(def (, ab) (, b (+ ab)))))

· Не використовуйте синтаксис s-виразу там, де призначений векторний синтаксис. Наприклад, факт
що перший із цих двох прикладів працює лише тому, що компілятор не надто надто
суворий. Насправді правильний синтаксис у таких місцях є останнім.

;; Поганий (і злий)
(defn foo (x) (друк x))
(foo 1)

;; Добре (і бажано)
(defn foo [x] (друк x))
(foo 1)

· Використовуйте макрос потоку або макрос потоку хвоста, коли зустрічаєте глибоко вкладені
s-вирази. Однак будьте розсудливі при їх використанні. Використовуйте їх, коли чіткість і
покращується читабельність; не конструюйте заплутані, важко зрозумілі вирази.

;; Бажано
(визначення *імена*
(з [f (відкрити "names.txt")]
(-> (.read f) (.strip) (.replace "\"" "") (.split ",") (sorted))))

;; Не так добре
(визначення *імена*
(з [f (відкрити "names.txt")]
(відсортовано (.split "," (.replace "\"" "" (.strip (.read f)))))))

;; Мабуть, не дуже гарна ідея
(квадрат визначення? [x]
(->> 2 (pow (int (sqrt x))) (= x)))

· Позначення в стилі Clojure кращим перед прямим викликом методу об'єкта,
хоча обидва й надалі підтримуватимуться.

;; добре
(з [fd (відкрити "/ etc / passwd")]
(друк (.readlines fd)))

;; Не так добре
(з [fd (відкрити "/ etc / passwd")]
(друк (fd.readlines)))

Висновок
«Мода зникає, стиль вічний» — Ів Сен-Лоран

Цей посібник — це лише набір принципів спільноти, і, очевидно, інструкції спільноти є
не має сенсу без активної спільноти. Внески вітаються. Приєднуйтесь до нас на #hy in
freenode, пишіть про це в блозі, твіти про це, а головне, розважайтеся з Hy.

Дякую
· Цей посібник дуже натхненний @paulttag допис у блозі Hy Виживання керівництво

· Clojure стиль керівництво

ДОКУМЕНТАЦІЯ ІНДЕКС


Зміст:

Command Лінія інтерфейс
hy
Command Лінія Опції
-c
Виконайте код Hy команда.

$ hy -c "(друк (+ 2 2))"
4

-i
Виконайте код Hy команда, потім залишайтеся в REPL.

-m
Виконайте код Hy Модулі, У тому числі defmain якщо визначено.

Команда -m flag завершує список параметрів, щоб усі аргументи після Модулі ім'я
передаються до модуля в sys.argv.

Нове у версії 0.10.2.

--шпигун Надрукуйте еквівалентний код Python перед виконанням. Наприклад:

=> (defn salutationsnm [ім'я] (друк (+ "Hy " name "!")
def salutationsnm(ім'я):
return print(((u'Hy ' + ім'я) + u'!'))
=> (вітання nm "Ваше ім'я")
salutationsnm(u'Ваше ім'я')
Хай, твоє ім'я!
=>

Нове у версії 0.9.11.

--show-tracebacks
Друк розширеного зворотного відстеження для винятків Hy.

Нове у версії 0.9.12.

-v Надрукуйте номер версії Hy та вийдіть.

hyc
Command Лінія Опції
файл [, файл N]
Скомпілювати код Hy в байт-код Python. Наприклад, збережіть наступний код як
hyname.hy:

(defn hy-hy [ім'я]
(друк (+ "Hy " name "!")

(hy-hy "Афроман")

Потім запустіть:

$ hyc hyname.hy
$ python hyname.pyc
Привіт Афроман!

hy2py
Нове у версії 0.10.1.

Command Лінія Опції
-s

--з джерелом
Показати проаналізовану вихідну структуру.

-a

--з-аст
Показати згенерований AST.

-наприклад

--без-python
Не показувати код Python, згенерований з AST.

Hy ( мова)
ПОПЕРЕДЖЕННЯ:
Це неповно; будь ласка, подумайте про свій внесок у роботу з документування.

Theory of Hy
Hy підтримує, крім усього іншого, 100% сумісність в обох напрямках з Python
себе. Весь код Hy відповідає кільком простим правилам. Запам’ятайте це, оскільки воно вийде
зручно.

Ці правила допомагають гарантувати, що код Hy є ідіоматичним і інтерфейсним на обох мовах.

· Символи в навушниках будуть перекладені у верхній регістр цього рядка. Для
наприклад, Foo стане FOO.

· Об’єкти UTF-8 будуть закодовані за допомогою punycode і з префіксом hy_. Наприклад,
стане hy_w7h, стане hy_g6h та я♥у стане hy_iu_t0x.

· Символи, які містять тире, будуть замінені символами підкреслення. Наприклад,
рендер-шаблон стане render_template. Це означає, що символи з тире будуть
затінюють їхні еквіваленти підкреслення, і навпаки.

Вбудовані
Hy містить ряд спеціальних форм, які використовуються для створення правильного Python AST.
Нижче наведено «спеціальні» форми, поведінка яких може бути трохи неочікуваною
деякі ситуації.

.
Нове у версії 0.10.0.

. використовується для доступу до об’єктів до атрибутів. Він використовує невеликий DSL для швидкого
доступ до атрибутів і елементів у вкладеній структурі даних.

Так, наприклад,

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

Компілюється до:

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

. компілює свій перший аргумент (у прикладі, Foo) як об'єкт, на якому потрібно зробити
розіменування атрибутів. Він використовує голі символи як атрибути для доступу (у прикладі, бар,
Baz, фроб), і компілює вміст списків (у прикладі, [(+ 1 2)]) для індексації.
Інші аргументи викликають помилку компіляції.

Доступ до невідомих атрибутів викликає an AttributeError. Доступ до невідомих ключів кидає an
Помилка IndexError (у списках і кортежах) або a KeyError (за словниками).

->
-> (Або різьблення макрос) використовується, щоб уникнути вкладення виразів. Макрос потоку
вставляє кожен вираз у місце першого аргументу наступного виразу. Наступне
код демонструє це:

=> (вивід визначення [ab] (друк ab))
=> (-> (+ 4 6) (вихід 5))
10 5

- >>
- >> (Або різьблення хвіст макрос) схожий на різьблення макрос, але замість
вставляючи кожен вираз у перший аргумент наступного виразу, він додає його як
останній аргумент. Наступний код демонструє це:

=> (вивід визначення [ab] (друк ab))
=> (->> (+ 4 6) (вихід 5))
5 10

застосовувати
застосовувати використовується для застосування необов'язкового списку аргументів і необов'язкового словника kwargs
до функції.

Використання: (застосувати fn-ім'я [args] [кварги])

Приклади:

(defn thunk []
"привіт")

(застосувати thunk)
;=> "привіт"

(визначення загальної суми покупки [сума ціни та необов'язкове [комісія 1.05] [пДВ 1.1]]
(* сума ціна комісія з ПДВ))

(застосувати total-purchase [10 15])
;=> 173.25

(застосувати total-purchase [10 15] {"vt" 1.05})
;=> 165.375

(застосувати total-purchase [] {"ціна" 10 "сума" 15 "пДВ" 1.05})
;=> 165.375

та
та використовується в логічних виразах. Для цього потрібні щонайменше два параметри. Якщо всі параметри
оцінити до Правда, повертається останній параметр. У будь-якому іншому випадку перше хибне значення
буде повернено. Приклад використання:

=> (і правда, неправда)
Помилковий

=> (і True True)
Правда

=> (і правда 1)
1

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

ПРИМІТКА:
та замикає і припиняє оцінку параметрів, як тільки виявляється перша помилка
стикалися.

=> (і False (друк "привіт"))
Помилковий

стверджувати
стверджувати використовується для перевірки умов під час роботи програми. Якщо умова ні
зустрівся, ан Помилка AssertionError піднімається. стверджувати може приймати один або два параметри. Перший
Параметр — це умова, яку потрібно перевірити, і він має оцінювати будь-яку з них Правда or Помилковий,
другий параметр, необов'язковий, є міткою для підтвердження і є рядком, який буде
піднятий з Помилка AssertionError, Наприклад:

(стверджувати (= змінна очікуване значення))

(стверджувати невірно)
; AssertionError

(стверджують (= 1 2) «один повинен дорівнювати двом»)
; AssertionError: один має дорівнювати двом

доц
доц використовується для зв’язування ключа зі значенням у словнику або для встановлення індексу списку
до значення. Для цього потрібні щонайменше три параметри: дані структура бути зміненим, а ключ
or індекс, А в значення. Якщо використовується більше трьох параметрів, він буде зв’язуватися парами.

Приклади використання:

=>(нехай [[колекція {}]]
... (дос.збірка «Собака» «Гав»)
... (колекція друку))
{u'Dog': u'Bark'}

=>(нехай [[колекція {}]]
... (досл. збірки «Собака» «Гавок» «Кіт» «Няу»)
... (колекція друку))
{u'Cat': u'Meow', u'Dog': u'Bark'}

=>(нехай [[колекція [1 2 3 4]]]
... (досл. збірка 2 Немає)
... (колекція друку))
[1, 2, Немає, 4]

ПРИМІТКА:
доц змінює структуру даних на місці та повертає ніхто.

перерву
перерву використовується для виходу з петлі. Цикл негайно закінчується. Наступне
приклад має нескінченність в той час як цикл, який завершується, щойно користувач входить k.

(у той час як True (якщо (= "k" (необроблений вхід "? "))
(перерву)
(друк "Спробуй ще раз")))

кондиц
кондиц можна використовувати для створення вкладених if заяви. Наступний приклад показує
зв'язок між макросом та його розширенням:

(cond [умова-1 результат-1]
[умова-2 результат-2])

(якщо умова-1 результат-1
(якщо умова-2 результат-2))

Як показано нижче, виконується лише перший відповідний блок результату.

=> (defn контрольне значення [значення]
... (cond [(< значення 5) (друк "значення менше 5")]
... [(= значення 5) (друк "значення дорівнює 5")]
... [(> значення 5) (друк "значення більше 5")]
... [Правда (друк "цінність - це те, чого не повинно бути")]))

=> (контрольне значення 6)
значення більше 5

продовжувати
продовжувати повертає виконання на початок циклу. У наступному прикладі
(побічний ефект1) викликається для кожної ітерації. (побічний ефект2), однак, викликається лише
кожне інше значення в списку.

;; припускаючи, що (side-effect1) і (side-effect2) є функціями і
;; Колекція — це список числових значень

(для [x колекції]
(робити
(побічний ефект 1 x)
(якщо (% x 2)
(продовжити))
(побічний ефект2 x)))

dict-comp
dict-comp використовується для створення словників. Для цього потрібні три-чотири параметри. Перший
два параметри призначені для керування значенням, що повертається (парою ключ-значення), а третій — це
використовується для вибору елементів із послідовності. Можна використовувати четвертий і необов’язковий параметр
відфільтрувати деякі елементи послідовності на основі умовного виразу.

=> (dict-comp x (* x 2) [x (діапазон 10)] (непарний? x))
{1: 2, 3: 6, 9: 18, 5: 10, 7: 14}

do / прогн
do та прогн використовуються для оцінки кожного з їхніх аргументів і повернення останнього. Повернення
значення з усіх інших аргументів, ніж останній, відкидаються. Його можна використовувати в лямбда or
список-комп для виконання більш складної логіки, як показано в одному з наступних прикладів.

Деякі приклади використання:

=> (якщо правда
... (зробити (друкувати "Побічні ефекти рок!")
... (друк "Так, справді!")))
Побічні ефекти рок!
Так, справді!

;; припускаючи, що (побічний ефект) є функцією, яку ми хочемо викликати для кожної з них
;; і кожне значення в списку, але чиє повертається значення нам не цікаве
=> (list-comp (do (побічний ефект x)
... (якщо (< x 5) (* 2 x)
... (* 4 х)))
... (x (діапазон 10)))
[0, 2, 4, 6, 8, 20, 24, 28, 32, 36]

do може приймати будь-яку кількість аргументів, від 1 до n.

захист / установка
захист та установка використовуються для прив’язки значення, об’єкта або функції до символу. Наприклад:

=> (def names ["Аліса" "Боб" "Чарлі"])
=> (друкувати назви)
[u'Alice', u'Bob', u'Charlie']

=> (лічильник setv (fn [предмет колекції] (.count collection item)))
=> (лічильник [1 2 3 4 5 2 3] 2)
2

defclass
Нові класи оголошуються з defclass. Він може приймати два необов’язкових параметра: вектор
визначення можливих суперкласів та іншого вектора, що містить атрибути new
клас у вигляді двох векторів елементів.

(назва класу defclass [супер-клас-1 супер-клас-2]
[[значення атрибута]])

І значення, і функції можна прив’язати до нового класу, як показано на прикладі нижче:

=> (defclass Cat []
... [[вік немає]
... [колір "білий"]
... [говорити (fn [само] (друкувати "мяу"))]])

=> (деф-спот (Кіт))
=> (setv spot.colour "Чорний")
'чорний'
=> (.говорити місце)
мяу

деф / розвінчуватися
деф та розвінчуватися макроси використовуються для визначення функцій. Вони приймають три параметри: ім'я
функції для визначення, вектор параметри, А тіло функції:

(назва визначення [параметри] тіло)

Перед параметрами можуть бути такі ключові слова:

&необов’язково
Параметр необов’язковий. Параметр можна надати у вигляді списку з двох елементів, де
перший елемент - це ім'я параметра, а другий - значення за замовчуванням. Параметр
також можна надати як один елемент, у цьому випадку значення за замовчуванням є ніхто.

=> (defn total-value [значення &опціонально [податок на додану вартість 10]]
... (+ (/ (* вартість податок на додану вартість) 100) вартість))

=> (загальне значення 100)
110.0

=> (загальне значення 100 1)
101.0

&ключ

&kwargs
Параметр міститиме 0 або більше аргументів ключового слова.

Наведені нижче приклади коду визначають функцію, яка друкуватиме всі ключові слова
аргументи та їх значення.

=> (defn print-parameters [&kwargs kwargs]
... (для [(, kv) (.items kwargs)] (друк kv)))

=> (застосувати параметри друку [] {"параметр-1" 1 "параметр-2" 2})
параметр-2 2
параметр-1 1

&відпочинок Параметр міститиме 0 або більше позиційних аргументів. Іншої позиційної немає
аргументи можуть бути вказані після цього.

Наступний приклад коду визначає функцію, якій можна надати числові значення від 0 до n
параметри. Потім він підсумовує кожне непарне число і віднімає кожне парне число.

=> (defn zig-zag-sum [&решта чисел]
(нехай [[непарні числа (список-комп x [x чисел] (непарні? x))]
[парні числа (список-комп. x [x чисел] (парні? x))]]
(- (сума непарних чисел) (сума парних чисел))

=> (зигзаг-сума)
0
=> (зигзаг-сума 3 9 4)
8
=> (зигзаг-сума 1 2 3 4 5 6)
-3

псевдонім defn / псевдонім defun
Нове у версії 0.10.0.

Команда псевдонім defn та псевдонім defun макроси дуже схожі деф, з тією відмінністю, що
замість визначення функції з одним ім'ям, вони також можуть визначати псевдоніми. Інший
ніж взяти список символів для назв функцій як перший параметр, псевдонім defn та
псевдонім defun нічим не відрізняються від деф та розвінчуватися.

=> (defn-псевдонім [псевдонім основного імені] []
... (друк "Привіт!"))
=> (основне ім'я)
"Здрастуйте!"
=> (псевдонім)
"Здрастуйте!"

defmain
Нове у версії 0.10.1.

Команда defmain макрос визначає головну функцію, яка негайно викликається with sys.argv as
аргументи тоді і тільки тоді, коли цей файл виконується як сценарій. Іншими словами, це:

(defmain [&rest args]
(робити щось із аргументами))

є еквівалентом:

def main(*args):
do_something_with(args)
повернення 0

якщо __name__ == "__main__":
імпортувати sys
retval = main(*sys.arg)

якщо isinstance(retval, int):
sys.exit(retval)

Зауважте, що, як ви бачите вище, якщо ви повернете ціле число з цієї функції, це буде
використовується як статус виходу для вашого сценарію. (Python за замовчуванням виходить зі статусу 0, інакше,
це означає, що все добре!)

(З тих пір (sys.exit 0) не запускається явно у випадку нецілого повернення з
defmain, це гарна ідея поставити (defmain) як останній фрагмент коду у вашому файлі.)

defmacro
defmacro використовується для визначення макросів. Загальний формат такий (defmacro ім'я [параметри]
вираз).

Наступний приклад визначає макрос, який можна використовувати для зміни порядку елементів у коді,
дозволяє користувачеві писати код в інфіксній нотації, де оператор знаходиться між символами
операнди.

=> (інфікс defmacro [код]
... (квазіцитата (
... (скасувати цитати (отримати код 1))
... (скасувати цитати (отримати код 0))
... (скасувати цитати (отримати код 2)))))

=> (інфікс (1 + 1))
2

псевдонім defmacro
псевдонім defmacro використовується для визначення макросів з кількома іменами (псевдонімами). Загальний формат
is (псевдонім defmacro [імена] [параметри] вираз). Він створює кілька макросів з однаковими
список параметрів і тіло, під вказаним списком імен.

У наступному прикладі визначаються два макроси, обидва з яких дозволяють користувачеві писати код
інфіксне позначення.

=> (псевдонім defmacro [infix infi] [код]
... (квазіцитата (
... (скасувати цитати (отримати код 1))
... (скасувати цитати (отримати код 0))
... (скасувати цитати (отримати код 2)))))

=> (інфікс (1 + 1))
2
=> (infi (1 + 1))
2

defmacro/g!
Нове у версії 0.9.12.

defmacro/g! є спеціальною версією defmacro який використовується для автоматичного створення gensym
для будь-якого символу, який починається з g!.

Наприклад, g!a став би (генсим "а").

СМ ТАКОЖ:
Розділ використання-gensym

розчитувач
Нове у версії 0.9.12.

розчитувач визначає макрос зчитувача, що дозволяє реструктуризувати або змінювати синтаксис.

=> (розшифровувач ^ [expr] (друк expr))
=> #^(1 2 3 4)
(1)
=> #^"Привіт"
"Здравствуйте"

СМ ТАКОЖ:
Макроси для читання розділів

Дель
Нове у версії 0.9.12.

Дель видаляє об’єкт з поточного простору імен.

=> (setv foo 42)
=> (del foo)
=> фу
Traceback (останній останній дзвінок):
Файл " ", рядок 1, в
NameError: ім'я 'foo' не визначено

Дель також можна видаляти об’єкти з відображень, списків тощо.

=> (тест setv (список (діапазон 10)))
=> тест
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
=> (del (зріз тесту 2 4)) ;; видалити елементи з 2 по 4 виключені
=> тест
[0, 1, 4, 5, 6, 7, 8, 9]
=> (setv dic {"foo" "bar"})
=> dic
{"foo": "bar"}
=> (del (отримати dic "foo"))
=> dic
{}

робити
Нове у версії 0.10.1.

робити використовується для спрощення послідовності викликів методів до об’єкта.

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

=> (колекція setv [])
=> (.додати колекцію 1)
=> (.додати колекцію 2)
=> (.зворотна колекція)
=> колекція
[2 1]

евал
евал оцінює вираз у лапках і повертає значення.

=> (eval '(друк "Hello World"))
"Привіт Світ"

eval-and-compile
eval-when-compile
перший / автомобіль
перший та автомобіль є макросами для доступу до першого елемента колекції:

=> (перший (діапазон 10))
0

та цінності
та цінності використовується для виклику функції для кожного елемента в списку або векторі. Результати кожного
виклик відхиляються, і та цінності вираз повертає ніхто замість цього. Код прикладу повторюється
над збір і для кожного елемент in збір телефонує побічний ефект функція за допомогою
елемент як його аргумент:

;; припускаючи, що (побічний ефект) є функцією, яка приймає один параметр
(для [колекції елементів] (елемент побічних ефектів))

;; for може мати необов'язковий блок else
(для [колекції елементів] (елемент побічних ефектів)
(Інше (побічний ефект-2)))

The optional ще блок виконується, лише якщо та цінності цикл завершується нормально. Якщо
виконання зупинено с перерву, ще блок не виконується.

=> (для [елемента [1 2 3]] (якщо (< елемент 3)
... (елемент друку)
... (перерву))
... (інакше (друк "цикл закінчено")))
1
2

=> (для [елемента [1 2 3]] (якщо (< елемент 4)
... (елемент друку)
... (перерву))
... (інакше (друк "цикл закінчено")))
1
2
3
цикл закінчено

geneexpr
geneexpr використовується для створення генераторних виразів. Для цього потрібні два-три параметри. The
перший параметр - це вираз, що контролює значення, що повертається, а другий використовується
щоб вибрати елементи зі списку. Третій і необов’язковий параметр можна використовувати для фільтрації
деякі елементи в списку засновані на умовному виразі. geneexpr аналогічно
список-комп, за винятком того, що він повертає ітератор, який оцінює значення по одному замість
негайно оцінюючи їх.

=> (колекція def (діапазон 10))
=> (відфільтровано за визначенням (genexpr x [x collection] (навіть? x)))
=> (список відфільтровано)
[0, 2, 4, 6, 8]

gensym
Нове у версії 0.9.12.

gensym використовується для створення унікального символу, який дозволяє записувати макроси без
випадкові зіткнення імені змінної.

=> (gensym)
u':G_1235'

=> (рід "x")
u':x_1236'

СМ ТАКОЖ:
Розділ використання-gensym

отримати
отримати використовується для доступу до окремих елементів у списках і словниках. отримати приймає два параметри:
дані структура і індекс or ключ пункту. Потім він поверне відповідне
значення зі словника або списку. Приклад використання:

=> (нехай [[тварини {"собака" "гавкає" "кіт" "мяу"}]
... [числа ["нуль" "один" "два" "три"]]]
... (роздрукувати (отримати тварин «собака»))
... (роздрукувати (отримати цифри 2)))
кора
два

ПРИМІТКА:
отримати викликає KeyError, якщо до словника запитується неіснуючий ключ.

ПРИМІТКА:
отримати викликає IndexError, якщо список або кортеж запитується щодо індексу, який не є
межі.

в цілому
в цілому можна використовувати для позначення символу як глобального. Це дозволяє програмісту призначити a
значення глобального символу. Читання глобального символу не вимагає в цілому ключове слово --
це робить лише призначення.

У наступному прикладі показано, як глобальний символ a призначається значення у функції та
пізніше друкується в іншій функції. Без в цілому ключове слово, друга функція
кинув би а Помилка імені.

(defn set-a [значення]
(глобальний а)
(встановити значення))

(defn print-a []
(друк а))

(набір-5)
(друк-а)

if / якщо ні
Нове у версії 0.10.0: якщо-ні

if використовується для умовного вибору коду для виконання. Він повинен містити умову
блок і блок, який буде виконано, якщо умовний блок оцінить як Правда. за бажанням,
він може містити кінцевий блок, який виконується у випадку, якщо оцінка умови є
Помилковий.

якщо ні подібний, але другий блок буде виконано, коли умова не виконується while
третій і останній блок виконується, коли тест проходить успішно – у протилежному порядку if.

Приклад використання:

(якщо (залишилися гроші? рахунок)
(друкувати «ходімо за покупками»)
(друкувати "їдемо працювати"))

(якщо ні (залишилися гроші? рахунок)
(друкувати «ходімо працювати»)
(друкуйте "ходімо за покупками"))

Правдивість Python поважається. ніхто, Помилковий, нуль будь-якого числового типу, порожня послідовність,
і порожній словник вважаються Помилковий; все інше враховується Правда.

шепелявець-якщо / волокно та шепелявий-якщо-ні / лайф-не
Нове у версії 0.10.0.

Нове у версії 0.10.2: lisp-if-not / lif-not

Для тих, хто віддає перевагу більш Lispy if пункт, ми маємо шепелявець-якщоабо волокно, це тільки вважає
ніхто / нуль бути фальшивим! Усі інші "false-ish" значення Python вважаються істинними.
І навпаки, маємо шепелявий-якщо-ні та лайф-не паралельно до if та якщо ні який перевертається
порівняння.

=> (шепелявість-якщо True "true" "false")
"True"
=> (lisp-if False "true" "false")
"True"
=> (lisp-якщо 0 "правда", "неправда")
"True"
=> (lisp-якщо nil "true", "false")
"False"
=> (lisp-if None "true", "false")
"False"
=> (lisp-if-not nil "true" "false")
"True"
=> (lisp-if-none None "true" "false")
"True"
=> (lisp-if-not False "true" "false")
"False"

; Еквівалентно, але коротше
=> (lif True "true" "false")
"True"
=> (lif nil "true" "false")
"False"
=> (lif-not None "true" "false")
"True"

імпорт
імпорт використовується для імпорту модулів, як у Python. Існує кілька способів імпорт може
бути використаним.

;; Імпортує кожен із цих модулів
;;
;; Python:
;; імпортувати sys
;; імпортувати os.path
(імпортувати sys os.path)

;; Імпорт із модуля
;;
;; Python: з os.path імпорт існує, isdir, isfile
(імпорт [os.path [існує isdir isfile]])

;; Імпорт із псевдонімом
;;
;; Python: імпортувати sys як systest
(імпортувати [sys :as systest])

;; Ви можете перерахувати будь-яку кількість імпортів різних типів.
(імпорт [tests.resources [kwtest function-with-a-dash]]
[os.path [існує isdir isfile]]
[sys: as systest])

;; Імпортуйте всі функції модуля в поточний простір імен
(імпортувати [sys [*]])

лямбда / fn
лямбда та fn можна використовувати для визначення анонімної функції. Параметри аналогічні
деф: перший параметр — це вектор параметрів, а решта — тіло параметра
функції. лямбда повертає нову функцію. У наступному прикладі анонімна функція
визначається і передається іншій функції для фільтрації виводу.

=> (def people [{:name "Alice" :age 20}
... {:name "Bob" :age 25}
... {:name "Чарлі" :вік 50}
... {:name "Dave" :age 5}])

=> (defn display-people [фільтр людей]
... (для [особи людей] (якщо (фільтр особи) (друк (:назва людини)))))

=> (відображати людей (fn [особа] (< (: вік людини) 25)))
Аліса
Дейв

Так само, як і у звичайних визначеннях функцій, якщо першим елементом тіла є рядок, він
служить рядком документів. Це корисно для надання методам класу рядків документів.

=> (setv разів-три
... (fn [x]
... "Помножує введені дані на три і повертає результат."
... (* х 3)))

Це можна підтвердити за допомогою вбудованого Python допомога функція:

=> (довідка разів-три)
Довідка щодо функції times_three:

разів_три (x)
Помножує введені дані на три і повертає результат
(КІНЕЦЬ)

останній
Нове у версії 0.10.2.

останній можна використовувати для доступу до останнього елемента колекції:

=> (останнє [2 4 6])
6

дозволяти
дозволяти використовується для створення змінних із лексичною областю дії. Вони створені на початку ст
дозволяти форму і перестають існувати після форми. Наступний приклад демонструє це
поведінка:

=> (нехай [[x 5]] (друк x)
... (нехай [[x 6]] (друк x))
... (друк x))
5
6
5

Команда дозволяти макрос приймає два параметри: визначення вектора змінні і тіло який отримує
страчено. змінні це вектор, де кожен елемент є або окремою змінною, або вектором
визначення пари значень змінної. У разі однієї змінної їй присвоюється значення
ніхто; в іншому випадку використовується надане значення.

=> (нехай [x [y 5]] (друк xy))
Жодного 5

список-комп
список-комп виконує осмислення списку. Для цього потрібні два-три параметри. Перший
Параметр — це вираз, що контролює значення, що повертається, тоді як другий використовується
виберіть елементи зі списку. Третій і необов’язковий параметр можна використовувати, щоб відфільтрувати деякі
елементів у списку на основі умовного виразу. Деякі приклади:

=> (колекція def (діапазон 10))
=> (list-comp x [x collection])
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

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

=> (список-комп. (* x 2) [х колекція] (< x 5))
[0, 2, 4, 6, 8]

НЕ
НЕ використовується в логічних виразах. Він приймає один параметр і повертає зворотний
істинна цінність. Якщо Правда задається як параметр, Помилковий буде повернено, і навпаки.
Приклад використання:

=> (неправда)
Помилковий

=> (не хибно)
Правда

=> (не Жодного)
Правда

or
or використовується в логічних виразах. Для цього потрібні щонайменше два параметри. Це поверне
перший нехибний параметр. Якщо такого значення не існує, буде повернуто останній параметр.

=> (або True False)
Правда

=> (і False False)
Помилковий

=> (і False 1 True False)
1

ПРИМІТКА:
or замикає і припиняє оцінку параметрів, як тільки буде перше істинне значення
стикалися.

=> (або True (друк "привіт"))
Правда

друк
друк використовується для виведення на екран. Приклад використання:

(друк «Привіт, світ!»)

ПРИМІТКА:
друк завжди повертається ніхто.

квазіцитата
квазіцитата дозволяє цитувати форму, а також вибірково оцінювати вирази.
Вирази всередині а квазіцитата можна вибірково оцінити за допомогою без коментарів (~).
оцінену форму також можна зрощувати за допомогою зрощення лапок (~@). Також може бути квазіцитата
написаний із використанням зворотних лапок (`) символ.

;; нехай `qux' буде змінною зі значенням (бар бази)
`(foo ~qux)
; еквівалент '(foo (bar baz))
`(фу ~@qux)
; еквівалент '(foo bar baz)

цитувати
цитувати повертає передану йому форму, не оцінюючи її. цитувати як альтернатива може бути
пишеться з використанням апострофа (') символ.

=> (setv x '(друк "Hello World"))
; змінна x має значення виразу і не оцінюється
=> х
(u'print' u'Hello World')
=> (eval x)
Привіт світ

вимагати
вимагати використовується для імпорту макросів із заданого модуля. Для цього потрібно хоча б один параметр
вказуючи модуль, які макроси слід імпортувати. Можна імпортувати декілька модулів
з єдиним вимагати.

Наступний приклад імпортує макроси з модуль-1 та модуль-2:

(потрібний модуль-1 модуль-2)

відпочинок / Cdr
відпочинок та Cdr повернути колекцію, передану як аргумент без першого елемента:

=> (відпочинок (діапазон 10))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

набір-комп
набір-комп використовується для створення наборів. Для цього потрібні два-три параметри. Перший параметр
для керування значенням, що повертається, а другий використовується для вибору елементів з a
послідовність. Третій і необов’язковий параметр можна використовувати, щоб відфільтрувати деякі елементи
послідовність на основі умовного виразу.

=> (дані установки [1 2 3 4 5 2 3 4 5 3 4 5])
=> (set-comp x [x data] (непарний? x))
{1, 3, 5}

частина
частина можна використовувати, щоб взяти підмножину списку та створити з нього новий список. Форма
приймає принаймні один параметр, що вказує список для поділу. Можуть бути два необов’язкові параметри
використовується для визначення початкової та кінцевої позиції підмножини. Якщо вони не надаються, то
значення за замовчуванням ніхто замість цього буде використано. Третій необов'язковий параметр використовується для
контрольний крок між елементами.

частина дотримується тих же правил, що й його аналог Python. Підраховуються негативні індекси
починаючи з кінця списку. Деякі приклади використання:

=> (колекція def (діапазон 10))

=> (колекція фрагментів)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

=> (збірка фрагментів 5)
[5, 6, 7, 8, 9]

=> (колекція фрагментів 2 8)
[2, 3, 4, 5, 6, 7]

=> (колекція фрагментів 2 8 2)
[2, 4, 6]

=> (збірка фрагментів -4 -2)
[6, 7]

кидати / підвищення
Команда кидати or підвищення форми можна використовувати для підвищення an Виняток під час виконання. Приклад використання:

(кинути)
; повторно сформуйте останній виняток

(викинути помилку IOEror)
; Викидає помилку IOEror

(кинути (IOError "foobar"))
; Видати помилку IOError("foobar")

кидати може прийняти один аргумент (an Виняток клас або екземпляр) або без аргументів до
повторно підняти останній Виняток.

намагатися
Команда намагатися форма використовується для початку a намагатися / зловити блокувати. Форма використовується наступним чином:

(спробуйте
(функція, схильна до помилок)
(ловити [e ZeroDivisionError] (друкувати "Ділення на нуль"))
(інакше (друк "без помилок"))
(нарешті (друк "все готово"))

намагатися має містити принаймні один зловити блок, і за бажанням може включати an ще or в кінці кінців
блокувати. Якщо виникла помилка з відповідним блоком catch під час виконання
функція, схильна до помилок, Що зловити блок буде виконано. Якщо помилок не виявлено, то ще
блок виконується. The в кінці кінців блок буде виконано останнім, незалежно від того, чи є an
виникла помилка.

якщо не
Команда якщо не макрос – це скорочення для запису if твердження, яке перевіряє, чи дано
умовний є Помилковий. Нижче показано розширення цього макросу.

(крім умовного твердження)

(якщо умовно
ніхто
(робити заяву))

без коментарів
У формі квазі лапок, без коментарів силове оцінювання символу. без коментарів має псевдонім
тильда (~) символ.

(визначена назва "Cuddles")
(квазіцитата (= ім'я (ім'я без лапок))
;=> (u'=' u'name' u'Cuddles')

`(= ім'я ~ім'я)
;=> (u'=' u'name' u'Cuddles')

зрощення лапок
зрощення лапок змушує оцінювати символ у формі квазі лапок, так само
без коментарів. зрощення лапок можна використовувати лише тоді, коли символ без лапок містить символ
iterable значення, оскільки воно "з'єднує" це ітераційне значення у форму квазі лапок. зрощення лапок is
псевдонімом ~@ символ.

(числа за визначенням [1 2 3 4])
(квазі лапки (+ (числа без лапок)
;=> (u'+' 1L 2L 3L 4L)

`(+ ~@числа)
;=> (u'+' 1L 2L 3L 4L)

коли
коли аналогічно якщо не, за винятком того, що він перевіряє, коли даний умовний є Правда. Це не так
можливо мати ще блок в а коли макрос. Нижче показано розширення
макрос.

(коли умовний оператор)

(якщо умовний (виконувати оператор))

в той час як
в той час як використовується для виконання одного або кількох блоків, якщо виконується умова. Наступне
приклад виведе "Hello world!" на екран на невизначений термін:

(у той час як True (друк "Hello world!"))

з
з використовується для обгортання виконання блоку в диспетчері контексту. Контекст
менеджер може потім налаштувати локальну систему та зруйнувати її контрольованим способом. The
архетиповий приклад використання з при обробці файлів. з може прив’язати контекст до an
аргументувати або повністю ігнорувати його, як показано нижче:

(з блоком [[arg (expr)]])

(з блоком [[(expr)]])

(з блоком [[arg (expr)] [(expr)]])

Наступний приклад відкриє файл НОВИНИ файл і роздрукуйте його вміст на екрані. The
файл автоматично закривається після його обробки.

(з [[f (відкрити "НОВИНИ")]] (друк (.читати f)))

з-декоратор
з-декоратор використовується для обгортання функції іншою. Функція, що виконує
decoration має приймати одне значення: функцію, що декорується, і повертати нове
функції. з-декоратор приймає мінімум два параметри: виконуюча функція
прикраса та функція, що декорується. Може бути більше однієї функції декоратора
прикладна; вони будуть застосовані в порядку від крайнього до внутрішнього, тобто. перший
декоратор буде крайнім, і так далі. Декоратори з аргументами називаються справедливими
як виклик функції.

(з-декоратор декоратор-забава
(defn some-function [] ...)

(з декоратором декоратор1 декоратор2 ...
(defn some-function [] ...)

(з-декоратором (декоратор arg) ..
(defn some-function [] ...)

У наступному прикладі вкл-декоратор використовується для прикраси функції доповнення з
функція, яка приймає два параметри і викликає декоровану функцію зі значеннями
збільшується на 1. При оформленні доповнення викликається зі значеннями 1 і 1, кінець
результат буде 4 (1+1 + 1+1).

=> (defn inc-decorator [func]
... (fn [значення-1 значення-2] (func (+ значення-1 1) (+ значення-2 1))
=> (defn inc2-decorator [func]
... (fn [значення-1 значення-2] (func (+ значення-1 2) (+ значення-2 2))

=> (with-decorator inc-decorator (defn додавання [ab] (+ ab)))
=> (додаток 1 1)
4
=> (with-decorator inc2-decorator inc-decorator
... (зазначення додавання [ab] (+ ab)))
=> (додаток 1 1)
8

з-генсимами
Нове у версії 0.9.12.

з-генсим використовується для створення набору gensym для використання в макросі. Наступний код:

(with-gensyms [abc]
...)

розширюється до:

(нехай [[a (gensym)
[b (gensym)
[c (gensym)]]
...)

СМ ТАКОЖ:
Розділ використання-gensym

Поступатися
Поступатися використовується для створення об’єкта генератора, який повертає одне або кілька значень. Генератор
є повторюваним і тому може використовуватися в циклах, осмисленні списків тощо
конструкти.

Функція випадкові числа показує, як генератори можна використовувати для створення нескінченних рядів
без споживання нескінченної кількості пам'яті.

=> (defn множити [базисні коефіцієнти]
... (для [[(, базовий коефіцієнт) (основні коефіцієнти zip)]]
... (дохідність (* базовий коефіцієнт))

=> (помножити (діапазон 5) (діапазон 5))


=> (значення списку-комп. [значення (помножити (діапазон 10) (діапазон 10))])
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

=> (випадковий імпорт)
=> (defn випадкові числа [низьке високе]
... (у той час як True (прибутковість (.randint випадкова низька висока))
=> (list-comp x [x (взяти 15 (випадкові числа 1 50))])])
[7, 41, 6, 22, 32, 17, 5, 38, 18, 38, 17, 14, 23, 23, 19]

вихід-від
Нове у версії 0.9.13.

ПІТОН 3.3 І UP ТІЛЬКИ!

вихід-від використовується для виклику підгенератора. Це корисно, якщо ви хочете, щоб ваша сопрограмма
мати можливість делегувати свої процеси іншій спрограмі, скажімо, якщо використовувати щось фантастичне
asyncio.

Hy Core
Core Функції
алеостаннє
Використання: (але останнє кол)

Повертає ітератор усіх елементів, крім останнього зб.

=> (список (але останній (діапазон 10)))
[0, 1, 2, 3, 4, 5, 6, 7, 8]

=> (список (але останній [1]))
[]

=> (список (але останній []))
[]

=> (імпортувати itertools)
=> (список (взяти 5 (але останній (itertools.count 10))
[10, 11, 12, 13, 14]

кол?
Нове у версії 0.10.0.

Використання: (збір? x)

Повернення Правда if x є ітераційним, а не рядком.

=> (збиратися? [1 2 3 4])
Правда

=> (збиратися? {"a" 1 "b" 2})
Правда

=> (збірка? "abc")
Помилковий

мінуси
Нове у версії 0.10.0.

Використання: (мінуси a b)

Повертає свіжу камеру мінусів з автомобілем a і cdr b.

=> (setv a (мінуси 'hd 'tl))

=> (= 'hd (автомобіль))
Правда

=> (= 'tl (cdr a))
Правда

мінуси?
Нове у версії 0.10.0.

Використання: (мінуси? фу)

Перевіряє чи Foo є мінусовою клітинкою.

=> (setv a (мінуси 'hd 'tl))

=> (мінуси? а)
Правда

=> (мінуси? нуль)
Помилковий

=> (мінуси? [1 2 3])
Помилковий

грудня
Використання: (гр x)

Повертає на один менше ніж x. Дорівнює (- x 1). Піднімає Помилка типу if (Не (числові? х)).

=> (3 грудня)
2

=> (0 грудня)
-1

=> (12.3 грудня)
11.3

розбирати
Нове у версії 0.10.0.

Використання: (розібрати дерево &необов’язково [codegen помилковий])

Дамп Python AST для даного Hy дерево на стандартний вихід. Якщо кодеген is Правда, функція
замість цього друкує код Python.

=> (розберіть '(надрукуйте "Hello World!"))
модуль(
тіло=[
Expr(value=Call(func=Name(id='print'), args=[Str(s='Hello World!')], keywords=[], starargs=None, kwargs=None))])

=> (розібрати '(друк "Hello World!") правда)
print('Hello World!')

порожній?
Використання: (порожній? кол)

Повернення Правда if зб пусто. Дорівнює (= 0 (лен кол)).

=> (пусто? [])
Правда

=> (порожній? "")
Правда

=> (пусто? (, 1 2))
Помилковий

кожен?
Нове у версії 0.10.0.

Використання: (кожен? раніше кол)

Повернення Правда if (пред x) логічно вірно для кожного x in збВ іншому випадку Помилковий. Повернення Правда
if зб пусто.

=> (кожен? парний? [2 4 6])
Правда

=> (кожен? парний? [1 3 5])
Помилковий

=> (кожен? парний? [2 4 5])
Помилковий

=> (кожний? парний? [])
Правда

плавати?
Використання: (плавати? x)

Повернення Правда if x є поплавком.

=> (float? 3.2)
Правда

=> (плавати? -2)
Помилковий

навіть?
Використання: (навіть? x)

Повернення Правда if x рівномірний. Піднімає Помилка типу if (Не (числові? х)).

=> (парні? 2)
Правда

=> (парні? 13)
Помилковий

=> (парні? 0)
Правда

особистість
Використання: (ідентичність x)

Повертає аргумент, наданий функції.

=> (ідентичність 4)
4

=> (список (ідентичність карти [1 2 3 4]))
[1 2 3 4]

вкл
Використання: (вкл x)

Повертає на один більше ніж x. Дорівнює (+ x 1). Піднімає Помилка типу if (Не (числові? х)).

=> (вкл. 3)
4

=> (вкл. 0)
1

=> (вкл. 12.3)
13.3

екземпляр?
Використання: (приклад? клас x)

Повернення Правда if x є екземпляром клас.

=> (екземпляр? float 1.0)
Правда

=> (екземпляр? int 7)
Правда

=> (екземпляр? str (str "foo"))
Правда

=> (defclass TestClass [об'єкт])
=> (setv inst (TestClass))
=> (екземпляр? TestClass inst)
Правда

ціле число?
Використання: (ціле число? x)

Повернення Правда if x є цілим числом. Для Python 2 це або Int or довго. Для Python 3,
це Int.

=> (ціле число? 3)
Правда

=> (ціле число? -2.4)
Помилковий

переплутати
Нове у версії 0.10.1.

Використання: (перемежувати послідовність 1 послідовність 2 ...)

Повертає ітерацію першого елемента в кожній із послідовностей, потім другого тощо.

=> (список (перемежування (діапазон 5) (діапазон 100 105))
[0, 100, 1, 101, 2, 102, 3, 103, 4, 104]

=> (список (перемежування (діапазон 1000000) "abc"))
[0, 'a', 1, 'b', 2, 'c']

вставляти
Нове у версії 0.10.1.

Використання: (вставити пункт послідовність)

Повертає ітерацію елементів послідовності, розділених елементом.

=> (список (вставити "!" "abcd"))
['а Б В Г']

=> (список (вставити -1 (діапазон 5)))
[0, -1, 1, -1, 2, -1, 3, -1, 4]

повторюваний?
Використання: (ітерується? x)

Повернення Правда if x є повторюваним. Ітераційні об’єкти повертають новий ітератор, коли (ітер x) is
дзвонив. Контраст із ітератор?.

=> ;; працює для струн
=> (ітерується? (str "abcde"))
Правда

=> ;; працює для списків
=> (ітерується? [1 2 3 4 5])
Правда

=> ;; працює для кортежів
=> (ітерується? (, 1 2 3))
Правда

=> ;; працює для диктантів
=> (ітерується? {:a 1 :b 2 :c 3})
Правда

=> ;; працює для ітераторів/генераторів
=> (ітерується? (повторити 3))
Правда

ітератор?
Використання: (ітератор? x)

Повернення Правда if x є ітератором. Ітератори – це об’єкти, які повертають себе як
ітератор, коли (ітер x) називається. Контраст із повторюваний?.

=> ;; не працює для списку
=> (ітератор? [1 2 3 4 5])
Помилковий

=> ;; але ми можемо отримати ітер зі списку
=> (ітератор? (ітер [1 2 3 4 5]))
Правда

=> ;; не працює для dict
=> (ітератор? {:a 1 :b 2 :c 3})
Помилковий

=> ;; створити ітератор із dict
=> (ітератор? (ітер {:a 1 :b 2 :c 3}))
Правда

список*
Використання: (список* голова &відпочинок хвіст)

Генерує ланцюжок вкладених мінус-комірок (пунктирний список), що містить аргументи. Якщо
список аргументів містить лише один елемент, поверніть його.

=> (список* 1 2 3 4)
(1 2 3 . 4)

=> (список* 1 2 3 [4])
[1, 2, 3, 4]

=> (список* 1)
1

=> (мінуси? (список* 1 2 3 4))
Правда

макророзгорнути
Нове у версії 0.10.0.

Використання: (макророзгорнути форма)

Повертає повне розширення макросу форма.

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

=> (макророзгорнути '(-> (ab) (-> (cd) (ef))))
(u'e' (u'c' (u'a' u'b') u'd') u'f')

макророзширення-1
Нове у версії 0.10.0.

Використання: (макророзширення-1 форма)

Повертає однокрокове розширення макросу форма.

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

злиття з
Нове у версії 0.10.1.

Використання: (злиття з f &відпочинок карти)

Повертає карту, яка складається з решти карт, об’єднаних першими. Якщо ключ зустрічається в
більше однієї карти, відображення(и) з останньої (зліва направо) буде поєднуватися з
відображення в результаті виклику (f вал-результат val-in-latter).

=> (злиття з (fn [xy] (+ xy)) {"a" 10 "b" 20} {"a" 1 "c" 30})
{u'a': 11 л, u'c': 30 л, u'b': 20 л}

нег?
Використання: (нег? x)

Повернення Правда if x менше нуля. Піднімає Помилка типу if (Не (числові? х)).

=> (від'ємна? -2)
Правда

=> (від'ємна? 3)
Помилковий

=> (від'ємна? 0)
Помилковий

нуль?
Використання: (ніль? x)

Повернення Правда if x is нуль / ніхто.

=> (нуль? нуль)
Правда

=> (нуль? Немає)
Правда

=> (нуль? 0)
Помилковий

=> (setf x nil)
=> (нуль? x)
Правда

=> ;; list.append завжди повертає None
=> (нуль? (.append [1 2 3] 4))
Правда

жодного?
Використання: (немає? x)

Повернення Правда if x is ніхто.

=> (немає? Немає)
Правда

=> (немає? 0)
Помилковий

=> (setf x Немає)
=> (немає? x)
Правда

=> ;; list.append завжди повертає None
=> (немає? (.append [1 2 3] 4))
Правда

n-й
Використання: (n-й зб n &необов’язково [за замовчуванням нуль])

Повертає n-ий елемент у колекції, рахуючи від 0. Повернути значення за замовчуванням, нуль, Якщо
поза межами (якщо не вказано інше). Піднімає ValueError if n є негативним.

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

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

=> (нуль? (nth [1 2 4 7] 5))
Правда

=> (nth [1 2 4 7] 5 "за замовчуванням")
"за замовчуванням"

=> (n-й (взяти 3 (опустити 2 [1 2 3 4 5 6])) 2))
5

=> (nth [1 2 4 7] -1)
Traceback (останній останній дзвінок):
...
ValueError: індекси для islice() повинні мати значення None або ціле число: 0 <= x <= sys.maxsize.

числові?
Використання: (числові? x)

Повернення Правда if x є числом, як визначено в Python числа.Число клас.

=> (числовий? -2)
Правда

=> (числовий? 3.2)
Правда

=> (числовий? "foo")
Помилковий

дивно?
Використання: (дивно? x)

Повернення Правда if x є дивним. Піднімає Помилка типу if (Не (числові? х)).

=> (непарний? 13)
Правда

=> (непарний? 2)
Помилковий

=> (непарний? 0)
Помилковий

поз?
Використання: (поз.? x)

Повернення Правда if x більше нуля. Піднімає Помилка типу if (Не (числові? х)).

=> (поз? 3)
Правда

=> (поз? -2)
Помилковий

=> (поз? 0)
Помилковий

другий
Використання: (друге кол)

Повертає другий член зб. Дорівнює (отримати зб 1).

=> (другий [0 1 2])
1

деякі
Нове у версії 0.10.0.

Використання: (дещо раніше кол)

Повертає перше логічно істинне значення (пред x) для будь-якого x in збВ іншому випадку нуль.
Повернення нуль if зб пусто.

=> (деякі навіть? [2 4 6])
Правда

=> (ніль? (деякі навіть? [1 3 5]))
Правда

=> (нуль? (деяка ідентичність [0 "" []]))
Правда

=> (деяка ідентичність [0 "непорожній рядок" []])
'непорожній рядок'

=> (ніль? (деякі навіть? []))
Правда

рядок?
Використання: (рядок? x)

Повернення Правда if x є рядком.

=> (рядок? "foo")
Правда

=> (рядок? -2)
Помилковий

символ?
Використання: (символ? x)

Повернення Правда if x є символом.

=> (символ? 'foo)
Правда

=> (символ? '[abc])
Помилковий

нульовий?
Використання: (нуль? x)

Повернення Правда if x дорівнює нулю.

=> (нуль? 3)
Помилковий

=> (нуль? -2)
Помилковий

=> (нуль? 0)
Правда

Послідовність Функції
Функції послідовності можуть створювати або працювати з потенційно нескінченною послідовністю без
вимагаючи, щоб послідовність була повністю реалізована в списку або подібному контейнері. Вони роблять це за допомогою
повертає ітератор Python.

Ми можемо використовувати канонічний генератор нескінченних чисел Фібоначчі як приклад того, як використовувати
деякі з цих функцій.

(defn fib []
(встановити 0)
(setv b 1)
(поки правда
(вихід а)
(setv (, ab) (, b (+ ab)))))

Зверніть увагу на (поки правда ...) петля. Якщо ми запустимо це в REPL,

=> (fib)


Виклик функції повертає лише ітератор, але не працює, поки ми його не використаємо.
Спробувати щось подібне не рекомендується, оскільки нескінченний цикл буде виконуватися доти
споживає всю доступну оперативну пам'ять, або в цьому випадку, поки я її не вбив.

=> (список (fib))
[1] 91474 убитих hy

Щоб отримати перші 10 чисел Фібоначчі, використовуйте приймати. Зверніть увагу на це приймати також повертає генератор,
тому я створюю з нього список.

=> (список (взяти 10 (фіб)))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Щоб отримати число Фібоначчі за індексом 9 (починаючи з 0):

=> (n-й (fib) 9)
34

цикл
Використання: (цикл кол)

Повертає нескінченний ітератор членів coll.

=> (список (список 7 (цикл [1 2 3])
[1, 2, 3, 1, 2, 3, 1]

=> (список (список 2 (цикл [1 2 3])
[1, 2]

чіткий
Використання: (різний кол)

Повертає ітератор, що містить лише унікальні члени зб.

=> (список (розрізнений [ 1 2 3 4 3 5 2 ]))
[1, 2, 3, 4, 5]

=> (список (розрізнений []))
[]

=> (список (розрізнений (ітер [ 1 2 3 4 3 5 2 ])))
[1, 2, 3, 4, 5]

падіння
Використання: (падіння n кол)

Повертає ітератор, пропускаючи перший n Члени зб. Піднімає ValueError if n is
негативний.

=> (список (перекинь 2 [1 2 3 4 5]))
[3, 4, 5]

=> (список (перекинь 4 [1 2 3 4 5]))
[5]

=> (список (перекинь 0 [1 2 3 4 5]))
[1, 2, 3, 4, 5]

=> (список (перекинь 6 [1 2 3 4 5]))
[]

крапля-останнє
Використання: (останнє n кол)

Повертає ітератор усіх, крім останнього n предмети в зб. Піднімає ValueError if n is
негативний.

=> (список (перекинь останні 5 (діапазон 10 20)))
[10, 11, 12, 13, 14]

=> (список (останнє 0 (діапазон 5)))
[0, 1, 2, 3, 4]

=> (список (останнє 100 (діапазон 100)))
[]

=> (імпортувати itertools)
=> (список (взяти 5 (відкинути останні 100 (itertools.count 10))
[10, 11, 12, 13, 14]

падіння-поки
Використання: (покинь-поки раніше кол)

Повертає ітератор, пропускаючи члени зб до раніше is Помилковий.

=> (список (опустити-поки парний? [2 4 7 8 9]))
[7, 8, 9]

=> (список (відкинути числові? [1 2 3 Немає "a"])))
[Немає, u'a']

=> (список (перекинь позицію? [2 4 7 8 9]))
[]

фільтрувати
Використання: (фільтр раніше кол)

Повертає ітератор для всіх елементів у зб які передають присудок раніше.

Дивіться також видаляти.

=> (список (поз. фільтра? [1 2 3 -4 5 -7]))
[1, 2, 3, 5]

=> (список (парний фільтр? [1 2 3 -4 5 -7]))
[2, -4]

сплющити
Нове у версії 0.9.12.

Використання: (зрівняти кол)

Повертає єдиний список усіх елементів у зб, вирівнюючи всі наявні списки та/або
кортежі.

=> (зрівняти [1 2 [3 4] 5])
[1, 2, 3, 4, 5]

=> (зрівняти ["foo" (, 1 2) [1 [2 3] 4] "bar"])
['foo', 1, 2, 1, 2, 3, 4, 'bar']

повторити
Використання: (ітерація fn x)

Повертає ітератор x, fn(x), fn(fn(x)), І т.д.

=> (список (взяти 5 (ітерація вкл. 5))
[5, 6, 7, 8, 9]

=> (список (взяти 5 (ітерація (fn [x] (* xx)) 5)))
[5, 25, 625, 390625, 152587890625]

зчитування
Використання: (прочитати &необов’язково [з-файл еоф])

Читає наступний вираз Hy з з файлу (за замовчуванням sys.stdin), і може приймати a
один байт як EOF (за замовчуванням це порожній рядок). Піднімає Помилка EOFE if з файлу закінчується раніше
повний вираз можна проаналізувати.

=> (читати)
(+ 2 2)
('+' 2 2)
=> (eval (читати))
(+ 2 2)
4

=> (імпорт io)
=> (буфер деф. (io.StringIO "(+ 2 2)\n(- 2 1)"))
=> (eval (застосувати read [] {"from_file" буфер}))
4
=> (eval (застосувати read [] {"from_file" буфер}))
1

=> ; припускаючи, що "example.hy" містить:
=> ; (друк "привіт")
=> ; (друкувати «друзі!»)
=> (за допомогою [[f (відкрити "example.hy")]]
... (спробуй
... (поки правда
... (нехай [[exp (прочитати f)]]
... (робити
... (друк "OHY" exp)
... (оцінений досвід))))
... (ловити [e EOFError]
... (друк "EOF!"))))
OHY ("друк" "привіт")
привіт
OHY ('print', hyfriends!')
друзі!
EOF!

видаляти
Використання: (видалити раніше кол)

Повертає ітератор з зб з елементами, які передають присудок, раніше, видалено.

Дивіться також фільтрувати.

=> (список (видалити непарні? [1 2 3 4 5 6 7]))
[2, 4, 6]

=> (список (видалити позицію? [1 2 3 4 5 6 7]))
[]

=> (список (видалити відсутнє? [1 2 3 4 5 6 7]))
[1, 2, 3, 4, 5, 6, 7]

повторювати
Використання: (повторити x)

Повертає ітератор (нескінченний). x.

=> (список (взяти 6 (повторити «s»))
[u's', u's', u's', u's', u's', u's']

неодноразово
Використання: (неодноразово fn)

Повертає ітератор шляхом виклику fn повторно.

=> (імпорт [випадковий [випадковий]])

=> (список (взяти 5 (повторно (fn [] (randint 0 10)))))
[6, 2, 0, 6, 7]

приймати
Використання: (брати n кол)

Повертає ітератор, що містить перший n Члени зб. Піднімає ValueError if n is
негативний.

=> (список (взяти 3 [1 2 3 4 5]))
[1, 2, 3]

=> (список (взяти 4 (повторити «s»))
[u's', u's', u's', u's']

=> (список (взяти 0 (повторити «s»))
[]

take-nth
Використання: (взяти-n-й n кол)

Повертає ітератор, що містить кожний n-й член зб.

=> (список (взяти-nth 2 [1 2 3 4 5 6 7]))
[1, 3, 5, 7]

=> (список (взяти-nth 3 [1 2 3 4 5 6 7]))
[1, 4, 7]

=> (список (взяти-nth 4 [1 2 3 4 5 6 7]))
[1, 5]

=> (список (взяти-nth 10 [1 2 3 4 5 6 7]))
[1]

на час
Використання: (на час раніше кол)

Повертає ітератор з зб поки раніше Умови повернення Правда.

=> (список (поз. на час? [ 1 2 3 -4 5]))
[1, 2, 3]

=> (список (нег.? [ -4 -3 1 2 5]))
[-4, -3]

=> (список (нег.? [ 1 2 3 -4 5]))
[]

блискавка
Нове у версії 0.9.13.

Використання: (zip з fn зб ...)

Дорівнює ZIP, але використовує функцію з кількома аргументами замість створення кортежу. Якщо
блискавка тоді викликається з N колекціями fn має прийняти N аргументів.

=> (оператор імпорту)
=> (список (zip з operator.add [1 2 3] [4 5 6]))
[5, 7, 9]

читач Макрос
Макроси Reader дають Lisp можливість змінювати та змінювати синтаксис на льоту. Ти не хочеш
Польська нотація? Макрос читача може легко зробити це. Хочете, як Clojure має а
регулярний вираз? Макроси Reader також можуть зробити це легко.

синтаксис
=> (розшифровувач ^ [expr] (друк expr))
=> #^(1 2 3 4)
(1)
=> #^"Привіт"
"Здравствуйте"
=> #^1+2+3+4+3+2
1+2+3+4+3+2

Hy не має літералу для кортежів. Скажімо, вам не подобається (, ...) і хочеться чогось іншого. Це
це проблема, яку макроси зчитувача можуть вирішити акуратно.

=> (розшифровувач t [expr] `(, ~@expr))
=> #t(1 2 3)
(1, 2, 3)

Ви навіть можете зробити це, як Clojure, і мати литерал для регулярних виразів!

=> (імпорт повторно)
=> (розшифровувач r [expr] `(re.compile ~expr))
=> #r".*"
<_sre.SRE_Pattern об'єкт на 0xcv7713ph15#>

Реалізація
розчитувач приймає один символ як назву символу для макросу читача; щось довше
поверне помилку. З точки зору реалізації, розчитувач розширюється в лямбду, покриту a
декоратор. Цей декоратор зберігає лямбду в словнику з назвою модуля і
символ.

=> (розшифровувач ^ [expr] (друк expr))
;=> (with_decorator (hy.macros.reader ^) (fn [expr] (print expr)))

# розширюється в (dispatch_reader_macro ...) куди передається символ і вираз
правильну функцію.

=> #^()
;=> (dispatch_reader_macro ^ ())
=> #^"Привіт"
"Здравствуйте"

ПОПЕРЕДЖЕННЯ:
Через обмеження в lexer і синтаксичний аналізатор Hy, макроси зчитувача не можуть повторно визначити визначені
синтаксис, наприклад ()[]{}. Це, швидше за все, буде вирішено в майбутньому.

Внутрішній Hy документація
ПРИМІТКА:
Ці фрагменти в основному корисні для людей, які зламують сам Hy, але також можуть бути використані для
ті, хто глибше заглиблюється в макропрограмування.

Hy моделі
Вступ до Hy моделі
Моделі Hy — це дуже тонкий шар поверх звичайних об’єктів Python, що представляє джерело Hy
код як дані. Моделі додають лише інформацію про вихідну позицію та кілька методів
підтримують чисті маніпуляції з вихідним кодом Hy, наприклад, у макросах. Щоб цього досягти
ціль, моделі Hy є міксинами базового класу Python і HyObject.

HyObject
hy.models.HyObject є базовим класом моделей Hy. Він реалізує лише один метод, замінювати,
який замінює вихідну позицію поточного об’єкта на позицію, передану як аргумент.
Це дозволяє нам відстежувати вихідну позицію виразів, які змінюються
макроси, будь то в компіляторі або в чистих макросах hy.

HyObject не призначений для використання безпосередньо для створення екземплярів Hy-моделей, а лише як міксин
для інших класів.

З'єднання моделі
Списки в дужках і в дужках аналізуються як складені моделі за допомогою аналізатора Hy.

HyList
hy.models.list.HyList є базовим класом "ітеративних" моделей Hy. Його основне використання полягає в тому, щоб
представляють у дужках [] списки, які, якщо використовуються як вираз верхнього рівня, перекладаються на
Літерали списку Python на етапі компіляції.

Додавання HyList до іншого ітераційного об’єкта повторно використовує клас лівого об’єкта,
корисна поведінка, коли ви хочете об’єднати об’єкти Hy в макрос, наприклад.

HyExpression
hy.models.expression.HyExpression успадковує HyList для круглих дужок () вирази. The
Результат компіляції цих виразів залежить від першого елемента списку: the
компілятор розсилає вирази між спеціальними формами компілятора, визначеними користувачем макросами та
звичайні виклики функцій Python.

HyDict
hy.models.dict.HyDict успадковує HyList для фігурних дужок {} вирази, які компілюються
аж до буквального словника Python.

Рішення про використання списку замість dict як базового класу для HyDict дозволяє легше
маніпулювання dicts у макросах, з додатковою перевагою дозволу складених виразів
як ключі dict (як, наприклад, HyExpression Клас Python не хешується).

Атомний моделі
У вхідному потоці рядки в подвійних лапках, дотримуючись нотації Python для рядків,
аналізуються як один маркер, який безпосередньо аналізується як a HyString.

Безперервний рядок символів, за винятком пробілів, дужок, лапок і подвійних лапок
і коментарів, аналізується як ідентифікатор.

Ідентифікатори розв’язуються в атомарних моделях під час фази аналізу в такому порядку:

· HyInteger

· HyFloat

· HyComplex (якщо атом не голий j)

· HyKeyword (якщо атом починається з :)

· HySymbol

HyString
hy.models.string.HyString є базовим класом рядкових еквівалентних моделей Hy. Він також
представляє рядкові літерали в подвійних лапках, "", які компілюються до рядка Unicode
літерали в Python. HyStrings успадковувати об'єкти Unicode в Python 2 і рядкові об'єкти в
Python 3 (і, отже, не залежать від кодування).

HyString засновані моделі є незмінними.

Рядки літералу Hy можуть охоплювати декілька рядків і розглядаються синтаксичним аналізатором як єдиний
unit, дотримуючись екранування Python для рядків Unicode.

Числовий моделі
hy.models.integer.HyInteger представляє цілі літерали (за допомогою довго введіть на Python 2,
та Int на Python 3).

hy.models.float.HyFloat представляє літерали з плаваючою комою.

hy.models.complex.HyComplex представляє складні літерали.

Числові моделі аналізуються з використанням відповідної підпрограми Python і допустимого числового Python
літерали будуть перетворені на їх аналог Hy.

HySymbol
hy.models.symbol.HySymbol це модель, яка використовується для представлення символів мовою Hy. Це
успадковує HyString.

HySymbol об'єкти змінюються на фазі аналізу, щоб допомогти Python взаємодіяти:

· Символи, оточені зірочками (*) перетворюються у великі літери;

· Тире (-) перетворюються на підкреслення (_);

· Один знак питання в кінці (?) перетворюється на провідну є_.

Застереження: оскільки маніпуляція виконується на фазі синтаксичного аналізу, це можливо
програмно генерувати HySymbols, які не можуть бути згенеровані за допомогою вихідного коду Hy. Такий
Механізм використовується gensym для генерації «неінтернованих» символів.

HyKeyword
hy.models.keyword.HyKeyword представляє ключові слова в Hy. Ключові слова – це символи, які починаються з
a :. Клас успадковує HyString.

Розрізняти HyKeywords від HySymbols, без можливості (мимовільно)
зіткнення, символ Unicode для приватного використання "\uFDD0" стоїть перед ключовим словом literal
перед зберіганням.

мінуси Клітини
hy.models.cons.HyCons є поданням, зручним для Python мінуси клітин. Мінуси клітини є
особливо корисно для імітації функцій "звичайних" варіантів LISP, таких як Scheme або Common
Шепелявець.

Недостатня клітинка — це об’єкт з 2 елементів, що містить a автомобіль (голова) і а Cdr (хвіст). У якомусь Lisp
варіанти, клітинка cons є основним будівельним блоком, а S-вирази насправді
представлені у вигляді зв'язаних списків мінус-комірок. У Hy, як зазвичай, це не так
вирази складаються зі списків Python, загорнутих у a HyExpression. Проте HyCons
імітує поведінку «звичайних» варіантів Lisp таким чином:

· (мінуси що в сім'ї щось нуль) is (HyExpression [щось])

· (мінуси що в сім'ї щось якийсь список) is ((тип якийсь список) (+ [щось] якийсь список)) (якщо
якийсь список успадковує від список).

· (отримати (мінуси a b) 0) is a

· (скибочка (мінуси a b) 1) is b

Hy підтримує синтаксис списку з пунктирами, де '(а . b) засоби (мінуси 'a 'б) та '(а b . c) засоби
(мінуси 'a (мінуси 'b в)). Якщо компілятор зустрічає комірку мінусів на верхньому рівні, він піднімає
помилка компіляції.

HyCons загортає передані аргументи (car і cdr) у типи Hy, щоб полегшити маніпулювання
мінус-комірки в контексті макросу.

Hy Внутрішній Theory
огляд
Внутрішні елементи Hy працюють, діючи як інтерфейс для байт-коду Python, так що сам Hy
компілюється до байт-коду Python, дозволяючи незміненому середовищу виконання Python запускати Hy-код,
навіть не помічаючи цього.

Ми робимо це шляхом перекладу Hy у внутрішню структуру даних Python AST, і
перетворення цього AST у байт-код Python за допомогою модулів стандарту Python
бібліотеки, щоб нам не довелося дублювати всю роботу внутрішніх компонентів Python для кожного
єдиний випуск Python.

Hy працює в чотири етапи. У наступних розділах буде розглянуто кожен крок Hy від джерела до
час виконання.

заходи 1 та 2: Токенування та Parsing
Перший етап компіляції Hy — це перетворення джерела на токени, з якими ми можемо мати справу. ми
використовуйте проект під назвою rply, який є дійсно гарним (і швидким) парсером, написаним у підмножині
Python під назвою rpython.

Весь код лексики визначено в hy.lex.lexer. Цей код здебільшого просто визначає Hy
граматику, а всі фактичні складні частини опікуються rply - ми просто визначаємо
"зворотні виклики" для rply in hy.lex.parser, який приймає згенеровані маркери та повертає
Hy моделі.

Ви можете думати про моделі Hy як про "AST" для Hy, це те, на чому працюють макроси
(безпосередньо), і це те, що компілятор використовує, коли компілює Hy down.

СМ ТАКОЖ:
розділ Hy моделі для отримання додаткової інформації про моделі Hy та їх значення.

Крок 3: Hy Compilation до Python АСТ
Саме тут відбувається більшість магії в Hy. Ось де ми беремо Hy AST (моделі),
і компілюйте їх у Python AST. Тут трапляється пара фанкових речей, які спрацьовують після кількох
проблеми в AST, а робота з компілятором є однією з найважливіших робіт, які ми виконуємо
є.

Компілятор дещо складний, тому не переживайте, якщо ви не робите його з першого пострілу,
може знадобитися трохи часу, щоб виправитися.

Основною точкою входу до компілятора є HyASTCompiler.compile. Цей метод викликається і
єдиний справжній «публічний» метод у класі (тобто ми насправді не обіцяємо
API за межами цього методу).

Насправді, навіть внутрішньо, ми майже ніколи не повертаємося безпосередньо, ми майже завжди змушуємо
дерево Hy через скласти, і часто буде робити це з піделементами виразу
що ми маємо. Правильно відправляти піделементи залежить від диспетчера на основі типу.

Усі методи, які формують компіляцію, позначені символом @builds() декоратор. Ти можеш
або передайте клас моделі Hy, яку вона компілює, або ви можете використовувати рядок
вирази. Я проясню це за секунду.

Перший Стажування Тип-Відправка
Почнемо в скласти метод. Перше, що ми робимо, це перевіряємо тип речі
ми будуємо. Ми дивимося, чи є у нас метод, який може створити тип () що ми
have та відправити до методу, який може це обробити. Якщо у нас немає жодних методів, які могли б
будуємо цей тип, ми піднімаємо внутрішній Виняток.

Наприклад, якщо ми маємо a HyString, ми маємо майже 1-до-1 відображення Hy AST до Python
АСТ. The рядок компіляції метод приймає HyString, і повертає an ast.Str() це
заповнено правильними номерами рядків і вмістом.

Макро-розгорнути
Якщо ми отримаємо a HyExpression, ми спробуємо перевірити, чи є це відомий макрос, і спробуємо створити
вона розширювалася за допомогою виклику hy.macros.macroexpand, потім вставте результат назад
HyASTCompiler.compile.

другий Стажування Expression-Dispatch
Єдиний окремий випадок – це HyExpression, оскільки нам потрібно створити різні AST залежно
на спеціальному бланку, про який йде мова. Наприклад, коли ми вдарили (якщо правда правда помилковий), Ми
необхідно створити a ast.Якщо, і правильно скомпілювати підвузли. Ось де @builds()
з аргументом String.

Для компілювати_вираз (який визначається за допомогою an @builds(HyExpression)) відправлять
на основі рядка першого аргументу. Якщо з якихось причин першого аргументу немає
рядок, він також належним чином оброблятиме цей випадок (швидше за все, піднявши an Виняток).

Якщо рядок не відомий Hy, він створить за замовчуванням ast.Дзвонити, який буде намагатися
зробити виклик під час виконання (у Python щось на кшталт foo ()).

Питання хіт з Python АСТ
Python AST чудовий; це те, що дозволило нам написати такий потужний проект поверх
Python без необхідності боротися з Python занадто важко. Як і в будь-якому випадку, ми отримали свою справедливу частку
проблеми, а ось короткий список поширених проблем, з якими ви можете зіткнутися.

Python диференціює між Заяви та Вирази.

Це може здатися невеликим – насправді для більшості програмістів Python це буде так
незабаром стане моментом "Ну, так".

У Python робити щось на кшталт:

друк та цінності x in діапазон(10): проходити, Так як друк друкує вирази, і та цінності не є
вираз, це оператор потоку керування. Подібні речі 1 + 1 є виразами, як є лямбда
x: 1 + x, але інші мовні особливості, наприклад if, та цінностіабо в той час як є заяви.

Оскільки вони не мають «цінності» для Python, це ускладнює роботу в Hy, оскільки щось робиться
як (друк (якщо правда правда помилковий)) це не просто поширене, а очікуване.

В результаті ми автоматично скасовуємо речі за допомогою a Результат об'єкт, де ми пропонуємо будь-який ast.stmt
що потрібно запустити, і одиночний ast.expr яку можна використати, щоб отримати цінність будь-чого
був просто запущений. Hy робить це, змушуючи призначати речі під час роботи.

Як приклад, Hy:

(друкувати (якщо true true, false))

перетвориться на:

якщо істина:
_mangled_name_here = Правда
ще:
_mangled_name_here = Неправда

роздрукувати _mangled_name_тут

Добре, це було трохи брехнею, оскільки ми фактично перетворюємо це твердження на:

надрукувати True, якщо True, інакше False

Змусивши речі в ast.expr якщо ми можемо, але загальна ідея зберігається.

Крок 4: Python Байт-код Вихід та Час виконання
Після того, як у нас буде завершене дерево AST Python, ми можемо спробувати скомпілювати його в Python
байт-код шляхом просування його евал. З цього моменту ми більше не контролюємо, і
Python подбає про все. Ось чому такі речі, як відстеження Python, pdb і
Програми django працюють.

Hy Макрос
використання gensym та цінності Безпечніше Макрос
При написанні макросів потрібно бути обережним, щоб уникнути захоплення зовнішніх змінних або використання
імена змінних, які можуть конфліктувати з кодом користувача.

Ми будемо використовувати приклад макросу NIF (Див.
http://letoverlambda.com/index.cl/guest/chap3.html#сек_5 для більш повного опису.)
NIF це приклад, щось на зразок числового if, де на основі виразу один із
3 форми називається залежно від того, чи є вираз додатним, нульовим чи від’ємним.

Перший прохід може бути таким:

(defmacro nif [expr pos-form нуль-форма neg-form]
`(нехай [[obscure-name ~expr]]
(cond [(поз? неясне-ім'я) ~поз-форма]
[(нуль? неясне ім'я) ~нульова форма]
[(neg? неясне ім'я) ~neg-form])))

де незрозуміле ім'я є спробою вибрати назву змінної, щоб не конфліктувати з іншою
код. Але, звісно, ​​це не гарантія, незважаючи на добрі наміри.

Метод gensym призначений для створення нового, унікального символу саме для такої події.
Набагато краща версія NIF було б:

(defmacro nif [expr pos-form нуль-форма neg-form]
(нехай [[g (gensym)]]
`(нехай [[~g ~expr]]
(cond [(поз? ~g) ~поз-форма]
[(нуль? ~g) ~нульова форма]
[(нег? ~g) ~нег-форма]))))

Це простий випадок, оскільки є лише один символ. Але якщо є потреба в кількох
gensym є другий макрос з-gensyms, який в основному розширюється до ряду дозволяти
твердження:

(with-gensyms [abc]
...)

розширюється до:

(нехай [[a (gensym)
[b (gensym)
[c (gensym)]]
...)

так наше переписано NIF буде виглядати так:

(defmacro nif [expr pos-form нуль-форма neg-form]
(з родами [g]
`(нехай [[~g ~expr]]
(cond [(поз? ~g) ~поз-форма]
[(нуль? ~g) ~нульова форма]
[(нег? ~g) ~нег-форма]))))

Нарешті, ми можемо створити новий макрос, який зробить все це за нас. defmacro/g! буде
всі символи, які починаються з g! і автоматично дзвонить gensym з рештою
символ. Тому g!a став би (генсим "а").

Наша остаточна версія NIF, побудований с defmacro/g! стає:

(defmacro/g! nif [expr pos-form нуль-форма neg-form]
`(нехай [[~g!res ~expr]]
(cond [(pos? ~g!res) ~pos-form]
[(нуль? ~g!res) ~нульова форма]
[(нег? ~g!res) ~нег-форма]))))

Перевірка Macro Аргументи та Залучення винятки
Hy компілятор Вбудовані

КОНТРІБУТОР МОДУЛІ ІНДЕКС


Зміст:

Анафоричний Макрос
Нове у версії 0.9.12.

Модуль анафоричних макросів робить функціональне програмування в Hy дуже стислим і простим
читати
Анафоричний макрос — це тип програмного макросу, який навмисно фіксує певну форму
надається макросу, на який може посилатися анафора (вираз, що посилається
до іншого). — Вікіпедія (http://en.wikipedia.org/wiki/Anaphoric_macro)

Макрос
ап-якщо
Використання: (ап-якщо (фу) (друк це))

Оцінює першу форму на правдивість і прив’язує її до it як в істинному, так і в хибному
гілки.

персик
Використання: (персик [1 2 3 4 5] (друк це))

Оцініть форму для кожного елемента в списку на предмет побічних ефектів.

кожен раз
Використання: (кожен-поки список раніше тіло)

Оцініть форму для кожного елемента, куди повертається форма предиката Правда.

=> (ap-each-while [1 2 3 4 5 6] (< it 4) (надрукувати))
1
2
3

ап-карта
Використання: (ap-карта форма список)

Анафорична форма карти працює так само, як і звичайна карта, за винятком того, що замість функції
об’єкт приймає форму Hy. Спеціальна назва it прив’язаний до поточного об’єкта з
список в ітерації.

=> (список (ap-map (* it 2) [1 2 3]))
[2, 4, 6]

ap-map-when
Використання: (ap-map-when передн репутація список)

Оцініть відображення списку за допомогою функції предиката, щоб визначити, коли застосовувати
формі.

=> (список (ap-map-when непарний? (* це 2) [1 2 3 4]))
[2, 2, 6, 4]

=> (список (ap-map-коли парний? (* це 2) [1 2 3 4]))
[1, 4, 3, 8]

ap-фільтр
Використання: (ap-фільтр форма список)

Як і в випадку ап-карта ми беремо спеціальну форму замість функції для фільтрації елементів
список. Спеціальна назва it прив’язаний до поточного елемента в ітерації.

=> (список (ap-фільтр (> (* it 2) 6) [1 2 3 4 5]))
[4, 5]

ап-відкинути
Використання: (ап-відхилити форма список)

Ця функція робить протилежне ap-фільтр, він відхиляє елементи, що передають
присудок . Спеціальна назва it прив’язаний до поточного елемента в ітерації.

=> (список (ap-reject (> (* it 2) 6) [1 2 3 4 5]))
[1, 2, 3]

ап-дочаси
Використання (ap-dotimes n тіло)

Ця функція оцінює організм n разів зі спеціальною змінною it зв'язаний з 0 до
1-н. Це корисно для побічних ефектів.

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

ap-перше
Використання (ap-перше передн список)

Ця функція повертає перший елемент, який передає предикат або ніхто, С
спеціальна змінна it прив’язаний до поточного елемента в ітерації.

=>(ap-first (> it 5) (діапазон 10))
6

ап-останнє
Використання (останнє передн список)

Ця функція повертає останній елемент, який передає предикат або ніхто, зі спец
змінна it прив’язаний до поточного елемента в ітерації.

=>(ap-last (> it 5) (діапазон 10))
9

ap-зменшити
Використання (ap-зменшити форма список &необов’язково початкове значення)

Ця функція повертає результат застосування форми до перших 2 елементів тіла і
застосовуючи результат і 3-й елемент тощо, поки список не буде вичерпано. За бажанням an
можна вказати початкове значення, тож функція буде застосована до початкового значення та
перший елемент замість цього. Це відкриває елемент, який повторюється як it і поточний
накопичена вартість як Точність.

=>(ap-reduce (+ it acc) (діапазон 10))
45

цикл/повтор
Нове у версії 0.10.0.

Команда петля / повторити макрос дає програмістам простий спосіб використовувати оптимізацію хвостового виклику (TCO)
в їх коді Hy.
Хвостовий виклик - це виклик підпрограми, який відбувається всередині іншої процедури як її остаточний
дія; він може видавати значення, що повертається, яке потім негайно повертається викликом
процедури. Якщо будь-який виклик, який виконує підпрограма, такий, що в кінцевому підсумку він може привести
ця сама підпрограма, яка знову викликається по ланцюжку викликів, знаходиться в хвостовій позиції,
така підпрограма називається хвостово-рекурсивною, що є окремим випадком рекурсії.
Хвостові виклики важливі, оскільки їх можна реалізувати без додавання нового стека
кадру до стеку викликів. Більша частина кадру поточної процедури не потрібна
більше, і його можна замінити каркасом хвостового дзвінка. Після цього програма може перейти
до викликаної підпрограми. Вироблення такого коду замість стандартної послідовності викликів є
називається усуненням хвостового виклику або оптимізацією хвостового виклику. Дозволяє усунення хвіст виклику
процедури виклики в хвостовій позиції, щоб бути реалізовані так само ефективно, як оператори goto,
що дозволяє ефективно структурувати програмування. — Вікіпедія (‐
http://en.wikipedia.org/wiki/Tail_call)

Макрос
петля
петля встановлює точку рекурсії. З петля, повторити повторно зв’язує змінні, встановлені в
точку рекурсії та надсилає виконання коду назад до цієї точки рекурсії. Якщо повторити використовується в
позиція без хвоста, створюється виняток.

Використання: (петля прив'язки &відпочинок тіло)

приклад:

(потрібно hy.contrib.loop)

(визначення факторіалу [n]
(цикл [[in] [acc 1]]
(якщо (нуль? я)
Точність
(повторюється (зниж. i) (* доп. i)))))

(факторіал 1000)

defmulti
Нове у версії 0.10.0.

defmulti дозволяє перевантажувати функцію арністю на задану кількість аргументів та/або kwargs.
Натхненний поглядом Clojure деф.

=> (потрібно hy.contrib.multi)
=> (defmulti fun
... ([a] "a")
... ([ab] "ab")
... ([abc] "abc"))
=> (весело 1)
"A"
=> (весело 1 2)
"аб"
=> (весело 1 2 3)
"abc"

ХАКІР ON HY


Приєднайся до наші Хайв!
Будь ласка, зламайте Хай!

Будь ласка, гуляйте з нами #hy on irc.freenode.net!

Будь ласка, поговоріть про це в Twitter з #hy хештег!

Будь ласка, блог про це!

Будь ласка, не фарбуйте його на сусідський паркан (не попросивши добре)!

Зламати!
Зробити це:

1 Створити віртуальний навколишнє середовище:

$ virtualenv venv

і активуйте його:

$ . venv/bin/активувати

або використовувати virtualenvwrapper щоб створити та керувати своїм віртуальним середовищем:

$ mkvirtualenv hy
$ workon hy

2. Отримайте вихідний код:

$ git клон https://github.com/hylang/hy.git

або скористайтеся вилкою:

$ git клон [захищено електронною поштою]: /hy.git

3. Встановіть для злому:

$ CD hy/
$ pip install -e .

4. Установіть інші вимоги для розробки:

$ pip install -r requirements-dev.txt

5. Робіть чудові речі; змусити когось кричати від захвату/відрази від того, що ви зробили.

Тест!
Тести розташовані в тести /. Ми використовуємо ніс.

Щоб запустити тести:

$ тести носа

Пишіть тести---тести хороші!

Крім того, добре проводити тести для всіх підтримуваних платформ і для PEP 8
код. Ви можете зробити це, запустивши tox:

$ Tox

Документ!
Документація знаходиться в документи/. Ми використовуємо Сфінкс.

Щоб створити документи в HTML:

$ cd документи
$ зробити html

Пишіть документи --- документи хороші! Навіть цей документ!

Сприяння
Внески вітаються та дуже вдячні, кожна дрібниця допомагає зробити Hy більше
приголомшливий

Запити на витяг - це чудово! Ми їх любимо; ось короткий посібник:

· Розділіть репо та створіть гілки теми для функції/виправлення. Уникайте прямого внесення змін
на головній гілці.

· Усі вхідні функції повинні супроводжуватися тестами.

· Перш ніж подавати PR, будь ласка, запустіть тести та перевірте свій код на відповідність стилю
гід. Ви можете робити обидві ці речі одночасно:

$ зробити d

· Зробіть коміти в логічні одиниці, щоб потім було легше відстежувати й переміщатися. Раніше
надсилаючи PR, спробуйте роздавити коміти в набори змін, до яких легко повернутися
пізніше. Також переконайтеся, що ви не залишаєте неправдивих пробілів у наборах змін; це
дозволяє уникнути створення фіксацій для виправлення пробілів пізніше.

· Що стосується повідомлень про фіксацію, намагайтеся дотримуватися наступного:

· Спробуйте дотримуватися обмеження в 50 символів для першого рядка повідомлень про фіксацію Git.

· Щоб отримати докладнішу інформацію/пояснення, додайте порожній рядок і продовжуйте
детально описуючи фіксацію.

· Нарешті, додайте себе до файлу AUTHORS (як окремий комміт): ви цього заслуговуєте :)

· Усі вхідні зміни повинні бути підтверджені 2 різними членами основної команди Hylang.
Додаткова перевірка безсумнівно вітається, але нам потрібно щонайменше 2 підтвердження для будь-якого
змінити.

· Якщо основний член надсилає PR, будь ласка, знайдіть 2 основних членів, які не включають
PR-подавач. Ідея тут полягає в тому, що з PR-автором можна працювати, а другий підтверджує
весь набір змін.

· Для документації та інших тривіальних змін ми добре об’єднуємось після одного ACK. У нас є
низьке покриття, тому було б чудово, щоб цей бар’єр був низьким.

Core професіонали
Основна команда розробників Hy складається з таких розробників:

· Джуліан Даньджу

· Мортен Ліндеруд

· J Кеннет King

· Гергелі Надь

· Туукка Турто

· Карен Рустад

· Абхішек L

· Крістофер Аллан Веббер

· Конрад Хінсен

· Уїлл Кан-Грін

· Пол Тальямонте

· Нікола Дандрімонт

· боб Толберт

· Berker Пексаг

· Клінтон N. Драйсбах

· він semaj

Використовуйте hy онлайн за допомогою служб onworks.net


Безкоштовні сервери та робочі станції

Завантажте програми для Windows і Linux

Команди Linux

Ad