COURSE ยท 7 LESSONS ยท 100% FREE
๐Ÿ’ง

Elixir Programming

Functional, concurrent, fault-tolerant. Built on the Erlang VM. Phoenix framework for web apps.

0Lessons
0Code Examples
ZeroPrerequisites
0%
You've completed 0 of 7 lessons
J/โ†“ Next
K/โ†‘ Prev
Esc Collapse
/ Search
Foundations
01

Hello World & Setup

IO.puts for output. String interpolation with #{}. Run: elixir file.exs

IO.puts "Hello, World!"

name = "Mayank"
age = 15
IO.puts "#{name} is #{age}"

# Run: elixir hello.exs
# Or: iex (interactive shell)
02

Variables & Types

Atoms (:ok), tuples {1,2}, lists [1,2], maps %{a: 1}. Pattern matching everywhere.

# Atoms (named constants)
status = :ok
direction = :north

# Tuples
point = {3, 4}
{:ok, data} = {:ok, "hello"}
IO.puts(data)

# Lists (linked)
languages = ["Elixir", "Erlang", "Ruby"]
[head | tail] = languages
IO.puts(head)   # Elixir
IO.puts(length(tail))  # 2

# Maps
person = %{name: "Mayank", age: 15}
IO.puts(person.name)

updated = Map.put(person, :email, "test@test.com")
IO.inspect(updated)

# Keyword lists
opts = [width: 100, height: 50]
IO.inspect(opts)
03

Pattern Matching & Guards

= is pattern match, not assignment. Guards add conditions to patterns.

# Pattern matching
def describe(x) when is_number(x) and x > 0, do: "positive number: #{x}"
def describe(x) when is_number(x) and x < 0, do: "negative number: #{x}"
def describe(x) when is_number(x), do: "zero"
def describe(s) when is_binary(s), do: "string: #{s}"
def describe(_), do: "unknown"

IO.puts(describe(42))
IO.puts(describe(-5))
IO.puts(describe(0))
IO.puts(describe("hi"))

# Case
result = {:ok, 42}
case result do
  {:ok, value} -> IO.puts("Got: #{value}")
  {:error, msg} -> IO.puts("Error: #{msg}")
end

# Pipe operator
"hello world" |> String.upcase() |> String.split() |> IO.inspect()
04

Functions & Modules

def/defp, defmodule. Anonymous functions with fn. Closures capture variables.

defmodule Math do
  def add(a, b), do: a + b
  defp secret(x), do: x * 2

  def factorial(0), do: 1
  def factorial(n) when n > 0, do: n * factorial(n - 1)
end

IO.puts(Math.add(3, 4))
IO.puts(Math.factorial(5))

# Anonymous functions
double = fn x -> x * 2 end
square = &(&1 * &1)  # shorthand

IO.puts(double.(5))
IO.puts(square.(4))

# Closures
defmodule Counter do
  def start(initial \ 0) do
    Agent.start_link(fn -> initial end, name: __MODULE__)
  end

  def increment do
    Agent.update(__MODULE__, &(&1 + 1))
  end

  def get do
    Agent.get(__MODULE__, & &1)
  end
end
Concurrency & OTP
05

Enum & Stream

100+ functions on collections. map, filter, reduce, sort, group_by. Stream for lazy.

nums = [5, 3, 1, 4, 2]

IO.inspect(Enum.sort(nums))
IO.inspect(Enum.reverse(nums))
IO.inspect(Enum.map(nums, &(&1 * 2)))
IO.inspect(Enum.filter(nums, &(&1 > 2)))
IO.inspect(Enum.reduce(nums, 0, &+/2))
IO.inspect(Enum.min(nums))
IO.inspect(Enum.max(nums))

# Chaining
result = nums
  |> Enum.filter(&(&1 > 2))
  |> Enum.map(&(&1 * 10))
  |> Enum.sort()
IO.inspect(result)  # [30, 40, 50]

# Group by
people = [
  %{name: "Alice", age: 20},
  %{name: "Bob", age: 12},
  %{name: "Charlie", age: 25},
]
grouped = Enum.group_by(people, fn p -> if p.age >= 18, do: :adult, else: :child end)
IO.inspect(grouped)

# Stream (lazy)
Stream.map(1..1_000_000, &(&1 * 2)) |> Enum.take(5) |> IO.inspect()
06

Process & Message Passing

spawn, send, receive. Processes don't share memory. Message passing is the only way.

# Spawning a process
pid = spawn(fn ->
  receive do
    {:hello, sender} -> send(sender, :world)
  end
end)

send(pid, {:hello, self()})

receive do
  :world -> IO.puts("Got response!")
end

# Agent (stateful process)
{:ok, agent} = Agent.start_link(fn -> [] end)
Agent.update(agent, fn state -> [1 | state] end)
Agent.update(agent, fn state -> [2 | state] end)
IO.inspect(Agent.get(agent, & &1))  # [2, 1]
Agent.stop(agent)

# GenServer
defmodule Counter do
  use GenServer

  def init(_), do: {:ok, 0}
  def handle_call(:get, _from, state), do: {:reply, state, state}
  def handle_cast(:inc, state), do: {:noreply, state + 1}
end

{:ok, pid} = Counter.start_link()
GenServer.cast(pid, :inc)
IO.puts(GenServer.call(pid, :get))  # 1
07

Phoenix Framework

Elixir's web framework. Routes, controllers, LiveView for real-time UIs.

# mix phx.new my_app
# cd my_app && mix ecto.create && mix phx.server

# router.ex
scope "/", MyAppWeb do
  pipe_through :browser
  get "/", PageController, :index
  resources "/users", UserController
end

# LiveView โ€” real-time without JS
defmodule MyAppWeb.CounterLive do
  use MyAppWeb, :live_view

  def mount(_params, _session, socket) do
    {:ok, assign(socket, count: 0)}
  end

  def render(assigns) do
    ~H"""
    <h1>Count: <%= @count %></h1>
    <button phx-click="inc">+1</button>
    """
  end

  def handle_event("inc", _params, socket) do
    {:noreply, update(socket, :count, &(&1 + 1))}
  end
end