diff --git a/docs/macros.rst b/docs/macros.rst index 693bc7e98..c4ad7e40f 100644 --- a/docs/macros.rst +++ b/docs/macros.rst @@ -156,22 +156,32 @@ Ultimately it's wisest to use only four kinds of names in macro expansions: gens Reader macros ------------- -Reader macros allow you to hook directly into Hy's parser to customize how text is parsed into models. They're defined with :hy:func:`defreader`, or, like regular macros, brought in from other modules with :hy:func:`require`. Rather than receiving function arguments, a reader macro has access to a :py:class:`HyReader ` object named ``&reader``, which provides all the text-parsing logic that Hy uses to parse itself (see :py:class:`HyReader ` and its base class :py:class:`Reader ` for the available methods). A reader macro is called with the hash sign ``#``, and like a regular macro, it should return a model or something convertible to a model. :: +Reader macros allow you to hook directly into Hy's parser to customize how text is parsed into models. They're defined with :hy:func:`defreader`, or, like regular macros, brought in from other modules with :hy:func:`require`. Rather than receiving function arguments, a reader macro has access to a :py:class:`HyReader ` object named ``&reader``, which provides all the text-parsing logic that Hy uses to parse itself (see :py:class:`HyReader ` and its base class :py:class:`Reader ` for the available methods). A reader macro is called with the hash sign ``#``, and like a regular macro, it should return a model or something convertible to a model. + +Here's a moderately complex example of a reader macro that couldn't be implemented as a regular macro. It reads in a list of lists in which the inner lists are newline-separated, but newlines are allowed inside elements. :: (defreader matrix (.slurp-space &reader) (setv start (.getc &reader)) (assert (= start "[")) + (.slurp-space &reader) (setv out [[]]) - (while (not (do (.slurp-space &reader) (.peek-and-getc &reader "]"))) - (setv x (.parse-one-form &reader)) - (if (= x '|) - (.append out []) - (.append (get out -1) x))) - (if (= out [[]]) [] out)) - - (print (hy.repr #matrix [1 2 3 | 4 5 6 | 7 8 9])) - ; => [[1 2 3] [4 5 6] [7 8 9]] + (while (not (.peek-and-getc &reader "]")) + (cond + (any (gfor c " \t" (.peek-and-getc &reader c))) + None + (.peek-and-getc &reader "\n") + (.append out []) + True + (.append (get out -1) (.parse-one-form &reader)))) + (lfor line out :if line line)) + + (print (hy.repr #matrix [ + 1 (+ 1 1) 3 + 4 ["element" "containing" + "a" "newline"] 6 + 7 8 9])) + ; => [[1 2 3] [4 ["element" "containing" "a" "newline"] 6] [7 8 9]] Note that because reader macros are evaluated at parse-time, and top-level forms are completely parsed before any further compile-time execution occurs, you can't use a reader macro in the same top-level form that defines it:: diff --git a/docs/whyhy.rst b/docs/whyhy.rst index e2c8f50da..861823292 100644 --- a/docs/whyhy.rst +++ b/docs/whyhy.rst @@ -150,8 +150,20 @@ aforementioned mixing of statements and expressions, :ref:`name mangling Python-legal identifiers, and a :hy:func:`let` macro to provide block-level scoping in place of Python's usual function-level scoping. -Overall, Hy, like Common Lisp, is intended to be an unopinionated big-tent -language that lets you do what you want. If you're interested in a more -small-and-beautiful approach to Lisp, in the style of Scheme, check out -`Hissp `_, another Lisp embedded in Python -that was created by a Hy developer. + +What Hy is not +-------------- + +Hy isn't minimal or elegant. Hy is big and ugly and proud of it; it's an +unopinionated big-tent language that lets you do what you want. It has all +of Python's least-motivated semantic features, plus more features, plus +various kinds of syntactic sugar. (The syntax isn't as complex as +Python's, but there are a lot of details beyond plain old S-expressions.) +If you're interested in a more small-and-beautiful approach to Lisp, in +the style of Scheme, check out `Hissp `_, +another Lisp embedded in Python that was created by a Hy developer. + +Also, Hy isn't a reimplementation of an older Lisp. It is its own +language. It looks kind of like Clojure and kind of like Common Lisp, but +nontrivial programs that run in one of these langauges can't be expected +to run on another unaltered.