Docs: Hy <-> Python interop fix #1061 (#1218)

* Docs: Hy <-> Python interop fix #1061

I separated the existing text in two sections, with some additional
explanations and a link to Hy's `import`.

* added interop page

* simplified interop section in tutorial

* remove the TODO from interop section in tutorial

Because yay

* Corrections from @Kodiologist

I kept the part about mangling, but added a warning about its incompleteness. I
think it can be useful for somebody who just wants to use a Python module in his
code. Maybe it can be removed when the actual documentation for mangling is
written.

* Added myself to AUTHORS.

I'll do my best to be worthy of it. Thanks for this awesome project!
This commit is contained in:
Charles de Lacombe 2017-02-11 02:11:21 +01:00 committed by Kodi Arfer
parent 99d31d153c
commit 83cdaf0a71
5 changed files with 149 additions and 25 deletions

View File

@ -74,3 +74,4 @@
* Karan Sharma <karansharma1295@gmail.com>
* Sergey Sobko <s.sobko@profitware.ru>
* Philip Xu <pyx@xrefactor.com>
* Charles de Lacombe <ealhad@mail.com>

View File

@ -1049,6 +1049,7 @@ reverses the comparison.
=> (lif-not False "true" "false")
"false"
.. _import:
import
------

View File

@ -8,6 +8,7 @@ Contents:
:maxdepth: 3
cli
interop
api
core
readermacros

135
docs/language/interop.rst Normal file
View File

@ -0,0 +1,135 @@
=====================
Hy <-> Python interop
=====================
“Keep in mind were not Clojure. Were not Common Lisp. Were Homoiconic
Python, with extra bits that make sense.” — Hy Style Guide
Despite being a Lisp, Hy aims to be fully compatible with Python. That means
every Python module or package can be imported in Hy code, and vice versa.
Using Python from Hy
====================
Using Python from Hy is nice and easy, you just have to :ref:`import` it.
If you have the following in ``greetings.py`` in Python::
def greet(name):
print("hello," name)
You can use it in Hy:
.. code-block:: clj
(import greetings)
(.greet greetings "foo") ; prints "hello, foo"
You can also import ``.pyc`` bytecode files, of course.
A quick note about mangling
--------
In Python, snake_case is used by convention. Lisp dialects tend to use dashes
instead of underscores, so Hy does some magic to give you more pleasant names.
In the same way, ``UPPERCASE_NAMES`` from Python can be used ``*with-earmuffs*``
instead.
You can use either the original names or the new ones.
Imagine ``example.py``::
def function_with_a_long_name():
print(42)
FOO = "bar"
Then, in Hy:
.. code-block:: clj
(import example)
(.function-with-a-long-name example) ; prints "42"
(.function_with_a_long_name example) ; also prints "42"
(print (. example *foo*)) ; prints "bar"
(print (. example FOO)) ; also prints "bar"
.. warning::
Mangling isnt that simple; there is more to discuss about it, yet it doesnt
belong in this section.
.. TODO: link to mangling section, when it is done
Using Hy from Python
====================
Suppose you have written some useful utilities in Hy, and you want to use them in
regular Python, or to share them with others as a package. Or suppose you work
with somebody else, who doesn't like Hy (!), and only uses Python.
In any case, you need to know how to use Hy from Python. Fear not, for it is
easy.
If you save the following in ``greetings.hy``:
.. code-block:: clj
(setv *this-will-be-in-caps-and-underscores* "See?")
(defn greet [name] (Print "hello from hy," name))
Then you can use it directly from Python, by importing Hy before importing
the module. In Python::
import hy
import greetings
greetings.greet("Foo") # prints "Hello from hy, Foo"
print(THIS_WILL_BE_IN_CAPS_AND_UNDERSCORES) # prints "See?"
If you create a package with Hy code, and you do the ``import hy`` in
``__init__.py``, you can then directly include the package. Of course, Hy still
has to be installed.
Compiled files
--------------
You can also compile a module with ``hyc``, which gives you a ``.pyc`` file. You
can import that file. Hy does not *really* need to be installed ; however, if in
your code, you use any symbol from :doc:`core`, a corresponding ``import``
statement will be generated, and Hy will have to be installed.
Even if you do not use a Hy builtin, but just another function or variable with
the name of a Hy builtin, the ``import`` will be generated. For example, the previous code
causes the import of ``name`` from ``hy.core.language``.
**Bottom line: in most cases, Hy has to be installed.**
Launching a Hy REPL from Python
-------------------------------
You can use the function ``run_repl()`` to launch the Hy REPL from Python::
>>> import hy.cmdline
>>> hy.cmdline.run_repl()
hy 0.12.1 using CPython(default) 3.6.0 on Linux
=> (defn foo [] (print "bar"))
=> (test)
bar
If you want to print the Python code Hy generates for you, use the ``spy``
argument::
>>> import hy.cmdline
>>> hy.cmdline.run_repl(spy=True)
hy 0.12.1 using CPython(default) 3.6.0 on Linux
=> (defn test [] (print "bar"))
def test():
return print('bar')
=> (test)
test()
bar

View File

@ -8,7 +8,6 @@ Tutorial
.. - How do I do array ranges? e.g. x[5:] or y[2:10]
.. - Blow your mind with macros!
.. - Where's my banana???
.. - Mention that you can import .hy files in .py files and vice versa!
Welcome to the Hy tutorial!
@ -585,7 +584,10 @@ compile-time. ``require`` uses the same syntax as ``import``.
Hy <-> Python interop
=====================
By importing Hy, you can use Hy directly from Python!
Using Hy from Python
--------------------
You can use Hy modules in Python!
If you save the following in ``greetings.hy``:
@ -593,7 +595,7 @@ If you save the following in ``greetings.hy``:
(defn greet [name] (print "hello from hy," name))
Then you can use it directly from python, by importing hy before importing
Then you can use it directly from Python, by importing Hy before importing
the module. In Python::
import hy
@ -601,40 +603,24 @@ the module. In Python::
greetings.greet("Foo")
You can also declare a function in python (or even a class!) and use it in Hy!
Using Python from Hy
--------------------
You can also use any Python module in Hy!
If you save the following in ``greetings.py`` in Python::
def greet(name):
print("hello, %s" % (name))
You can use it in Hy:
You can use it in Hy (see :ref:`import`):
.. code-block:: clj
(import greetings)
(.greet greetings "foo")
To use keyword arguments, you can use in ``greetings.py``::
def greet(name, title="Sir"):
print("Greetings, %s %s" % (title,name))
.. code-block:: clj
(import greetings)
(.greet greetings "Foo")
(.greet greetings "Foo" "Darth")
(apply (. greetings greet) ["Foo"] {:title "Lord"})
Which would output::
Greetings, Sir Foo
Greetings, Darth Foo
Greetings, Lord Foo
More information on :doc:`../language/interop`.
Protips!