Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions docs/pyinterop.rst
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ Type hints may be applied to :lpy:form:`def` names, function arguments and retur
Python Decorators
-----------------

.. note::

Users wishing to apply decorators to functions are not limited to using ``:decorators`` metadata.
This feature is provided primarily to simplify porting Python code to Basilisp.
In Python, decorators are syntactic sugar for functions which return functions, but given the rich library of tools provided for composing functions and the ease of defining anonymous functions in Basilisp, the use of ``:decorators`` is not typically necessary in standard Basilisp code.

Python decorators are functions that modify the behavior of other functions or methods.
They are applied to a function by prefixing it with the ``@decorator_name`` syntax. A decorator takes a function as input, performs some action, and returns a new function that typically extends or alters the original function's behavior.

Expand Down Expand Up @@ -299,7 +305,7 @@ These decorators are applied from right to left, similar to how Python decorator
((fn ^{:decorators [add-5-decorator]} seven [] 7))
;; => 12

;;; Decorators with arguments, and order of application
;;; Decorators with arguments, and order of application (right to left)
;;
;; example decorator
(defn mult-x-decorator
Expand All @@ -325,11 +331,6 @@ These decorators are applied from right to left, similar to how Python decorator
(asyncio/run (six))
;; => 13

.. note::

Users wishing to apply decorators to functions are not limited to using ``:decorators`` metadata.
The ``:decorators`` feature is provided primarily to simplify porting Python code to Basilisp.
In Python, decorators are syntactic sugar for functions which return functions, but given the rich library of tools provided for composing functions and the ease of defining anonymous functions in Basilisp, the use of ``:decorators`` is not typically necessary in standard Basilisp code.
.. _arithmetic_division:

Arithmetic Division
Expand Down
6 changes: 6 additions & 0 deletions src/basilisp/core.lpy
Original file line number Diff line number Diff line change
Expand Up @@ -6004,6 +6004,12 @@
decorators and the ``comp`` function, decorators are applied to the
generated function from right to left.

.. note::

The ``name`` metadata (i.e., ``(fn ^{...} <name> ...)``) takes
precedence over the ``form`` metadata (i.e., ``^{...} (fn <name?> ...)``)
when both specify the same key.

Function argument vectors support sequential and associative :ref:`destructuring` .

See :lpy:form:`fn` for more details."
Expand Down
20 changes: 13 additions & 7 deletions tests/basilisp/test_core_macros.lpy
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,30 @@
(testing "decorators"
(testing "in form meta"
(let [add-5% #(fn [] (+ (%) 5))
f1 ^{:decorators [add-5%]} (fn [] 7)]
f1 ^{:decorators [add-5%]} (fn [] 7)]
(is (= 12 (f1)))))

(testing "in fn name meta"
(let [add-5% #(fn [] (+ (%) 5))
f2 (fn ^{:decorators [add-5%]} f2 [] 13)]
f2 (fn ^{:decorators [add-5%]} f2 [] 13)]
(is (= 18 (f2)))))

(testing "in both form and name meta"
(let [add-2% #(fn [] (+ (%) 2))
add-7% #(fn [] (+ (%) 7))
f3 ^{:decorators [add-2%]} (fn ^{:decorators [add-7%]} f3 [] 20)]
(is (= 27 (f3)))))

(testing "with single arg"
(let [add-x% (fn [x] #(fn [] (+ (%) x)))
f3 (fn ^{:decorators [(add-x% 10)]} f3 [] 7)]
(is (= 17 (f3)))))
f4 (fn ^{:decorators [(add-x% 10)]} f4 [] 7)]
(is (= 17 (f4)))))

(testing "order"
(let [add-5% #(fn [] (+ (%) 5))
(let [add-5% #(fn [] (+ (%) 5))
mult-x% (fn [x] #(fn [] (* (%) x)))
fvar (defn f4 {:decorators [add-5% (mult-x% -1)]} [] 9)]
(is (= -4 (f4)))))))
f5 ^{:decorators [add-5% (mult-x% -1)]} (fn [] 9)]
(is (= -4 (f5)))))))

(deftest defn-test
(testing "single arity defn"
Expand Down
Loading