2013-04-07 17:35:10 +02:00
|
|
|
=================
|
|
|
|
Hy (the language)
|
|
|
|
=================
|
|
|
|
|
|
|
|
.. warning::
|
|
|
|
This is incomplete; please consider contributing to the documentation
|
|
|
|
effort.
|
|
|
|
|
|
|
|
|
|
|
|
Theory of Hy
|
|
|
|
============
|
|
|
|
|
|
|
|
Hy maintains, over everything else, 100% compatibility in both directions
|
2013-06-07 05:53:53 +02:00
|
|
|
with Python itself. All Hy code follows a few simple rules. Memorize
|
2014-12-06 21:28:28 +01:00
|
|
|
this, as it's going to come in handy.
|
2013-04-07 17:35:10 +02:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
These rules help ensure that Hy code is idiomatic and interfaceable in both
|
2013-04-07 17:35:10 +02:00
|
|
|
languages.
|
|
|
|
|
|
|
|
|
2014-12-06 21:28:28 +01:00
|
|
|
* Symbols in earmufs will be translated to the upper-cased version of that
|
2014-12-07 07:05:52 +01:00
|
|
|
string. For example, ``foo`` will become ``FOO``.
|
2013-04-07 17:35:10 +02:00
|
|
|
|
|
|
|
* UTF-8 entities will be encoded using
|
|
|
|
`punycode <http://en.wikipedia.org/wiki/Punycode>`_ and prefixed with
|
2014-12-07 07:05:52 +01:00
|
|
|
``hy_``. For instance, ``⚘`` will become ``hy_w7h``, ``♥`` will become
|
|
|
|
``hy_g6h``, and ``i♥u`` will become ``hy_iu_t0x``.
|
2013-04-07 17:35:10 +02:00
|
|
|
|
|
|
|
* Symbols that contain dashes will have them replaced with underscores. For
|
2014-12-07 07:05:52 +01:00
|
|
|
example, ``render-template`` will become ``render_template``. This means
|
|
|
|
that symbols with dashes will shadow their underscore equivalents, and vice
|
2014-01-11 15:58:47 +01:00
|
|
|
versa.
|
2013-04-07 17:35:10 +02:00
|
|
|
|
|
|
|
|
2014-12-06 21:28:28 +01:00
|
|
|
Built-Ins
|
|
|
|
=========
|
2013-04-07 17:35:10 +02:00
|
|
|
|
2014-01-16 00:25:43 +01:00
|
|
|
Hy features a number of special forms that are used to help generate
|
2013-04-07 17:35:10 +02:00
|
|
|
correct Python AST. The following are "special" forms, which may have
|
|
|
|
behavior that's slightly unexpected in some situations.
|
|
|
|
|
2014-01-09 03:46:35 +01:00
|
|
|
.
|
|
|
|
-
|
|
|
|
|
2014-04-10 20:21:32 +02:00
|
|
|
.. versionadded:: 0.10.0
|
2014-01-09 03:46:35 +01:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``.`` is used to perform attribute access on objects. It uses a small DSL
|
2014-12-06 21:28:28 +01:00
|
|
|
to allow quick access to attributes and items in a nested data structure.
|
2014-01-09 03:46:35 +01:00
|
|
|
|
|
|
|
For instance,
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
(. foo bar baz [(+ 1 2)] frob)
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
Compiles down to:
|
2014-01-09 03:46:35 +01:00
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
foo.bar.baz[1 + 2].frob
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``.`` compiles its first argument (in the example, *foo*) as the object on
|
|
|
|
which to do the attribute dereference. It uses bare symbols as attributes
|
|
|
|
to access (in the example, *bar*, *baz*, *frob*), and compiles the contents
|
|
|
|
of lists (in the example, ``[(+ 1 2)]``) for indexation. Other arguments
|
|
|
|
throw a compilation error.
|
2014-01-09 03:46:35 +01:00
|
|
|
|
|
|
|
Access to unknown attributes throws an :exc:`AttributeError`. Access to
|
|
|
|
unknown keys throws an :exc:`IndexError` (on lists and tuples) or a
|
2014-12-06 21:28:28 +01:00
|
|
|
:exc:`KeyError` (on dictionaries).
|
2014-01-09 03:46:35 +01:00
|
|
|
|
2013-07-22 22:36:59 +02:00
|
|
|
->
|
|
|
|
--
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``->`` (or the *threading macro*) is used to avoid nesting of expressions. The
|
|
|
|
threading macro inserts each expression into the next expression's first argument
|
|
|
|
place. The following code demonstrates this:
|
2013-07-22 23:36:34 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (defn output [a b] (print a b))
|
|
|
|
=> (-> (+ 5 5) (output 5))
|
|
|
|
10 5
|
|
|
|
|
2013-07-22 22:36:59 +02:00
|
|
|
|
|
|
|
->>
|
|
|
|
---
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``->>`` (or the *threading tail macro*) is similar to the *threading macro*, but
|
|
|
|
instead of inserting each expression into the next expression's first argument,
|
|
|
|
it appends it as the last argument. The following code demonstrates this:
|
2013-07-22 23:36:34 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (defn output [a b] (print a b))
|
|
|
|
=> (->> (+ 5 5) (output 5))
|
|
|
|
5 10
|
|
|
|
|
2013-07-22 22:36:59 +02:00
|
|
|
|
2014-01-10 22:09:56 +01:00
|
|
|
apply
|
|
|
|
-----
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``apply`` is used to apply an optional list of arguments and an optional
|
2014-01-10 22:14:20 +01:00
|
|
|
dictionary of kwargs to a function.
|
2014-01-10 22:09:56 +01:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
Usage: ``(apply fn-name [args] [kwargs])``
|
2014-01-10 22:09:56 +01:00
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
|
|
|
.. code-block:: clj
|
2014-01-14 05:08:54 +01:00
|
|
|
|
2014-01-10 22:14:20 +01:00
|
|
|
(defn thunk []
|
|
|
|
"hy there")
|
|
|
|
|
|
|
|
(apply thunk)
|
|
|
|
;=> "hy there"
|
2014-01-10 22:09:56 +01:00
|
|
|
|
|
|
|
(defn total-purchase [price amount &optional [fees 1.05] [vat 1.1]]
|
|
|
|
(* price amount fees vat))
|
|
|
|
|
|
|
|
(apply total-purchase [10 15])
|
|
|
|
;=> 173.25
|
|
|
|
|
|
|
|
(apply total-purchase [10 15] {"vat" 1.05})
|
|
|
|
;=> 165.375
|
|
|
|
|
|
|
|
(apply total-purchase [] {"price" 10 "amount" 15 "vat" 1.05})
|
|
|
|
;=> 165.375
|
|
|
|
|
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
and
|
|
|
|
---
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``and`` is used in logical expressions. It takes at least two parameters. If
|
|
|
|
all parameters evaluate to ``True``, the last parameter is returned. In any
|
|
|
|
other case, the first false value will be returned. Example usage:
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (and True False)
|
|
|
|
False
|
|
|
|
|
|
|
|
=> (and True True)
|
|
|
|
True
|
|
|
|
|
|
|
|
=> (and True 1)
|
|
|
|
1
|
|
|
|
|
|
|
|
=> (and True [] False True)
|
|
|
|
[]
|
|
|
|
|
2014-03-14 22:53:10 +01:00
|
|
|
.. note::
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``and`` short-circuits and stops evaluating parameters as soon as the first
|
2014-03-14 22:53:10 +01:00
|
|
|
false is encountered.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (and False (print "hello"))
|
|
|
|
False
|
|
|
|
|
2013-07-06 22:43:47 +02:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
assert
|
|
|
|
------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``assert`` is used to verify conditions while the program is running. If the
|
|
|
|
condition is not met, an ``AssertionError`` is raised. Example usage:
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
(assert (= variable expected-value))
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``assert`` takes a single parameter, a conditional that evaluates to either
|
|
|
|
``True`` or ``False``.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2013-07-06 22:43:47 +02:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
assoc
|
|
|
|
-----
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``assoc`` is used to associate a key with a value in a dictionary or to set an
|
|
|
|
index of a list to a value. It takes at least three parameters: the *data
|
|
|
|
structure* to be modified, a *key* or *index*, and a *value*. If more than
|
|
|
|
three parameters are used, it will associate in pairs.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
Examples of usage:
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
2013-07-17 16:25:22 +02:00
|
|
|
=>(let [[collection {}]]
|
2013-06-30 15:39:06 +02:00
|
|
|
... (assoc collection "Dog" "Bark")
|
|
|
|
... (print collection))
|
|
|
|
{u'Dog': u'Bark'}
|
|
|
|
|
2013-07-17 16:25:22 +02:00
|
|
|
=>(let [[collection {}]]
|
|
|
|
... (assoc collection "Dog" "Bark" "Cat" "Meow")
|
|
|
|
... (print collection))
|
|
|
|
{u'Cat': u'Meow', u'Dog': u'Bark'}
|
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
=>(let [[collection [1 2 3 4]]]
|
|
|
|
... (assoc collection 2 None)
|
|
|
|
... (print collection))
|
|
|
|
[1, 2, None, 4]
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
.. note:: ``assoc`` modifies the datastructure in place and returns ``None``.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2013-07-06 22:43:47 +02:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
break
|
|
|
|
-----
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``break`` is used to break out from a loop. It terminates the loop immediately.
|
|
|
|
The following example has an infinite ``while`` loop that is terminated as soon
|
|
|
|
as the user enters *k*.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
2014-12-06 21:28:28 +01:00
|
|
|
(while True (if (= "k" (raw-input "? "))
|
|
|
|
(break)
|
2013-06-30 15:39:06 +02:00
|
|
|
(print "Try again")))
|
|
|
|
|
|
|
|
|
2013-07-22 22:36:59 +02:00
|
|
|
cond
|
|
|
|
----
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``cond`` can be used to build nested ``if`` statements. The following example
|
|
|
|
shows the relationship between the macro and its expansion:
|
2013-07-22 22:59:21 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
2013-10-16 18:31:18 +02:00
|
|
|
(cond [condition-1 result-1]
|
|
|
|
[condition-2 result-2])
|
2013-07-22 22:59:21 +02:00
|
|
|
|
|
|
|
(if condition-1 result-1
|
|
|
|
(if condition-2 result-2))
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
As shown below, only the first matching result block is executed.
|
2013-07-22 22:59:21 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (defn check-value [value]
|
2013-10-16 18:31:18 +02:00
|
|
|
... (cond [(< value 5) (print "value is smaller than 5")]
|
|
|
|
... [(= value 5) (print "value is equal to 5")]
|
|
|
|
... [(> value 5) (print "value is greater than 5")]
|
|
|
|
... [True (print "value is something that it should not be")]))
|
2014-12-06 21:28:28 +01:00
|
|
|
|
2013-07-22 22:59:21 +02:00
|
|
|
=> (check-value 6)
|
|
|
|
value is greater than 5
|
|
|
|
|
2013-07-22 22:36:59 +02:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
continue
|
|
|
|
--------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``continue`` returns execution to the start of a loop. In the following example,
|
|
|
|
``(side-effect1)`` is called for each iteration. ``(side-effect2)``, however,
|
|
|
|
is only called on every other value in the list.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
;; assuming that (side-effect1) and (side-effect2) are functions and
|
|
|
|
;; collection is a list of numerical values
|
|
|
|
|
2013-12-31 19:35:31 +01:00
|
|
|
(for [x collection]
|
|
|
|
(do
|
|
|
|
(side-effect1 x)
|
|
|
|
(if (% x 2)
|
|
|
|
(continue))
|
|
|
|
(side-effect2 x)))
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2013-07-06 22:43:47 +02:00
|
|
|
|
2014-04-28 20:09:06 +02:00
|
|
|
dict-comp
|
|
|
|
---------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``dict-comp`` is used to create dictionaries. It takes three or four parameters.
|
|
|
|
The first two parameters are for controlling the return value (key-value pair)
|
|
|
|
while the third is used to select items from a sequence. The fourth and optional
|
|
|
|
parameter can be used to filter out some of the items in the sequence based on a
|
|
|
|
conditional expression.
|
2014-04-28 20:09:06 +02:00
|
|
|
|
2014-04-28 20:35:28 +02:00
|
|
|
.. code-block:: hy
|
2014-04-28 20:09:06 +02:00
|
|
|
|
|
|
|
=> (dict-comp x (* x 2) [x (range 10)] (odd? x))
|
|
|
|
{1: 2, 3: 6, 9: 18, 5: 10, 7: 14}
|
|
|
|
|
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
do / progn
|
|
|
|
----------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``do`` and `progn` are used to evaluate each of their arguments and return the
|
|
|
|
last one. Return values from every other than the last argument are discarded.
|
|
|
|
It can be used in ``lambda`` or ``list-comp`` to perform more complex logic as
|
|
|
|
shown in one of the following examples.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
Some example usage:
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (if true
|
|
|
|
... (do (print "Side effects rock!")
|
|
|
|
... (print "Yeah, really!")))
|
|
|
|
Side effects rock!
|
|
|
|
Yeah, really!
|
|
|
|
|
|
|
|
;; assuming that (side-effect) is a function that we want to call for each
|
2014-05-17 19:46:01 +02:00
|
|
|
;; and every value in the list, but whose return value we do not care about
|
2014-12-06 21:28:28 +01:00
|
|
|
=> (list-comp (do (side-effect x)
|
|
|
|
... (if (< x 5) (* 2 x)
|
|
|
|
... (* 4 x)))
|
2013-06-30 15:39:06 +02:00
|
|
|
... (x (range 10)))
|
|
|
|
[0, 2, 4, 6, 8, 20, 24, 28, 32, 36]
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``do`` can accept any number of arguments, from 1 to n.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
|
2013-07-10 02:16:49 +02:00
|
|
|
def / setv
|
2014-12-06 21:28:28 +01:00
|
|
|
----------
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``def`` and ``setv`` are used to bind a value, object, or function to a symbol.
|
|
|
|
For example:
|
2013-07-06 22:43:47 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
2013-08-25 20:29:24 +02:00
|
|
|
=> (def names ["Alice" "Bob" "Charlie"])
|
2013-07-06 22:43:47 +02:00
|
|
|
=> (print names)
|
|
|
|
[u'Alice', u'Bob', u'Charlie']
|
|
|
|
|
2013-07-10 10:39:27 +02:00
|
|
|
=> (setv counter (fn [collection item] (.count collection item)))
|
2013-07-06 22:43:47 +02:00
|
|
|
=> (counter [1 2 3 4 5 2 3] 2)
|
|
|
|
2
|
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
defclass
|
|
|
|
--------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
New classes are declared with ``defclass``. It can takes two optional parameters:
|
2013-07-10 06:11:11 +02:00
|
|
|
a vector defining a possible super classes and another vector containing
|
2013-07-06 22:43:47 +02:00
|
|
|
attributes of the new class as two item vectors.
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
2013-07-10 06:11:11 +02:00
|
|
|
(defclass class-name [super-class-1 super-class-2]
|
2013-07-06 22:43:47 +02:00
|
|
|
[[attribute value]])
|
|
|
|
|
|
|
|
Both values and functions can be bound on the new class as shown by the example
|
|
|
|
below:
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (defclass Cat []
|
|
|
|
... [[age None]
|
|
|
|
... [colour "white"]
|
|
|
|
... [speak (fn [self] (print "Meow"))]])
|
|
|
|
|
|
|
|
=> (def spot (Cat))
|
|
|
|
=> (setv spot.colour "Black")
|
|
|
|
'Black'
|
|
|
|
=> (.speak spot)
|
|
|
|
Meow
|
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2014-01-17 12:47:05 +01:00
|
|
|
.. _defn:
|
|
|
|
|
2013-07-22 22:36:59 +02:00
|
|
|
defn / defun
|
|
|
|
------------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``defn`` and ``defun`` macros are used to define functions. They take three
|
|
|
|
parameters: the *name* of the function to define, a vector of *parameters*,
|
|
|
|
and the *body* of the function:
|
2013-07-23 15:50:12 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
(defn name [params] body)
|
|
|
|
|
2014-12-06 21:28:28 +01:00
|
|
|
Parameters may have the following keywords in front of them:
|
2013-08-05 22:23:35 +02:00
|
|
|
|
|
|
|
&optional
|
2014-12-06 21:28:28 +01:00
|
|
|
Parameter is optional. The parameter can be given as a two item list, where
|
2013-08-05 22:23:35 +02:00
|
|
|
the first element is parameter name and the second is the default value. The
|
|
|
|
parameter can be also given as a single item, in which case the default
|
2014-12-07 07:05:52 +01:00
|
|
|
value is ``None``.
|
2013-08-05 22:23:35 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (defn total-value [value &optional [value-added-tax 10]]
|
|
|
|
... (+ (/ (* value value-added-tax) 100) value))
|
|
|
|
|
|
|
|
=> (total-value 100)
|
|
|
|
110.0
|
|
|
|
|
|
|
|
=> (total-value 100 1)
|
|
|
|
101.0
|
|
|
|
|
|
|
|
&key
|
2014-12-06 21:28:28 +01:00
|
|
|
|
2013-08-05 22:23:35 +02:00
|
|
|
|
|
|
|
&kwargs
|
2014-12-06 21:28:28 +01:00
|
|
|
Parameter will contain 0 or more keyword arguments.
|
2013-08-05 22:23:35 +02:00
|
|
|
|
|
|
|
The following code examples defines a function that will print all keyword
|
|
|
|
arguments and their values.
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (defn print-parameters [&kwargs kwargs]
|
|
|
|
... (for [(, k v) (.items kwargs)] (print k v)))
|
|
|
|
|
2014-01-22 21:38:53 +01:00
|
|
|
=> (apply print-parameters [] {"parameter-1" 1 "parameter-2" 2})
|
2013-08-05 22:23:35 +02:00
|
|
|
parameter-2 2
|
|
|
|
parameter-1 1
|
|
|
|
|
|
|
|
&rest
|
2014-12-06 21:28:28 +01:00
|
|
|
Parameter will contain 0 or more positional arguments. No other positional
|
2013-08-05 22:23:35 +02:00
|
|
|
arguments may be specified after this one.
|
|
|
|
|
|
|
|
The following code example defines a function that can be given 0 to n
|
2014-05-17 20:04:41 +02:00
|
|
|
numerical parameters. It then sums every odd number and subtracts
|
2013-08-05 22:23:35 +02:00
|
|
|
every even number.
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (defn zig-zag-sum [&rest numbers]
|
|
|
|
(let [[odd-numbers (list-comp x [x numbers] (odd? x))]
|
|
|
|
[even-numbers (list-comp x [x numbers] (even? x))]]
|
|
|
|
(- (sum odd-numbers) (sum even-numbers))))
|
|
|
|
|
|
|
|
=> (zig-zag-sum)
|
|
|
|
0
|
|
|
|
=> (zig-zag-sum 3 9 4)
|
|
|
|
8
|
|
|
|
=> (zig-zag-sum 1 2 3 4 5 6)
|
2013-08-05 22:30:03 +02:00
|
|
|
-3
|
2013-07-22 22:36:59 +02:00
|
|
|
|
2014-01-17 12:47:05 +01:00
|
|
|
.. _defn-alias / defun-alias:
|
|
|
|
|
|
|
|
defn-alias / defun-alias
|
|
|
|
------------------------
|
|
|
|
|
2014-04-10 20:21:32 +02:00
|
|
|
.. versionadded:: 0.10.0
|
2014-01-17 12:47:05 +01:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
The ``defn-alias`` and ``defun-alias`` macros are much like `defn`_,
|
|
|
|
with the distinction that instead of defining a function with a single
|
2014-01-17 12:47:05 +01:00
|
|
|
name, these can also define aliases. Other than taking a list of
|
2014-12-07 07:05:52 +01:00
|
|
|
symbols for function names as the first parameter, ``defn-alias`` and
|
|
|
|
``defun-alias`` are no different from ``defn`` and ``defun``.
|
2014-01-17 12:47:05 +01:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (defn-alias [main-name alias] []
|
|
|
|
... (print "Hello!"))
|
|
|
|
=> (main-name)
|
|
|
|
"Hello!"
|
|
|
|
=> (alias)
|
|
|
|
"Hello!"
|
|
|
|
|
2014-03-11 19:37:29 +01:00
|
|
|
|
|
|
|
defmain
|
|
|
|
-------
|
|
|
|
|
2014-05-02 11:27:19 +02:00
|
|
|
.. versionadded:: 0.10.1
|
2014-03-11 19:37:29 +01:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
The ``defmain`` macro defines a main function that is immediately called
|
2014-12-06 21:28:28 +01:00
|
|
|
with ``sys.argv`` as arguments if and only if this file is being executed
|
|
|
|
as a script. In other words, this:
|
2014-03-11 19:37:29 +01:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
(defmain [&rest args]
|
|
|
|
(do-something-with args))
|
|
|
|
|
|
|
|
is the equivalent of::
|
|
|
|
|
|
|
|
def main(*args):
|
|
|
|
do_something_with(args)
|
|
|
|
return 0
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
import sys
|
|
|
|
retval = main(*sys.arg)
|
|
|
|
|
|
|
|
if isinstance(retval, int):
|
|
|
|
sys.exit(retval)
|
|
|
|
|
2014-12-06 21:28:28 +01:00
|
|
|
Note that as you can see above, if you return an integer from this
|
2014-03-11 19:37:29 +01:00
|
|
|
function, this will be used as the exit status for your script.
|
|
|
|
(Python defaults to exit status 0 otherwise, which means everything's
|
|
|
|
okay!)
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
(Since ``(sys.exit 0)`` is not run explicitly in the case of a non-integer
|
|
|
|
return from ``defmain``, it's a good idea to put ``(defmain)`` as the last
|
|
|
|
piece of code in your file.)
|
2014-03-11 19:37:29 +01:00
|
|
|
|
|
|
|
|
2013-12-30 22:42:55 +01:00
|
|
|
.. _defmacro:
|
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
defmacro
|
|
|
|
--------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``defmacro`` is used to define macros. The general format is
|
|
|
|
``(defmacro name [parameters] expr)``.
|
2013-07-18 14:00:24 +02:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
The following example defines a macro that can be used to swap order of elements
|
|
|
|
in code, allowing the user to write code in infix notation, where operator is in
|
2013-07-19 11:06:23 +02:00
|
|
|
between the operands.
|
2013-07-18 14:00:24 +02:00
|
|
|
|
2013-07-22 22:36:59 +02:00
|
|
|
.. code-block:: clj
|
2013-07-18 14:00:24 +02:00
|
|
|
|
2013-07-19 11:06:23 +02:00
|
|
|
=> (defmacro infix [code]
|
|
|
|
... (quasiquote (
|
|
|
|
... (unquote (get code 1))
|
|
|
|
... (unquote (get code 0))
|
|
|
|
... (unquote (get code 2)))))
|
2013-07-18 14:00:24 +02:00
|
|
|
|
2013-07-19 11:06:23 +02:00
|
|
|
=> (infix (1 + 1))
|
|
|
|
2
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2014-01-17 12:05:35 +01:00
|
|
|
.. _defmacro-alias:
|
|
|
|
|
|
|
|
defmacro-alias
|
|
|
|
--------------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``defmacro-alias`` is used to define macros with multiple names
|
|
|
|
(aliases). The general format is ``(defmacro-alias [names] [parameters]
|
|
|
|
expr)``. It creates multiple macros with the same parameter list and
|
2014-01-17 12:05:35 +01:00
|
|
|
body, under the specified list of names.
|
|
|
|
|
|
|
|
The following example defines two macros, both of which allow the user
|
|
|
|
to write code in infix notation.
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (defmacro-alias [infix infi] [code]
|
|
|
|
... (quasiquote (
|
|
|
|
... (unquote (get code 1))
|
|
|
|
... (unquote (get code 0))
|
|
|
|
... (unquote (get code 2)))))
|
|
|
|
|
|
|
|
=> (infix (1 + 1))
|
|
|
|
2
|
|
|
|
=> (infi (1 + 1))
|
|
|
|
2
|
|
|
|
|
2013-12-30 22:42:55 +01:00
|
|
|
.. _defmacro/g!:
|
|
|
|
|
|
|
|
defmacro/g!
|
|
|
|
------------
|
|
|
|
|
|
|
|
.. versionadded:: 0.9.12
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``defmacro/g!`` is a special version of ``defmacro`` that is used to
|
|
|
|
automatically generate :ref:`gensym` for any symbol that starts with
|
|
|
|
``g!``.
|
2013-12-30 22:42:55 +01:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
For example, ``g!a`` would become ``(gensym "a")``.
|
2013-12-30 22:42:55 +01:00
|
|
|
|
|
|
|
.. seealso::
|
|
|
|
|
|
|
|
Section :ref:`using-gensym`
|
|
|
|
|
2013-12-31 02:06:51 +01:00
|
|
|
defreader
|
|
|
|
---------
|
|
|
|
|
|
|
|
.. versionadded:: 0.9.12
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``defreader`` defines a reader macro, enabling you to restructure or
|
2013-12-31 02:06:51 +01:00
|
|
|
modify syntax.
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (defreader ^ [expr] (print expr))
|
|
|
|
=> #^(1 2 3 4)
|
|
|
|
(1 2 3 4)
|
|
|
|
=> #^"Hello"
|
|
|
|
"Hello"
|
|
|
|
|
|
|
|
.. seealso::
|
|
|
|
|
|
|
|
Section :ref:`Reader Macros <reader-macros>`
|
2013-12-30 22:42:55 +01:00
|
|
|
|
2013-12-21 23:33:44 +01:00
|
|
|
del
|
|
|
|
---
|
|
|
|
|
|
|
|
.. versionadded:: 0.9.12
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``del`` removes an object from the current namespace.
|
2013-12-21 23:33:44 +01:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (setv foo 42)
|
|
|
|
=> (del foo)
|
|
|
|
=> foo
|
|
|
|
Traceback (most recent call last):
|
|
|
|
File "<console>", line 1, in <module>
|
|
|
|
NameError: name 'foo' is not defined
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``del`` can also remove objects from mappings, lists, and more.
|
2013-12-21 23:33:44 +01:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (setv test (list (range 10)))
|
|
|
|
=> test
|
|
|
|
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
|
|
=> (del (slice test 2 4)) ;; remove items from 2 to 4 excluded
|
|
|
|
=> test
|
|
|
|
[0, 1, 4, 5, 6, 7, 8, 9]
|
|
|
|
=> (setv dic {"foo" "bar"})
|
|
|
|
=> dic
|
|
|
|
{"foo": "bar"}
|
|
|
|
=> (del (get dic "foo"))
|
|
|
|
=> dic
|
|
|
|
{}
|
|
|
|
|
2014-04-21 12:28:08 +02:00
|
|
|
doto
|
|
|
|
----
|
|
|
|
|
2014-04-25 15:19:22 +02:00
|
|
|
.. versionadded:: 0.10.1
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``doto`` is used to simplify a sequence of method calls to an object.
|
2014-04-21 12:28:08 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
2014-04-21 21:35:56 +02:00
|
|
|
=> (doto [] (.append 1) (.append 2) .reverse)
|
|
|
|
[2 1]
|
2014-04-21 12:28:08 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (setv collection [])
|
2014-04-21 21:35:56 +02:00
|
|
|
=> (.append collection 1)
|
|
|
|
=> (.append collection 2)
|
|
|
|
=> (.reverse collection)
|
2014-04-21 12:28:08 +02:00
|
|
|
=> collection
|
2014-04-21 21:35:56 +02:00
|
|
|
[2 1]
|
2014-04-21 12:28:08 +02:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
eval
|
|
|
|
----
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``eval`` evaluates a quoted expression and returns the value.
|
2013-11-26 19:31:10 +01:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (eval '(print "Hello World"))
|
|
|
|
"Hello World"
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
eval-and-compile
|
|
|
|
----------------
|
|
|
|
|
|
|
|
|
|
|
|
eval-when-compile
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
|
2013-07-22 22:36:59 +02:00
|
|
|
first / car
|
|
|
|
-----------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``first`` and ``car`` are macros for accessing the first element of a collection:
|
2013-07-22 23:36:34 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (first (range 10))
|
|
|
|
0
|
|
|
|
|
2013-07-22 22:36:59 +02:00
|
|
|
|
|
|
|
for
|
2014-12-06 21:28:28 +01:00
|
|
|
---
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``for`` is used to call a function for each element in a list or vector.
|
|
|
|
The results of each call are discarded and the ``for`` expression returns
|
|
|
|
``None`` instead. The example code iterates over *collection* and for each
|
|
|
|
*element* in *collection* calls the ``side-effect`` function with *element*
|
|
|
|
as its argument:
|
2013-07-06 22:43:47 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
;; assuming that (side-effect) is a function that takes a single parameter
|
2013-12-31 19:35:31 +01:00
|
|
|
(for [element collection] (side-effect element))
|
2013-07-06 22:43:47 +02:00
|
|
|
|
2013-11-10 19:00:01 +01:00
|
|
|
;; for can have an optional else block
|
2013-12-31 19:35:31 +01:00
|
|
|
(for [element collection] (side-effect element)
|
2013-11-10 19:00:01 +01:00
|
|
|
(else (side-effect-2)))
|
2013-07-10 07:24:58 +02:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
The optional ``else`` block is only executed if the ``for`` loop terminates
|
|
|
|
normally. If the execution is halted with ``break``, the ``else`` block does
|
|
|
|
not execute.
|
2013-07-10 07:24:58 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
2013-12-31 19:35:31 +01:00
|
|
|
=> (for [element [1 2 3]] (if (< element 3)
|
2014-12-06 21:28:28 +01:00
|
|
|
... (print element)
|
2013-11-10 19:00:01 +01:00
|
|
|
... (break))
|
2013-07-10 07:24:58 +02:00
|
|
|
... (else (print "loop finished")))
|
|
|
|
1
|
|
|
|
2
|
|
|
|
|
2013-12-31 19:35:31 +01:00
|
|
|
=> (for [element [1 2 3]] (if (< element 4)
|
2013-11-10 19:00:01 +01:00
|
|
|
... (print element)
|
|
|
|
... (break))
|
2013-07-10 07:24:58 +02:00
|
|
|
... (else (print "loop finished")))
|
|
|
|
1
|
|
|
|
2
|
|
|
|
3
|
|
|
|
loop finished
|
2013-07-06 22:43:47 +02:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2014-04-28 20:09:06 +02:00
|
|
|
genexpr
|
|
|
|
-------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``genexpr`` is used to create generator expressions. It takes two or three
|
|
|
|
parameters. The first parameter is the expression controlling the return value,
|
|
|
|
while the second is used to select items from a list. The third and optional
|
2014-12-06 21:28:28 +01:00
|
|
|
parameter can be used to filter out some of the items in the list based on a
|
2014-12-07 07:05:52 +01:00
|
|
|
conditional expression. ``genexpr`` is similar to ``list-comp``, except it
|
|
|
|
returns an iterable that evaluates values one by one instead of evaluating them
|
|
|
|
immediately.
|
2014-04-28 20:09:06 +02:00
|
|
|
|
2014-04-28 20:35:28 +02:00
|
|
|
.. code-block:: hy
|
2014-04-28 20:09:06 +02:00
|
|
|
|
|
|
|
=> (def collection (range 10))
|
|
|
|
=> (def filtered (genexpr x [x collection] (even? x)))
|
|
|
|
=> (list filtered)
|
|
|
|
[0, 2, 4, 6, 8]
|
|
|
|
|
|
|
|
|
2013-12-30 22:42:55 +01:00
|
|
|
.. _gensym:
|
|
|
|
|
|
|
|
gensym
|
|
|
|
------
|
|
|
|
|
|
|
|
.. versionadded:: 0.9.12
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``gensym`` is used to generate a unique symbol that allows macros to be
|
|
|
|
written without accidental variable name clashes.
|
2013-12-30 22:42:55 +01:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (gensym)
|
|
|
|
u':G_1235'
|
|
|
|
|
|
|
|
=> (gensym "x")
|
|
|
|
u':x_1236'
|
|
|
|
|
|
|
|
.. seealso::
|
|
|
|
|
|
|
|
Section :ref:`using-gensym`
|
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
get
|
|
|
|
---
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``get`` is used to access single elements in lists and dictionaries. ``get``
|
|
|
|
takes two parameters: the *data structure* and the *index* or *key* of the
|
|
|
|
item. It will then return the corresponding value from the dictionary or the
|
|
|
|
list. Example usage:
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (let [[animals {"dog" "bark" "cat" "meow"}]
|
|
|
|
... [numbers ["zero" "one" "two" "three"]]]
|
|
|
|
... (print (get animals "dog"))
|
|
|
|
... (print (get numbers 2)))
|
|
|
|
bark
|
|
|
|
two
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
.. note:: ``get`` raises a KeyError if a dictionary is queried for a
|
|
|
|
non-existing key.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
.. note:: ``get`` raises an IndexError if a list or a tuple is queried for an
|
|
|
|
index that is out of bounds.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2013-07-06 22:43:47 +02:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
global
|
|
|
|
------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``global`` can be used to mark a symbol as global. This allows the programmer to
|
2013-07-19 14:57:25 +02:00
|
|
|
assign a value to a global symbol. Reading a global symbol does not require the
|
2014-12-07 07:05:52 +01:00
|
|
|
``global`` keyword -- only assigning it does.
|
2013-07-19 14:57:25 +02:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
The following example shows how the global symbol ``a`` is assigned a value in a
|
|
|
|
function and is later on printed in another function. Without the ``global``
|
|
|
|
keyword, the second function would have thrown a ``NameError``.
|
2013-07-19 14:57:25 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
(defn set-a [value]
|
|
|
|
(global a)
|
|
|
|
(setv a value))
|
|
|
|
|
|
|
|
(defn print-a []
|
|
|
|
(print a))
|
|
|
|
|
|
|
|
(set-a 5)
|
|
|
|
(print-a)
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2014-01-18 16:27:26 +01:00
|
|
|
if / if-not
|
|
|
|
-----------
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2014-12-06 21:28:28 +01:00
|
|
|
.. versionadded:: 0.10.0
|
|
|
|
if-not
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``if`` is used to conditionally select code to be executed. It has to contain a
|
2014-12-06 21:28:28 +01:00
|
|
|
condition block and the block to be executed if the condition block evaluates
|
2014-12-07 07:05:52 +01:00
|
|
|
to ``True``. Optionally, it may contain a final block that is executed in case
|
|
|
|
the evaluation of the condition is ``False``.
|
|
|
|
|
|
|
|
``if-not`` is similar, but the second block will be executed when the condition
|
|
|
|
fails while the third and final block is executed when the test succeeds -- the
|
|
|
|
opposite order of ``if``.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
Example usage:
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
(if (money-left? account)
|
2014-12-06 21:28:28 +01:00
|
|
|
(print "let's go shopping")
|
|
|
|
(print "let's go and work"))
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2014-01-18 16:27:26 +01:00
|
|
|
(if-not (money-left? account)
|
2014-12-06 21:28:28 +01:00
|
|
|
(print "let's go and work")
|
|
|
|
(print "let's go shopping"))
|
2014-01-18 16:27:26 +01:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
Python truthiness is respected. ``None``, ``False``, zero of any numeric type,
|
|
|
|
an empty sequence, and an empty dictionary are considered ``False``; everything
|
|
|
|
else is considered ``True``.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
|
2014-09-10 18:55:11 +02:00
|
|
|
lisp-if / lif and lisp-if-not / lif-not
|
|
|
|
---------------------------------------
|
2014-02-24 16:39:45 +01:00
|
|
|
|
2014-04-13 16:42:48 +02:00
|
|
|
.. versionadded:: 0.10.0
|
|
|
|
|
2014-09-10 18:55:11 +02:00
|
|
|
.. versionadded:: 0.10.2
|
|
|
|
lisp-if-not / lif-not
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
For those that prefer a more Lispy ``if`` clause, we have ``lisp-if``, or
|
|
|
|
``lif``. This *only* considers ``None`` / ``nil`` to be false! All other
|
|
|
|
"false-ish" Python values are considered true. Conversely, we have
|
|
|
|
``lisp-if-not`` and ``lif-not`` in parallel to ``if`` and ``if-not`` which
|
|
|
|
reverses the comparison.
|
2014-02-24 16:39:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (lisp-if True "true" "false")
|
|
|
|
"true"
|
|
|
|
=> (lisp-if False "true" "false")
|
|
|
|
"true"
|
|
|
|
=> (lisp-if 0 "true" "false")
|
|
|
|
"true"
|
|
|
|
=> (lisp-if nil "true" "false")
|
|
|
|
"false"
|
|
|
|
=> (lisp-if None "true" "false")
|
|
|
|
"false"
|
2014-09-10 18:55:11 +02:00
|
|
|
=> (lisp-if-not nil "true" "false")
|
|
|
|
"true"
|
|
|
|
=> (lisp-if-not None "true" "false")
|
|
|
|
"true"
|
|
|
|
=> (lisp-if-not False "true" "false")
|
|
|
|
"false"
|
2014-02-24 16:39:45 +01:00
|
|
|
|
2014-12-06 21:28:28 +01:00
|
|
|
; Equivalent but shorter
|
2014-02-24 16:39:45 +01:00
|
|
|
=> (lif True "true" "false")
|
|
|
|
"true"
|
|
|
|
=> (lif nil "true" "false")
|
|
|
|
"false"
|
2014-09-10 18:55:11 +02:00
|
|
|
=> (lif-not None "true" "false")
|
|
|
|
"true"
|
2014-02-24 16:39:45 +01:00
|
|
|
|
|
|
|
|
2013-05-09 04:16:03 +02:00
|
|
|
import
|
|
|
|
------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``import`` is used to import modules, like in Python. There are several ways
|
|
|
|
that ``import`` can be used.
|
2013-05-09 04:16:03 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
2013-05-09 04:32:11 +02:00
|
|
|
|
2013-05-09 04:16:03 +02:00
|
|
|
;; Imports each of these modules
|
|
|
|
;;
|
|
|
|
;; Python:
|
|
|
|
;; import sys
|
|
|
|
;; import os.path
|
|
|
|
(import sys os.path)
|
|
|
|
|
|
|
|
;; Import from a module
|
|
|
|
;;
|
|
|
|
;; Python: from os.path import exists, isdir, isfile
|
|
|
|
(import [os.path [exists isdir isfile]])
|
|
|
|
|
|
|
|
;; Import with an alias
|
|
|
|
;;
|
|
|
|
;; Python: import sys as systest
|
|
|
|
(import [sys :as systest])
|
|
|
|
|
|
|
|
;; You can list as many imports as you like of different types.
|
|
|
|
(import [tests.resources [kwtest function-with-a-dash]]
|
|
|
|
[os.path [exists isdir isfile]]
|
|
|
|
[sys :as systest])
|
|
|
|
|
2014-02-11 16:25:17 +01:00
|
|
|
;; Import all module functions into current namespace
|
|
|
|
(import [sys [*]])
|
|
|
|
|
2013-05-09 04:16:03 +02:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
lambda / fn
|
|
|
|
-----------
|
2013-04-09 03:53:06 +02:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``lambda`` and ``fn`` can be used to define an anonymous function. The parameters are
|
|
|
|
similar to ``defn``: the first parameter is vector of parameters and the rest is the
|
|
|
|
body of the function. ``lambda`` returns a new function. In the following example, an
|
2014-12-06 21:28:28 +01:00
|
|
|
anonymous function is defined and passed to another function for filtering output.
|
2013-07-06 22:43:47 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (def people [{:name "Alice" :age 20}
|
|
|
|
... {:name "Bob" :age 25}
|
|
|
|
... {:name "Charlie" :age 50}
|
|
|
|
... {:name "Dave" :age 5}])
|
|
|
|
|
|
|
|
=> (defn display-people [people filter]
|
2013-12-31 19:35:31 +01:00
|
|
|
... (for [person people] (if (filter person) (print (:name person)))))
|
2013-07-06 22:43:47 +02:00
|
|
|
|
|
|
|
=> (display-people people (fn [person] (< (:age person) 25)))
|
|
|
|
Alice
|
|
|
|
Dave
|
|
|
|
|
2014-02-23 22:20:43 +01:00
|
|
|
Just as in normal function definitions, if the first element of the
|
2014-12-07 07:05:52 +01:00
|
|
|
body is a string, it serves as a docstring. This is useful for giving
|
2014-02-23 22:20:43 +01:00
|
|
|
class methods docstrings.
|
|
|
|
|
2014-04-13 17:04:42 +02:00
|
|
|
.. code-block:: clj
|
|
|
|
|
2014-02-23 22:20:43 +01:00
|
|
|
=> (setv times-three
|
|
|
|
... (fn [x]
|
|
|
|
... "Multiplies input by three and returns the result."
|
|
|
|
... (* x 3)))
|
|
|
|
|
2014-12-06 21:28:28 +01:00
|
|
|
This can be confirmed via Python's built-in ``help`` function::
|
2014-04-13 17:04:42 +02:00
|
|
|
|
2014-02-23 22:20:43 +01:00
|
|
|
=> (help times-three)
|
|
|
|
Help on function times_three:
|
|
|
|
|
|
|
|
times_three(x)
|
|
|
|
Multiplies input by three and returns result
|
|
|
|
(END)
|
|
|
|
|
2013-04-09 03:53:06 +02:00
|
|
|
|
2013-07-22 22:36:59 +02:00
|
|
|
let
|
|
|
|
---
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``let`` is used to create lexically scoped variables. They are created at the
|
|
|
|
beginning of the ``let`` form and cease to exist after the form. The following
|
2013-07-23 15:50:12 +02:00
|
|
|
example showcases this behaviour:
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
2014-12-06 21:28:28 +01:00
|
|
|
=> (let [[x 5]] (print x)
|
|
|
|
... (let [[x 6]] (print x))
|
2013-07-23 15:50:12 +02:00
|
|
|
... (print x))
|
|
|
|
5
|
|
|
|
6
|
|
|
|
5
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
The ``let`` macro takes two parameters: a vector defining *variables* and the
|
|
|
|
*body* which gets executed. *variables* is a vector where each element is either
|
2014-12-06 21:28:28 +01:00
|
|
|
a single variable or a vector defining a variable value pair. In the case of a
|
2014-12-07 07:05:52 +01:00
|
|
|
single variable, it is assigned value ``None``; otherwise, the supplied value is
|
2013-07-23 15:50:12 +02:00
|
|
|
used.
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (let [x [y 5]] (print x y))
|
|
|
|
None 5
|
|
|
|
|
2013-07-22 22:36:59 +02:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
list-comp
|
|
|
|
---------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``list-comp`` performs list comprehensions. It takes two or three parameters.
|
2013-06-30 15:39:06 +02:00
|
|
|
The first parameter is the expression controlling the return value, while
|
|
|
|
the second is used to select items from a list. The third and optional
|
2014-12-06 21:28:28 +01:00
|
|
|
parameter can be used to filter out some of the items in the list based on a
|
2013-06-30 15:39:06 +02:00
|
|
|
conditional expression. Some examples:
|
2013-04-09 03:53:06 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
=> (def collection (range 10))
|
|
|
|
=> (list-comp x [x collection])
|
|
|
|
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
2013-04-09 03:53:06 +02:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
=> (list-comp (* x 2) [x collection])
|
|
|
|
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
|
|
|
|
|
|
|
|
=> (list-comp (* x 2) [x collection] (< x 5))
|
|
|
|
[0, 2, 4, 6, 8]
|
|
|
|
|
2013-07-06 22:43:47 +02:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
not
|
|
|
|
---
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``not`` is used in logical expressions. It takes a single parameter and
|
|
|
|
returns a reversed truth value. If ``True`` is given as a parameter, ``False``
|
|
|
|
will be returned, and vice-versa. Example usage:
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (not True)
|
|
|
|
False
|
|
|
|
|
|
|
|
=> (not False)
|
|
|
|
True
|
|
|
|
|
|
|
|
=> (not None)
|
|
|
|
True
|
|
|
|
|
|
|
|
|
|
|
|
or
|
|
|
|
--
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``or`` is used in logical expressions. It takes at least two parameters. It
|
|
|
|
will return the first non-false parameter. If no such value exists, the last
|
2013-06-30 15:39:06 +02:00
|
|
|
parameter will be returned.
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (or True False)
|
|
|
|
True
|
|
|
|
|
|
|
|
=> (and False False)
|
|
|
|
False
|
|
|
|
|
|
|
|
=> (and False 1 True False)
|
|
|
|
1
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
.. note:: ``or`` short-circuits and stops evaluating parameters as soon as the
|
2014-12-06 21:28:28 +01:00
|
|
|
first true value is encountered.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (or True (print "hello"))
|
|
|
|
True
|
|
|
|
|
|
|
|
|
|
|
|
print
|
|
|
|
-----
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``print`` is used to output on screen. Example usage:
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
(print "Hello world!")
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
.. note:: ``print`` always returns ``None``.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2013-07-06 22:43:47 +02:00
|
|
|
|
2013-11-26 19:31:10 +01:00
|
|
|
quasiquote
|
|
|
|
----------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``quasiquote`` allows you to quote a form, but also selectively evaluate
|
|
|
|
expressions. Expressions inside a ``quasiquote`` can be selectively evaluated
|
|
|
|
using ``unquote`` (``~``). The evaluated form can also be spliced using
|
|
|
|
``unquote-splice`` (``~@``). Quasiquote can be also written using the backquote
|
|
|
|
(`````) symbol.
|
2013-11-26 19:31:10 +01:00
|
|
|
|
|
|
|
.. code-block:: clj
|
2013-11-30 20:50:58 +01:00
|
|
|
|
2013-11-26 19:31:10 +01:00
|
|
|
;; let `qux' be a variable with value (bar baz)
|
|
|
|
`(foo ~qux)
|
|
|
|
; equivalent to '(foo (bar baz))
|
|
|
|
`(foo ~@qux)
|
|
|
|
; equivalent to '(foo bar baz)
|
|
|
|
|
|
|
|
|
|
|
|
quote
|
|
|
|
-----
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``quote`` returns the form passed to it without evaluating it. ``quote`` can
|
|
|
|
alternatively be written using the apostrophe (``'``) symbol.
|
2013-11-26 19:31:10 +01:00
|
|
|
|
|
|
|
.. code-block:: clj
|
2013-11-30 20:50:58 +01:00
|
|
|
|
2013-11-26 19:31:10 +01:00
|
|
|
=> (setv x '(print "Hello World"))
|
|
|
|
; variable x is set to expression & not evaluated
|
|
|
|
=> x
|
|
|
|
(u'print' u'Hello World')
|
|
|
|
=> (eval x)
|
|
|
|
Hello World
|
|
|
|
|
2013-11-30 20:50:58 +01:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
require
|
|
|
|
-------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``require`` is used to import macros from a given module. It takes at least one
|
2013-07-23 05:39:29 +02:00
|
|
|
parameter specifying the module which macros should be imported. Multiple
|
2014-12-07 07:05:52 +01:00
|
|
|
modules can be imported with a single ``require``.
|
2013-07-22 22:36:59 +02:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
The following example will import macros from ``module-1`` and ``module-2``:
|
2013-07-22 22:36:59 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
2013-07-23 05:39:29 +02:00
|
|
|
(require module-1 module-2)
|
2013-07-22 22:36:59 +02:00
|
|
|
|
|
|
|
|
|
|
|
rest / cdr
|
|
|
|
----------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``rest`` and ``cdr`` return the collection passed as an argument without the
|
|
|
|
first element:
|
2013-07-22 23:36:34 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (rest (range 10))
|
|
|
|
[1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2014-04-28 20:35:28 +02:00
|
|
|
set-comp
|
|
|
|
--------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``set-comp`` is used to create sets. It takes two or three parameters.
|
2014-04-28 20:35:28 +02:00
|
|
|
The first parameter is for controlling the return value, while the second is
|
|
|
|
used to select items from a sequence. The third and optional parameter can be
|
|
|
|
used to filter out some of the items in the sequence based on a conditional
|
|
|
|
expression.
|
|
|
|
|
|
|
|
.. code-block:: hy
|
|
|
|
|
|
|
|
=> (setv data [1 2 3 4 5 2 3 4 5 3 4 5])
|
|
|
|
=> (set-comp x [x data] (odd? x))
|
|
|
|
{1, 3, 5}
|
|
|
|
|
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
slice
|
|
|
|
-----
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``slice`` can be used to take a subset of a list and create a new list from it.
|
2013-06-30 15:39:06 +02:00
|
|
|
The form takes at least one parameter specifying the list to slice. Two
|
|
|
|
optional parameters can be used to give the start and end position of the
|
2014-12-07 07:05:52 +01:00
|
|
|
subset. If they are not supplied, the default value of ``None`` will be used
|
|
|
|
instead. The third optional parameter is used to control step between the elements.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``slice`` follows the same rules as its Python counterpart. Negative indices are
|
2014-12-06 21:28:28 +01:00
|
|
|
counted starting from the end of the list. Some example usage:
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (def collection (range 10))
|
|
|
|
|
|
|
|
=> (slice collection)
|
|
|
|
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
|
|
|
|
|
|
=> (slice collection 5)
|
|
|
|
[5, 6, 7, 8, 9]
|
|
|
|
|
|
|
|
=> (slice collection 2 8)
|
|
|
|
[2, 3, 4, 5, 6, 7]
|
|
|
|
|
|
|
|
=> (slice collection 2 8 2)
|
|
|
|
[2, 4, 6]
|
|
|
|
|
|
|
|
=> (slice collection -4 -2)
|
|
|
|
[6, 7]
|
2013-04-09 03:53:06 +02:00
|
|
|
|
|
|
|
|
|
|
|
throw / raise
|
|
|
|
-------------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
The ``throw`` or ``raise`` forms can be used to raise an ``Exception`` at
|
|
|
|
runtime. Example usage:
|
2013-04-09 03:53:06 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
(throw)
|
|
|
|
; re-rase the last exception
|
2014-12-06 21:28:28 +01:00
|
|
|
|
2013-04-09 03:53:06 +02:00
|
|
|
(throw IOError)
|
|
|
|
; Throw an IOError
|
2014-12-06 21:28:28 +01:00
|
|
|
|
2013-04-09 03:53:06 +02:00
|
|
|
(throw (IOError "foobar"))
|
|
|
|
; Throw an IOError("foobar")
|
|
|
|
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``throw`` can accept a single argument (an ``Exception`` class or instance)
|
|
|
|
or no arguments to re-raise the last ``Exception``.
|
2013-04-09 03:53:06 +02:00
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
---
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
The ``try`` form is used to start a ``try`` / ``catch`` block. The form is
|
|
|
|
used as follows:
|
2013-04-09 03:53:06 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
(try
|
|
|
|
(error-prone-function)
|
2013-06-30 07:27:15 +02:00
|
|
|
(catch [e ZeroDivisionError] (print "Division by zero"))
|
|
|
|
(else (print "no errors"))
|
|
|
|
(finally (print "all done")))
|
2013-04-09 03:53:06 +02:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``try`` must contain at least one ``catch`` block, and may optionally include
|
|
|
|
an ``else`` or ``finally`` block. If an error is raised with a matching catch
|
|
|
|
block during the execution of ``error-prone-function``, that ``catch`` block
|
|
|
|
will be executed. If no errors are raised, the ``else`` block is executed. The
|
|
|
|
``finally`` block will be executed last regardless of whether or not an error
|
2014-12-06 21:28:28 +01:00
|
|
|
was raised.
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
|
2013-07-22 22:36:59 +02:00
|
|
|
unless
|
|
|
|
------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
The ``unless`` macro is a shorthand for writing an ``if`` statement that checks if
|
|
|
|
the given conditional is ``False``. The following shows the expansion of this macro.
|
2013-07-22 23:36:34 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
(unless conditional statement)
|
|
|
|
|
2014-12-06 21:28:28 +01:00
|
|
|
(if conditional
|
|
|
|
None
|
2013-07-22 23:36:34 +02:00
|
|
|
(do statement))
|
2013-07-22 22:36:59 +02:00
|
|
|
|
2014-01-12 05:29:48 +01:00
|
|
|
|
|
|
|
unquote
|
|
|
|
-------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
Within a quasiquoted form, ``unquote`` forces evaluation of a symbol. ``unquote``
|
|
|
|
is aliased to the tilde (``~``) symbol.
|
2014-01-12 05:29:48 +01:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
(def name "Cuddles")
|
|
|
|
(quasiquote (= name (unquote name)))
|
|
|
|
;=> (u'=' u'name' u'Cuddles')
|
|
|
|
|
|
|
|
`(= name ~name)
|
|
|
|
;=> (u'=' u'name' u'Cuddles')
|
|
|
|
|
|
|
|
|
|
|
|
unquote-splice
|
|
|
|
--------------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``unquote-splice`` forces the evaluation of a symbol within a quasiquoted form,
|
|
|
|
much like ``unquote``. ``unquote-splice`` can only be used when the symbol
|
|
|
|
being unquoted contains an iterable value, as it "splices" that iterable into
|
|
|
|
the quasiquoted form. ``unquote-splice`` is aliased to the ``~@`` symbol.
|
2014-01-12 05:29:48 +01:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
(def nums [1 2 3 4])
|
|
|
|
(quasiquote (+ (unquote-splice nums)))
|
|
|
|
;=> (u'+' 1L 2L 3L 4L)
|
|
|
|
|
|
|
|
`(+ ~@nums)
|
|
|
|
;=> (u'+' 1L 2L 3L 4L)
|
|
|
|
|
|
|
|
|
2013-07-22 22:36:59 +02:00
|
|
|
when
|
|
|
|
----
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``when`` is similar to ``unless``, except it tests when the given conditional is
|
|
|
|
``True``. It is not possible to have an ``else`` block in a ``when`` macro. The
|
|
|
|
following shows the expansion of the macro.
|
2013-07-22 23:36:34 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
(when conditional statement)
|
|
|
|
|
|
|
|
(if conditional (do statement))
|
2013-07-22 22:36:59 +02:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
while
|
|
|
|
-----
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``while`` is used to execute one or more blocks as long as a condition is met.
|
|
|
|
The following example will output "Hello world!" to the screen indefinitely:
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
(while True (print "Hello world!"))
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2013-07-06 22:43:47 +02:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
with
|
|
|
|
----
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``with`` is used to wrap the execution of a block within a context manager. The
|
2014-12-06 21:28:28 +01:00
|
|
|
context manager can then set up the local system and tear it down in a controlled
|
2014-12-07 07:05:52 +01:00
|
|
|
manner. The archetypical example of using ``with`` is when processing files.
|
|
|
|
``with`` can bind context to an argument or ignore it completely, as shown below:
|
2013-07-06 22:43:47 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
2013-11-10 19:00:01 +01:00
|
|
|
(with [[arg (expr)]] block)
|
|
|
|
|
|
|
|
(with [[(expr)]] block)
|
2013-07-06 22:43:47 +02:00
|
|
|
|
2013-11-10 19:00:01 +01:00
|
|
|
(with [[arg (expr)] [(expr)]] block)
|
2013-07-06 22:43:47 +02:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
The following example will open the ``NEWS`` file and print its content to the
|
|
|
|
screen. The file is automatically closed after it has been processed.
|
2013-07-06 22:43:47 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
2013-11-10 19:00:01 +01:00
|
|
|
(with [[f (open "NEWS")]] (print (.read f)))
|
2013-07-06 22:43:47 +02:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
|
|
|
|
with-decorator
|
|
|
|
--------------
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``with-decorator`` is used to wrap a function with another. The function
|
2014-12-06 21:28:28 +01:00
|
|
|
performing the decoration should accept a single value: the function being
|
2014-12-07 07:05:52 +01:00
|
|
|
decorated, and return a new function. ``with-decorator`` takes a minimum
|
2014-12-06 21:28:28 +01:00
|
|
|
of two parameters: the function performing decoration and the function
|
|
|
|
being decorated. More than one decorator function can be applied; they
|
2014-05-23 19:33:38 +02:00
|
|
|
will be applied in order from outermost to innermost, ie. the first
|
2014-12-06 21:28:28 +01:00
|
|
|
decorator will be the outermost one, and so on. Decorators with arguments
|
2014-05-23 19:33:38 +02:00
|
|
|
are called just like a function call.
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
(with-decorator decorator-fun
|
|
|
|
(defn some-function [] ...)
|
|
|
|
|
|
|
|
(with-decorator decorator1 decorator2 ...
|
|
|
|
(defn some-function [] ...)
|
|
|
|
|
|
|
|
(with-decorator (decorator arg) ..
|
|
|
|
(defn some-function [] ...)
|
2013-07-06 22:43:47 +02:00
|
|
|
|
2014-05-23 19:33:38 +02:00
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
In the following example, ``inc-decorator`` is used to decorate the function
|
|
|
|
``addition`` with a function that takes two parameters and calls the
|
2014-05-23 19:33:38 +02:00
|
|
|
decorated function with values that are incremented by 1. When
|
2014-12-07 07:05:52 +01:00
|
|
|
the decorated ``addition`` is called with values 1 and 1, the end result
|
|
|
|
will be 4 (``1+1 + 1+1``).
|
2013-07-06 22:43:47 +02:00
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
2014-05-23 19:33:38 +02:00
|
|
|
=> (defn inc-decorator [func]
|
2013-07-06 22:43:47 +02:00
|
|
|
... (fn [value-1 value-2] (func (+ value-1 1) (+ value-2 1))))
|
2014-05-23 19:33:38 +02:00
|
|
|
=> (defn inc2-decorator [func]
|
|
|
|
... (fn [value-1 value-2] (func (+ value-1 2) (+ value-2 2))))
|
|
|
|
|
2013-07-06 22:43:47 +02:00
|
|
|
=> (with-decorator inc-decorator (defn addition [a b] (+ a b)))
|
|
|
|
=> (addition 1 1)
|
|
|
|
4
|
2014-05-23 19:33:38 +02:00
|
|
|
=> (with-decorator inc2-decorator inc-decorator
|
|
|
|
... (defn addition [a b] (+ a b)))
|
|
|
|
=> (addition 1 1)
|
|
|
|
8
|
2013-07-06 22:43:47 +02:00
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2013-12-30 22:42:55 +01:00
|
|
|
.. _with-gensyms:
|
|
|
|
|
|
|
|
with-gensyms
|
|
|
|
-------------
|
|
|
|
|
|
|
|
.. versionadded:: 0.9.12
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``with-gensym`` is used to generate a set of :ref:`gensym` for use in a macro.
|
|
|
|
The following code:
|
2013-12-30 22:42:55 +01:00
|
|
|
|
2014-03-14 14:01:47 +01:00
|
|
|
.. code-block:: hy
|
2013-12-30 22:42:55 +01:00
|
|
|
|
|
|
|
(with-gensyms [a b c]
|
|
|
|
...)
|
|
|
|
|
|
|
|
expands to:
|
|
|
|
|
2014-03-14 14:01:47 +01:00
|
|
|
.. code-block:: hy
|
2013-12-30 22:42:55 +01:00
|
|
|
|
|
|
|
(let [[a (gensym)
|
|
|
|
[b (gensym)
|
|
|
|
[c (gensym)]]
|
|
|
|
...)
|
|
|
|
|
|
|
|
.. seealso::
|
|
|
|
|
|
|
|
Section :ref:`using-gensym`
|
|
|
|
|
|
|
|
|
2013-06-30 15:39:06 +02:00
|
|
|
yield
|
|
|
|
-----
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``yield`` is used to create a generator object that returns one or more values.
|
2013-07-06 22:43:47 +02:00
|
|
|
The generator is iterable and therefore can be used in loops, list
|
|
|
|
comprehensions and other similar constructs.
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
The function ``random-numbers`` shows how generators can be used to generate
|
2013-07-06 22:43:47 +02:00
|
|
|
infinite series without consuming infinite amount of memory.
|
|
|
|
|
|
|
|
.. code-block:: clj
|
|
|
|
|
|
|
|
=> (defn multiply [bases coefficients]
|
2013-11-10 19:00:01 +01:00
|
|
|
... (for [[(, base coefficient) (zip bases coefficients)]]
|
2013-07-06 22:43:47 +02:00
|
|
|
... (yield (* base coefficient))))
|
|
|
|
|
|
|
|
=> (multiply (range 5) (range 5))
|
|
|
|
<generator object multiply at 0x978d8ec>
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2013-07-06 22:43:47 +02:00
|
|
|
=> (list-comp value [value (multiply (range 10) (range 10))])
|
|
|
|
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
|
2013-06-30 15:39:06 +02:00
|
|
|
|
2013-07-06 22:43:47 +02:00
|
|
|
=> (import random)
|
|
|
|
=> (defn random-numbers [low high]
|
|
|
|
... (while True (yield (.randint random low high))))
|
|
|
|
=> (list-comp x [x (take 15 (random-numbers 1 50))])])
|
|
|
|
[7, 41, 6, 22, 32, 17, 5, 38, 18, 38, 17, 14, 23, 23, 19]
|
2014-02-20 03:27:49 +01:00
|
|
|
|
2014-02-23 17:48:33 +01:00
|
|
|
|
|
|
|
yield-from
|
|
|
|
----------
|
|
|
|
|
|
|
|
.. versionadded:: 0.9.13
|
|
|
|
|
|
|
|
**PYTHON 3.3 AND UP ONLY!**
|
|
|
|
|
2014-12-07 07:05:52 +01:00
|
|
|
``yield-from`` is used to call a subgenerator. This is useful if you
|
2014-02-23 17:48:33 +01:00
|
|
|
want your coroutine to be able to delegate its processes to another
|
2014-12-06 21:28:28 +01:00
|
|
|
coroutine, say, if using something fancy like
|
2014-02-23 17:48:33 +01:00
|
|
|
`asyncio <http://docs.python.org/3.4/library/asyncio.html>`_.
|