The defmodule macro is also something `use Application` could inject for us, i.e.:
defmodule Phoenix do use Application, alias: Phoenix end > On Dec 2, 2016, at 5:05 PM, Chris McCord <[email protected]> wrote: > > 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 <[email protected] >> <mailto:[email protected]>> 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 <[email protected] >> <mailto:[email protected]>> 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 <[email protected] >> <mailto:[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] >> > <mailto:[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] >> > <mailto:elixir-lang-core%[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 >> > >> > <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 [email protected] >> <mailto:elixir-lang-core%[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 >> >> <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 [email protected] >> <mailto:[email protected]>. >> 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 [email protected] >> <mailto:[email protected]>. >> 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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/7F4EC61D-8366-4074-92BD-85228D897F3B%40chrismccord.com. For more options, visit https://groups.google.com/d/optout.
