From bdecc446db806da26d6ea0a2f7e4b404e639f66d Mon Sep 17 00:00:00 2001 From: Vadim Tsvetkov Date: Sun, 14 Nov 2021 03:07:23 +0300 Subject: [PATCH 1/9] Refactor __using__'s Move `:except` handling to `Witchcraft.Internal` --- lib/witchcraft/applicative.ex | 11 ++------ lib/witchcraft/apply.ex | 12 ++------ lib/witchcraft/arrow.ex | 12 ++------ lib/witchcraft/bifunctor.ex | 13 ++------- lib/witchcraft/category.ex | 11 ++------ lib/witchcraft/chain.ex | 12 ++------ lib/witchcraft/comonad.ex | 12 ++------ lib/witchcraft/extend.ex | 11 ++------ lib/witchcraft/foldable.ex | 29 +------------------- lib/witchcraft/functor.ex | 11 ++------ lib/witchcraft/internal.ex | 50 ++++++++++++++++++++++++++++++++++ lib/witchcraft/monad.ex | 12 ++------ lib/witchcraft/monoid.ex | 11 ++------ lib/witchcraft/ord.ex | 25 +---------------- lib/witchcraft/semigroup.ex | 23 +--------------- lib/witchcraft/semigroupoid.ex | 22 +-------------- lib/witchcraft/setoid.ex | 23 +--------------- lib/witchcraft/traversable.ex | 12 ++------ 18 files changed, 85 insertions(+), 227 deletions(-) create mode 100644 lib/witchcraft/internal.ex diff --git a/lib/witchcraft/applicative.ex b/lib/witchcraft/applicative.ex index 1fe9179..4e26866 100644 --- a/lib/witchcraft/applicative.ex +++ b/lib/witchcraft/applicative.ex @@ -28,16 +28,9 @@ defclass Witchcraft.Applicative do alias __MODULE__ extend Witchcraft.Apply - @type t :: any() - - defmacro __using__(opts \\ []) do - module_imports = [except: Keyword.get(opts, :except, [])] + use Witchcraft.Internal, deps: [Witchcraft.Apply] - quote do - use Witchcraft.Apply, unquote(opts) - import unquote(__MODULE__), unquote(module_imports) - end - end + @type t :: any() where do @doc """ diff --git a/lib/witchcraft/apply.ex b/lib/witchcraft/apply.ex index 84da34f..d397ff4 100644 --- a/lib/witchcraft/apply.ex +++ b/lib/witchcraft/apply.ex @@ -122,20 +122,14 @@ defclass Witchcraft.Apply do alias Witchcraft.Functor extend Witchcraft.Functor + + use Witchcraft.Internal, deps: [Witchcraft.Functor] + use Witchcraft.Functor @type t :: any() @type fun :: any() - defmacro __using__(opts \\ []) do - module_imports = [except: Keyword.get(opts, :except, [])] - - quote do - use Witchcraft.Functor, unquote(opts) - import unquote(__MODULE__), unquote(module_imports) - end - end - where do @doc """ Pipe arguments to functions, when both are wrapped in the same diff --git a/lib/witchcraft/arrow.ex b/lib/witchcraft/arrow.ex index abe3cc1..cfd88d6 100644 --- a/lib/witchcraft/arrow.ex +++ b/lib/witchcraft/arrow.ex @@ -39,18 +39,12 @@ defclass Witchcraft.Arrow do alias __MODULE__ extend Witchcraft.Category - use Witchcraft.Category - @type t :: fun() + use Witchcraft.Internal, deps: [Witchcraft.Category] - defmacro __using__(opts \\ []) do - module_imports = [except: Keyword.get(opts, :except, [])] + use Witchcraft.Category - quote do - use Witchcraft.Category, unquote(opts) - import unquote(__MODULE__), unquote(module_imports) - end - end + @type t :: fun() where do @doc """ diff --git a/lib/witchcraft/bifunctor.ex b/lib/witchcraft/bifunctor.ex index ef5f7b4..8889c1e 100644 --- a/lib/witchcraft/bifunctor.ex +++ b/lib/witchcraft/bifunctor.ex @@ -18,22 +18,15 @@ defclass Witchcraft.Bifunctor do """ + alias __MODULE__ extend Witchcraft.Functor - alias __MODULE__ + use Witchcraft.Internal + use Quark @type t :: any() - defmacro __using__(opts \\ []) do - module_imports = [except: Keyword.get(opts, :except, [])] - - quote do - use Witchcraft.Functor, unquote(opts) - import unquote(__MODULE__), unquote(module_imports) - end - end - where do @doc """ `map` separate fuctions over two fields in a product type. diff --git a/lib/witchcraft/category.ex b/lib/witchcraft/category.ex index e9b9a2b..3c12fac 100644 --- a/lib/witchcraft/category.ex +++ b/lib/witchcraft/category.ex @@ -24,16 +24,9 @@ defclass Witchcraft.Category do extend Witchcraft.Semigroupoid - @type t :: any() - - defmacro __using__(opts \\ []) do - module_imports = [except: Keyword.get(opts, :except, [])] + use Witchcraft.Internal, deps: [Witchcraft.Semigroupoid] - quote do - use Witchcraft.Semigroupoid, unquote(opts) - import unquote(__MODULE__), unquote(module_imports) - end - end + @type t :: any() where do @doc """ diff --git a/lib/witchcraft/chain.ex b/lib/witchcraft/chain.ex index 63dab27..6b9426c 100644 --- a/lib/witchcraft/chain.ex +++ b/lib/witchcraft/chain.ex @@ -37,20 +37,14 @@ defclass Witchcraft.Chain do alias __MODULE__ extend Witchcraft.Apply + + use Witchcraft.Internal, deps: [Witchcraft.Apply] + use Witchcraft.Apply @type t :: any() @type link :: (any() -> Chain.t()) - defmacro __using__(opts \\ []) do - module_imports = [except: Keyword.get(opts, :except, [])] - - quote do - use Witchcraft.Apply, unquote(opts) - import unquote(__MODULE__), unquote(module_imports) - end - end - where do @doc """ Sequentially compose actions, piping values through successive function chains. diff --git a/lib/witchcraft/comonad.ex b/lib/witchcraft/comonad.ex index f1d8e26..5d9dca3 100644 --- a/lib/witchcraft/comonad.ex +++ b/lib/witchcraft/comonad.ex @@ -23,18 +23,12 @@ defclass Witchcraft.Comonad do alias __MODULE__ extend Witchcraft.Extend - use Quark - @type t :: any() + use Witchcraft.Internal, deps: [Witchcraft.Extend] - defmacro __using__(opts \\ []) do - module_imports = [except: Keyword.get(opts, :except, [])] + use Quark - quote do - use Witchcraft.Extend, unquote(opts) - import unquote(__MODULE__), unquote(module_imports) - end - end + @type t :: any() where do @doc """ diff --git a/lib/witchcraft/extend.ex b/lib/witchcraft/extend.ex index 3414992..c6390b6 100644 --- a/lib/witchcraft/extend.ex +++ b/lib/witchcraft/extend.ex @@ -27,20 +27,13 @@ defclass Witchcraft.Extend do extend Witchcraft.Functor + use Witchcraft.Internal, deps: [Witchcraft.Functor] + use Quark @type t :: any() @type colink :: (Extend.t() -> any()) - defmacro __using__(opts \\ []) do - module_imports = [except: Keyword.get(opts, :except, [])] - - quote do - use Witchcraft.Functor, unquote(opts) - import unquote(__MODULE__), unquote(module_imports) - end - end - where do @doc """ Wrap some nestable data structure in another layer of itself diff --git a/lib/witchcraft/foldable.ex b/lib/witchcraft/foldable.ex index d094103..667ae91 100644 --- a/lib/witchcraft/foldable.ex +++ b/lib/witchcraft/foldable.ex @@ -30,43 +30,16 @@ defclass Witchcraft.Foldable do alias __MODULE__ alias Witchcraft.{Apply, Ord, Monad, Monoid, Semigroup, Unit} - import Kernel, except: [length: 1, max: 2, min: 2] import Exceptional.Safe, only: [safe: 1] require Foldable.EmptyError + use Witchcraft.Internal, overrides: [min: 2, max: 2, length: 1], deps: [Semigroup, Ord] use Witchcraft.Applicative use Quark @type t :: any() - defmacro __using__(opts \\ []) do - overrides = [length: 1, max: 2, min: 2] - excepts = Keyword.get(opts, :except, []) - - if Access.get(opts, :override_kernel, true) do - kernel_imports = Macro.escape(except: overrides -- excepts) - module_imports = Macro.escape(except: excepts) - - quote do - use Witchcraft.Semigroup, unquote(opts) - use Witchcraft.Ord, unquote(opts) - - import Kernel, unquote(kernel_imports) - import unquote(__MODULE__), unquote(module_imports) - end - else - module_imports = Macro.escape(except: Enum.uniq(overrides ++ excepts)) - - quote do - use Witchcraft.Semigroup, unquote(opts) - use Witchcraft.Ord, unquote(opts) - - import unquote(__MODULE__), unquote(module_imports) - end - end - end - where do @doc ~S""" Right-associative fold over a structure to alter the structure and/or reduce diff --git a/lib/witchcraft/functor.ex b/lib/witchcraft/functor.ex index 4f392cf..bad95a9 100644 --- a/lib/witchcraft/functor.ex +++ b/lib/witchcraft/functor.ex @@ -18,17 +18,12 @@ defclass Witchcraft.Functor do """ alias __MODULE__ - use Quark - @type t :: any() + use Witchcraft.Internal - defmacro __using__(opts \\ []) do - module_imports = [except: Keyword.get(opts, :except, [])] + use Quark - quote do - import unquote(__MODULE__), unquote(module_imports) - end - end + @type t :: any() where do @doc ~S""" diff --git a/lib/witchcraft/internal.ex b/lib/witchcraft/internal.ex new file mode 100644 index 0000000..284b340 --- /dev/null +++ b/lib/witchcraft/internal.ex @@ -0,0 +1,50 @@ +defmodule Witchcraft.Internal do + def use_multi(modules, opts) do + for module <- modules do + quote do + use unquote(module), unquote(opts) + end + end + end + + def import_helper(opts, overrides, deps, module) do + excepts = Keyword.get(opts, :except, []) + deps_quoted = use_multi(deps, opts) + + if Access.get(opts, :override_kernel, true) do + kernel_imports = Macro.escape(except: overrides -- excepts) + module_imports = Macro.escape(except: excepts) + + quote do + import Kernel, unquote(kernel_imports) + + unquote(deps_quoted) + + import unquote(module), unquote(module_imports) + end + else + module_imports = Macro.escape(except: Enum.uniq(overrides ++ excepts)) + + quote do + unquote(deps_quoted) + + import unquote(module), unquote(module_imports) + end + end + end + + defmacro __using__(opts \\ []) do + overrides = Keyword.get(opts, :overrides, []) + deps = Keyword.get(opts, :deps, []) + + quote do + @overrides unquote(overrides) + + import Kernel, except: unquote(overrides) + + defmacro __using__(opts \\ []) do + Witchcraft.Internal.import_helper(opts, unquote(overrides), unquote(deps), __MODULE__) + end + end + end +end diff --git a/lib/witchcraft/monad.ex b/lib/witchcraft/monad.ex index 7dc3ef1..4db931d 100644 --- a/lib/witchcraft/monad.ex +++ b/lib/witchcraft/monad.ex @@ -39,19 +39,11 @@ defclass Witchcraft.Monad do extend Witchcraft.Applicative extend Witchcraft.Chain + use Witchcraft.Internal, deps: [Witchcraft.Applicative, Witchcraft.Chain] + use Witchcraft.Applicative use Witchcraft.Chain - defmacro __using__(opts \\ []) do - module_imports = [except: Keyword.get(opts, :except, [])] - - quote do - use Witchcraft.Applicative, unquote(opts) - use Witchcraft.Chain, unquote(opts) - import unquote(__MODULE__), unquote(module_imports) - end - end - properties do import Witchcraft.Applicative import Witchcraft.Chain diff --git a/lib/witchcraft/monoid.ex b/lib/witchcraft/monoid.ex index 805420c..729dd8c 100644 --- a/lib/witchcraft/monoid.ex +++ b/lib/witchcraft/monoid.ex @@ -17,16 +17,9 @@ defclass Witchcraft.Monoid do alias __MODULE__ extend Witchcraft.Semigroup, alias: true - @type t :: any() - - defmacro __using__(opts \\ []) do - module_imports = [except: Keyword.get(opts, :except, [])] + use Witchcraft.Internal, deps: [Witchcraft.Semigroup] - quote do - use Witchcraft.Semigroup, unquote(opts) - import unquote(__MODULE__), unquote(module_imports) - end - end + @type t :: any() where do @doc ~S""" diff --git a/lib/witchcraft/ord.ex b/lib/witchcraft/ord.ex index 3489a55..3d90052 100644 --- a/lib/witchcraft/ord.ex +++ b/lib/witchcraft/ord.ex @@ -23,30 +23,7 @@ defclass Witchcraft.Ord do @type ordering :: :lesser | :equal | :greater alias __MODULE__ - import Kernel, except: [<: 2, >: 2, <=: 2, >=: 2] - - defmacro __using__(opts \\ []) do - overrides = [<: 2, >: 2, <=: 2, >=: 2] - excepts = Keyword.get(opts, :except, []) - - if Access.get(opts, :override_kernel, true) do - kernel_imports = Macro.escape(except: overrides -- excepts) - module_imports = Macro.escape(except: excepts) - - quote do - import Kernel, unquote(kernel_imports) - use Witchcraft.Semigroupoid, unquote(opts) - import unquote(__MODULE__), unquote(module_imports) - end - else - module_imports = Macro.escape(except: Enum.uniq(overrides ++ excepts)) - - quote do - use Witchcraft.Semigroupoid, unquote(opts) - import unquote(__MODULE__), unquote(module_imports) - end - end - end + use Witchcraft.Internal, overrides: [<: 2, >: 2, <=: 2, >=: 2] where do @doc """ diff --git a/lib/witchcraft/semigroup.ex b/lib/witchcraft/semigroup.ex index dc82da0..9764920 100644 --- a/lib/witchcraft/semigroup.ex +++ b/lib/witchcraft/semigroup.ex @@ -22,31 +22,10 @@ defclass Witchcraft.Semigroup do """ alias __MODULE__ - import Kernel, except: [<>: 2] + use Witchcraft.Internal, overrides: [<>: 2] @type t :: any() - defmacro __using__(opts \\ []) do - overrides = [<>: 2] - excepts = Keyword.get(opts, :except, []) - - if Access.get(opts, :override_kernel, true) do - kernel_imports = Macro.escape(except: overrides -- excepts) - module_imports = Macro.escape(except: excepts) - - quote do - import Kernel, unquote(kernel_imports) - import unquote(__MODULE__), unquote(module_imports) - end - else - module_imports = Macro.escape(except: Enum.uniq(overrides ++ excepts)) - - quote do - import unquote(__MODULE__), unquote(module_imports) - end - end - end - where do @doc ~S""" `append`enate two data of the same type. These can be chained together an arbitrary number of times. For example: diff --git a/lib/witchcraft/semigroupoid.ex b/lib/witchcraft/semigroupoid.ex index 1fc780a..d247c53 100644 --- a/lib/witchcraft/semigroupoid.ex +++ b/lib/witchcraft/semigroupoid.ex @@ -13,30 +13,10 @@ defclass Witchcraft.Semigroupoid do """ alias __MODULE__ - import Kernel, except: [apply: 2] @type t :: any() - defmacro __using__(opts \\ []) do - overrides = [apply: 2] - excepts = Keyword.get(opts, :except, []) - - if Access.get(opts, :override_kernel, true) do - kernel_imports = Macro.escape(except: overrides -- excepts) - module_imports = Macro.escape(except: excepts) - - quote do - import Kernel, unquote(kernel_imports) - import unquote(__MODULE__), unquote(module_imports) - end - else - module_imports = Macro.escape(except: Enum.uniq(overrides ++ excepts)) - - quote do - import unquote(__MODULE__), unquote(module_imports) - end - end - end + use Witchcraft.Internal, overrides: [apply: 2] where do @doc """ diff --git a/lib/witchcraft/setoid.ex b/lib/witchcraft/setoid.ex index 8ad2449..b2be1d2 100644 --- a/lib/witchcraft/setoid.ex +++ b/lib/witchcraft/setoid.ex @@ -18,28 +18,7 @@ defclass Witchcraft.Setoid do """ alias __MODULE__ - import Kernel, except: [==: 2, !=: 2] - - defmacro __using__(opts \\ []) do - overrides = [==: 2, !=: 2] - excepts = Keyword.get(opts, :except, []) - - if Access.get(opts, :override_kernel, true) do - kernel_imports = Macro.escape(except: overrides -- excepts) - module_imports = Macro.escape(except: excepts) - - quote do - import Kernel, unquote(kernel_imports) - import unquote(__MODULE__), unquote(module_imports) - end - else - module_imports = Macro.escape(except: Enum.uniq(overrides ++ excepts)) - - quote do - import unquote(__MODULE__), unquote(module_imports) - end - end - end + use Witchcraft.Internal, overrides: [==: 2, !=: 2] @type t :: any() diff --git a/lib/witchcraft/traversable.ex b/lib/witchcraft/traversable.ex index a2e1032..751127b 100644 --- a/lib/witchcraft/traversable.ex +++ b/lib/witchcraft/traversable.ex @@ -25,6 +25,8 @@ defclass Witchcraft.Traversable do extend Witchcraft.Foldable extend Witchcraft.Functor + use Witchcraft.Internal, deps: [Witchcraft.Foldable, Witchcraft.Functor] + use Witchcraft.Applicative use Witchcraft.Foldable, except: [equal?: 2] @@ -33,16 +35,6 @@ defclass Witchcraft.Traversable do @type t :: any() @type link :: (any() -> Traversable.t()) - defmacro __using__(opts \\ []) do - module_imports = [except: Keyword.get(opts, :except, [])] - - quote do - use Witchcraft.Foldable, unquote(opts) - use Witchcraft.Functor, unquote(opts) - import unquote(__MODULE__), unquote(module_imports) - end - end - where do @doc """ Convert elements to actions, and then evaluate the actions from left-to-right, From eb597de1da8449f2cda5b212407c3c250d563c9f Mon Sep 17 00:00:00 2001 From: Vadim Tsvetkov Date: Sun, 14 Nov 2021 03:17:00 +0300 Subject: [PATCH 2/9] Fix formatting --- lib/witchcraft/applicative.ex | 1 + lib/witchcraft/apply.ex | 4 ++-- lib/witchcraft/bifunctor.ex | 1 + lib/witchcraft/chain.ex | 1 + lib/witchcraft/comonad.ex | 1 + lib/witchcraft/extend.ex | 1 + lib/witchcraft/foldable.ex | 1 + lib/witchcraft/monoid.ex | 1 + lib/witchcraft/ord.ex | 6 +++--- lib/witchcraft/semigroup.ex | 1 + lib/witchcraft/semigroupoid.ex | 4 ++-- lib/witchcraft/setoid.ex | 1 + 12 files changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/witchcraft/applicative.ex b/lib/witchcraft/applicative.ex index 4e26866..d4de6d7 100644 --- a/lib/witchcraft/applicative.ex +++ b/lib/witchcraft/applicative.ex @@ -26,6 +26,7 @@ defclass Witchcraft.Applicative do """ alias __MODULE__ + extend Witchcraft.Apply use Witchcraft.Internal, deps: [Witchcraft.Apply] diff --git a/lib/witchcraft/apply.ex b/lib/witchcraft/apply.ex index d397ff4..89729c1 100644 --- a/lib/witchcraft/apply.ex +++ b/lib/witchcraft/apply.ex @@ -118,14 +118,14 @@ defclass Witchcraft.Apply do """ alias __MODULE__ - use Quark - alias Witchcraft.Functor + extend Witchcraft.Functor use Witchcraft.Internal, deps: [Witchcraft.Functor] use Witchcraft.Functor + use Quark @type t :: any() @type fun :: any() diff --git a/lib/witchcraft/bifunctor.ex b/lib/witchcraft/bifunctor.ex index 8889c1e..e66a342 100644 --- a/lib/witchcraft/bifunctor.ex +++ b/lib/witchcraft/bifunctor.ex @@ -19,6 +19,7 @@ defclass Witchcraft.Bifunctor do """ alias __MODULE__ + extend Witchcraft.Functor use Witchcraft.Internal diff --git a/lib/witchcraft/chain.ex b/lib/witchcraft/chain.ex index 6b9426c..8f7f5bb 100644 --- a/lib/witchcraft/chain.ex +++ b/lib/witchcraft/chain.ex @@ -36,6 +36,7 @@ defclass Witchcraft.Chain do """ alias __MODULE__ + extend Witchcraft.Apply use Witchcraft.Internal, deps: [Witchcraft.Apply] diff --git a/lib/witchcraft/comonad.ex b/lib/witchcraft/comonad.ex index 5d9dca3..dc48499 100644 --- a/lib/witchcraft/comonad.ex +++ b/lib/witchcraft/comonad.ex @@ -22,6 +22,7 @@ defclass Witchcraft.Comonad do """ alias __MODULE__ + extend Witchcraft.Extend use Witchcraft.Internal, deps: [Witchcraft.Extend] diff --git a/lib/witchcraft/extend.ex b/lib/witchcraft/extend.ex index c6390b6..a824ddc 100644 --- a/lib/witchcraft/extend.ex +++ b/lib/witchcraft/extend.ex @@ -23,6 +23,7 @@ defclass Witchcraft.Extend do """ alias __MODULE__ + alias Witchcraft.Functor extend Witchcraft.Functor diff --git a/lib/witchcraft/foldable.ex b/lib/witchcraft/foldable.ex index 667ae91..7e6c32e 100644 --- a/lib/witchcraft/foldable.ex +++ b/lib/witchcraft/foldable.ex @@ -35,6 +35,7 @@ defclass Witchcraft.Foldable do require Foldable.EmptyError use Witchcraft.Internal, overrides: [min: 2, max: 2, length: 1], deps: [Semigroup, Ord] + use Witchcraft.Applicative use Quark diff --git a/lib/witchcraft/monoid.ex b/lib/witchcraft/monoid.ex index 729dd8c..ece8bee 100644 --- a/lib/witchcraft/monoid.ex +++ b/lib/witchcraft/monoid.ex @@ -15,6 +15,7 @@ defclass Witchcraft.Monoid do """ alias __MODULE__ + extend Witchcraft.Semigroup, alias: true use Witchcraft.Internal, deps: [Witchcraft.Semigroup] diff --git a/lib/witchcraft/ord.ex b/lib/witchcraft/ord.ex index 3d90052..a1c30d2 100644 --- a/lib/witchcraft/ord.ex +++ b/lib/witchcraft/ord.ex @@ -16,15 +16,15 @@ defclass Witchcraft.Ord do ↓ Ord [compare/2] """ + alias __MODULE__ extend Witchcraft.Setoid + use Witchcraft.Internal, overrides: [<: 2, >: 2, <=: 2, >=: 2] + @type t :: any() @type ordering :: :lesser | :equal | :greater - alias __MODULE__ - use Witchcraft.Internal, overrides: [<: 2, >: 2, <=: 2, >=: 2] - where do @doc """ Get the ordering relationship between two elements. diff --git a/lib/witchcraft/semigroup.ex b/lib/witchcraft/semigroup.ex index 9764920..7af8df6 100644 --- a/lib/witchcraft/semigroup.ex +++ b/lib/witchcraft/semigroup.ex @@ -22,6 +22,7 @@ defclass Witchcraft.Semigroup do """ alias __MODULE__ + use Witchcraft.Internal, overrides: [<>: 2] @type t :: any() diff --git a/lib/witchcraft/semigroupoid.ex b/lib/witchcraft/semigroupoid.ex index d247c53..3813eb7 100644 --- a/lib/witchcraft/semigroupoid.ex +++ b/lib/witchcraft/semigroupoid.ex @@ -14,10 +14,10 @@ defclass Witchcraft.Semigroupoid do alias __MODULE__ - @type t :: any() - use Witchcraft.Internal, overrides: [apply: 2] + @type t :: any() + where do @doc """ Take two morphisms and return their composition "the math way". diff --git a/lib/witchcraft/setoid.ex b/lib/witchcraft/setoid.ex index b2be1d2..6c4c9cc 100644 --- a/lib/witchcraft/setoid.ex +++ b/lib/witchcraft/setoid.ex @@ -18,6 +18,7 @@ defclass Witchcraft.Setoid do """ alias __MODULE__ + use Witchcraft.Internal, overrides: [==: 2, !=: 2] @type t :: any() From 43fcb86a2c92dc449d168f4645d6322ff1bc42d1 Mon Sep 17 00:00:00 2001 From: Vadim Tsvetkov Date: Sun, 14 Nov 2021 03:46:50 +0300 Subject: [PATCH 3/9] Add `:only` support for __using__'s --- lib/witchcraft/internal.ex | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/witchcraft/internal.ex b/lib/witchcraft/internal.ex index 284b340..547eb20 100644 --- a/lib/witchcraft/internal.ex +++ b/lib/witchcraft/internal.ex @@ -9,11 +9,12 @@ defmodule Witchcraft.Internal do def import_helper(opts, overrides, deps, module) do excepts = Keyword.get(opts, :except, []) + only = Keyword.get(opts, :only) deps_quoted = use_multi(deps, opts) - if Access.get(opts, :override_kernel, true) do - kernel_imports = Macro.escape(except: overrides -- excepts) - module_imports = Macro.escape(except: excepts) + if Keyword.get(opts, :override_kernel, true) do + kernel_imports = kernel_imports(overrides -- excepts, only) + module_imports = module_imports(excepts, only) quote do import Kernel, unquote(kernel_imports) @@ -23,7 +24,7 @@ defmodule Witchcraft.Internal do import unquote(module), unquote(module_imports) end else - module_imports = Macro.escape(except: Enum.uniq(overrides ++ excepts)) + module_imports = module_imports(Enum.uniq(overrides ++ excepts), only) quote do unquote(deps_quoted) @@ -33,6 +34,12 @@ defmodule Witchcraft.Internal do end end + defp kernel_imports(excepts, nil), do: Macro.escape(except: excepts) + defp kernel_imports(_, only), do: Macro.escape(except: only) + + defp module_imports(excepts, nil), do: Macro.escape(except: excepts) + defp module_imports(excepts, only), do: Macro.escape(only: only -- excepts) + defmacro __using__(opts \\ []) do overrides = Keyword.get(opts, :overrides, []) deps = Keyword.get(opts, :deps, []) From 6042c90b5175c864847e4b7d65f679ca8ddd4951 Mon Sep 17 00:00:00 2001 From: Vadim Tsvetkov Date: Sun, 14 Nov 2021 03:47:30 +0300 Subject: [PATCH 4/9] Reformat `Witchcraft.Internal` --- lib/witchcraft/internal.ex | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/witchcraft/internal.ex b/lib/witchcraft/internal.ex index 547eb20..b33f710 100644 --- a/lib/witchcraft/internal.ex +++ b/lib/witchcraft/internal.ex @@ -1,8 +1,15 @@ defmodule Witchcraft.Internal do - def use_multi(modules, opts) do - for module <- modules do - quote do - use unquote(module), unquote(opts) + defmacro __using__(opts \\ []) do + overrides = Keyword.get(opts, :overrides, []) + deps = Keyword.get(opts, :deps, []) + + quote do + @overrides unquote(overrides) + + import Kernel, except: unquote(overrides) + + defmacro __using__(opts \\ []) do + Witchcraft.Internal.import_helper(opts, unquote(overrides), unquote(deps), __MODULE__) end end end @@ -34,24 +41,17 @@ defmodule Witchcraft.Internal do end end + def use_multi(modules, opts) do + for module <- modules do + quote do + use unquote(module), unquote(opts) + end + end + end + defp kernel_imports(excepts, nil), do: Macro.escape(except: excepts) defp kernel_imports(_, only), do: Macro.escape(except: only) defp module_imports(excepts, nil), do: Macro.escape(except: excepts) defp module_imports(excepts, only), do: Macro.escape(only: only -- excepts) - - defmacro __using__(opts \\ []) do - overrides = Keyword.get(opts, :overrides, []) - deps = Keyword.get(opts, :deps, []) - - quote do - @overrides unquote(overrides) - - import Kernel, except: unquote(overrides) - - defmacro __using__(opts \\ []) do - Witchcraft.Internal.import_helper(opts, unquote(overrides), unquote(deps), __MODULE__) - end - end - end end From 946b92a3e8ca5758272a9956e3ee2da8d24f2baf Mon Sep 17 00:00:00 2001 From: Vadim Tsvetkov Date: Sun, 14 Nov 2021 04:25:37 +0300 Subject: [PATCH 5/9] use `Witchcraft.Internal` in `Witchcraft` module --- lib/witchcraft.ex | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/lib/witchcraft.ex b/lib/witchcraft.ex index 1c769da..5994800 100644 --- a/lib/witchcraft.ex +++ b/lib/witchcraft.ex @@ -33,14 +33,5 @@ defmodule Witchcraft do the dependency chart (above). """ - defmacro __using__(opts \\ []) do - quote do - use Witchcraft.Arrow, unquote(opts) - use Witchcraft.Monoid, unquote(opts) - use Witchcraft.Bifunctor, unquote(opts) - use Witchcraft.Traversable, unquote(opts) - use Witchcraft.Monad, unquote(opts) - use Witchcraft.Comonad, unquote(opts) - end - end + use Witchcraft.Internal, deps: [Witchcraft.Arrow, Witchcraft.Monoid, Witchcraft.Bifunctor, Witchcraft.Traversable, Witchcraft.Monad, Witchcraft.Comonad] end From 6228b6d907c08e05194a7437eb306636eee56bfe Mon Sep 17 00:00:00 2001 From: Vadim Tsvetkov Date: Sun, 14 Nov 2021 04:42:12 +0300 Subject: [PATCH 6/9] Add docs for `Witchcraft.Internal` --- lib/witchcraft/internal.ex | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/witchcraft/internal.ex b/lib/witchcraft/internal.ex index b33f710..be37495 100644 --- a/lib/witchcraft/internal.ex +++ b/lib/witchcraft/internal.ex @@ -1,4 +1,23 @@ defmodule Witchcraft.Internal do + @moduledoc """ + A module for handling `use Witchcraft` and other modules + + Provides support for overriding `Kernel` functions and for auto dependecies using via `__using__/1` macro. + """ + + @doc ~S""" + Generates `Kernel` import and `__using__/1` macro in module where used. + + ## Options + + - `:overrides` – List of overrides in module where used + - `:deps` – List of modules that will be used in generated `__using__/1` macro + + ## Generated `__usnig__(opts \\ [])` macro supports the following options: + + - `:override_kernel` – If true, overrides function from `Kernel` in module where used. Defaults to true + - `:except` and `:only` – Keyword of functions (Like in [import](https://hexdocs.pm/elixir/Kernel.SpecialForms.html#import/2-selector)). Example: `[fun: ]` where `` is function `fun` arity + """ defmacro __using__(opts \\ []) do overrides = Keyword.get(opts, :overrides, []) deps = Keyword.get(opts, :deps, []) @@ -14,6 +33,7 @@ defmodule Witchcraft.Internal do end end + @doc false def import_helper(opts, overrides, deps, module) do excepts = Keyword.get(opts, :except, []) only = Keyword.get(opts, :only) @@ -41,7 +61,7 @@ defmodule Witchcraft.Internal do end end - def use_multi(modules, opts) do + defp use_multi(modules, opts) do for module <- modules do quote do use unquote(module), unquote(opts) From 30c85dd747a3ad9510473f1154191769f287f03c Mon Sep 17 00:00:00 2001 From: Vadim Tsvetkov Date: Mon, 15 Nov 2021 08:23:40 +0300 Subject: [PATCH 7/9] Fix formatting --- lib/witchcraft.ex | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/witchcraft.ex b/lib/witchcraft.ex index 5994800..64a947c 100644 --- a/lib/witchcraft.ex +++ b/lib/witchcraft.ex @@ -33,5 +33,13 @@ defmodule Witchcraft do the dependency chart (above). """ - use Witchcraft.Internal, deps: [Witchcraft.Arrow, Witchcraft.Monoid, Witchcraft.Bifunctor, Witchcraft.Traversable, Witchcraft.Monad, Witchcraft.Comonad] + use Witchcraft.Internal, + deps: [ + Witchcraft.Arrow, + Witchcraft.Monoid, + Witchcraft.Bifunctor, + Witchcraft.Traversable, + Witchcraft.Monad, + Witchcraft.Comonad + ] end From 6b7a48dbc75f57ce9e683bb061e9c67930b41dee Mon Sep 17 00:00:00 2001 From: "Jechol Lee (Trevor)" Date: Thu, 18 Nov 2021 14:42:53 +0900 Subject: [PATCH 8/9] Update lib/witchcraft/internal.ex --- lib/witchcraft/internal.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/witchcraft/internal.ex b/lib/witchcraft/internal.ex index be37495..393ff81 100644 --- a/lib/witchcraft/internal.ex +++ b/lib/witchcraft/internal.ex @@ -13,7 +13,7 @@ defmodule Witchcraft.Internal do - `:overrides` – List of overrides in module where used - `:deps` – List of modules that will be used in generated `__using__/1` macro - ## Generated `__usnig__(opts \\ [])` macro supports the following options: + ## Generated `__using__(opts \\ [])` macro supports the following options: - `:override_kernel` – If true, overrides function from `Kernel` in module where used. Defaults to true - `:except` and `:only` – Keyword of functions (Like in [import](https://hexdocs.pm/elixir/Kernel.SpecialForms.html#import/2-selector)). Example: `[fun: ]` where `` is function `fun` arity From 95aeed5647805fde1be429ff4bd9bdd7100cd812 Mon Sep 17 00:00:00 2001 From: "Jechol Lee (Trevor)" Date: Thu, 18 Nov 2021 14:42:58 +0900 Subject: [PATCH 9/9] Update lib/witchcraft/internal.ex --- lib/witchcraft/internal.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/witchcraft/internal.ex b/lib/witchcraft/internal.ex index 393ff81..feb0986 100644 --- a/lib/witchcraft/internal.ex +++ b/lib/witchcraft/internal.ex @@ -2,7 +2,7 @@ defmodule Witchcraft.Internal do @moduledoc """ A module for handling `use Witchcraft` and other modules - Provides support for overriding `Kernel` functions and for auto dependecies using via `__using__/1` macro. + Provides support for overriding `Kernel` functions and for auto dependencies using via `__using__/1` macro. """ @doc ~S"""