Well, its runtime dependencies that create transitive compile time dependencies, isn't it? So if I have a function like
defmodule Foo do # callers are aware that they can't use the module at compile time def returns_a_module() do SomeSpecificModule end def something_used_at_compile_time() do 10 end end # and then some other module defmodule Bar do @something Foo.something_used_at_compile_time() end This induces a transitive compile time dependency from Bar to SomeSpecificModule. In the case of Ash DSLs, for example, this happens because we store the resulting configuration in a module attribute. Users are aware that you can't call these pluggable modules at compile time. Only the framework code calls those modules. The above example is contrived, of course, I'm not suggesting that we need a feature to make *that* work, just trying to draw some kind of parallel. I don't see a reasonable way to handle this without essentially removing the ability to use modules in the way that we are. It would be a pretty unreasonable amount of work/change for users to change the way that we plug behavior in Ash. To me, another kind of module dependency, like `runtime-only`, would solve for this, and it would have to be explicitly requested, i.e `expand_literal(.., runtime_only: true)`. Then when determining transitive compile time dependencies, the compiler would not use those modules. On Tue, Sep 13, 2022 at 6:51 PM, José Valim < jose.va...@dashbit.co > wrote: > > As I mentioned, the issue on transitive compile-time dependencies are the > compile-time deps, not the runtime ones. So I would focus on how to > eliminate those. Otherwise I am not sure we will agree on the problem > statement. :) > > > On Wed, Sep 14, 2022 at 12:49 AM Zach Daniel < zachary. s. daniel@ gmail. com > ( zachary.s.dan...@gmail.com ) > wrote: > > >> Although the solution I originally proposed may not be correct (totally >> fine with me 😃), I think the problem statement is still valid. Can we >> agree that there are some cases where you may want to reference a module >> without creating transitive compile time dependencies, i.e in the case of >> a DSL like what Ash provides? >> >> >> >> >> On Sun, Sep 11, 2022 at 3:08 PM, Zach Daniel < zachary. s. daniel@ gmail. com >> ( zachary.s.dan...@gmail.com ) > wrote: >> >>> Hm...yeah, that makes sense. Are there other things a runtime dependency >>> is meant to do aside from ensure that transitive compile time dependencies >>> are properly tracked? If so, is there a way to solve for the transitive >>> dependencies without removing the runtime dependency? Because ultimately >>> the idea here is that this module is essentially just a big >>> validated/extensible configuration. The resource itself doesn't do >>> anything. So requiring things that refer to a resource to recompile when >>> any of the modules it refers to in a `change` like that is unnecessary. >>> However we can express that reality is totally fine with me. >>> >>> >>> >>> >>> On Sunday, September 11, 2022 at 3:05:18 PM UTC-4 José Valim wrote: >>> >>> >>>> The issue is in the transitive compile time dependencies, not the runtime >>>> dependencies. >>>> >>>> >>>> I don't think we should be encouraging removing the runtime dependencies >>>> when they are explicitly listed in the code as above. When done via >>>> configuration, at least you are not literally listing it. >>>> >>>> >>>> >>>> On Sun, Sep 11, 2022 at 8:59 PM Zach Daniel < zachary.... @ gmail. com > >>>> wrote: >>>> >>>> >>>>> So all we we do is hold onto the module, and then at runtime we go through >>>>> the list of modules that we should call and call a specific function on >>>>> them. Requiring a runtime dependency for that is causing really slow >>>>> compile times because of transitive dependencies. Maybe there is some >>>>> consequence I don't see, but I removed the runtime dependencies by >>>>> disabling the lexical tracker when expanding the alias, and its been that >>>>> way for months w/o anyone reporting any issues with that implementation. >>>>> Aside from having to use `warn: false` if they use aliases. >>>>> >>>>> To me, its the same as if they gave us, instead of a module, an `atom` >>>>> that referred to application configuration, i.e the adapter pattern. That >>>>> would work without a runtime dependency, so why couldn't this? >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>> >>>> >>>>> On Sun, Sep 11, 2022 at 2:56 PM, José Valim < jose.... @ dashbit. co > >>>>> wrote: >>>>> >>>>> >>>>> >>>> >>>> >>>>> >>>>>> Sorry, correction: If, at any moment, you call any function from that >>>>>> module at runtime, you must not remove the *runtime* time dependency. >>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>> >>>> >>>>> >>>>>> On Sun, Sep 11, 2022 at 8:55 PM José Valim < jose.... @ dashbit. co > >>>>>> wrote: >>>>>> >>>>>> >>>>> >>>>> >>>> >>>> >>>>> >>>>>> >>>>>>> Why do you want to remove the runtime dependency when, per your >>>>>>> description: >>>>>>> >>>>>>> >>>>>>> > In Ash Framework, we have declarative ways to construct *runtime* >>>>>>> > behavior >>>>>>> using behaviors. >>>>>>> >>>>>>> >>>>>>> Emphasis mine. If, at any moment, you call any function from that module >>>>>>> at runtime, you must not remove the compile time dependency. >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>> >>>> >>>>> >>>>>> >>>>>>> On Sun, Sep 11, 2022 at 8:52 PM Zach Daniel < zachary.... @ gmail. com > >>>>>>> wrote: >>>>>>> >>>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>> >>>> >>>>> >>>>>> >>>>>>> >>>>>>>> `expand_literal` removes the compile time dependency, but leaves a >>>>>>>> runtime >>>>>>>> dependency when used inside of a module. >>>>>>>> >>>>>>>> What I'm trying to do is remove both the compile time dependency *and* >>>>>>>> the >>>>>>>> runtime dependency, without requiring the use of `warn: false` on >>>>>>>> aliases. >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On Sunday, September 11, 2022 at 2:31:42 PM UTC-4 José Valim wrote: >>>>>>>> >>>>>>>> >>>>>>>>> Sorry, I don't understand the proposal. You mentioned expand_literal, >>>>>>>>> which already removes the compile-time dependency but keeps the >>>>>>>>> remaining >>>>>>>>> functionality such as warnings. Can you please expand? >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Sun, Sep 11, 2022 at 7:57 PM Zach Daniel < zachary.... @ gmail. >>>>>>>>> com > >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>> >>>>>>>>>> For clarity, the dependency I'm talking about there is the >>>>>>>>>> dependency from >>>>>>>>>> `MyApp.User` to `MyApp.User.Changes.HashPassword`. >>>>>>>>>> On Sunday, September 11, 2022 at 1:55:51 PM UTC-4 Zach Daniel wrote: >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> In Ash Framework, we have declarative ways to construct runtime >>>>>>>>>>> behavior >>>>>>>>>>> using behaviors. So an Ash resource might look like this: >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> ```elixir >>>>>>>>>>> defmodule MyApp.User do >>>>>>>>>>> use Ash.Resource >>>>>>>>>>> >>>>>>>>>>> alias MyApp.User.Changes.HashPassword >>>>>>>>>>> >>>>>>>>>>> attributes do >>>>>>>>>>> uuid_primary_key :id >>>>>>>>>>> .... >>>>>>>>>>> end >>>>>>>>>>> >>>>>>>>>>> actions do >>>>>>>>>>> create :register do >>>>>>>>>>> change HashPassword >>>>>>>>>>> end >>>>>>>>>>> end >>>>>>>>>>> end >>>>>>>>>>> ``` >>>>>>>>>>> >>>>>>>>>>> However, by default, this would incur a compile time dependency. >>>>>>>>>>> This >>>>>>>>>>> compile time dependency is unnecessary, as we won't call any >>>>>>>>>>> functions on >>>>>>>>>>> this module or use it in any way until runtime. >>>>>>>>>>> >>>>>>>>>>> That optimization is well and good, but due to transitive compile >>>>>>>>>>> time >>>>>>>>>>> dependencies, we see some interesting behavior. Something you'd >>>>>>>>>>> often see >>>>>>>>>>> in a change module is things like pattern matching on other >>>>>>>>>>> resources, or >>>>>>>>>>> the resource in question in function heads. Resources are meant to >>>>>>>>>>> be >>>>>>>>>>> introspectable at compile time, and so this runtime dependency on a >>>>>>>>>>> change, with a compile time dependency on a resource, incurs a >>>>>>>>>>> transitive >>>>>>>>>>> compile time dependency. This problem multiplies over time, and >>>>>>>>>>> causes >>>>>>>>>>> users to have to do things solely to optimize compile times, like >>>>>>>>>>> only use >>>>>>>>>>> map pattern matches instead of struct pattern matches. >>>>>>>>>>> >>>>>>>>>>> So what we do is we actually disable the lexical tracker when >>>>>>>>>>> accepting >>>>>>>>>>> certain parts of the DSL. This prevents *any* dependency. >>>>>>>>>>> Naturally, at >>>>>>>>>>> compile time you are no longer safe to call a resource's change >>>>>>>>>>> module as >>>>>>>>>>> changes in that module won't cause recompiles, but that was never a >>>>>>>>>>> thing >>>>>>>>>>> you should have done in the first place so I'm not worried about >>>>>>>>>>> that. >>>>>>>>>>> >>>>>>>>>>> This leads us to the primary issue: disabling the lexical tracker >>>>>>>>>>> when >>>>>>>>>>> expanding aliases also causes warnings about unused aliases, even >>>>>>>>>>> though >>>>>>>>>>> they *are* used. I believe I've brought this issue up before and we >>>>>>>>>>> were >>>>>>>>>>> hoping that the feature introduced in 1.14 for `defimpl` would >>>>>>>>>>> help, but >>>>>>>>>>> that only helps prevent compile time issues, which is something I >>>>>>>>>>> had >>>>>>>>>>> already solved for in the same way it was solved for 1.14. I've >>>>>>>>>>> laid it >>>>>>>>>>> all out to help clarify exactly *why* I need it so perhaps someone >>>>>>>>>>> can >>>>>>>>>>> point me in a better direction. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> The simplest thing that could help: >>>>>>>>>>> >>>>>>>>>>> A way to tell the lexical tracker that an alias has just been >>>>>>>>>>> referenced >>>>>>>>>>> without inducing any kind of compile or runtime dependency. The >>>>>>>>>>> idea is to >>>>>>>>>>> just prevent it from warning about the alias. >>>>>>>>>>> >>>>>>>>>>> I'm open to other solutions as well. >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> 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/ >>>>>>>>>> 54627973-7b74-47d7-9e35-4270621e6c91n%40googlegroups. >>>>>>>>>> com ( >>>>>>>>>> https://groups.google.com/d/msgid/elixir-lang-core/54627973-7b74-47d7-9e35-4270621e6c91n%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-co... @ googlegroups. com. >>>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>> >>>> >>>>> >>>>>> >>>>>>> >>>>>>>> To view this discussion on the web visit https:/ / groups. google. >>>>>>>> com/ d/ >>>>>>>> msgid/ elixir-lang-core/ >>>>>>>> 22887a7e-a1b6-4ccc-98bf-69a5ad3551a5n%40googlegroups. >>>>>>>> com ( >>>>>>>> https://groups.google.com/d/msgid/elixir-lang-core/22887a7e-a1b6-4ccc-98bf-69a5ad3551a5n%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-co... @ googlegroups. com. >>>>>> >>>>>> >>>>> >>>>> >>>> >>>> >>>>> >>>>>> To view this discussion on the web visit https:/ / groups. google. com/ >>>>>> d/ >>>>>> msgid/ elixir-lang-core/ >>>>>> CAGnRm4%2BVkL%2B1V7LTDVyzhCqcNWrmHFPoWx2Fp916Ur%2ByL%2BiVBA%40mail. >>>>>> gmail. com ( >>>>>> https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2BVkL%2B1V7LTDVyzhCqcNWrmHFPoWx2Fp916Ur%2ByL%2BiVBA%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-co... @ googlegroups. com. >>>>> >>>> >>>> >>>> >>>>> To view this discussion on the web visit https:/ / groups. google. com/ d/ >>>>> msgid/ elixir-lang-core/ l7xp6eut. >>>>> 444ff913-f528-4b88-805a-cac120cdb4d6%40we. >>>>> are. superhuman. com ( >>>>> https://groups.google.com/d/msgid/elixir-lang-core/l7xp6eut.444ff913-f528-4b88-805a-cac120cdb4d6%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/ >>> 072bb99d-09a0-4567-a934-f8893015dd91n%40googlegroups. >>> com ( >>> https://groups.google.com/d/msgid/elixir-lang-core/072bb99d-09a0-4567-a934-f8893015dd91n%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/ l80s9s37. 13dfe243-83b3-4133-8aad-7a86910f56fa%40we. >> are. superhuman. com ( >> https://groups.google.com/d/msgid/elixir-lang-core/l80s9s37.13dfe243-83b3-4133-8aad-7a86910f56fa%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/ > CAGnRm4J8qxM%3DKxMUUW6X%2Bt%2BrD9rKn0yDHbDY1fDgopxRvtNn5A%40mail. > gmail. com ( > https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4J8qxM%3DKxMUUW6X%2Bt%2BrD9rKn0yDHbDY1fDgopxRvtNn5A%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/l80tn3jj.9205d976-8cf7-42b4-9444-52f835130e14%40we.are.superhuman.com.