Runtime dependencies are unideal in this case because of transitive compile time dependencies. An example of what we use this for is for what Ash calls a "change", which is effectively a `plug` but for changeset modifiers. i.e
``` defmodule DoSomething do use Ash.Resource.Change def change(changeset, _, _) do …do something with the changeset end end ``` So now if someone has a compile time dependency against a resource (or any resource that in any way relates back to that resource, because relationships create runtime dependencies), then they have to recompile. However, Ash resources are declarative/static configuration, and so the idea is that they are *meant* to be usable at compile time/for meta-programming. At no point does the resource DSL module actually care about the module you've configured for things like this, it will only ever matter at runtime when it gets called. On Mon, Jul 11, 2022 at 2:39 PM, José Valim < jose.va...@dashbit.co > wrote: > > The best bet we can have at the moment is to add a runtime dependency > indeed... why would a runtime dependency be bad in your case? > > > On Mon, Jul 11, 2022 at 8:37 PM José Valim < jose. valim@ dashbit. co ( > jose.va...@dashbit.co ) > wrote: > > >> I see. Great find. Back to the drawing board. >> >> >> On Mon, Jul 11, 2022 at 8:34 PM Zach Daniel < zachary. s. daniel@ gmail. com >> ( zachary.s.dan...@gmail.com ) > wrote: >> >> >>> hm… I'm pretty sure that this issue exists for `defimpl` in the new code >>> that you've added. >>> >>> >>> >>> ``` >>> >>> defmodule Foo. Bar. Baz ( http://foo.bar.baz/ ) do >>> >>> end >>> >>> >>> >>> alias Foo. Bar. Baz ( http://foo.bar.baz/ ) >>> >>> >>> >>> defimpl Proto, for: Baz do >>> >>> def foo(_thing), do: 10 >>> >>> end >>> >>> >>> >>> ``` >>> >>> will show an `unused alias Baz` warning. >>> >>> >>> >>> On Mon, Jul 11, 2022 at 1:48 PM, Zach Daniel < zachary. s. daniel@ gmail. >>> com >>> ( zachary.s.dan...@gmail.com ) > wrote: >>> >>>> Interesting…I'll do some spelunking and try to figure out why `defimpl` >>>> doesn't yield the same unused alias warnings that my code does then >>>> >>>> >>>> >>>> >>>> >>>> ``` >>>> >>>> defmodule Foo. Bar. Baz ( http://foo.bar.baz/ ) do >>>> >>>> end >>>> >>>> >>>> >>>> alias Foo. Bar. Baz ( http://foo.bar.baz/ ) >>>> >>>> >>>> >>>> defimpl Proto, for: Baz do >>>> >>>> def foo(_thing), do: 10 >>>> >>>> end >>>> >>>> ``` >>>> >>>> >>>> >>>> >>>> On Mon, Jul 11, 2022 at 1:42 PM, José Valim < jose. valim@ dashbit. co ( >>>> jose.va...@dashbit.co ) > wrote: >>>> >>>>> In this case you pass lexical_tracker: nil indeed, that's what we do for >>>>> defimpl for now, although it is a private API for now. >>>>> >>>>> >>>>> On Mon, Jul 11, 2022 at 7:08 PM Zach Daniel < zachary. s. daniel@ gmail. >>>>> com >>>>> ( zachary.s.dan...@gmail.com ) > wrote: >>>>> >>>>> >>>>>> So I tried out doing the same thing that you are currently doing in >>>>>> `expand_literal/2` and I've hit a snag. >>>>>> >>>>>> In the Ash DSL, there are some module references where we don't want to >>>>>> incur a runtime dependency *or* a compile time dependency. From what I >>>>>> can >>>>>> tell, the pattern of `expand_literal/2` still incurs runtime >>>>>> dependencies. >>>>>> In Ash, we have this code: >>>>>> >>>>>> ``` >>>>>> def expand_alias(ast, %Macro.Env{} = env) do >>>>>> Macro.prewalk(ast, fn >>>>>> {:__aliases__, _, _} = node -> >>>>>> Macro.expand(node, %{env | function: {:__ash_placeholder__, 0}}) >>>>>> >>>>>> other -> >>>>>> other >>>>>> end) >>>>>> end >>>>>> >>>>>> def expand_alias_no_require(ast, %Macro.Env{} = env) do >>>>>> Macro.prewalk(ast, fn >>>>>> {:__aliases__, _, _} = node -> >>>>>> Macro.expand(node, %{env | lexical_tracker: nil}) >>>>>> >>>>>> other -> >>>>>> other >>>>>> end) >>>>>> end >>>>>> ``` >>>>>> >>>>>> which models the difference between how we are currently doing things. >>>>>> The >>>>>> primary issue here is that the things using `expand_alias_no_require/2` >>>>>> currently are marked as unused alias, and from what I can tell >>>>>> `expand_literal/2` doesn't solve for that issue. >>>>>> On Monday, May 9, 2022 at 4:33:58 PM UTC-4 Zach Daniel wrote: >>>>>> >>>>>> >>>>>>> Awesome, thanks! >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Mon, May 09, 2022 at 4:10 PM, José Valim < jose.... @ dashbit. co > >>>>>>> wrote: >>>>>>> >>>>>>> >>>>>>> >>>>>>>> It should be added when I fix this: https:/ / github. com/ >>>>>>>> elixir-lang/ elixir/ >>>>>>>> issues/ 11706 ( https://github.com/elixir-lang/elixir/issues/11706 ) :) >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> >>>>>>>> On Mon, May 9, 2022 at 8:02 PM Zach Daniel < zachary. s. daniel@ >>>>>>>> gmail. com >>>>>>>> > wrote: >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> >>>>>>>> >>>>>>>>> That sounds perfect! Is there any place that I can see what that >>>>>>>>> public >>>>>>>>> API will look like? I totally understand on being careful in that >>>>>>>>> regard. >>>>>>>>> Since Ash DSLs are more like static configuration, there are a few >>>>>>>>> places >>>>>>>>> where this is acceptable, but we don't use it for every (or even >>>>>>>>> most) of >>>>>>>>> the places where a module name might be. >>>>>>>>> >>>>>>>>> >>>>>>>>> On Monday, May 9, 2022 at 2:00:11 PM UTC-4 José Valim wrote: >>>>>>>>> >>>>>>>>> >>>>>>>>>> Btw, we will also have a public API on Elixir v1.14 for expanding >>>>>>>>>> literals, so the problem shall disappear altogether. However, you >>>>>>>>>> must be >>>>>>>>>> extremely careful: this should only be used if you indeed don't use >>>>>>>>>> it at >>>>>>>>>> compile time. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Mon, May 9, 2022 at 7:56 PM Zach Daniel < zachary.... @ gmail. >>>>>>>>>> com > >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> Also, I forgot to mention, it was @icecreamcohen on discord who had >>>>>>>>>>> the >>>>>>>>>>> idea that redefining alias may work (although they didn't really >>>>>>>>>>> condone >>>>>>>>>>> it), don't want to take credit for anyone elses ideas though. >>>>>>>>>>> On Monday, May 9, 2022 at 1:53:50 PM UTC-4 Zach Daniel wrote: >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> This is something coming from a compile time optimization that Ash >>>>>>>>>>>> Framework does. >>>>>>>>>>>> >>>>>>>>>>>> In an Ash resource there is something called a change its >>>>>>>>>>>> basically like a >>>>>>>>>>>> plug but it operates on an Ash.Changeset >>>>>>>>>>>> >>>>>>>>>>>> So you might see something like this: >>>>>>>>>>>> ``` >>>>>>>>>>>> # in the resource >>>>>>>>>>>> actions do >>>>>>>>>>>> create :create_with_employee do >>>>>>>>>>>> change MyApp.CreateEmployee >>>>>>>>>>>> end >>>>>>>>>>>> end >>>>>>>>>>>> # the change module >>>>>>>>>>>> defmodule MyApp.CreateEmployee do >>>>>>>>>>>> use Ash.Resource.Change >>>>>>>>>>>> >>>>>>>>>>>> def change(changeset, _opts, _context) do >>>>>>>>>>>> Ash.Changeset.after_action(changeset, fn _changeset, result -> >>>>>>>>>>>> MyApp.Employee.create!(result.stuff, ...) >>>>>>>>>>>> end) >>>>>>>>>>>> end >>>>>>>>>>>> end >>>>>>>>>>>> >>>>>>>>>>>> Now, the change itself, when it comes to the resource, is simple >>>>>>>>>>>> static >>>>>>>>>>>> configuration. It cannot affect the compilation of the resource >>>>>>>>>>>> nor should >>>>>>>>>>>> any thing doing metaprogramming at compile time leverage the >>>>>>>>>>>> internals of >>>>>>>>>>>> that change >>>>>>>>>>>> >>>>>>>>>>>> Something that changes do often is refer to other related >>>>>>>>>>>> resources, like >>>>>>>>>>>> in this example case. So we drastically increase the surface area >>>>>>>>>>>> for >>>>>>>>>>>> transitive compile time dependencies >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Because a runtime dependency in one link becomes a compile time >>>>>>>>>>>> dependency >>>>>>>>>>>> when chained down the road. I.e I depend on the source resource, >>>>>>>>>>>> call it >>>>>>>>>>>> Post at compile time, and Post depends on Employee now at runtime, >>>>>>>>>>>> so I >>>>>>>>>>>> now depend on Employee at compile time. >>>>>>>>>>>> >>>>>>>>>>>> So to help people with their compile times, I've added some >>>>>>>>>>>> metaprogramming magic that does the following (only in very >>>>>>>>>>>> specific >>>>>>>>>>>> places for specific options) Macro.expand(node, %{env | >>>>>>>>>>>> lexical_tracker: >>>>>>>>>>>> nil}) and it works, no more unnecessary dependency. however, if >>>>>>>>>>>> you do >>>>>>>>>>>> this: >>>>>>>>>>>> ``` >>>>>>>>>>>> alias MyApp.CreateEmployee >>>>>>>>>>>> create :name do >>>>>>>>>>>> change CreateEmployee >>>>>>>>>>>> end >>>>>>>>>>>> ``` >>>>>>>>>>>> it yells at you for not using the alias, because I just disabled >>>>>>>>>>>> the thing >>>>>>>>>>>> that would inform the compiler that the alias was used >>>>>>>>>>>> >>>>>>>>>>>> I don't necessarily want to add back in those unnecessary compile >>>>>>>>>>>> time >>>>>>>>>>>> increases, so I'm looking for a way to detect that an alias had >>>>>>>>>>>> been used >>>>>>>>>>>> in these cases, and produce a compiler warning if you didn't add >>>>>>>>>>>> warn: >>>>>>>>>>>> false to the alias, that way you don't get a confusing "alias not >>>>>>>>>>>> used" >>>>>>>>>>>> error, you get (well, I guess you get both) an explanation of why >>>>>>>>>>>> the >>>>>>>>>>>> alias wasn't used and instructions to add warn: false to fix it. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> The options I have so far: >>>>>>>>>>>> >>>>>>>>>>>> 1. redefine `alias` and default to `warn: false` >>>>>>>>>>>> 2. redefine `alias` and track which ones have `warn: false` and >>>>>>>>>>>> print a >>>>>>>>>>>> warning if its used in one of these instances, so they can add it >>>>>>>>>>>> 3. if I detect that an alias is used, raise an error at compile >>>>>>>>>>>> time and >>>>>>>>>>>> say that aliases aren't supported here >>>>>>>>>>>> 4. get something in elixir core that allows explicit control to add >>>>>>>>>>>> something to an explicit list of "used aliases" >>>>>>>>>>>> >>>>>>>>>>>> Looking at the code for the lexical_tracker, it could be as simple >>>>>>>>>>>> as >>>>>>>>>>>> tracking a separate list of explicitly provided modules, or it >>>>>>>>>>>> could be a >>>>>>>>>>>> different mode of reference, i.e `:compile` `:runtime` or >>>>>>>>>>>> `:ignore`, that >>>>>>>>>>>> kind of thing. >>>>>>>>>>>> >>>>>>>>>>>> Also, if there is another way to accomplish the goal here I'm open >>>>>>>>>>>> to >>>>>>>>>>>> suggestions. >>>>>>>>>>>> >>>>>>>>>>>> Thanks! >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> You received this message because you are subscribed to the Google >>>>>>>>>>> Groups >>>>>>>>>>> "elixir-lang-core" group. >>>>>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>>>>> send an >>>>>>>>>>> email to elixir-lang-co... @ googlegroups. com. >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> To view this discussion on the web visit https:/ / groups. google. >>>>>>>>>>> com/ d/ >>>>>>>>>>> msgid/ elixir-lang-core/ >>>>>>>>>>> f8e4ed44-f3a8-41cc-b82c-f6175ea461fdn%40googlegroups. >>>>>>>>>>> com ( >>>>>>>>>>> https://groups.google.com/d/msgid/elixir-lang-core/f8e4ed44-f3a8-41cc-b82c-f6175ea461fdn%40googlegroups.com?utm_medium=email&utm_source=footer >>>>>>>>>>> ). >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> You received this message because you are subscribed to the Google >>>>>>>>> Groups >>>>>>>>> "elixir-lang-core" group. >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> >>>>>>>> >>>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>>> send an >>>>>>>>> email to elixir-lang-core+unsubscribe@ googlegroups. com. >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> >>>>>>>> >>>>>>>>> >>>>>>>>> To view this discussion on the web visit https:/ / groups. google. >>>>>>>>> com/ d/ >>>>>>>>> msgid/ elixir-lang-core/ >>>>>>>>> a249ae72-fc35-4ff2-be69-567aa53ceb87n%40googlegroups. >>>>>>>>> com ( >>>>>>>>> https://groups.google.com/d/msgid/elixir-lang-core/a249ae72-fc35-4ff2-be69-567aa53ceb87n%40googlegroups.com?utm_medium=email&utm_source=footer >>>>>>>>> ). >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> >>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> >>>>>>>> You received this message because you are subscribed to the Google >>>>>>>> Groups >>>>>>>> "elixir-lang-core" group. >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> >>>>>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>>>>> an >>>>>>>> email to elixir-lang-core+unsubscribe@ googlegroups. com. >>>>>>>> To view this discussion on the web visit https:/ / groups. google. >>>>>>>> com/ d/ >>>>>>>> msgid/ elixir-lang-core/ >>>>>>>> CAGnRm4Lue_uJZdyChHFL_crrW6PVARBFUzm%3DvS5mmPGSSTFi9A%40mail. >>>>>>>> gmail. com ( >>>>>>>> https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4Lue_uJZdyChHFL_crrW6PVARBFUzm%3DvS5mmPGSSTFi9A%40mail.gmail.com?utm_medium=email&utm_source=footer >>>>>>>> ). >>>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> You received this message because you are subscribed to the Google Groups >>>>>> "elixir-lang-core" group. >>>>>> To unsubscribe from this group and stop receiving emails from it, send an >>>>>> email to elixir-lang-core+unsubscribe@ googlegroups. com ( >>>>>> elixir-lang-core+unsubscr...@googlegroups.com ). >>>>>> To view this discussion on the web visit https:/ / groups. google. com/ >>>>>> d/ >>>>>> msgid/ elixir-lang-core/ >>>>>> 136de6d8-f330-4135-8549-3ad70767a0efn%40googlegroups. >>>>>> com ( >>>>>> https://groups.google.com/d/msgid/elixir-lang-core/136de6d8-f330-4135-8549-3ad70767a0efn%40googlegroups.com?utm_medium=email&utm_source=footer >>>>>> ). >>>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google Groups >>>>> "elixir-lang-core" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send an >>>>> email to elixir-lang-core+unsubscribe@ googlegroups. com ( >>>>> elixir-lang-core+unsubscr...@googlegroups.com ). >>>>> To view this discussion on the web visit https:/ / groups. google. com/ d/ >>>>> msgid/ elixir-lang-core/ >>>>> CAGnRm4JFV6XO-3QsYYTCyFDSCUx%2BZvk8WNWYF3-HTE-ksnuC3Q%40mail. >>>>> gmail. com ( >>>>> https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4JFV6XO-3QsYYTCyFDSCUx%2BZvk8WNWYF3-HTE-ksnuC3Q%40mail.gmail.com?utm_medium=email&utm_source=footer >>>>> ). >>>>> >>>> >>>> >>> >>> >>> >>> >>> >>> >>> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "elixir-lang-core" group. >>> To unsubscribe from this group and stop receiving emails from it, send an >>> email to elixir-lang-core+unsubscribe@ googlegroups. com ( >>> elixir-lang-core+unsubscr...@googlegroups.com ). >>> To view this discussion on the web visit https:/ / groups. google. com/ d/ >>> msgid/ elixir-lang-core/ l5h31mlq. >>> 8b02b89a-781a-410a-9f22-50c707b5e571%40we. >>> are. superhuman. com ( >>> https://groups.google.com/d/msgid/elixir-lang-core/l5h31mlq.8b02b89a-781a-410a-9f22-50c707b5e571%40we.are.superhuman.com?utm_medium=email&utm_source=footer >>> ). >>> >> >> >> > > > > > > -- > You received this message because you are subscribed to the Google Groups > "elixir-lang-core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to elixir-lang-core+unsubscribe@ googlegroups. com ( > elixir-lang-core+unsubscr...@googlegroups.com ). > To view this discussion on the web visit https:/ / groups. google. com/ d/ > msgid/ elixir-lang-core/ > CAGnRm4KoK-HHxniugy%2BjGdcUXKEF%2Bmv61XR4hmcHEEXAe2v2cw%40mail. > gmail. com ( > https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4KoK-HHxniugy%2BjGdcUXKEF%2Bmv61XR4hmcHEEXAe2v2cw%40mail.gmail.com?utm_medium=email&utm_source=footer > ). > -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/l5h3xeml.b4e74313-a7c7-45d7-92c6-dcdb0312e912%40we.are.superhuman.com.