in elixir .ex is for compiled code .exs if for interpreted code
IO.puts("Hello World from elixirel")- create our project ( mix new project-name )
- compile our project(mix compile)
- run our project
defmodule Example do
Β use Application
Β @x 5
Β def start(_type,_args) do
Β Β Example.main()
Β Β Supervisor.start_link([],strategy: :one_for_one)
Β end
Β def main do
Β Β name="Saugat"
Β Β status=:gold
Β Β IO.puts("name: #{name} status: #{status} constant no: #{@x}")
Β end
enddefmodule Example do
Β use Application
Β def start(_type,_args) do
Β Β Example.main()
Β Β Supervisor.start_link([],strategy: :one_for_one)
Β end
Β def main do
Β Β name="Saugat"
Β Β status=Enum.random([:gold,:silver,:bronze])
Β Β if status===:gold do
Β Β Β IO.puts("Welcome to Fancy lounge, #{name} ")
Β Β else
Β Β Β IO.puts("Get lost")
Β Β end
Β end
enddefmodule Example do
Β use Application
Β def start(_type,_args) do
Β Β Example.main()
Β Β Supervisor.start_link([],strategy: :one_for_one)
Β end
Β def main do
Β Β name="Saugat"
Β Β status=Enum.random([:gold,:silver,:bronze,:"not a member"])
Β Β case status do
Β Β Β :gold->IO.puts("Welcome to the fancy laung, #{name} ")
Β Β Β :silver->IO.puts("Come in sir")
Β Β Β :bronze->IO.puts("Come in")
Β Β Β :"not a member"->IO.puts("Get subscribed");
Β Β Β _->IO.puts("Get lost")
Β Β end
Β end
enddefmodule Example do
Β use Application
Β def start(_type, _args) do
Β Β Example.main()
Β Β Supervisor.start_link([], strategy: :one_for_one)
Β end
Β def main do
Β Β IO.puts("This\nis\n\tmessage\n")
Β Β IO.puts("After")
Β Β IO.puts("String interpoluayion looks like \#{}")
Β Β #numeric representation of unicode
Β Β IO.puts(?a)
Β end
enddefmodule Example do
Β use Application
Β def start(_type, _args) do
Β Β Example.main()
Β Β Supervisor.start_link([], strategy: :one_for_one)
Β end
Β def main do
Β Β a=10
Β Β a=a+10.0
Β Β b=3
Β Β IO.puts(a/b)
Β Β :io.format("~20f\n",[0.1])
Β Β IO.puts(Float.ceil(1.6))
Β Β IO.puts(Float.ceil(1.1,1))
Β Β IO.puts(Integer.gcd(20,5))
Β end
enddefmodule Example do
Β use Application
Β def start(_type, _args) do
Β Β Example.main()
Β Β Supervisor.start_link([], strategy: :one_for_one)
Β end
Β def main do
Β Β # Create a specific time (16:30:00)
Β Β time = Time.new!(16, 30, 0, 0)
Β Β # Create a specific date (January 1, 2025)
Β Β date = Date.new!(2025, 1, 1)
Β Β # Combine the date and time into a DateTime in the UTC timezone
Β Β date_time = DateTime.new!(date, time, "Etc/UTC")
Β Β # Print the date, time, and combined DateTime
Β Β IO.inspect(date, label: "Date")
Β Β IO.inspect(time, label: "Time")
Β Β IO.inspect(date_time, label: "DateTime")
Β Β # Create a future DateTime (January 1, 2082, 00:00:00 UTC)
Β Β future_time = DateTime.new!(Date.new!(2082, 1, 1), Time.new!(0, 0, 0, 0), "Etc/UTC")
Β Β # Calculate the difference in seconds between now and the future time
Β Β time_till = DateTime.diff(DateTime.utc_now(), future_time)
Β Β # Print the total seconds until the future time
Β Β IO.puts("Total seconds until future time: #{time_till}")
Β Β # Calculate the number of days from the total seconds
Β Β days = div(time_till, 86_400) # 86,400 seconds in a day
Β Β # Print the remaining seconds after dividing by days
Β Β IO.puts("Remaining seconds after days: #{rem(time_till, 86_400)}")
Β Β # Calculate the number of hours from the remaining seconds
Β Β hours = div(rem(time_till, 86_400), 60 * 60) # 60 * 60 seconds in an hour
Β Β # Calculate the number of minutes from the remaining seconds after hours
Β Β mins = div(rem(time_till, 60 * 60), 60) # 60 seconds in a minute
Β Β IO.puts(
Β Β Β "Time until 2082: #{days} days, #{hours} hours, #{mins} minutes"
Β Β )
Β end
enddefmodule Example do
Β use Application
Β def start(_type, _args) do
Β Β Example.main()
Β Β Supervisor.start_link([], strategy: :one_for_one)
Β end
Β def main do
Β Β membership={:bronz,:silver}
Β Β membership=Tuple.append(membership,":gold")
Β Β IO.inspect(membership)
Β Β prices={5,10,15}
Β Β avg=Tuple.sum(prices)/tuple_size(prices)
Β Β IO.puts(avg)
Β Β IO.puts("Average price from #{elem(membership,0)} #{elem(membership,1)} #{elem(membership,2)} avg is #{avg}")
Β Β user1={"Saugat",:gold}
Β Β user2={"Hari",:silver}
Β Β user3={"Sits",:bronz}
Β Β {name,membership}=user1
Β Β IO.puts("#{name} has a #{membership} membership")
Β Β {name,membership}=user2
Β Β IO.puts("#{name} has a #{membership} membership")
Β Β {name,membership}=user3
Β Β IO.puts("#{name} has a #{membership} membership")
Β end
enddefmodule Example do
Β use Application
Β def start(_type, _args) do
Β Β Example.main()
Β Β Supervisor.start_link([], strategy: :one_for_one)
Β end
Β def main do
Β Β users=[
Β Β Β {"Saugat",:gold},
Β Β Β {"Hari",:silver},
Β Β Β {"Sits",:bronz},
Β Β Β {"John",:bronz},
Β Β ]
Β Enum.each(users,fn {name,membership}->IO.puts("#{name} has a #{membership} membership")
Β end
Β )
Β end
enddefmodule Example do
Β use Application
Β def start(_type, _args) do
Β Β Example.main()
Β Β Supervisor.start_link([], strategy: :one_for_one)
Β end
Β def main do
Β Β # :apple type str is called adem
Β Β prices=%{
Β Β Β gold: 25,
Β Β Β silver: 20,
Β Β Β bronze: 25,
Β Β Β none: 0,
Β Β }
Β Β memberships=%{
Β Β Β gold: :gold ,
Β Β Β silver: :silver,
Β Β Β bronze: :bronze,
Β Β Β none: :none
Β Β }
Β Β users=[
Β Β Β {"Saugat",memberships.gold},
Β Β Β {"Hari",memberships.silver},
Β Β Β {"Sits",memberships.bronze},
Β Β Β {"John",memberships.bronze},
Β Β ]
Β Enum.each(users,fn {name,membership}->IO.puts("#{name} has a #{membership} membership which price is #{prices[membership]}")
Β end
Β )
Β end
enddefmodule Membership do
Β defstruct [:type, :price]
end
defmodule User do
Β defstruct [:name, :membership]
end
defmodule Example do
Β use Application
Β def start(_type, _args) do
Β Β Example.main()
Β Β Supervisor.start_link([], strategy: :one_for_one)
Β end
Β def main do
Β Β # :apple type str is called adem
Β Β gold_membership = %Membership{type: :gold, price: 25}
Β Β silver_membership = %Membership{type: :silver, price: 20}
Β Β bronze_membership = %Membership{type: :bronze, price: 15}
Β Β none_membership = %Membership{type: :none, price: 0}
Β Β users = [
Β Β Β %User{name: "Saugat", membership: gold_membership},
Β Β Β %User{name: "Hari", membership: silver_membership},
Β Β Β %User{name: "Sits", membership: bronze_membership},
Β Β Β %User{name: "John", membership: none_membership}
Β Β ]
Β Β Enum.each(users, fn %User{name: name,membership: membership} ->
Β Β Β IO.puts("#{name} has a #{membership.type} membership which price is #{membership.price}")
Β Β end)
Β end
enddefmodule Example do
Β use Application
Β def start(_type, _args) do
Β Β Example.main()
Β Β Supervisor.start_link([], strategy: :one_for_one)
Β end
Β def main do
Β Β correct=:rand.uniform(11)-1
Β Β guess=IO.gets("Guess a number between 0 & 10: ") |> String.trim() ##method chaining
Β Β if String.to_integer(guess)==correct do
Β Β Β IO.puts("You won")
Β Β else
Β Β Β IO.puts("You lost")
Β Β end
Β Β IO.puts("You guess #{guess} , correct was #{correct}")
Β end
enddefmodule Example do
Β use Application
Β def start(_type, _args) do
Β Β Example.main()
Β Β Supervisor.start_link([], strategy: :one_for_one)
Β end
Β def main do
Β Β correct=:rand.uniform(11)-1
Β Β guess=IO.gets("Guess a number between 0 & 10: ") |> String.trim() |> Integer.parse() ##method chaining
Β Β IO.inspect(guess)
Β Β case guess do
Β Β Β {result, ""}->IO.puts("parse sucessful #{result}")
Β Β Β {result,other}->IO.puts("parse partially sucessful #{result} and #{other}")
Β Β :error->IO.puts("Something went wrong !")
Β Β end
Β end
enddefmodule Example do
Β use Application
Β def start(_type, _args) do
Β Β Example.main()
Β Β Supervisor.start_link([], strategy: :one_for_one)
Β end
Β def main do
Β Β correct=:rand.uniform(11)-1
Β Β guess=IO.gets("Guess a number between 0 & 10: ") |> String.trim() |> Integer.parse() ##method chaining
Β Β IO.inspect(guess)
Β Β case guess do
Β Β Β {result, _}->
Β Β Β IO.puts("parse sucessful #{result}")
Β Β Β if result===correct do
Β Β Β Β IO.puts("You won")
Β Β Β else
Β Β Β Β IO.puts("You lose the correct ans is : #{correct}")
Β Β Β end
Β Β :error->IO.puts("The correct !")
Β Β end
Β end
enddefmodule Example do
Β require Integer
Β use Application
Β def start(_type, _args) do
Β Β Example.main()
Β Β Supervisor.start_link([], strategy: :one_for_one)
Β end
Β def main do
Β Β grades=[25,50,75,100]
Β Β for n <- grades do
Β Β Β Β IO.puts(n)
Β Β end
Β Β grades=[25,50,75,100]
Β Β new= for n <- grades,do: n+5
Β Β new=new ++ [125]
Β Β new=new ++ [150,175]
Β Β IO.inspect(new)
Β Β final=[5|new]
Β Β IO.inspect(final)
Β Β even=for n <- final,rem(n,2)==0, do: n
Β Β # even=for n <- final,Integer.is_even(n)==0, do: n
Β Β IO.inspect(even)
Β end
enddefmodule Example do
Β require Integer
Β use Application
Β def start(_type, _args) do
Β Β Example.main()
Β Β Supervisor.start_link([], strategy: :one_for_one)
Β end
Β # function that takes numbers then return sum and average
Β def sum_and_average(numbers) do
Β Β sum=Enum.sum(numbers)
Β Β average=sum/Enum.count(numbers)
Β Β {sum,average}
Β end
Β @spec print_numbers(any()) :: none()
Β def print_numbers(numbers) do
Β Β numbers |> Enum.join(" ") |> IO.puts()
Β end
Β def get_numbers_from_user do
Β Β IO.puts("Enter number seperated by spaces:> ")
Β Β user_input=IO.gets("") |>String.trim()
Β Β String.split(user_input," ")|>Enum.map(&String.to_integer/1)
Β end
Β def main do
Β user_given_numbers=get_numbers_from_user()
Β IO.inspect(sum_and_average(user_given_numbers))
Β {sum,average}=sum_and_average(user_given_numbers)
Β IO.puts("The sum is #{sum} and the average is #{average}")
Β Β numbers =[1,2,3,4,5,6]
Β Β #ananomus function
Β Β Enum.each(numbers,fn num->IO.puts(num) end)
Β Β numbers =["1","2","3","4","5","6"]
Β # Β passing function as argument with &
Β Β result=Enum.map(numbers,&String.to_integer/1)
Β Β IO.inspect(sum_and_average(result))
Β end
endPhoenix is a web framework built on Elixir, designed for high performance, scalability, and maintainability. It is particularly well-suited for real-time applications and APIs. If you're coming from frameworks like Django, Express, or Rails, this guide will help you get started with Phoenix.
Hex is the package manager for the Elixir ecosystem, similar to npm for Node.js or pip for Python. It is used to manage dependencies in your Phoenix project.
mix local.hex- What it does: Installs or updates Hex locally.
- Where it stores Hex:
~/.mix/archives/
The Phoenix project generator (phx_new) scaffolds a new Phoenix project with all the necessary files and dependencies.
mix archive.install hex phx_new- What it does: Installs the
phx_newarchive, which is used to generate new Phoenix projects. - Versioning: The latest version (e.g.,
1.7.21) is stored as an.ezarchive.
This command creates a new Phoenix project with a specified name and database backend.
mix phx.new forum --database sqlite3-
What it does:
- Creates a new app named
forum. - Sets up the project structure.
- Installs dependencies.
- Configures SQLite3 as the database backend (you can also use PostgreSQL or MySQL).
- Creates a new app named
-
Key Flags:
--database sqlite3: Specifies the database adapter. Replacesqlite3withpostgresormysqlif needed.
cd forum- Why?: Phoenix commands like
mix phx.serverandmix ecto.createmust be run from within the project folder to access themix.exsfile and configuration files.
mix ecto.create-
What it does:
- Compiles the project (if not already compiled).
- Creates the database using Ecto, Phoenix's database wrapper and query generator.
-
Ecto: Think of Ecto as the ORM (like Django ORM or Sequelize). It handles database migrations, queries, and schema definitions.
mix phx.server-
What it does:
- Starts the Phoenix web server (default:
http://localhost:4000). - Watches for code changes and recompiles automatically.
- Starts the Phoenix web server (default:
-
Default Web Server: Phoenix uses the Cowboy web server, which is highly performant and lightweight.
iex -S mix phx.server- What it does:
- Starts the Phoenix server with the interactive Elixir shell (IEx).
- Useful for debugging, testing database queries, and exploring the application state.
If you see a warning like:
βPhoenix is unable to create symlinks...β
Fix:
- Run your terminal as Administrator at least once.
- Phoenix will then be able to create symlinks for faster reloads.
Phoenix organizes its files in a way that promotes separation of concerns. Here's how it compares to Django and Express:
| Path | Phoenix Purpose | Django Equivalent | Express Equivalent |
|---|---|---|---|
mix.exs |
Project config (like package.json) |
settings.py, pyproject.toml |
package.json |
config/ |
App and database configs | settings.py, env.py |
.env, config files |
lib/ |
Main application code | Django project/ folder |
src/ or main app folder |
test/ |
Unit tests (ExUnit) | tests/ |
test/, __tests__/ |
.formatter.exs |
Elixir code formatting | pyproject.toml (Black) |
.prettierrc, .eslintrc |
assets/ |
JavaScript/CSS (frontend assets) | static/, templates/ |
public/, views/ |
| Path | Phoenix Purpose | Django Equivalent | Express Equivalent |
|---|---|---|---|
forum.ex |
Main app entrypoint | __init__.py |
index.js, app.js |
forum/application.ex |
Supervision tree / app lifecycle | Not applicable | App setup in app.js |
forum_web/ |
Web layer: routes, controllers, templates | Views, URLs, templates | Routes & views |
| Path | Phoenix Purpose | Django Equivalent | Express Equivalent |
|---|---|---|---|
controllers/ |
Request logic handlers | views.py |
Route handler functions |
views/ |
Rendering logic (separate from controllers) | Context processors | Templating logic (optional) |
templates/ |
EEx templates (HTML) | templates/ |
EJS/Pug templates |
router.ex |
Route definitions | urls.py |
app.get(), app.post() |
endpoint.ex |
Entry point for HTTP requests (Bandit/Cowboy) | WSGI application | Express app (app) |
| Path | Phoenix Purpose | Django Equivalent | Express Equivalent |
|---|---|---|---|
priv/repo/migrations/ |
Ecto migration files | migrations/ |
Sequelize/Mongoose files |
lib/forum/repo.ex |
Ecto Repo for DB operations | Django ORM | Mongoose/Sequelize |
schema files (*.ex) |
Define database schema + changesets | models.py |
Models in Mongoose/ORM |
| Path | Phoenix Purpose | Django Equivalent | Express Equivalent |
|---|---|---|---|
assets/js/ |
JavaScript (esbuild or webpack) | Static JS in static/ |
public/ or views/ |
assets/css/ |
CSS stylesheets | Static CSS in static/ |
Same |
assets/ |
Overall frontend pipeline | Django static/ + templates/ |
public/ or static files |
| Task | Phoenix | Django | Express |
|---|---|---|---|
| Generate project | mix phx.new app_name |
django-admin startproject |
express-generator (optional) |
| Run dev server | mix phx.server |
python manage.py runserver |
node app.js or nodemon |
| Migrate DB | mix ecto.migrate |
python manage.py migrate |
ORM-dependent |
| Create migration | mix ecto.gen.migration |
python manage.py makemigrations |
ORM-dependent |
| Create model/schema | mix phx.gen.schema |
Django models | ORM-dependent |
| Concept | Phoenix | Django | Express |
|---|---|---|---|
| Project Config | mix.exs |
settings.py |
package.json |
| Routing | router.ex |
urls.py |
app.get() etc. |
| Controllers | controllers/ |
views.py |
Route handlers |
| Templates | templates/ |
templates/ |
EJS/Pug views |
| ORM/Models | schema + changeset |
Django Models | Mongoose/Sequelize |
| DB Migrations | ecto.migrations |
Django migrations | ORM-based tools |
| Frontend | assets/ |
static/ |
public/ |
Phoenix provides a powerful generator for creating JSON APIs. This is particularly useful for API-first applications or when building a backend for a frontend framework like React or Vue.
mix phx.gen.json Posts Post posts body:string title:string| Part | Description |
|---|---|
mix phx.gen.json |
Generates a JSON-only resource (no HTML views/templates). |
Posts (Context) |
A module grouping logic (e.g., Forum.Posts). |
Post (Schema) |
The database model (e.g., Posts.Post). |
posts (DB Table) |
Table name used in the DB (plural of schema). |
body:string |
Adds :body field (type :string). |
title:string |
Adds :title field (type :string). |
| File | Purpose |
|---|---|
lib/forum/posts/post.ex |
Defines the Post Ecto schema. |
lib/forum/posts.ex |
CRUD functions (context): list_posts/0, create_post/1, etc. |
| File | Purpose |
|---|---|
priv/repo/migrations/*_create_posts.exs |
Migration to create the posts table. |
| File | Purpose |
|---|---|
lib/forum_web/controllers/post_controller.ex |
Handles API endpoints. |
lib/forum_web/views/post_json.ex |
Formats JSON responses. |
Adds:
scope "/api", ForumWeb do
pipe_through :api
resources "/posts", PostController, except: [:new, :edit]
endmix ecto.migratemix phx.server| Method | Route | Action |
|---|---|---|
| GET | /api/posts |
List posts |
| GET | /api/posts/:id |
Show post |
| POST | /api/posts |
Create post |
| PUT | /api/posts/:id |
Update post |
| DELETE | /api/posts/:id |
Delete post |
Phoenix is a powerful framework for building scalable, maintainable web applications. It provides a clean separation of concerns with contexts, schemas, and controllers. The mix tool simplifies common tasks like generating code, running migrations, and starting the server. Phoenix is ideal for API-first applications or real-time features using WebSockets.
mix phx.gen.json Accounts User users name:string email:string:unique| Part | Description |
|---|---|
mix phx.gen.json |
Generates a JSON-only resource (no HTML views/templates). |
Accounts (Context) |
The context module that groups related logic (e.g., Forum.Accounts). |
User (Schema) |
The schema module for User (e.g., Accounts.User). |
users (DB Table) |
The name of the table in the database (e.g., users). |
name:string |
Adds a name field (type string). |
email:string:unique |
Adds an email field (type string) with a unique constraint to ensure no duplicate emails. |
| File | Purpose |
|---|---|
lib/forum/accounts/user.ex |
Defines the User schema with name and email fields. |
lib/forum/accounts.ex |
Context module for Accounts, containing functions for CRUD operations on users. |
| File | Purpose |
|---|---|
*_create_users.exs |
Migration to create the users table with name and email fields, and ensure the email field is unique. |
| File | Purpose |
|---|---|
lib/forum_web/controllers/user_controller.ex |
Handles API requests for users. |
lib/forum_web/views/user_json.ex |
Renders JSON responses for users. |
Adds the following route to handle user-related API requests:
scope "/api", ForumWeb do
pipe_through :api
resources "/users", UserController, except: [:new, :edit]
endEnsure your database is updated to reflect the changes:
mix ecto.migrateRun your server to start receiving requests:
mix phx.server| Method | Route | Action |
|---|---|---|
GET |
/api/users |
List users |
GET |
/api/users/:id |
Show user |
POST |
/api/users |
Create user |
PUT |
/api/users/:id |
Update user |
DELETE |
/api/users/:id |
Delete user |
| Phoenix JSON Generator | Django Equivalent | Express Equivalent |
|---|---|---|
mix phx.gen.json |
Django REST Framework (DRF) ViewSet | Express + Mongoose/Sequelize |
| Context | Django accounts/ app |
Folder/module for accounts |
| Schema | Django models.py for User |
Mongoose schema for User |
| Controller | DRF ViewSet for User |
Express route/controller |
| Migration | Django makemigrations + migrate |
Sequelize migration |
- The
mix phx.gen.jsoncommand simplifies the creation of JSON APIs in Phoenix. - It generates a clean separation of concerns with context, schema, controller, and view files.
- The generated API is ready to handle CRUD operations for the
Userresource. - Phoenix's
mixtool ensures a streamlined development process, from migrations to server setup.