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