|
4544 | 4544 | ;;;;;;;;;;;;;;;;
|
4545 | 4545 |
|
4546 | 4546 | (defn ^:private collect-methods
|
4547 |
| - "Collect method and interface declarations for `deftype` and `defrecord` |
| 4547 | + "Collect method and interface declarations for `deftype`, `defrecord`, and `reify` |
4548 | 4548 | into a map containing `:interfaces` and `:methods` keys."
|
4549 | 4549 | [method-impls]
|
4550 | 4550 | (group-by (fn [v]
|
|
4574 | 4574 |
|
4575 | 4575 | Interface or protocol implementations are declared as the name of the
|
4576 | 4576 | interface or protocol as a symbol, followed by 1 or more method
|
4577 |
| - definitions for that interface. Types are not required to declare |
4578 |
| - any interface implementations. Types which do declare interface |
4579 |
| - implementations are required to implement all interface methods. Failing |
4580 |
| - to implement all interface methods is a compile time error. Types |
4581 |
| - implementing `object` are not required to implement all `object` methods. |
| 4577 | + definitions for that interface. Types are not required to declare any |
| 4578 | + interface implementations. Types which do declare interface implementations |
| 4579 | + are required to implement all interface methods. Failing to implement all |
| 4580 | + interface methods is a compile time error. Types implementing `object` are |
| 4581 | + not required to implement all `object` methods. |
4582 | 4582 |
|
4583 | 4583 | Method declarations should appear as:
|
4584 | 4584 |
|
| 4585 | + (method-name [arg1] & body) |
4585 | 4586 | (method-name [arg1 arg2 ...] & body)
|
4586 | 4587 |
|
4587 |
| - Unlike in Clojure, interface and protocol methods are permitted to |
4588 |
| - include variadic arguments. |
| 4588 | + Unlike in Clojure, interface and protocol methods are permitted to include |
| 4589 | + variadic arguments. Single-arity methods may also declare support for |
| 4590 | + keyword arguments using either the `:apply` or `:collect` strategy on the |
| 4591 | + `:kwargs` metadata on the method name. Methods may be declared as static |
| 4592 | + (using the `:staticmethod`) or class methods (using the `:classmethod`) |
| 4593 | + metadata on the the name. Both static methods and class methods can be |
| 4594 | + declared with multiple arities or may be defined with a single arity and |
| 4595 | + keyword arguments. Finally, single-arity methods may be declared as Python |
| 4596 | + properties using the `:property` metadata on the method name. These facilities |
| 4597 | + are provided as a means to interoperate with Python code and their use is |
| 4598 | + discouraged in pure Basilisp code. |
4589 | 4599 |
|
4590 | 4600 | Type objects are created with sensible `object` defaults as by `attrs`.
|
4591 | 4601 | New types may override `object` defaults. An `__init__` function is
|
|
4612 | 4622 | (def ~ctor-name ~type-name)
|
4613 | 4623 | ~type-name)))
|
4614 | 4624 |
|
| 4625 | +(defmacro reify |
| 4626 | + "Create a new Python object of an anonymous type which implements 0 or more |
| 4627 | + Python interfaces or Basilisp protocols. |
| 4628 | + |
| 4629 | + Unlike types created via `deftype`, `reify` returns an object which implements |
| 4630 | + the named interfaces using the implementations provided. You may not provide |
| 4631 | + fields as such to `reify`, though `reify` closes over any local names defined |
| 4632 | + in the same lexical context. These fields may serve as private fields of the |
| 4633 | + created object. |
| 4634 | + |
| 4635 | + Interface or protocol implementations are declared as the name of the |
| 4636 | + interface or protocol as a symbol, followed by 1 or more method |
| 4637 | + definitions for that interface. Types are not required to declare any |
| 4638 | + interface implementations. Types which do declare interface implementations |
| 4639 | + are required to implement all interface methods. Failing to implement all |
| 4640 | + interface methods is a compile time error. Types implementing `object` are |
| 4641 | + not required to implement all `object` methods. |
| 4642 | + |
| 4643 | + Method declarations should appear as: |
| 4644 | + |
| 4645 | + (method-name [arg1] & body) |
| 4646 | + (method-name [arg1 arg2 ...] & body) |
| 4647 | + |
| 4648 | + Unlike in Clojure, interface and protocol methods are permitted to |
| 4649 | + include variadic arguments. Single-arity methods may also declare support for |
| 4650 | + keyword arguments using either the `:apply` or `:collect` strategy on the |
| 4651 | + `:kwargs` metadata on the method name. Finally, single-arity methods may be |
| 4652 | + declared as Python properties using the `:property` metadata on the method |
| 4653 | + name. These facilities are provided as a means to interoperate with Python |
| 4654 | + code and their use is discouraged in pure Basilisp code. |
| 4655 | + |
| 4656 | + `reify` does not support class method or static method members and attempting |
| 4657 | + to declare `reify` members as class or static members will result in a |
| 4658 | + compile time error. |
| 4659 | + |
| 4660 | + Type objects are created with sensible `object` defaults as by `attrs`. |
| 4661 | + New types may override `object` defaults. |
| 4662 | + |
| 4663 | + Reified objects always implement `basilisp.lang.interfaces/IWithMeta` and |
| 4664 | + transfer the metadata from the form to the created object. |
| 4665 | + |
| 4666 | + Methods must supply a `this` or `self` parameter. `recur` special forms |
| 4667 | + used in the body of a method should not include that parameter, as it |
| 4668 | + will be supplied automatically." |
| 4669 | + [& method-impls] |
| 4670 | + (let [{:keys [interfaces methods]} (collect-methods method-impls)] |
| 4671 | + (with-meta |
| 4672 | + `(reify* :implements [~@interfaces python/object] |
| 4673 | + ~@methods) |
| 4674 | + (meta &form)))) |
| 4675 | + |
4615 | 4676 | ;;;;;;;;;;;;;
|
4616 | 4677 | ;; Records ;;
|
4617 | 4678 | ;;;;;;;;;;;;;
|
|
4677 | 4738 |
|
4678 | 4739 | Interface or protocol implementations are declared as the name of the
|
4679 | 4740 | interface or protocol as a symbol, followed by 1 or more method
|
4680 |
| - definitions for that interface. Records are not required to declare |
4681 |
| - any interface implementations. Records which do declare interface |
4682 |
| - implementations are required to implement all interface methods. Failing |
4683 |
| - to implement all interface methods is a compile time error. Records |
4684 |
| - implementing `object` are not required to implement all `object` methods. |
| 4741 | + definitions for that interface. Types are not required to declare any |
| 4742 | + interface implementations. Types which do declare interface implementations |
| 4743 | + are required to implement all interface methods. Failing to implement all |
| 4744 | + interface methods is a compile time error. Types implementing `object` are |
| 4745 | + not required to implement all `object` methods. |
4685 | 4746 |
|
4686 | 4747 | Method declarations should appear as:
|
4687 | 4748 |
|
| 4749 | + (method-name [arg1] & body) |
4688 | 4750 | (method-name [arg1 arg2 ...] & body)
|
4689 | 4751 |
|
4690 | 4752 | Records objects are created with sensible `object` defaults as by `attrs`.
|
|
0 commit comments