SlideShare a Scribd company logo
Elixir in a nutshell
- Training sessions
Ben Khalfallah Héla
What will see during different sessions ?
2
Ecosystem
Fundamental
concepts
Rest API
1 2 3
Elixir in a nutshell
- Fundamental concepts
Today2
Roadmap
4
functional
programming
types, operators &
pattern matching
numbers & strings
modules & functions
alias, import, require,
use
naming conventions
case, cond and if
list, enum, stream
map (key/value)
try/rescue/after,
throw/catch, exit
tuple
structs
5
Source
Code
https://github.com/helabenkhalfallah/elixir_in_nutshell
https://medium.com/@helabenkhalfallah/elixir-in-a-nutshell-6655f1851520
1. functional programming
7
SHORT & DECLARATIVE
Like mathematical function :
● short formula.
● what to do more than how to
do.
SINGLE RESPONSIBILITY
● Function should do only one
thing.
● Each function should acts
like an independent
Microservice.
PURE & IMMUTABLE
● Function must depends only
on its parameters.
● For the same inputs, function
should always keep the same
output.
● Function shouldn’t affect its
input.
● Data transformation rather
than mutation.
● Without side effects.
COMPOSE, CHAIN, PIPE
Breaking a complex problem down
to smaller parts, and then
composing those smaller solutions
together to form the application.
[1,2,3]
|> mutiply_elements(2)
|> sort_elements()
WHY
functional
programming ?
Easy to test
& to debug
Predictable
Parallelisation,
memoization,
lazy evaluation
Distribution,
scalability
8
Functional
programming benefits
2. naming conventions
files extensions
10
.ex
.exs
elixir file
elixir scripts file
file name
11
snake_case
module name
12
UpperCamelCase
function name
13
snake_case
variable name
14
snake_case
atoms name
15
snake_case or UpperCamelCase
:true, :is_connected?, :debit_type_card
underscore _foo
16
{:error, _changeset} ->
{
200,
ServiceUtils.endpoint_error("exception")
}
unused variable
def _complex_operation(a,
b) do
sum_numbers(a, b)
|> mul_numbers(2)
|> sub_numbers(1)
|> div_numbers(2)
end
underscore _foo
17
function never imported by default
** (UndefinedFunctionError) function
ModulesFunctions.complex_operation/2 is undefined or private.
trailing bang foo!
18
function or macro where failure
cases raise an exception
trailing bang foo!
19
function or macro where failure
cases raise an exception
https://hexdocs.pm/elixir/Enum.html#fetch!/2
trailing bang foo!
20
function or macro where failure
cases raise an exception
trailing question mark foo?
21
functions that return a boolean
are named with “?”
https://hexdocs.pm/elixir/Enum.html#empty?/1
trailing question mark foo?
22
functions that return a boolean
are named with “?”
https://hexdocs.pm/elixir/Enum.html#member?/2
trailing question mark foo?
23
functions that return a boolean
are named with “?”
https://hexdocs.pm/elixir/Enum.html#all?/2
prefix is_
24
type checks are named with an
“is_” prefix
prefix is_
25
type checks are named with an
“is_” prefix
prefix is_
26
type checks are named with an
“is_” prefix
more details
27
https://hexdocs.pm/elixir/master/naming-conventions.html#content
To console log
IO.puts "Starting Application..."
IO.puts('area : #{area}')
https://hexdocs.pm/elixir/IO.html
3. types, operators &
pattern matching
basic types
30
:hello # atom
# numbers
3 # integer
0x1F # integer
3.0 # float
{1,2,3} # tuple
[1,2,3] # (Linked) Lists
<<1,2,3>> # binary
"hello" # string
'hello' # char list
# Multi-line strings
"""
I'm a multi-line
string.
"""
# Maps are key-value pairs
genders = %{"david" => "male", "gillian" => "female"}
genders["david"] #=> "male"
type checks
31
is_atom/1
is_bitstring/1
is_boolean/1
is_function/1
is_function/2
is_integer/1
is_float/1
is_binary/1
is_list/1
is_map/1
is_tuple/1
is_nil/1
is_number/1
is_pid/1
is_port/1
is_reference/1
https://hexdocs.pm/elixir/Kernel.html#is_atom/1
pipe operators
32
source
|> transform(:hello)
|> print()
# Same as:
print(transform(source, :hello))
Result are piped between functions
pipe operators
33
list |> at(0) # → :a
list |> count() # → 3
list |> empty?() # → false
list |> any?() # → true
n |> digits() # → [1, 2]
n |> to_charlist() # → '12'
n |> to_string() # → "12"
n |> is_even()
n |> is_odd()
str = "hello"
str |> length() # → 5
str |> codepoints() # → ["h", "e", "l", "l", "o"]
str |> slice(2..-1) # → "llo"
str |> split(" ") # → ["hello"]
str |> capitalize() # → "Hello"
str |> match(regex)
Transformation + Immutable
basic operators
34
1 + 1 #=> 2
10 - 5 #=> 5
5 * 2 #=> 10
10 / 2 #=> 5.0 => always float
# To do integer division use `div`
div(10, 2) #=> 5
# To get the division remainder use
`rem`
rem(10, 3) #=> 1
basic operators
35
# boolean operators: `or`, `and` and `not`.
# These operators expect a boolean as their first argument.
true and true #=> true
false or true #=> true
# 1 and true
#=> ** (BadBooleanError) expected a boolean on left-side of "and",
got: 1
basic operators
36
# All values except `false` and `nil` will evaluate to true.
1 || true #=> 1
false && 1 #=> false
nil && 20 #=> nil
!true #=> false
basic operators
37
# Comparisons:`==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` and `>`
1 == 1 #=> true
1 != 1 #=> false
1 < 2 #=> true
basic operators
38
# `===` and `!==` are more strict when comparing integers
and floats:
1 == 1.0 #=> true
1 === 1.0 #=> false
pattern matching
39
# Tuples
iex> {:ok, value} = {:ok, "Successful!"}
{:ok, "Successful!"}
iex> value
"Successful!"
iex> {:ok, value} = {:error}
** (MatchError) no match of right hand side value:
{:error}
like JS destructuring
pattern matching
40
iex> {a, b, c} = {:hello, "world", 42}
{:hello, "world", 42}
iex> a
:hello
iex> b
"world"
like JS destructuring
user = %{name: "Tom", age: 23}
%{name: username} = user
pattern matching
41
iex> {a, b, c} = {:hello, "world"}
** (MatchError) no match of right hand side value: {:hello, "world"}
iex> {a, b, c} = [:hello, "world", 42]
** (MatchError) no match of right hand side value: [:hello, "world", 42]
iex> {:ok, result} = {:ok, 13}
{:ok, 13}
iex> result
13
iex> {:ok, result} = {:error, :oops}
** (MatchError) no match of right hand side value: {:error, :oops}
iex> [head | tail] = []
** (MatchError) no match of right hand side value:
[]
pattern matching
42
def greet(%{name: username}) do
IO.puts "Hello, " <> username
end
user = %{name: "Tom", age: 23}
greet(user)
pattern matching in functions
4. numbers
numbers operations
44
abs(n)
round(n)
rem(a, b) # remainder (modulo)
div(a, b) # integer division
integer operations
45
import Integer
n = 12
n |> digits() # → [1, 2]
n |> to_charlist() # → '12'
n |> to_string() # → "12"
n |> is_even()
n |> is_odd()
# Different base:
n |> digits(2) # → [1, 1, 0, 0]
n |> to_charlist(2) # → '1100'
n |> to_string(2) # → "1100"
parse("12") # → {12, ""}
undigits([1, 2]) # → 12
https://hexdocs.pm/elixir/Integer.html#content
float operations
46
import Float
n = 10.3
n |> ceil() # → 11.0
n |> ceil(2) # → 11.30
n |> to_string() # → "1.030000+e01"
n |> to_string([decimals: 2, compact: true])
Float.parse("34") # → { 34.0, "" }
https://hexdocs.pm/elixir/Float.html#content
type casting
47
Float.parse("34.1") # → {34.1, ""}
Integer.parse("34") # → {34, ""}
Float.to_string(34.1) # → "3.4100e+01"
Float.to_string(34.1, [decimals: 2, compact: true]) # → "34.1"
5. strings
string operations
49
import String
str = "hello"
str |> length() # → 5
str |> codepoints() # → ["h", "e", "l", "l", "o"]
str |> slice(2..-1) # → "llo"
str |> split(" ") # → ["hello"]
str |> capitalize() # → "Hello"
str |> match(regex)
https://hexdocs.pm/elixir/String.html
6. list, enum, stream
list definition
51
list = [3.14, :pie, "Apple"]
list concatenation
52
iex> [1, 2] ++ [3, 4, 1]
[1, 2, 3, 4, 1]
list prepending
53
iex> list = [3.14, :pie, "Apple"]
[3.14, :pie, "Apple"]
iex> ["π" | list]
["π", 3.14, :pie, "Apple"]
list performance
54
Elixir implements list collections
as linked lists
accessing list length is (O(n))
prepend is faster than append
list performance
55
iex> list = [3.14, :pie, "Apple"]
[3.14, :pie, "Apple"]
# Prepending (fast)
iex> ["π" | list]
["π", 3.14, :pie, "Apple"]
# Appending (slow)
iex> list ++ ["Cherry"]
[3.14, :pie, "Apple", "Cherry"]
list subtraction
56
iex> ["foo", :bar, 42] -- [42, "zoo"]
["foo", :bar]
iex> [2] -- [2.0]
[2]
iex> [2.0] -- [2.0]
[]
safe to subtract a missing value ‘zoo’
strict comparison
list head/tail
57
iex> [head | tail] = [3.14, :pie, "Apple"]
[3.14, :pie, "Apple"]
iex> head
3.14
iex> tail
[:pie, "Apple"]
pattern matching
list head/tail
58
iex> hd [3.14, :pie, "Apple"]
3.14
iex> tl [3.14, :pie, "Apple"]
[:pie, "Apple"]
list operations
59https://hexdocs.pm/elixir/List.html#functions
list operations
60https://hexdocs.pm/elixir/List.html#functions
list operations
61https://hexdocs.pm/elixir/List.html#functions
keyword list
62
list = [{:a, 1}, {:b, 2}]
● The keys must be atoms
● The key/value pairs have an order
● Keys can be used more than once
keyword lists are most commonly used to pass options to functions.
keyword list
63
keyword lists are most commonly used to pass options to functions.
String.split("Elixir", "")
# ["", "E", "l", "i", "x", "i", "r", ""]
String.split("Elixir", "", [trim: true])
# ["E", "l", "i", "x", "i", "r"]
remove odd ""
keyword list - reading
64
list = [{:a, 1}, {:b, 2}]
list[:a] # 1
Keyword.get([a: 1, b: 2 ], :b)
# 2
OR
keyword list - add or replace
65
Keyword.put([a: 1, b: 2], :c, 3)
# [c: 3, a: 1, b: 2]
Keyword.put([a: 1, b: 2], :b, 5)
# [b: 5, a: 1]
https://hexdocs.pm/elixir/Keyword.html#content
keyword list - pattern matching
66
[a: a, b: b] = [a: 1, b: 2]
# a is 1 and b is 2
[b: b, a: a] = [a: 1, b: 2]
# MatchError (the order doesn't match)
[a: a] = [a: 1, b: 2]
# MatchError (the size doesn't match)
list & enum
67https://hexdocs.pm/elixir/Enum.html
Enum module provides a huge range of functions to
transform, sort, group, filter and retrieve items from
enumerables.
Enum functions are limited to enumerating values in
data structures.
For specific operations, like inserting and updating
particular elements, you may need to reach for modules
specific to the data type (List.insert_at/3).
list & enum
68https://hexdocs.pm/elixir/Enum.html
list & enum
69https://hexdocs.pm/elixir/Enum.html
list & enum
70https://hexdocs.pm/elixir/Enum.html
list & enum
71https://hexdocs.pm/elixir/Enum.html
list & stream
72
1..3
|> Enum.map(fn x -> IO.inspect(x) end)
|> Enum.map(fn x -> x * 2 end)
|> Enum.map(fn x -> IO.inspect(x) end)
1
2
3
2
4
6
#=> [2,4,6]
first enum
last enum after (x * 2)
Each enum should complete before piping
result to next enum
list & stream
73
1..3
|> Enum.map(fn x -> IO.inspect(x) end)
|> Enum.map(fn x -> x * 2 end)
|> Enum.map(fn x -> IO.inspect(x) end)
1
2
3
2
4
6
#=> [2,4,6]
This is a problem if we have too much data
(database), we must wait to all enum finish.
first enum
last enum after (x * 2)
Each enum should complete before piping
result to next enum
list & stream
74
stream =(
1..3
|> Stream.map(&IO.inspect(&1))
|> Stream.map(&(&1 * 2))
|> Stream.map(&IO.inspect(&1)))
Enum.to_list(stream)
1
2
2
4
3
6
#=> [2,4,6]
Each number is completely evaluated
before moving to the next number in the
enumeration !
list & stream
75
Streams are lazy, composable enumerables.
Streams are useful when working with large, possibly infinite, collections.
https://hexdocs.pm/elixir/Stream.html
7. tuple
review list performance
77
Lists are represented internally as linked lists.
They have the following characteristics:
● They support adding/removing elements.
● Memory usage scales with the list size. The more elements the list has,
the more memory it requires.
● Fetching elements may sometimes be slow (O(n)).
To add a new element, a new memory slot is reserved anywhere where free
memory is available, and then a reference to it is added to the previous last
element.
https://blog.appsignal.com/2018/08/21/elixir-alchemy-list-vs-tuples.html
tuple definition
78
list = [1, 2, true, 3]
tuple = {1, 2, true, 3}
tuple definition
79
Tuples are like a statically-sized arrays :
● They are meant to hold a fixed number of elements.
● As a result of the previous point, memory usage is also static, and allocated
upfront.
● The data structure does not support addition/removal of elements.
● Any change requires recreating an entirely new version of the structure.
Memory usage is a lot more predictable.
https://blog.appsignal.com/2018/08/21/elixir-alchemy-list-vs-tuples.html
tuple usage
80
It is common for tuples to be used as a mechanism to return additional
information from functions; the usefulness of this will be more apparent when
we get into pattern matching :
iex> File.read("path/to/existing/file")
{:ok, "... contents ..."}
iex> File.read("path/to/unknown/file")
{:error, :enoent}
https://elixir-lang.org/getting-started/basic-types.html#lists-or-tuples
tuple operations
81https://hexdocs.pm/elixir/Tuple.html#functions
8. map (key/value)
map definition
83
maps are the key-value store
iex> map = %{"foo" => "bar", "hello" => "world"}
%{"foo" => "bar", "hello" => "world"}
iex> map["foo"]
"bar"
iex> map["hello"]
"world"
map atom as key
84
iex> %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex> %{foo: "bar", hello: "world"} == %{:foo => "bar", :hello => "world"}
true
iex> map.hello
"world"
m = %{name: "hi"} # atom keys (:name)
m = %{"name" => "hi"} # string keys ("name")
map variable as key
85
iex> key = "hello"
"hello"
iex> %{key => "world"}
%{"hello" => "world"}
map like js spread
86
iex> map = %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex> map_copy = %{map | foo: "baz"}
%{foo: "baz", hello: "world"}
map operations
87
https://hexdocs.pm/elixir/Map.html#functions
https://devhints.io/elixir#map
9. modules & functions
module & functions definition
89
defmodule ModulesFunctions do
# This is module documentation @moduledoc
# for a single line you can use ""
# for multiple lines use """ """
@moduledoc """
Inside ModuleFunctions we handle module & functions features.
"""
@moduledoc since: "1.0.0"
# defining a constant
@pi 3.14159
@doc "Sum two numbers (multiline function)"
@spec sum_numbers(integer, integer) :: integer
def sum_numbers(a, b) do
a + b
end
end
module documentation
constants definitions
function doc
typespecs
function definition
comments
last expression is the return value (return is implicit)
10. structs
structs definition
91
defmodule User do
defstruct name: "John", age: 27
end
iex> %User{}
%User{age: 27, name: "John"}
iex> %User{name: "Jane"}
%User{age: 27, name: "Jane"
return default values
override name default
value
iex> %User{oops: :field}
** (KeyError) key :oops not found in: %User{age: 27, name: "John"}
structs access & update
92
iex> john = %User{}
%User{age: 27, name: "John"}
iex> john.name
"John"
iex> jane = %{john | name: "Jane"}
%User{age: 27, name: "Jane"}
iex> %{jane | oops: :field}
** (KeyError) key :oops not found in: %User{age: 27, name: "Jane"}
structs pattern matching
93
iex> %User{name: name} = john
%User{age: 27, name: "John"}
iex> name
"John"
iex> %User{} = %{}
** (MatchError) no match of right hand side value: %{}
11. alias, import, require,
use
alias, import, require, use
95
# Alias the module so it can be called as Bar instead of Foo.Bar
alias Foo.Bar, as: Bar
# Require the module in order to use its macros
require Foo
# Import functions from Foo so they can be called without the
`Foo.` prefix
import Foo
# Invokes the custom code defined in Foo as an extension point
use Foo
https://elixir-lang.org/getting-started/alias-require-and-import.html
12. case, cond and if
if
97
if condition do
...
else
...
end
if condition, do: something, else: another_thing
def max(a, b) do
if a >= b, do: a, else: b
end
iex> if String.valid?("Hello") do
...> "Valid string!"
...> else
...> "Invalid string."
...> end
"Valid string!"
iex> if "a string value" do
...> "Truthy"
...> end
"Truthy"
cond
98
cond do
expression_1 ->
...
expression_2 ->
...
...
end
def max(a, b) do
cond do
a >= b -> a
true -> b
end
end
cond will raise an error if there is no
match. To handle this, we should
define a condition set to true..
defmodule Greeter do
def greet(lang) do
cond do
lang == "en" ->
"Hello"
lang == "fr" ->
"Bonjour"
lang == "es" ->
"Hola"
true ->
"We don't have a greeting for that."
end
end
cond
99
def endpoint_error(error_type) do
Poison.encode!(%{
"status" => 200,
"fail_reason" =>
cond do
error_type == 'empty' -> "Empty Data"
error_type == 'not_found' -> "Not found"
error_type == 'missing_email' -> "Missing email"
error_type == 'missing_username' -> "Missing username"
error_type == 'missing_prams' -> "Missing query params"
true -> "An expected error was occurred"
end
})
end
case
100
case expression do
pattern_1 ->
...
pattern_2 ->
...
...
end
def max(a,b) do
case a >= b do
true -> a
false -> b
end
end
defmodule Greeter do
def greet(lang) do
case lang do
"eng" -> "Hello"
"fr" -> "Bonjour"
"es" -> "Hola"
_ -> "We don't have a greeting for that."
end
end
end
If none of the clauses match, an
error is raised.
case
101
case UserWriter.add_user(user_to_add) do
{:ok, user} ->
{
200,
ServiceUtils.endpoint_success(user)
}
{:error, _changeset} ->
{
200,
ServiceUtils.endpoint_error("exception")
}
end
case
102
# Get user by email
post "/user-by-email" do
case conn.body_params do
%{"email" => email} ->
conn
|> put_resp_content_type("application/json")
|> send_resp(
200,
ServiceUtils.endpoint_success(UserReader.user_by_email(email))
)
_ ->
conn
|> put_resp_content_type("application/json")
|> send_resp(200, ServiceUtils.endpoint_error("missing_email"))
end
end
13.
try/rescue/after,
throw/catch, exit
try/rescue/after
104
try do
opts
|> Keyword.fetch!(:source_file)
|> File.read!()
rescue
e in KeyError -> IO.puts("missing :source_file option")
e in File.Error -> IO.puts("unable to read source file")
after
IO.puts "The end!"
end
try
catch exception
finally
throw/catch
105
iex> try do
...> for x <- 0..10 do
...> if x == 5, do: throw(x)
...> IO.puts(x)
...> end
...> catch
...> x -> "Caught: #{x}"
...> end
0
1
2
3
4
"Caught: 5"
The throw function gives us the ability to exit execution
with a specific value we can catch and use.
new exception
106
defmodule ExampleError do
defexception message: "an example error has occurred"
end
iex> try do
...> raise ExampleError
...> rescue
...> e in ExampleError -> e
...> end
%ExampleError{message: "an example error has occurred" }
exit
107
iex> spawn_link fn -> exit("oh no") end
** (EXIT from #PID<0.101.0>) evaluator process exited with reason: "oh no"
iex> try do
...> exit "oh no!"
...> catch
...> :exit, _ -> "exit blocked"
...> end
"exit blocked"
https://github.com/helabenkhalfallah | https://medium.com/@helabenkhalfallah | @b_k_hela
Thanks !
See you in
next session !
Elixir in a nutshell - Restful API

More Related Content

PPTX
Redux training
PDF
Why Use React Js A Complete Guide (1).pdf
PDF
Clean architecture
PDF
Avoiding the domino effect in our [micro]services (SOLID at macro-design level)
PPTX
ABI란 무엇인가요?
PDF
Elixir talk
PDF
Elixir cheatsheet
Redux training
Why Use React Js A Complete Guide (1).pdf
Clean architecture
Avoiding the domino effect in our [micro]services (SOLID at macro-design level)
ABI란 무엇인가요?
Elixir talk
Elixir cheatsheet

Similar to Elixir in a nutshell - Fundamental Concepts (20)

ODP
Elixir basics
PPTX
PDF
Elixir and OTP Apps introduction
PDF
Introduction to Elixir
PDF
Introducción a Elixir
PDF
Programming Elixir 13 Functional Concurrent Pragmatic Fun Dave Thomas
PDF
What is the deal with Elixir?
PDF
Introduction to Elixir and Phoenix.pdf
PDF
Introduction to Elixir
PDF
Learn Elixir at Manchester Lambda Lounge
PDF
Learning Elixir as a Rubyist
PDF
Programming Elixir Functional Concurrent Pragmatic Fun 1st Edition Dave Thomas
PDF
Introducing Elixir Getting Started In Functional Programming 2nd Edition Simo...
PDF
Ruby Language - A quick tour
PPTX
Introducing Elixir
PDF
Elixir and Phoenix for Rubyists
PPTX
Getting functional with elixir
PDF
Elixir for aspiring Erlang developers
PDF
EMPEX LA 2018 - Inclusion Starts with Docs
PDF
Elixir: the not-so-hidden path to Erlang
Elixir basics
Elixir and OTP Apps introduction
Introduction to Elixir
Introducción a Elixir
Programming Elixir 13 Functional Concurrent Pragmatic Fun Dave Thomas
What is the deal with Elixir?
Introduction to Elixir and Phoenix.pdf
Introduction to Elixir
Learn Elixir at Manchester Lambda Lounge
Learning Elixir as a Rubyist
Programming Elixir Functional Concurrent Pragmatic Fun 1st Edition Dave Thomas
Introducing Elixir Getting Started In Functional Programming 2nd Edition Simo...
Ruby Language - A quick tour
Introducing Elixir
Elixir and Phoenix for Rubyists
Getting functional with elixir
Elixir for aspiring Erlang developers
EMPEX LA 2018 - Inclusion Starts with Docs
Elixir: the not-so-hidden path to Erlang
Ad

More from Héla Ben Khalfallah (12)

PDF
DATABASE_DATA_STRUCTURE_DEVOXXFRANCE2024.pdf
PDF
CSS selectors
PDF
PDF
Elixir in a nutshell - Ecosystem (session 1)
PDF
FP Using ES6+ (Cheat Sheet)
PDF
PDF
Process & Methodologies (1.2)
PDF
Process & Methodologies (1.1)
PDF
Process & Methodologies (1.0)
PDF
La gestion en boucle fermée
PDF
Les règles de développement Angular
PDF
Architecture ASIS (iOS)
DATABASE_DATA_STRUCTURE_DEVOXXFRANCE2024.pdf
CSS selectors
Elixir in a nutshell - Ecosystem (session 1)
FP Using ES6+ (Cheat Sheet)
Process & Methodologies (1.2)
Process & Methodologies (1.1)
Process & Methodologies (1.0)
La gestion en boucle fermée
Les règles de développement Angular
Architecture ASIS (iOS)
Ad

Recently uploaded (20)

PPTX
MYSQL Presentation for SQL database connectivity
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
cuic standard and advanced reporting.pdf
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Electronic commerce courselecture one. Pdf
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Empathic Computing: Creating Shared Understanding
PDF
Spectral efficient network and resource selection model in 5G networks
PPTX
Cloud computing and distributed systems.
MYSQL Presentation for SQL database connectivity
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Review of recent advances in non-invasive hemoglobin estimation
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
cuic standard and advanced reporting.pdf
Network Security Unit 5.pdf for BCA BBA.
20250228 LYD VKU AI Blended-Learning.pptx
The Rise and Fall of 3GPP – Time for a Sabbatical?
Chapter 3 Spatial Domain Image Processing.pdf
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Advanced methodologies resolving dimensionality complications for autism neur...
Unlocking AI with Model Context Protocol (MCP)
Electronic commerce courselecture one. Pdf
The AUB Centre for AI in Media Proposal.docx
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Building Integrated photovoltaic BIPV_UPV.pdf
Empathic Computing: Creating Shared Understanding
Spectral efficient network and resource selection model in 5G networks
Cloud computing and distributed systems.

Elixir in a nutshell - Fundamental Concepts