compile/decorate
Syntax: (decorate [DECORATOR ...] FORM)
Form |
Expands to |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
a |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Behaviour: What @ lines read to, and usable directly. The name of
a def, var, class, global var, global def, global class,
define or define-global subject is
hoisted out so the decorated value is what gets bound; then the
decorator list folds through
decorate-subject one decorator per
step, outermost first, so @d1 over @d2 over a definition applies as
(d1 (d2 ...)), as in Python.
A typed value subject keeps its annotation and wraps only the value, so
@d var x :: int 0 in a class body still records x in
__annotations__; type: TYPE reads the same as :: TYPE. A
declaration, var x, var [a b], global var x, define x or
define-global x, with or without a type, binds no value, so a
decorator over it has nothing to transform and the compiler raises
CompilerError naming the form. A binding form of any other shape is
not a declaration; it reaches its special and fails as it would
undecorated, with SyntaxMatchError.
Examples:
>>> (macroexpand-1 '(decorate (d1) (def foo [x] x)))
(var foo (decorate [d1] (function foo [x] x)))
import-from functools lru_cache
@(lru_cache maxsize: None)
@demand
def fib [n]:
if (< n 2) n (+ (fib (- n 1)) (fib (- n 2)))
The layout lines read as
(decorate ((lru_cache maxsize: None) demand) (def fib ...)). See
Decorators.