I’m not yet sure how I feel about adding a feature to the language to solve 
this issue since I don’t think it’s hard to solve with find/replace and I’ve 
come to prefer the explicit, if not a little boilerplate'y namespacing. For the 
moment, I probably lean more towards -1. That said, I don’t particularly like 
solutions mentioned so far. Counterproposal:

1) we already have a configured `:application` module in mix. Let’s use Phoenix 
as an example:

mix.exs:

defmodule Phoenix.Mixfile do
  def application do
    [mod: {Phoenix, []}, …

So mix knows what module our “application” uses to start. What if mix can 
autorequire this module for us, and also auto alias this module to `App`? This 
would then allow us to write (or mix new to generate):

defmodule Phoenix do
  use Application

  defmacro defmodule(name, do: block)
    quote do
      defmodule unquote(Module.concat(Phoenix, name)), do: unquote(block)
    end
  end

  def start(_type, _args) do
  ...
end


Then any file in your project:

App.defmodule Router do
  ...
end


To me, this is the least magic’y way to solve the issue, doesn’t introduce any 
new syntax to the language, doesn’t introduce a way for folks to get carried 
away with globals, and doesn’t leave a bad feeling in my stomach like the 
others. Cons are that it introduces a single global alias, `App`.


> On Dec 2, 2016, at 4:44 PM, Adam Kittelson <a...@apathydrive.com> wrote:
> 
> I realize they aren't proposals, but I do like #1, perhaps with an eye toward 
> having @MODULE in conjunction with __MODULE__ for a time before eventually 
> deprecating the latter.
> 
> Alternatively we could have @@compiler_attributes and @module_attributes 
> because it would amuse me to have module attributes look like ruby instance 
> variables and compiler attributes look like ruby class variables. ;)
> 
> Adam
> 
> On Fri, Dec 2, 2016 at 3:33 PM, José Valim <jose.va...@plataformatec.com.br 
> <mailto:jose.va...@plataformatec.com.br>> wrote:
> As Michał said, I don't think we want exactly __APP__. After all, the 
> application name is an atom, like :my_app, and we likely want the inflected 
> application module, which would be MyApp.
> 
> Furthermore, as Michał also said, the inflection does not automatically work 
> for all applications, so I believe we should rather explicitly say the top 
> name module instead of inflecting it from a slightly related variable.
> 
> ## Understanding the problem
> 
> If we take a step back, I believe the feature we are looking for is actually 
> compiler constants. We want the ability to specify, when you compile this 
> application, you are going to have this app wide constant with the value of 
> X. For example, one could specify in their mix.exs:
> 
> def project do
>   [constants: [APP: MyApp]]
> end
> 
> And then you would:
> 
> defmodule __APP__.Foo do
> end
> 
> The benefit of generalizing this mechanism is that we no longer need to 
> hardcode to Mix and we can also make it work with the regular Elixir command 
> line. As a matter of fact, both C and Erlang have this feature. In Erlang it 
> is in the format of macros:
> 
> erlc -Dapp=MyApp
> 
> And in your code you would be able to access the app name as "?app".
> 
> ## Existing solutions
> 
> Before proposing new solutions, let's consider if we can use anything that 
> already exists today to solve this issue.
> 
> For example, maybe we could use application environment variables? Although 
> defining a module like below probably wouldn't make anybody happy:
> 
> defmodule Module.concat(Application.fetch_env!(:my_app, :app), Foo) do
> 
> From the above, we also get the requirement the new construct must be 
> concise. And we very likely want it to expand and be checked at compile time.
> 
> Hrm... wait... aren't we talking about module attributes? It has a concise 
> syntax and expands at compile time. But wait... those only work inside 
> modules. Maybe those could be extended?
> 
> ## Proposing a solution
> 
> Left as an exercise to the reader. :)
> 
> The point of this email was to illustrate how we could generalize the 
> proposal and see if we could adopt an existing solution or extend it somehow. 
> Many options pass through my mind. For example:
> 
> 1. Use @APP for compiler attributes (in contrast to @foo as module 
> attributes). Pros: it is concise, can be made compile time. Cons: slightly 
> new syntax, conflicts with __MODULE__ (which could arguably be @MODULE)
> 
> 2. Use @app for compiler attributes. Compiler attributes could be overridden 
> inside modules by a module attribute. Pros: it is concise, can be made to 
> warn at compile time. Cons: overloads existing syntax.
> 
> 3. Introduce a new syntax, such as $app. Pros: it is concise, can be made 
> compile time. Cons: introduce completely new syntax, conflicts with 
> __MODULE__ (which could arguable be $MODULE)
> 
> I am not effectively proposing *any* of them but I thought it would be 
> interesting to keep the discussion going. After all my job is much easier if 
> you do it all for me. :)
> 
> 
> 
> 
> José Valim
> www.plataformatec.com.br <http://www.plataformatec.com.br/>
> Skype: jv.ptec
> Founder and Director of R&D
> 
> On Wed, Nov 30, 2016 at 10:34 PM, Michał Muskała <mic...@muskala.eu 
> <mailto:mic...@muskala.eu>> wrote:
> How often one needs to rename the application? I had to do this only once, 
> and it was a simple find & replace.
> 
> While __APP__ would simplify it, I find it a bit ugly to have every module 
> defined like this. And if there was an __APP__ variable, I would certainly 
> expect it to be the OTP application name, not some mutated module name. As of 
> now there's no place in mix.exs that defines the "base" module for an 
> application, and it's nor reliable to inflect it automatically from the OTP 
> application name, some examples:
> 
> mongodb uses Mongo, mongodb_ecto uses Mongo.Ecto, phoenix_html uses 
> Phpenix.HTML, phoenix_pubsub uses Phoenix.PubSub, cors_plug uses CORSPlug, 
> plug_cors uses PlugCors.
> 
> I don't see a way how we can inflect those automatically.
> 
> Michał.
> 
> > On 30 Nov 2016, at 17:40, Dave Thomas <d...@pragdave.me 
> > <mailto:d...@pragdave.me>> wrote:
> >
> > I just tried to change the application name in a trivial Phoenix project. 
> > The name of the project is embedded into the source code 48 times. I have 
> > one controller, one view, and a channel.
> >
> > My suggestion: assume anything created using mix will be build using mix. 
> > For these builds, add the definition __APP__, set to the application name 
> > (in module-name form) from the mix.exs file.
> >
> > Then generate all the underlying files using
> >
> > defmodule __APP__.EndPoint do
> >
> >  ...
> >
> > This could apply to both mix new and mix phoenix.new, as well as anything 
> > else that comes along.
> >
> > Dave
> >
> >
> > --
> > 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 
> > <mailto:elixir-lang-core%2bunsubscr...@googlegroups.com>.
> > To view this discussion on the web visit 
> > https://groups.google.com/d/msgid/elixir-lang-core/fe291b67-82f9-411e-ae3a-a1821867ebc6%40googlegroups.com
> >  
> > <https://groups.google.com/d/msgid/elixir-lang-core/fe291b67-82f9-411e-ae3a-a1821867ebc6%40googlegroups.com>.
> > For more options, visit https://groups.google.com/d/optout 
> > <https://groups.google.com/d/optout>.
> 
> --
> 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 
> <mailto:elixir-lang-core%2bunsubscr...@googlegroups.com>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/elixir-lang-core/64EDFB02-CE5A-42F5-B690-716E419E689A%40muskala.eu
>  
> <https://groups.google.com/d/msgid/elixir-lang-core/64EDFB02-CE5A-42F5-B690-716E419E689A%40muskala.eu>.
> For more options, visit https://groups.google.com/d/optout 
> <https://groups.google.com/d/optout>.
> 
> 
> -- 
> 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 
> <mailto:elixir-lang-core+unsubscr...@googlegroups.com>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2BwQoC6mggL1QiU1auT27krVEcWcsNiQqcJTj7J9kU3bw%40mail.gmail.com
>  
> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2BwQoC6mggL1QiU1auT27krVEcWcsNiQqcJTj7J9kU3bw%40mail.gmail.com?utm_medium=email&utm_source=footer>.
> 
> For more options, visit https://groups.google.com/d/optout 
> <https://groups.google.com/d/optout>.
> 
> 
> -- 
> 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 
> <mailto:elixir-lang-core+unsubscr...@googlegroups.com>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/elixir-lang-core/CABqbXnuEd6gbBhv_Xop4%2BJARU%2BZt0w3%2BM-TaswjBvi2L_xVpng%40mail.gmail.com
>  
> <https://groups.google.com/d/msgid/elixir-lang-core/CABqbXnuEd6gbBhv_Xop4%2BJARU%2BZt0w3%2BM-TaswjBvi2L_xVpng%40mail.gmail.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout 
> <https://groups.google.com/d/optout>.

-- 
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/AC34399F-1D52-4202-8D69-554B8AC2555C%40chrismccord.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to