2013-04-05 20:56:59 +02:00
|
|
|
========
|
2013-04-03 23:21:31 +02:00
|
|
|
Tutorial
|
|
|
|
========
|
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
.. image:: _static/cuddles-transparent-small.png
|
|
|
|
:alt: Karen Rustard's Cuddles
|
2013-05-21 01:26:36 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
This chapter provides a quick introduction to Hy. It assumes a basic background
|
|
|
|
in programming, but no specific prior knowledge of Python or Lisp.
|
2013-03-14 00:43:19 +01:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Lisp-stick on a Python
|
|
|
|
======================
|
2013-04-03 01:55:59 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Let's start with the classic::
|
2013-04-01 16:27:30 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(print "Hy, world!")
|
2013-04-01 16:27:30 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
This program calls the :func:`print` function, which, like all of Python's
|
|
|
|
:ref:`built-in functions <py:built-in-funcs>`, is available in Hy.
|
2013-03-14 00:43:19 +01:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
All of Python's :ref:`binary and unary operators <py:expressions>` are
|
|
|
|
available, too, although ``==`` is spelled ``=`` in deference to Lisp
|
|
|
|
tradition. Here's how we'd use the addition operator ``+``::
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(+ 1 3)
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
This code returns ``4``. It's equivalent to ``1 + 3`` in Python and many other
|
|
|
|
languages. Languages in the `Lisp
|
|
|
|
<https://en.wikipedia.org/wiki/Lisp_(programming_language)>`_ family, including
|
|
|
|
Hy, use a prefix syntax: ``+``, just like ``print`` or ``sqrt``, appears before
|
|
|
|
all of its arguments. The call is delimited by parentheses, but the opening
|
|
|
|
parenthesis appears before the operator being called instead of after it, so
|
|
|
|
instead of ``sqrt(2)``, we write ``(sqrt 2)``. Multiple arguments, such as the
|
|
|
|
two integers in ``(+ 1 3)``, are separated by whitespace. Many operators,
|
|
|
|
including ``+``, allow more than two arguments: ``(+ 1 2 3)`` is equivalent to
|
|
|
|
``1 + 2 + 3``.
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Here's a more complex example::
|
2013-04-01 18:02:24 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(- (* (+ 1 3 88) 2) 8)
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
This code returns ``176``. Why? We can see the infix equivalent with the
|
|
|
|
command ``echo "(- (* (+ 1 3 88) 2) 8)" | hy2py``, which returns the Python
|
|
|
|
code corresponding to the given Hy code, or by passing the ``--spy`` option to
|
|
|
|
Hy when starting the REPL, which shows the Python equivalent of each input line
|
|
|
|
before the result. The infix equivalent in this case is:
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
.. code-block:: python
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
((1 + 3 + 88) * 2) - 8
|
2013-04-01 18:02:24 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
To evaluate this infix expression, you'd of course evaluate the innermost
|
|
|
|
parenthesized expression first and work your way outwards. The same goes for
|
|
|
|
Lisp. Here's what we'd get by evaluating the above Hy code one step at a time::
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(- (* (+ 1 3 88) 2) 8)
|
|
|
|
(- (* 92 2) 8)
|
|
|
|
(- 184 8)
|
|
|
|
176
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
The basic unit of Lisp syntax, which is similar to a C or Python expression, is
|
|
|
|
the **form**. ``92``, ``*``, and ``(* 92 2)`` are all forms. A Lisp program
|
|
|
|
consists of a sequence of forms nested within forms. Forms are typically
|
|
|
|
separated from each other by whitespace, but some forms, such as string
|
|
|
|
literals (``"Hy, world!"``), can contain whitespace themselves. An
|
|
|
|
**expression** is a form enclosed in parentheses; its first child form, called
|
|
|
|
the **head**, determines what the expression does, and should generally be a
|
|
|
|
function, macro, or special operator. Functions are the most ordinary sort of
|
|
|
|
head, whereas macros (described in more detail below) are functions executed at
|
|
|
|
compile-time instead and return code to be executed at run-time. Special
|
|
|
|
operators are one of :ref:`a fixed set of names <special-forms>` that are
|
|
|
|
hard-coded into the compiler, and used to implement everything else.
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Comments start with a ``;`` character and continue till the end of the line. A
|
|
|
|
comment is functionally equivalent to whitespace. ::
|
2013-04-01 18:02:24 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(print (** 2 64)) ; Max 64-bit unsigned integer value
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Although ``#`` isn't a comment character in Hy, a Hy program can begin with a
|
|
|
|
`shebang line <https://en.wikipedia.org/wiki/Shebang_(Unix)>`_, which Hy itself
|
|
|
|
will ignore::
|
2013-04-01 18:02:24 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
#!/usr/bin/env hy
|
|
|
|
(print "Make me executable, and run me!")
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Literals
|
|
|
|
========
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Hy has :ref:`literal syntax <syntax>` for all of the same data types that
|
|
|
|
Python does. Here's an example of Hy code for each type and the Python
|
|
|
|
equivalent.
|
|
|
|
|
|
|
|
============== ================ =================
|
|
|
|
Hy Python Type
|
|
|
|
============== ================ =================
|
|
|
|
``1`` ``1`` :class:`int`
|
|
|
|
``1.2`` ``1.2`` :class:`float`
|
|
|
|
``4j`` ``4j`` :class:`complex`
|
|
|
|
``True`` ``True`` :class:`bool`
|
|
|
|
``None`` ``None`` :class:`NoneType`
|
|
|
|
``"hy"`` ``'hy'`` :class:`str`
|
|
|
|
``b"hy"`` ``b'hy'`` :class:`bytes`
|
|
|
|
``(, 1 2 3)`` ``(1, 2, 3)`` :class:`tuple`
|
|
|
|
``[1 2 3]`` ``[1, 2, 3]`` :class:`list`
|
|
|
|
``#{1 2 3}`` ``{1, 2, 3}`` :class:`set`
|
|
|
|
``{1 2 3 4}`` ``{1: 2, 3: 4}`` :class:`dict`
|
|
|
|
============== ================ =================
|
|
|
|
|
|
|
|
In addition, Hy has a Clojure-style literal syntax for
|
|
|
|
:class:`fractions.Fraction`: ``1/3`` is equivalent to ``fractions.Fraction(1,
|
|
|
|
3)``.
|
|
|
|
|
|
|
|
The Hy REPL prints output in Python syntax by default::
|
2013-03-31 23:46:56 +02:00
|
|
|
|
|
|
|
=> [1 2 3]
|
|
|
|
[1, 2, 3]
|
2015-06-26 23:10:22 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
But if you start Hy like this (a shell alias might be helpful)::
|
2017-03-24 17:03:12 +01:00
|
|
|
|
|
|
|
$ hy --repl-output-fn=hy.contrib.hy-repr.hy-repr
|
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
the interactive mode will use :ref:`hy-repr-fn` instead of Python's native
|
|
|
|
``repr`` function to print out values, so you'll see values in Hy syntax::
|
2017-03-24 17:03:12 +01:00
|
|
|
|
|
|
|
=> [1 2 3]
|
|
|
|
[1 2 3]
|
2013-03-31 23:46:56 +02:00
|
|
|
|
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Basic operations
|
|
|
|
================
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Set variables with :ref:`setv`::
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(setv zone-plane 8)
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Access the elements of a list, dictionary, or other data structure with
|
|
|
|
:ref:`get`::
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(setv fruit ["apple" "banana" "cantaloupe"])
|
|
|
|
(print (get fruit 0)) ; => apple
|
|
|
|
(setv (get fruit 1) "durian")
|
|
|
|
(print (get fruit 1)) ; => durian
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Access a range of elements in an ordered structure with :ref:`cut`::
|
2013-04-01 18:02:24 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(print (cut "abcdef" 1 4)) ; => bcd
|
2013-04-01 18:02:24 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Conditional logic can be built with :ref:`if`::
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(if (= 1 1)
|
|
|
|
(print "Math works. The universe is safe.")
|
|
|
|
(print "Math has failed. The universe is doomed."))
|
2013-04-01 17:49:04 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
As in this example, ``if`` is called like ``(if CONDITION THEN ELSE)``. It
|
|
|
|
executes and returns the form ``THEN`` if ``CONDITION`` is true (according to
|
|
|
|
:class:`bool`) and ``ELSE`` otherwise. If ``ELSE`` is omitted, ``None`` is used
|
|
|
|
in its place.
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
What if you want to use more than form in place of the ``THEN`` or ``ELSE``
|
|
|
|
clauses, or in place of ``CONDITION``, for that matter? Use the special
|
|
|
|
operator :ref:`do` (known more traditionally in Lisp as ``progn``), which
|
|
|
|
combines several forms into one, returning the last::
|
2013-04-01 14:14:23 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(if (do (print "Let's check.") (= 1 1))
|
|
|
|
(do
|
|
|
|
(print "Math works.")
|
|
|
|
(print "The universe is safe."))
|
|
|
|
(do
|
|
|
|
(print "Math has failed.")
|
|
|
|
(print "The universe is doomed.")))
|
2013-04-01 14:14:23 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
For branching on more than one case, try :ref:`cond`::
|
2013-04-01 18:02:24 +02:00
|
|
|
|
2016-02-11 18:45:01 +01:00
|
|
|
(setv somevar 33)
|
2013-04-01 18:02:24 +02:00
|
|
|
(cond
|
2013-10-16 18:31:18 +02:00
|
|
|
[(> somevar 50)
|
|
|
|
(print "That variable is too big!")]
|
|
|
|
[(< somevar 10)
|
|
|
|
(print "That variable is too small!")]
|
2016-11-24 03:35:17 +01:00
|
|
|
[True
|
2013-10-16 18:31:18 +02:00
|
|
|
(print "That variable is jussssst right!")])
|
2013-04-01 14:14:23 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
The macro ``(when CONDITION THEN-1 THEN-2 …)`` is shorthand for ``(if CONDITION
|
|
|
|
(do THEN-1 THEN-2 …))``. ``unless`` works the same as ``when``, but inverts the
|
|
|
|
condition with ``not``.
|
2013-04-03 02:12:33 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Hy's basic loops are :ref:`while` and :ref:`for`::
|
2013-04-03 02:12:33 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(setv x 3)
|
|
|
|
(while (> x 0)
|
|
|
|
(print x)
|
|
|
|
(setv x (- x 1))) ; => 3 2 1
|
2013-03-31 23:46:56 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(for [x [1 2 3]]
|
|
|
|
(print x)) ; => 1 2 3
|
2013-04-03 02:56:10 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
A more functional way to iterate is provided by the comprehension forms such as
|
|
|
|
:ref:`lfor`. Whereas ``for`` always returns ``None``, ``lfor`` returns a list
|
|
|
|
with one element per iteration. ::
|
2014-12-06 08:13:40 +01:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(print (lfor x [1 2 3] (* x 2))) ; => [2, 4, 6]
|
2014-12-06 08:13:40 +01:00
|
|
|
|
2013-04-03 02:56:10 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Functions, classes, and modules
|
|
|
|
===============================
|
2013-04-03 02:56:10 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Define named functions with :ref:`defn`::
|
2013-05-09 22:35:47 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(defn fib [n]
|
|
|
|
(if (< n 2)
|
|
|
|
n
|
|
|
|
(+ (fib (- n 1)) (fib (- n 2)))))
|
|
|
|
(print (fib 8)) ; => 21
|
2013-05-09 22:35:47 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Define anonymous functions with :ref:`fn`::
|
2013-05-09 22:35:47 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(print (list (filter (fn [x] (% x 2)) (range 10))))
|
|
|
|
; => [1, 3, 5, 7, 9]
|
2014-12-23 22:05:36 +01:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Special symbols in the parameter list of ``defn`` or ``fn`` allow you to
|
|
|
|
indicate optional arguments, provide default values, and collect unlisted
|
|
|
|
arguments::
|
2014-12-23 22:05:36 +01:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(defn test [a b &optional c [d "x"] &rest e]
|
|
|
|
[a b c d e])
|
|
|
|
(print (test 1 2)) ; => [1, 2, None, 'x', ()]
|
|
|
|
(print (test 1 2 3 4 5 6 7)) ; => [1, 2, 3, 4, (5, 6, 7)]
|
2013-05-09 22:35:47 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Set a function parameter by name with a ``:keyword``::
|
2014-12-22 22:52:34 +01:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(test 1 2 :d "y") ; => [1, 2, None, 'y', ()]
|
2013-05-09 22:35:47 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Define classes with :ref:`defclass`::
|
2013-05-09 22:35:47 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(defclass FooBar []
|
|
|
|
(defn __init__ [self x]
|
|
|
|
(setv self.x x))
|
|
|
|
(defn get-x [self]
|
|
|
|
self.x))
|
2013-05-09 22:35:47 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Here we create a new instance ``fb`` of ``FooBar`` and access its attributes by
|
|
|
|
various means::
|
2013-05-09 22:35:47 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(setv fb (FooBar 15))
|
|
|
|
(print fb.x) ; => 15
|
|
|
|
(print (. fb x)) ; => 15
|
|
|
|
(print (.get-x fb)) ; => 15
|
|
|
|
(print (fb.get-x)) ; => 15
|
2013-05-09 22:40:32 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Note that syntax like ``fb.x`` and ``fb.get-x`` only works when the object
|
|
|
|
being invoked (``fb``, in this case) is a simple variable name. To get an
|
|
|
|
attribute or call a method of an arbitrary form ``FORM``, you must use the
|
|
|
|
syntax ``(. FORM x)`` or ``(.get-x FORM)``.
|
2013-05-09 22:35:47 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Access an external module, whether written in Python or Hy, with
|
|
|
|
:ref:`import`::
|
2013-05-09 23:00:30 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
(import math)
|
|
|
|
(print (math.sqrt 2)) ; => 1.4142135623730951
|
2013-05-09 23:00:30 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Python can import a Hy module like any other module so long as Hy itself has
|
|
|
|
been imported first, which, of course, must have already happened if you're
|
|
|
|
running a Hy program.
|
2013-05-09 22:35:47 +02:00
|
|
|
|
2015-10-03 12:24:43 +02:00
|
|
|
Macros
|
|
|
|
======
|
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Macros are the basic metaprogramming tool of Lisp. A macro is a function that
|
|
|
|
is called at compile time (i.e., when a Hy program is being translated to
|
|
|
|
Python :mod:`ast` objects) and returns code, which becomes part of the final
|
|
|
|
program. Here's a simple example::
|
|
|
|
|
|
|
|
(print "Executing")
|
|
|
|
(defmacro m []
|
|
|
|
(print "Now for a slow computation")
|
|
|
|
(setv x (% (** 10 10 7) 3))
|
|
|
|
(print "Done computing")
|
|
|
|
x)
|
|
|
|
(print "Value:" (m))
|
|
|
|
(print "Done executing")
|
|
|
|
|
|
|
|
If you run this program twice in a row, you'll see this::
|
|
|
|
|
|
|
|
$ hy example.hy
|
|
|
|
Now for a slow computation
|
|
|
|
Done computing
|
|
|
|
Executing
|
|
|
|
Value: 1
|
|
|
|
Done executing
|
2019-10-08 16:37:42 +02:00
|
|
|
$ hy example.hy
|
2019-08-19 20:00:53 +02:00
|
|
|
Executing
|
|
|
|
Value: 1
|
|
|
|
Done executing
|
|
|
|
|
|
|
|
The slow computation is performed while compiling the program on its first
|
|
|
|
invocation. Only after the whole program is compiled does normal execution
|
|
|
|
begin from the top, printing "Executing". When the program is called a second
|
|
|
|
time, it is run from the previously compiled bytecode, which is equivalent to
|
|
|
|
simply::
|
|
|
|
|
|
|
|
(print "Executing")
|
|
|
|
(print "Value:" 1)
|
|
|
|
(print "Done executing")
|
|
|
|
|
|
|
|
Our macro ``m`` has an especially simple return value, an integer, which at
|
|
|
|
compile-time is converted to an integer literal. In general, macros can return
|
|
|
|
arbitrary Hy forms to be executed as code. There are several special operators
|
|
|
|
and macros that make it easy to construct forms programmatically, such as
|
|
|
|
:ref:`quote` (``'``), :ref:`quasiquote` (`````), :ref:`unquote` (``~``), and
|
|
|
|
:ref:`defmacro!`. The previous chapter has :ref:`a simple example <do-while>`
|
|
|
|
of using ````` and ``~`` to define a new control construct ``do-while``.
|
2015-10-03 12:24:43 +02:00
|
|
|
|
2017-04-21 17:07:48 +02:00
|
|
|
Sometimes it's nice to be able to call a one-parameter macro without
|
2019-08-19 20:00:53 +02:00
|
|
|
parentheses. Tag macros allow this. The name of a tag macro is often just one
|
|
|
|
character long, but since Hy allows most Unicode characters in the name of a
|
|
|
|
macro (or ordinary variable), you won't out of characters soon. ::
|
2015-10-03 12:24:43 +02:00
|
|
|
|
2017-06-21 05:48:54 +02:00
|
|
|
=> (deftag ↻ [code]
|
2017-02-09 20:33:09 +01:00
|
|
|
... (setv op (last code) params (list (butlast code)))
|
|
|
|
... `(~op ~@params))
|
2015-10-03 12:24:43 +02:00
|
|
|
=> #↻(1 2 3 +)
|
|
|
|
6
|
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
What if you want to use a macro that's defined in a different module?
|
|
|
|
``import`` won't help, because it merely translates to a Python ``import``
|
|
|
|
statement that's executed at run-time, and macros are expanded at compile-time,
|
|
|
|
that is, during the translation from Hy to Python. Instead, use :ref:`require`,
|
|
|
|
which imports the module and makes macros available at compile-time.
|
|
|
|
``require`` uses the same syntax as ``import``. ::
|
2015-10-17 13:32:01 +02:00
|
|
|
|
|
|
|
=> (require tutorial.macros)
|
Give `require` the same features as `import` (#1142)
Give `require` the same features as `import`
You can now do (require foo), (require [foo [a b c]]), (require [foo [*]]), and (require [foo :as bar]). The first and last forms get you macros named foo.a, foo.b, etc. or bar.a, bar.b, etc., respectively. The second form only gets the macros in the list.
Implements #1118 and perhaps partly addresses #277.
N.B. The new meaning of (require foo) will cause all existing code that uses macros to break. Simply replace these forms with (require [foo [*]]) to get your code working again.
There's a bit of a hack involved in the forms (require foo) or (require [foo :as bar]). When you call (foo.a ...) or (bar.a ...), Hy doesn't actually look inside modules. Instead, these (require ...) forms give the macros names that have periods in them, which happens to work fine with the way Hy finds and interprets macro calls.
* Make `require` syntax stricter and add tests
* Update documentation for `require`
* Documentation wording improvements
* Allow :as in `require` name lists
2016-11-03 08:35:58 +01:00
|
|
|
=> (tutorial.macros.rev (1 2 3 +))
|
2015-10-17 13:32:01 +02:00
|
|
|
6
|
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Next steps
|
|
|
|
==========
|
2013-04-02 03:20:44 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
You now know enough to be dangerous with Hy. You may now smile villainously and
|
|
|
|
sneak off to your Hydeaway to do unspeakable things.
|
2013-04-02 03:20:44 +02:00
|
|
|
|
2019-08-19 20:00:53 +02:00
|
|
|
Refer to Python's documention for the details of Python semantics, and the rest
|
|
|
|
of this manual for Hy-specific features. Like Hy itself, the manual is
|
|
|
|
incomplete, but :ref:`contributions <hacking>` are always welcome.
|