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.