Знакомство с Hy / Андрей Жлобич / Web Developer Wargaming
Язык Hy – это новый диалект Lisp, транслируемый в Python AST. При его использовании разработчик может работать с любыми Python-библиотеками и фреймворки, а гомоиконная природа Lisp позволяет взаимодействовать с кодом как с данными, что полезно при написании DSL. Андрей рассказывает о том, что такое Hy и каковы его преимущества и недостатки.
Python Meetup - встречи минского сообщества любителей языка программирования Python.
Присоединяйся к нам!
Мы в twitter: https://twitter.com/pythonminsk
Мы на Youtube: https://www.youtube.com/playlist?list=PL0QujlH3yeFuEhrUbLpEAJ0FZxFcNGaiD
Мы на Facebook: https://www.facebook.com/MinskPythonMeetup
5. In a nutshell, Hy is a Lisp dialect, but one
that converts its structure into Python...
literally a conversion into Python’s abstract
syntax tree!
Or to put it in more crude terms,
Hy is lisp-stick on a Python!
( копипаста N
1 )
6. ( копипаста N
2 )
● A Lisp that feels very Pythonic.
● For Lispers, a great way to use Lisp’s crazy
powers but in the wide world of Python’s
libraries (why yes, you now can write a Django
application in Lisp!)
● For Pythonistas, a great way to start exploring
Lisp, from the comfort of Python!
● For everyone: a pleasant language that has a
lot of neat ideas!
7. ( на самом деле )
we do what we must,
because we can
just for fun
8. from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from polls.models import Choice, Question
def vote(request, question_id):
p = get_object_or_404(Question, pk=question_id)
try:
sc = p.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', {
'question': p,
'error_message': "You didn't select a choice."})
else:
sc.votes += 1
sc.save()
return HttpResponseRedirect(reverse('results', args=(p.id,)))
( код Py )
() - 9, [] - 1
12. ( hy abstract syntax tree )
from hy import *
HyExpression([
HySymbol('defn'),
HySymbol('my-fun'),
HyList([
HySymbol('x'),
HySymbol('y')]),
HyExpression([
HySymbol('+'),
HySymbol('x'),
HyExpression([
HySymbol('*'),
HyInteger(2),
HySymbol('y'),
])])])
Code
(defn my-fun [x y]
(+ x (* 2 y)))
AST (py)
13. ( hy.models )
class HyObject(object):
def replace(self, other):
assert isinstance(other, HyObject)
for a in ["start_line", "end_line",
"start_column", "end_column"]:
if not hasattr(self, a) and hasattr(other, a):
setattr(self, a, getattr(other, a))
class HyString(HyObject, str):
pass
class HySymbol(HyString):
pass
class HyInteger(HyObject, int):
pass
# ...
# HyList, HyExpression, HyDict
# HyFloat, HyComplex, HyKeyword, HyCons
14. ( большая разница )
'(defn my-fun [x y]
(+ x (* 2 y)))
(defn my-fun [x y]
(+ x (* 2 y)))
CodeAST (hy)
15. ( vs )
123.4
None
"some string"
[1, 2, 3]
{"a": 1, "b": 2}
(1, 2, "z")
123.4
nil or
null or
None
"some string"
[1 2 3]
{"a" 1 "b" 2}
(, 1 2 "z")
Py Hy
16. ( основа )
( verb n1
n2
… ns
) → r
Verb:
● Специальная форма
● Функция
● Метод объекта
● Макрос
17. . , != % %= & &= * ** **= *= + += - | / ~
/= < << <<= <= = > >= >> >>= ^ ^= -= |=
and apply assert assoc break catch
continue def defclass defmacro defreader
del dict-comp dispatch-reader-macro do
eval eval-and-compile eval-when-compile
except fn for* genexpr get global if
import in is is-not list-comp not not-in
or quasiquote quote raise require set-comp
setv slice try unquote unquote-splicing
while with* with-decorator
yield yield-from
( специальные формы )
18. ( vs )
foo(x, y)
True or False
1 + 2
x = 123
"abbc".count("b")
vd[123]
(foo x y)
(or true false)
(+ 1 2)
(setv x 123)
(.count "abbc" "b")
(get vd 123)
Py Hy
24. ( киллер-фича )
Метаклассы
Метапрограммирование
вид программирования, связанный с созданием
программ, которые порождают другие программы
как результат своей работы, либо программ,
которые меняют себя во время выполнения
25. ( макросы )
Hy compiler
Python compiler
parser
lexer
macroexpand
S-exprs
ф-ии + спец.формы
+ макросы
S-exprs
ф-ии + спец. формы
run code
at compile time
26. ( простейший )
(defmacro unless [expr &rest body]
`(if (not ~expr)
(do ~@body)))
(print ">>"
(unless (> 1 2)
(+= x 1)
(+= y 2)))
(print ">>"
(if (not (> 1 2))
(do
(+= x 1)
(+= y 2))))
27. ( еще один... )
(import [collections [namedtuple]])
(defmacro deftuple [tname &rest columns]
`(def ~tname
(namedtuple
~(name tname)
~(list (map name columns)))))
;; ...
(deftuple Point x y)
(def a (Point 1 2))
(print a.x (get a 0))
30. ( let it be )
(defmacro let [vars &rest body]
`((fn []
~@(list-comp
`(setv ~k ~v)
[[k v] vars])
~@body)))
(let [[x 1]
[y 2]]
(let [[y 10]]
(+= y x) ;; ok
(assert (= 11 y))
;; (+= x 1) - fail!
)
(assert 3 (+ x y)))
31. • Hy -- это Python на S-exprs
• Есть плюсы, есть минусы
• Непривычный синтаксис
• Местами многословный
• Ма-акрос!
• Гибкость!
• Доступ к Python runtime
• Ведь Hy... всего лишь Python
( итого )