2013-12-31 02:06:51 +01:00
|
|
|
.. _reader-macros:
|
|
|
|
|
|
|
|
.. highlight:: clj
|
|
|
|
|
|
|
|
=============
|
|
|
|
Reader Macros
|
|
|
|
=============
|
|
|
|
|
|
|
|
Reader macros gives LISP the power to modify and alter syntax on the fly.
|
|
|
|
You don't want polish notation? A reader macro can easily do just that. Want
|
|
|
|
Clojure's way of having a regex? Reader macros can also do this easily.
|
|
|
|
|
|
|
|
|
|
|
|
Syntax
|
|
|
|
======
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
=> (defreader ^ [expr] (print expr))
|
|
|
|
=> #^(1 2 3 4)
|
|
|
|
(1 2 3 4)
|
|
|
|
=> #^"Hello"
|
|
|
|
"Hello"
|
|
|
|
=> #^1+2+3+4+3+2
|
|
|
|
1+2+3+4+3+2
|
|
|
|
|
2014-01-17 20:28:24 +01:00
|
|
|
Hy has no literal for tuples. Lets say you dislike `(, ...)` and want something
|
2014-01-14 02:38:16 +01:00
|
|
|
else. This is a problem reader macros are able to solve in a neat way.
|
2013-12-31 02:06:51 +01:00
|
|
|
|
2014-01-14 02:38:16 +01:00
|
|
|
::
|
2013-12-31 02:06:51 +01:00
|
|
|
|
2014-01-14 02:38:16 +01:00
|
|
|
=> (defreader t [expr] `(, ~@expr))
|
|
|
|
=> #t(1 2 3)
|
|
|
|
(1, 2, 3)
|
2013-12-31 02:06:51 +01:00
|
|
|
|
2014-01-17 20:28:24 +01:00
|
|
|
You could even do like clojure, and have a literal for regular expressions!
|
2014-01-14 02:38:16 +01:00
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
=> (import re)
|
|
|
|
=> (defreader r [expr] `(re.compile ~expr))
|
|
|
|
=> #r".*"
|
|
|
|
<_sre.SRE_Pattern object at 0xcv7713ph15#>
|
2013-12-31 02:06:51 +01:00
|
|
|
|
|
|
|
|
2014-01-14 02:38:16 +01:00
|
|
|
Implementation
|
|
|
|
==============
|
|
|
|
|
2013-12-31 02:06:51 +01:00
|
|
|
``defreader`` takes a single character as symbol name for the reader macro,
|
|
|
|
anything longer will return an error. Implementation wise, ``defreader``
|
2014-12-05 16:07:44 +01:00
|
|
|
expands into a lambda covered with a decorator, this decorator saves the
|
2013-12-31 02:06:51 +01:00
|
|
|
lambda in a dict with its module name and symbol.
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
=> (defreader ^ [expr] (print expr))
|
|
|
|
;=> (with_decorator (hy.macros.reader ^) (fn [expr] (print expr)))
|
|
|
|
|
2014-01-14 02:38:16 +01:00
|
|
|
``#`` expands into ``(dispatch_reader_macro ...)`` where the symbol
|
|
|
|
and expression is passed to the correct function.
|
2013-12-31 02:06:51 +01:00
|
|
|
|
|
|
|
::
|
|
|
|
|
2014-01-14 02:38:16 +01:00
|
|
|
=> #^()
|
|
|
|
;=> (dispatch_reader_macro ^ ())
|
2013-12-31 02:06:51 +01:00
|
|
|
=> #^"Hello"
|
|
|
|
"Hello"
|
|
|
|
|
2014-01-14 02:38:16 +01:00
|
|
|
|
2013-12-31 02:06:51 +01:00
|
|
|
.. warning::
|
|
|
|
Because of a limitation in Hy's lexer and parser, reader macros can't
|
|
|
|
redefine defined syntax such as ``()[]{}``. This will most likely be
|
2014-05-05 20:17:14 +02:00
|
|
|
addressed in the future.
|