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+unsubscr...@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.

Reply via email to