parent
b22f477081
commit
35e28e52ac
@ -38,6 +38,217 @@ Hy features a number special forms that are used to help generate
|
||||
correct Python AST. The following are "special" forms, which may have
|
||||
behavior that's slightly unexpected in some situations.
|
||||
|
||||
and
|
||||
---
|
||||
|
||||
`and` form 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. Examples of usage:
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=> (and True False)
|
||||
False
|
||||
|
||||
=> (and True True)
|
||||
True
|
||||
|
||||
=> (and True 1)
|
||||
1
|
||||
|
||||
=> (and True [] False True)
|
||||
[]
|
||||
|
||||
.. note:: `and` shortcuts and stops evaluating parameters as soon as the first
|
||||
false is encountered. However, in the current implementation of Hy
|
||||
statements are executed as soon as they are converted to expressions.
|
||||
The following two examples demonstrates the difference.
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=> (and False (print "hello"))
|
||||
hello
|
||||
False
|
||||
|
||||
=> (defn side-effects [x] (print "I can has" x) x)
|
||||
=> (and (side-effects false) (side-effects 42))
|
||||
I can has False
|
||||
False
|
||||
|
||||
assert
|
||||
------
|
||||
|
||||
`assert` is used to verify conditions while the program is running. If the
|
||||
condition is not met, an `AssertionError` is raised. The example usage:
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
(assert (= variable expected-value))
|
||||
|
||||
Assert takes a single parameter, a conditional that evaluates to either `True`
|
||||
or `False`.
|
||||
|
||||
assoc
|
||||
-----
|
||||
|
||||
`assoc` form 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 three parameters: `datastructure` to be
|
||||
modified, `key` or `index` and `value`.
|
||||
|
||||
Examples of usage:
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=>(let [[collection ({})]]
|
||||
... (assoc collection "Dog" "Bark")
|
||||
... (print collection))
|
||||
{u'Dog': u'Bark'}
|
||||
|
||||
=>(let [[collection [1 2 3 4]]]
|
||||
... (assoc collection 2 None)
|
||||
... (print collection))
|
||||
[1, 2, None, 4]
|
||||
|
||||
.. note:: `assoc` modifies the datastructure in place and returns `None`.
|
||||
|
||||
break
|
||||
-----
|
||||
|
||||
`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`.
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
(while True (if (= "k" (raw-input "? "))
|
||||
(break)
|
||||
(print "Try again")))
|
||||
|
||||
|
||||
continue
|
||||
--------
|
||||
|
||||
`continue` returns execution to the start of a loop. In the following example,
|
||||
function `(side-effect1)` is called for each iteration. `(side-effect2)`
|
||||
however is called only for every other value in the list.
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
;; assuming that (side-effect1) and (side-effect2) are functions and
|
||||
;; collection is a list of numerical values
|
||||
|
||||
(for (x collection) (do
|
||||
(side-effect1 x)
|
||||
(if (% x 2)
|
||||
(continue))
|
||||
(side-effect2 x)))
|
||||
|
||||
do / progn
|
||||
----------
|
||||
|
||||
the `do` and `progn` forms 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 show by one of the examples.
|
||||
|
||||
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
|
||||
;; and every value in the list, but which return values we do not care
|
||||
=> (list-comp (do (side-effect x)
|
||||
... (if (< x 5) (* 2 x)
|
||||
... (* 4 x)))
|
||||
... (x (range 10)))
|
||||
[0, 2, 4, 6, 8, 20, 24, 28, 32, 36]
|
||||
|
||||
`do` can accept any number of arguments, from 1 to n.
|
||||
|
||||
|
||||
def / setf / setv
|
||||
-----------------
|
||||
|
||||
|
||||
defclass
|
||||
--------
|
||||
|
||||
|
||||
defmacro
|
||||
--------
|
||||
|
||||
|
||||
eval
|
||||
----
|
||||
|
||||
|
||||
eval-and-compile
|
||||
----------------
|
||||
|
||||
|
||||
eval-when-compile
|
||||
-----------------
|
||||
|
||||
|
||||
foreach
|
||||
-------
|
||||
|
||||
|
||||
get
|
||||
---
|
||||
|
||||
`get` form is used to access single elements in lists and dictionaries. `get`
|
||||
takes two parameters, the `datastructure` and the `index` or `key` of the item.
|
||||
It will then return the corresponding value from the dictionary or the list.
|
||||
Example usages:
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=> (let [[animals {"dog" "bark" "cat" "meow"}]
|
||||
... [numbers ["zero" "one" "two" "three"]]]
|
||||
... (print (get animals "dog"))
|
||||
... (print (get numbers 2)))
|
||||
bark
|
||||
two
|
||||
|
||||
.. note:: `get` raises a KeyError if a dictionary is queried for a non-existing
|
||||
key.
|
||||
|
||||
.. note:: `get` raises an IndexError if a list is queried for an index that is
|
||||
out of bounds.
|
||||
|
||||
global
|
||||
------
|
||||
|
||||
|
||||
if
|
||||
--
|
||||
|
||||
the `if` form is used to conditionally select code to be executed. It has to
|
||||
contain the condition block and the block to be executed if the condition
|
||||
evaluates `True`. Optionally it may contain a block that is executed in case
|
||||
the evaluation of the condition is `False`.
|
||||
|
||||
Example usage:
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
(if (money-left? account)
|
||||
(print "lets go shopping")
|
||||
(print "lets go and work"))
|
||||
|
||||
Truth values of Python objects are respected. Values `None`, `False`, zero of
|
||||
any numeric type, empty sequence and empty dictionary are considered `False`.
|
||||
Everything else is considered `True`.
|
||||
|
||||
|
||||
import
|
||||
------
|
||||
|
||||
@ -69,24 +280,136 @@ of import you can use.
|
||||
[sys :as systest])
|
||||
|
||||
|
||||
do / progn
|
||||
----------
|
||||
|
||||
the `do` or `progn` forms can be used in full code branches. What that means
|
||||
is basically `(do)` and `(progn)` can only be used where a Python expression
|
||||
can be used. These forms don't actually allow you to break Pythonic internals
|
||||
such as `lambda` or `list-comp`, where you can only have one expression.
|
||||
kwapply
|
||||
-------
|
||||
|
||||
|
||||
Some example usage
|
||||
lambda / fn
|
||||
-----------
|
||||
|
||||
|
||||
list-comp
|
||||
---------
|
||||
|
||||
`list-comp` performs list comprehensions. 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
|
||||
parameter can be used to filter out some of the items in the list based on a
|
||||
conditional expression. Some examples:
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
(if true
|
||||
(do (print "Side effects rock!")
|
||||
(print "Yeah, really!")))
|
||||
=> (def collection (range 10))
|
||||
=> (list-comp x [x collection])
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
|
||||
`do` can accept any number of arguments, from 1 to n.
|
||||
=> (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]
|
||||
|
||||
not
|
||||
---
|
||||
|
||||
`not` form 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. Examples for usage:
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=> (not True)
|
||||
False
|
||||
|
||||
=> (not False)
|
||||
True
|
||||
|
||||
=> (not None)
|
||||
True
|
||||
|
||||
|
||||
or
|
||||
--
|
||||
|
||||
`or` form is used in logical expressions. It takes at least two parameters. It
|
||||
will return the first non-false parameter. If no such value exist, the last
|
||||
parameter will be returned.
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=> (or True False)
|
||||
True
|
||||
|
||||
=> (and False False)
|
||||
False
|
||||
|
||||
=> (and False 1 True False)
|
||||
1
|
||||
|
||||
.. note:: `or` shortcuts and stops evaluating parameters as soon as the first
|
||||
true is encountered. However, in the current implementation of Hy
|
||||
statements are executed as soon as they are converted to expressions.
|
||||
The following two examples demonstrates the difference.
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=> (or True (print "hello"))
|
||||
hello
|
||||
True
|
||||
|
||||
=> (defn side-effects [x] (print "I can has" x) x)
|
||||
=> (or (side-effects 42) (side-effects False))
|
||||
I can has 42
|
||||
42
|
||||
|
||||
|
||||
print
|
||||
-----
|
||||
|
||||
the `print` form is used to output on screen. Example usage:
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
(print "Hello world!")
|
||||
|
||||
.. note:: `print` always returns None
|
||||
|
||||
require
|
||||
-------
|
||||
|
||||
|
||||
slice
|
||||
-----
|
||||
|
||||
`slice` can be used to take a subset of a list and create a new list from it.
|
||||
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
|
||||
subset. If they are not supplied, default value of None will be used instead.
|
||||
Third optional parameter is used to control step between the elements.
|
||||
|
||||
`slice` follows the same rules as the Python counterpart. Negative indecies are
|
||||
counted starting from the end of the list.
|
||||
Some examples of
|
||||
usage:
|
||||
|
||||
.. 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]
|
||||
|
||||
|
||||
throw / raise
|
||||
@ -132,3 +455,30 @@ as follows
|
||||
block during execution of `error-prone-function` then that catch block will
|
||||
be executed. If no errors are raised the `else` block is executed. Regardless
|
||||
if an error was raised or not, the `finally` block is executed as last.
|
||||
|
||||
|
||||
while
|
||||
-----
|
||||
|
||||
`while` form is used to execute a single or more blocks as long as a condition
|
||||
is being met.
|
||||
|
||||
The following example will output "hello world!" on screen indefinetely:
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
(while True (print "hello world!"))
|
||||
|
||||
with
|
||||
----
|
||||
|
||||
|
||||
with-decorator
|
||||
--------------
|
||||
|
||||
|
||||
yield
|
||||
-----
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user