hfalzon

hfalzon

How to get to grips with Elixir tooling/IDEs?

Hey all again, I am back → a few months ago I started dabbling with Elixir and Phoenix.

Long story short, I came away a little confused and little jaded. I just couldn’t get the appeal (of phoenix)

I suspect it is simply just a matter of unfamiliarity and not really thinking in the same way as the framework at this time. (I like building things from the ground up as it helps me understand more about what I have built → It is why I like Go so much… I tend to be able to reason a lot more about what I need to do to achieve something)

However, I really like elixir (baring some issues that I would like some help with and the point of this post) So I have been trying to look more into setting up http servers with elixir, and I have got to say I am little lost…

A lot of the docs (for example in Bandit) assume that you are using phoenix.

I guess my main confusion comes from the tooling. Is there a secret sauce so to speak to make the tooling a little more useful in my IDE?

for example: I will install bandit and then… I just don’t know what to do with it.

In go for example it would be:
go mod init <name>
go get <module>
import <module>

Then I can start getting autocompletes within my ide fairly consistently

in Elixir, (I really like the language… just I am really struggling with the tooling)

  • Place my imports into the mix.exs
  • mix deps.get
  • Then I am lost… some libs want to be placed in a config… but that just confuses me as it just seem like values are going everywhere, without me really understanding why (despite looking at all the docs) or sometimes using mix.Install
  • I am really unsure how to start seeing import options/ or autocompletes or documentation. (How to configure)
  • Take Plug for example (which is what I am trying to use over phoenix at this time) I just don’t get why we configure things in the way the docs are configuring them.

I know that this is stemming somewhat from my unfamiliarity with at least the mental model. But I build my own frameworks in php, go, node… so I do feel like I should be able to get this. I am just really struggling dealing with the tooling and setup of a project. And I don’t know where to look or things feel really inconsistent and/or magical… like… you do this thing here for this library… just “because”… And that is the one part of the language (right now… that is just not gelling with me)

Is there a resource and / or book to help with this aspect of Elixir? (I have Elixir in Action (third addition) coming this week so I hope that might help

Marked As Solved

dogweather

dogweather

Yep. I’ve gotten first-hand great experiences from it because of the OTP & BEAM:

  • An ultra-fast “redirect server” that simply returns 301’s for an old domain. It processes http requests in micro-seconds (a 1/1000th of a millisecond) while using effectively zero CPU and RAM.
  • A queue-based SaaS that uses the built-in technology and is rock solid.

So maybe one reason for your shock: you’re stepping into a large “batteries included” framework - not just an http library. So lots of these concepts like Supervisor means wrapping your head around someone else’s design, and figuring out how to plug your ideas in.

I got familiar with Elixir on its own, without the framework overhead, from exercism.org - you do the coding exercises in a test-driven style, on your own computer. I compare my solutions to the highest rated ones. My profile: dogweather's profile on Exercism

Also Liked

sodapopcan

sodapopcan

On top of this suggestion, feel free to ask any, and I mean any Elixir-related question here if you want to talk to an actual person. There are a variety of people carrying a variety of knowledge here who check this site multiple times per day, and many of us are more than happy to answer and discuss topics that have already been answered and discussed to death. Most will even non-judgmentally answer many RTMF-type questions. Don’t get me wrong, we’re human and can be grumpy sometimes, so there’s that, but at least every answer (probably) won’t be prefixed with “Certainly!”

sorentwo

sorentwo

Oban Core Team

Others seem to have helped with the tooling and easing into learning side of things. There is a lot to learn about the “how” and “why” for OTP, but I’ll try to answer your specific questions as best I can…

Application and Supervisor are modules provided by Elixir’s standard library. Modules don’t need to be imported/required/aliased to reference them or call functions on them. They are available globally within a single namespace.

The use Application bit invokes a compile time macro. It’s a way to inject functions, implement behaviors, generate additional modules, and otherwise minimize boilerplate.

There are some hard rules about what is done at compile time vs runtime, and that guides most of where libraries instruct you to put things.

  • config.exs/dev.exs - compile time configuration must go here, e.g. config that’s used as module attributes (like constants)
  • runtime.exs - dynamic configuration that’s read from the environment, e.g. the PORT environment variable for a http server
  • application.ex - startup functionality and the supervision tree for your specific application. You can define runtime configuration in here if needed, but it’s not conventional

Beyond that it comes down to convention, really. The only way to absorb the style and convention is by looking at more libraries and applications.

Starting with Plug to make a minimal server, ala go, is starting in hard mode compared to using the components provided by a full framework like phoenix. It’s great for learning, but will require you to dig deeper into OTP behaviours than is needed to start building applications.

I’d encourage you to get started with existing libraries to get a feel for how they’re configured and composed, then start building something minimal from OTP primitives once you have your footing.

sodapopcan

sodapopcan

I would take the time to really learn how the module system works as you’ll find it’s likely more sane than you think. It’s not a huge topic but more than I can type out here, but the docs do a good job.

A few points that may be helpful (that expand on @sorentwo’s answer):

import doesn’t work like it does in many languages. As touched on by @sorentwo, you don’t have to import a module to use it, they are all always available. import is for importing functions (and macros), and only functions (and macros), you cannot import variables or module attributes.

There is no way to magically affect what is available inside a defmodule from the outside. The exception is that every module has an implicit import Kernel which contains such important functions/macros as + and def. This is hard coded into the compiler and there is no way to do this with any other module. If you see just the following:

defmodule A do
  def foo do
    B.foo()
  end
end

B is a top level module, full stop. If it’s not in your project it’s either from a library or it’s builtin.

If you see this:

defmodule B do
  def foo do
    foobar()
  end
end

…that’s a compilation error :slight_smile: Without any imports or uses, there is no way to make a random function call like that work.

As you correctly identified, a wrench is thrown into things as soon as you see a use. This means there are macros and therefore metaprogramming at play. It is encouraged to always have a callout block in the documentation to describe what useing your library will do, so usually you can look to the docs to know what’s up.

It’s very important to at least get comfortable with the ideas of macros because from a technical standpoint (not trying to be reductive here, BEAM friends), Elixir’s powerful and well-designed macro system is the thing it’s bringing to the table as a BEAM language. There are other really good reasons to be here like the community, the syntax, and of course the libraries, but a lot of the best libraries and projects are so good because of macros. I’m absolutely not trying to discourage you from getting to know Elixir better, but the cool thing is that if you decide it just isn’t for you, there are other great macro-free BEAM languages like Gleam and, of course, Erlang itself! But I think it’s worth it to stick to Elixir :smiley:

mikesax

mikesax

In my Claude.md:

Don't EVER say "You're absolutely right!"

dogweather

dogweather

When I hover my mouse over Application in VS Code with ElixirLS I get this:

That’s pretty nice, IMO. And that View on hexdocs link is super-useful.

Where Next?

Popular in Questions Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New

Other popular topics Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement