```keywords
a list of tuples where the first item of the tuple is an atom

iex> x = [{:a, 1}, {:b, 2}]
[a: 1, b: 2]
iex> x[:a]
1

keys can be given more than once

keyword lists provide the same linear performance characteristics as lists
for this reason, keyword lists are used mainly as options

module Keyword
iex> k1 = Keyword.new

iex> k2 = Keyword.new([{:a, 1}, {:a, 2}, {:a, 3}])
[a: 3]

iex> Keyword.put(k1,:two,222)
[two: 222]

iex> k3 = Keyword.new([{:c, 1},{:b, 2},{:a, 3}], fn {x, y} -> {x, y + 2} end)
[c: 3, b: 4, a: 5]

iex> x
[a: 1, b: 2]
iex> Keyword.delete(x, :b)
[a: 1]

iex> x
[a: 1, b: 2, c: 3]
iex(5)> Keyword.delete(x, :b, 10)
[a: 1, b: 2, c: 3]
iex(6)> Keyword.delete(x, :b, 2)
[a: 1, c: 3]

delete_first/2
Deletes the first entry in the keyword list for a specific key

iex> Keyword.drop([a: 1, b: 2, c: 3], [:b, :d])
[a: 1, c: 3]

fetch!/2             fetch/2

get/3                get_lazy/3           get_values/2
has_key?/2
keyword?/1

merge/2              merge/3

pop/3                pop_first/3          pop_lazy/3

put_new/3            put_new_lazy/3

take/2

to_list/1
update!/3            update/4

keys/1
values/1

maps
a map is created using the %{} syntax:

iex> x = %{:a => 1, 2 => :b}
%{2 => :b, :a => 1}
iex> x[:a]
1
iex> x[2]
:b
iex> x[:c]
nil

maps allow any value as a key. maps’ keys do not follow any ordering

module Map
iex> Map.get(%{:a => 1, 2 => :b} , :a)
1

iex> Map.to_list(%{:a => 1 , 2 => :b})
[{2 , :b}, {:a , 1}]

iex> x = Map.new [{:a, 1},{:b, 2}] , fn({x , y}) -> {x , y + 1} end
%{a: 2, b: 3}

iex> x = %{a: 1, b: 2}
%{a: 1 , b: 2}

iex> x = %{:a => 1, 2 => :b}
%{:a => 1, 2 => :b}

iex> x.a
1
iex> x.c
** (KeyError) key :c not found in: %{2 => :b, :a => 1}

iex> %{x | :a => 2}
%{:a => 2, 2 => :b}
iex> %{x | :c => 3}
** (KeyError) key :c not found in: %{2 => :b, :a => 1}

when all the keys in a map are atoms, you can use the keyword syntax:

iex> y = %{:a => 1, :b => 2}
%{a: 1, b: 2}
iex> y.a
1
iex> y[:a]
1

new/0                new/1                new/2

merge/2              merge/3

iex> Map.split(%{a: 1, b: 2, c: 3}, [:a, :c, :e])
{%{a: 1, c: 3}, %{b: 2}}

to_list/1
from_struct/1

delete/2             drop/2

fetch!/2             fetch/2
get/3                get_and_update!/3    get_and_update/3        get_lazy/3

has_key?/2           keys/1               values/1

pop/3                pop_lazy/3
put/3                put_new/3            put_new_lazy/3

iex> Map.take(%{a: 1, b: 2, c: 3}, [:a, :c, :e])
%{a: 1, c: 3}
takes all entries corresponding to the given keys and returns them in a new map

iex> Map.update!(%{a: 1}, :a, &(&1 * 2))
%{a: 2}
iex> Map.update!(%{a: 1}, :b, &(&1 * 2))
updates the key with the given function
if the key does not exist, raises KeyError

iex> Map.update(%{a: 1}, :a, 13, &(&1 * 2))
%{a: 2}
iex> Map.update(%{a: 1}, :b, 11, &(&1 * 2))
%{a: 1, b: 11}
updates the key in map with the given function
if the key does not exist, inserts the given initial value

structs
structs are bare maps underneath. to define a struct, the defstruct construct is used:

defmodule User
do
defstruct name: "John", age: 27
end

structs take the name of the module they’re defined in

iex> %User{}
%User{age: 27, name: "John"}
iex> %User{name: "Meg"}
%User{age: 27, name: "Meg"}

iex> john = %User{}
%User{age: 27, name: "John"}
iex> john.name
"John"

iex> meg = %{john | name: "Meg"}
%User{age: 27, name: "Meg"}
iex> %{meg | oops: :field}

when using the update syntax (|), the VM is aware that no new keys will be added to the struct,
allowing the maps underneath to share their structure in memory

structs can also be used in pattern matching:

iex> %User{name: n} = john
%User{age: 27, name: "John"}
iex> n
"John"
iex> %User{} = %{}
** (MatchError) no match of right hand side value: %{}
```