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 Skype: jv.ptec Founder and Director of R&D On Wed, Nov 30, 2016 at 10:34 PM, Michał Muskała <[email protected]> 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 <[email protected]> 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 [email protected]. > > To view this discussion on the web visit 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. > > -- > 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 [email protected]. > To view this discussion on the web visit 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. > -- 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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2BwQoC6mggL1QiU1auT27krVEcWcsNiQqcJTj7J9kU3bw%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
