Remove let
from documentation
This commit is contained in:
parent
2a44928eb7
commit
3ec919278d
@ -286,17 +286,20 @@ Examples of usage:
|
|||||||
|
|
||||||
.. code-block:: clj
|
.. code-block:: clj
|
||||||
|
|
||||||
=>(let [collection {}]
|
=>(do
|
||||||
|
... (setv collection {})
|
||||||
... (assoc collection "Dog" "Bark")
|
... (assoc collection "Dog" "Bark")
|
||||||
... (print collection))
|
... (print collection))
|
||||||
{u'Dog': u'Bark'}
|
{u'Dog': u'Bark'}
|
||||||
|
|
||||||
=>(let [collection {}]
|
=>(do
|
||||||
|
... (setv collection {})
|
||||||
... (assoc collection "Dog" "Bark" "Cat" "Meow")
|
... (assoc collection "Dog" "Bark" "Cat" "Meow")
|
||||||
... (print collection))
|
... (print collection))
|
||||||
{u'Cat': u'Meow', u'Dog': u'Bark'}
|
{u'Cat': u'Meow', u'Dog': u'Bark'}
|
||||||
|
|
||||||
=>(let [collection [1 2 3 4]]
|
=>(do
|
||||||
|
... (setv collection [1 2 3 4])
|
||||||
... (assoc collection 2 None)
|
... (assoc collection 2 None)
|
||||||
... (print collection))
|
... (print collection))
|
||||||
[1, 2, None, 4]
|
[1, 2, None, 4]
|
||||||
@ -555,9 +558,9 @@ Parameters may have the following keywords in front of them:
|
|||||||
.. code-block:: clj
|
.. code-block:: clj
|
||||||
|
|
||||||
=> (defn zig-zag-sum [&rest numbers]
|
=> (defn zig-zag-sum [&rest numbers]
|
||||||
(let [odd-numbers (list-comp x [x numbers] (odd? x))
|
(setv odd-numbers (list-comp x [x numbers] (odd? x))
|
||||||
even-numbers (list-comp x [x numbers] (even? x))]
|
even-numbers (list-comp x [x numbers] (even? x)))
|
||||||
(- (sum odd-numbers) (sum even-numbers))))
|
(- (sum odd-numbers) (sum even-numbers)))
|
||||||
|
|
||||||
=> (zig-zag-sum)
|
=> (zig-zag-sum)
|
||||||
0
|
0
|
||||||
@ -578,10 +581,10 @@ Parameters may have the following keywords in front of them:
|
|||||||
.. code-block:: clj
|
.. code-block:: clj
|
||||||
|
|
||||||
=> (defn compare [a b &kwonly keyfn [reverse false]]
|
=> (defn compare [a b &kwonly keyfn [reverse false]]
|
||||||
... (let [result (keyfn a b)]
|
... (setv result (keyfn a b))
|
||||||
... (if (not reverse)
|
... (if (not reverse)
|
||||||
... result
|
... result
|
||||||
... (- result))))
|
... (- result)))
|
||||||
=> (apply compare ["lisp" "python"]
|
=> (apply compare ["lisp" "python"]
|
||||||
... {"keyfn" (fn [x y]
|
... {"keyfn" (fn [x y]
|
||||||
... (reduce - (map (fn [s] (ord (first s))) [x y])))})
|
... (reduce - (map (fn [s] (ord (first s))) [x y])))})
|
||||||
@ -932,8 +935,9 @@ list. Example usage:
|
|||||||
|
|
||||||
.. code-block:: clj
|
.. code-block:: clj
|
||||||
|
|
||||||
=> (let [animals {"dog" "bark" "cat" "meow"}
|
=> (do
|
||||||
... numbers ["zero" "one" "two" "three"]]
|
... (setv animals {"dog" "bark" "cat" "meow"}
|
||||||
|
... numbers ["zero" "one" "two" "three"])
|
||||||
... (print (get animals "dog"))
|
... (print (get animals "dog"))
|
||||||
... (print (get numbers 2)))
|
... (print (get numbers 2)))
|
||||||
bark
|
bark
|
||||||
@ -1148,36 +1152,6 @@ last
|
|||||||
6
|
6
|
||||||
|
|
||||||
|
|
||||||
let
|
|
||||||
---
|
|
||||||
|
|
||||||
``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
|
|
||||||
example showcases this behaviour:
|
|
||||||
|
|
||||||
.. code-block:: clj
|
|
||||||
|
|
||||||
=> (let [x 5] (print x)
|
|
||||||
... (let [x 6] (print x))
|
|
||||||
... (print x))
|
|
||||||
5
|
|
||||||
6
|
|
||||||
5
|
|
||||||
|
|
||||||
The ``let`` macro takes two parameters: a vector defining *variables*
|
|
||||||
and the *body* which gets executed. *variables* is a vector of
|
|
||||||
variable and value pairs.
|
|
||||||
|
|
||||||
Note that the variable assignments are executed one by one, from left to right.
|
|
||||||
The following example takes advantage of this:
|
|
||||||
|
|
||||||
.. code-block:: clj
|
|
||||||
|
|
||||||
=> (let [x 5
|
|
||||||
y (+ x 1)] (print x y))
|
|
||||||
5 6
|
|
||||||
|
|
||||||
|
|
||||||
list-comp
|
list-comp
|
||||||
---------
|
---------
|
||||||
|
|
||||||
@ -1209,30 +1183,20 @@ nonlocal
|
|||||||
|
|
||||||
``nonlocal`` can be used to mark a symbol as not local to the current scope.
|
``nonlocal`` can be used to mark a symbol as not local to the current scope.
|
||||||
The parameters are the names of symbols to mark as nonlocal. This is necessary
|
The parameters are the names of symbols to mark as nonlocal. This is necessary
|
||||||
to modify variables through nested ``let`` or ``fn`` scopes:
|
to modify variables through nested ``fn`` scopes:
|
||||||
|
|
||||||
.. code-block:: clj
|
.. code-block:: clj
|
||||||
|
|
||||||
(let [x 0]
|
|
||||||
(for [y (range 10)]
|
|
||||||
(let [z (inc y)]
|
|
||||||
(nonlocal x) ; allow the setv to "jump scope" to resolve x
|
|
||||||
(setv x (+ x y))))
|
|
||||||
x)
|
|
||||||
|
|
||||||
(defn some-function []
|
(defn some-function []
|
||||||
(let [x 0]
|
(setv x 0)
|
||||||
(register-some-callback
|
(register-some-callback
|
||||||
(fn [stuff]
|
(fn [stuff]
|
||||||
(nonlocal x)
|
(nonlocal x)
|
||||||
(setv x stuff)))))
|
(setv x stuff))))
|
||||||
|
|
||||||
In the first example, without the call to ``(nonlocal x)``, this code would
|
Without the call to ``(nonlocal x)``, the inner function would redefine ``x`` to
|
||||||
result in an UnboundLocalError being raised during the call to ``setv``.
|
``stuff`` inside its local scope instead of overwriting the ``x`` in the outer
|
||||||
|
function.
|
||||||
In the second example, without the call to ``(nonlocal x)``, the inner function
|
|
||||||
would redefine ``x`` to ``stuff`` inside its local scope instead of overwriting
|
|
||||||
the ``x`` in the outer function
|
|
||||||
|
|
||||||
See `PEP3104 <https://www.python.org/dev/peps/pep-3104/>`_ for further
|
See `PEP3104 <https://www.python.org/dev/peps/pep-3104/>`_ for further
|
||||||
information.
|
information.
|
||||||
@ -1698,9 +1662,10 @@ expands to:
|
|||||||
|
|
||||||
.. code-block:: hy
|
.. code-block:: hy
|
||||||
|
|
||||||
(let [a (gensym)
|
(do
|
||||||
b (gensym)
|
(setv a (gensym)
|
||||||
c (gensym)]
|
b (gensym)
|
||||||
|
c (gensym))
|
||||||
...)
|
...)
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
@ -1203,10 +1203,9 @@ if *from-file* ends before a complete expression can be parsed.
|
|||||||
=> (with [f (open "example.hy")]
|
=> (with [f (open "example.hy")]
|
||||||
... (try
|
... (try
|
||||||
... (while True
|
... (while True
|
||||||
... (let [exp (read f)]
|
... (setv exp (read f))
|
||||||
... (do
|
... (print "OHY" exp)
|
||||||
... (print "OHY" exp)
|
... (eval exp))
|
||||||
... (eval exp))))
|
|
||||||
... (except [e EOFError]
|
... (except [e EOFError]
|
||||||
... (print "EOF!"))))
|
... (print "EOF!"))))
|
||||||
OHY ('print' 'hello')
|
OHY ('print' 'hello')
|
||||||
|
@ -381,7 +381,8 @@ A first pass might be something like:
|
|||||||
.. code-block:: hy
|
.. code-block:: hy
|
||||||
|
|
||||||
(defmacro nif [expr pos-form zero-form neg-form]
|
(defmacro nif [expr pos-form zero-form neg-form]
|
||||||
`(let [obscure-name ~expr]
|
`(do
|
||||||
|
(setv obscure-name ~expr)
|
||||||
(cond [(pos? obscure-name) ~pos-form]
|
(cond [(pos? obscure-name) ~pos-form]
|
||||||
[(zero? obscure-name) ~zero-form]
|
[(zero? obscure-name) ~zero-form]
|
||||||
[(neg? obscure-name) ~neg-form])))
|
[(neg? obscure-name) ~neg-form])))
|
||||||
@ -396,15 +397,16 @@ such an occasion. A much better version of ``nif`` would be:
|
|||||||
.. code-block:: hy
|
.. code-block:: hy
|
||||||
|
|
||||||
(defmacro nif [expr pos-form zero-form neg-form]
|
(defmacro nif [expr pos-form zero-form neg-form]
|
||||||
(let [g (gensym)]
|
(setv g (gensym))
|
||||||
`(let [~g ~expr]
|
`(do
|
||||||
(cond [(pos? ~g) ~pos-form]
|
(setv ~g ~expr)
|
||||||
[(zero? ~g) ~zero-form]
|
(cond [(pos? ~g) ~pos-form]
|
||||||
[(neg? ~g) ~neg-form]))))
|
[(zero? ~g) ~zero-form]
|
||||||
|
[(neg? ~g) ~neg-form])))
|
||||||
|
|
||||||
This is an easy case, since there is only one symbol. But if there is
|
This is an easy case, since there is only one symbol. But if there is
|
||||||
a need for several gensym's there is a second macro :ref:`with-gensyms` that
|
a need for several gensym's there is a second macro :ref:`with-gensyms` that
|
||||||
basically expands to a series of ``let`` statements:
|
basically expands to a ``setv`` form:
|
||||||
|
|
||||||
.. code-block:: hy
|
.. code-block:: hy
|
||||||
|
|
||||||
@ -415,9 +417,10 @@ expands to:
|
|||||||
|
|
||||||
.. code-block:: hy
|
.. code-block:: hy
|
||||||
|
|
||||||
(let [a (gensym)
|
(do
|
||||||
b (gensym)
|
(setv a (gensym)
|
||||||
c (gensym)]
|
b (gensym)
|
||||||
|
c (gensym))
|
||||||
...)
|
...)
|
||||||
|
|
||||||
so our re-written ``nif`` would look like:
|
so our re-written ``nif`` would look like:
|
||||||
@ -426,10 +429,10 @@ so our re-written ``nif`` would look like:
|
|||||||
|
|
||||||
(defmacro nif [expr pos-form zero-form neg-form]
|
(defmacro nif [expr pos-form zero-form neg-form]
|
||||||
(with-gensyms [g]
|
(with-gensyms [g]
|
||||||
`(let [~g ~expr]
|
`(setv [~g ~expr])
|
||||||
(cond [(pos? ~g) ~pos-form]
|
`(cond [(pos? ~g) ~pos-form]
|
||||||
[(zero? ~g) ~zero-form]
|
[(zero? ~g) ~zero-form]
|
||||||
[(neg? ~g) ~neg-form]))))
|
[(neg? ~g) ~neg-form])))
|
||||||
|
|
||||||
Finally, though we can make a new macro that does all this for us. :ref:`defmacro/g!`
|
Finally, though we can make a new macro that does all this for us. :ref:`defmacro/g!`
|
||||||
will take all symbols that begin with ``g!`` and automatically call ``gensym`` with the
|
will take all symbols that begin with ``g!`` and automatically call ``gensym`` with the
|
||||||
@ -440,10 +443,11 @@ Our final version of ``nif``, built with ``defmacro/g!`` becomes:
|
|||||||
.. code-block:: hy
|
.. code-block:: hy
|
||||||
|
|
||||||
(defmacro/g! nif [expr pos-form zero-form neg-form]
|
(defmacro/g! nif [expr pos-form zero-form neg-form]
|
||||||
`(let [~g!res ~expr]
|
`(do
|
||||||
|
(setv ~g!res ~expr)
|
||||||
(cond [(pos? ~g!res) ~pos-form]
|
(cond [(pos? ~g!res) ~pos-form]
|
||||||
[(zero? ~g!res) ~zero-form]
|
[(zero? ~g!res) ~zero-form]
|
||||||
[(neg? ~g!res) ~neg-form]))))
|
[(neg? ~g!res) ~neg-form])))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,15 +101,6 @@ Layout & Indentation
|
|||||||
) ; GAH, BURN IT WITH FIRE
|
) ; GAH, BURN IT WITH FIRE
|
||||||
|
|
||||||
|
|
||||||
+ Vertically align ``let`` blocks.
|
|
||||||
|
|
||||||
.. code-block:: clj
|
|
||||||
|
|
||||||
(let [foo (bar)
|
|
||||||
qux (baz)]
|
|
||||||
(foo qux))
|
|
||||||
|
|
||||||
|
|
||||||
+ Inline comments shall be two spaces from the end of the code; they
|
+ Inline comments shall be two spaces from the end of the code; they
|
||||||
must always have a space between the comment character and the start
|
must always have a space between the comment character and the start
|
||||||
of the comment. Also, try to not comment the obvious.
|
of the comment. Also, try to not comment the obvious.
|
||||||
|
@ -539,8 +539,8 @@ We can also manipulate code with macros:
|
|||||||
.. code-block:: clj
|
.. code-block:: clj
|
||||||
|
|
||||||
=> (defmacro rev [code]
|
=> (defmacro rev [code]
|
||||||
... (let [op (last code) params (list (butlast code))]
|
... (setv op (last code) params (list (butlast code)))
|
||||||
... `(~op ~@params)))
|
... `(~op ~@params))
|
||||||
=> (rev (1 2 3 +))
|
=> (rev (1 2 3 +))
|
||||||
6
|
6
|
||||||
|
|
||||||
@ -559,8 +559,8 @@ characters that soon):
|
|||||||
.. code-block:: clj
|
.. code-block:: clj
|
||||||
|
|
||||||
=> (defreader ↻ [code]
|
=> (defreader ↻ [code]
|
||||||
... (let [op (last code) params (list (butlast code))]
|
... (setv op (last code) params (list (butlast code)))
|
||||||
... `(~op ~@params)))
|
... `(~op ~@params))
|
||||||
=> #↻(1 2 3 +)
|
=> #↻(1 2 3 +)
|
||||||
6
|
6
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user