diff --git a/doc/1_KC3/1.01_Introduction.en.md b/doc/1_KC3/1.01_Introduction.en.md
index 81b06f5..73f2ef9 100644
--- a/doc/1_KC3/1.01_Introduction.en.md
+++ b/doc/1_KC3/1.01_Introduction.en.md
@@ -95,4 +95,4 @@ Top : [KC3 documentation](/doc/)
Previous : [1 KC3](/doc/1_KC3)
-Next : [1.2 Integer](1.2_Integer)
+Next : [1.02 Array](1.02_Array)
diff --git a/doc/1_KC3/1.02_Array.en.md b/doc/1_KC3/1.02_Array.en.md
new file mode 100644
index 0000000..d1f9f1e
--- /dev/null
+++ b/doc/1_KC3/1.02_Array.en.md
@@ -0,0 +1,34 @@
+# 1.2 Array
+
+Arrays have an array type and are multidimensional like in C.
+
+Litteral values start with an array cast and are followed by a tuple.
+
+Use `List.to_array` to convert a `List` to an array type.
+
+## 1.2.1 Examples
+
+```
+ikc3> a = (U8[]) {0, 1, 2}
+(U8[]) {0, 1, 2}
+ikc3> type(a)
+U8[]
+ikc3> a[0]
+0
+ikc3> a[1]
+1
+ikc3> a[2]
+2
+ikc3> List.to_array
+cfn Array "kc3_list_to_array" (List, Sym, Result)
+ikc3> List.to_array([0, 1, 2], U8[])
+(U8[]) {0, 1, 2}
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.01 Introduction](/doc/1.01_Introduction)
+
+Next : [1.03 Block](1.03_Block)
diff --git a/doc/1_KC3/1.02_Integer.en.md b/doc/1_KC3/1.02_Integer.en.md
deleted file mode 100644
index 35c7c18..0000000
--- a/doc/1_KC3/1.02_Integer.en.md
+++ /dev/null
@@ -1,136 +0,0 @@
-# 1.2 Integer
-
-## 1.2.1 Small integers
-
-IKC3 supports all C integer type sizes from `U8` (matching the C type `uint8_t`)
-to `U64` (matching the C type `uint64_t`) for unsigned integers,
-and from `S8` to `S64` for signed integers.
-
-In addition to these 8 basic integer types there are 2 pointer-sized
-integer types :
-`Uw` for unsigned pointer-sized integers,
-and `Sw` for signed pointer-sized integers.
-
-Small integers take little space, are static, they are passed directly and
-not as a pointer, and for these reasons are fast.
-
-They do not need to be cleaned after use and thus can be used in arrays like
-is usually done in C.
-
-```elixir
-ikc3> type(-1)
-S8
-ikc3> type(-128)
-S16
-ikc3> type(-32768)
-S32
-ikc3> type(-2147483648)
-S64
-ikc3> type(-9223372036854775807)
-S64
-ikc3> type(0)
-U8
-ikc3> type(256)
-U16
-ikc3> type(65536)
-U32
-ikc3> type(4294967296)
-U64
-ikc3> type(18446744073709551615)
-U64
-```
-
-## 1.2.2 Large integers
-
-IKC3 supports large integers and they are compatible with small integers.
-Their type is `Integer` and can support numbers as large as memory allows.
-They are slow because they are allocated dynamically on the heap
-using malloc.
-
-```elixir
-ikc3> type(1000000000000000000000000000000)
-Integer
-```
-
-
-## 1.2.3 Operations on integers
-
-### 1.2.3.1 Operator `~`
-
-Binary not.
-
-```elixir
-ikc3> ~ 1
-254
-ikc3> ~ -1
-0
-ikc3> ~ 0
-255
-ikc3> ~ 255
-0
-ikc3> ~ (U16) 1
-65534
-ikc3> ~ (S16) 1
--2
-```
-
-### 1.2.3.2 Operator `+`
-
-Integer addition.
-
-All positive integers can be defined in terms of addition of :
-zero or a positive integer, and one. E.g.
-
-```elixir
-1 = 0 + 1
-2 = 0 + 1 + 1
-3 = 0 + 1 + 1 + 1
-etc.
-```
-
-### 1.2.3.3 Operator `-`
-
-Integer subtraction. Take an integer and remove another integer from it.
-
-### 1.2.3.4 Operator `*`
-
-Integer multiplication. Init result to zero, add an integer `a` and
-repeat `b` times.
-
-### 1.2.3.5 Operator `/`
-
-Integer division. The inverse of multiplication :
-for all integers `a` and `b` there is a couple `q` and `r` that satisfies
-`a = b * q + r`. Integer division returns `q`.
-
-### 1.2.3.6 Operator `mod`
-
-Integer modulo. Returns `r` in the previous equation (see Operator `/`)
-
-### 1.2.3.7 Operator `<<`
-
-Left shift
-
-
-## 1.2.4 Examples
-
-```elixir
-ikc3> type(1)
-U8
-ikc3> type(1000000000000000000000000000000)
-Integer
-ikc3> a = 1 + 100000000000000000000000000000000
-100000000000000000000000000000001
-ikc3> a * a
-10000000000000000000000000000000200000000000000000000000000000001
-ikc3> a * a / 1000000000000000000000000000000000000000000000000000
-10000000000000
-```
-
----
-
-Top : [KC3 documentation](/doc/)
-
-Previous : [1.1 Introduction](1.1_Introduction)
-
-Next : [1.3 Map](1.3_Map)
diff --git a/doc/1_KC3/1.03_Block.en.md b/doc/1_KC3/1.03_Block.en.md
new file mode 100644
index 0000000..6d5c778
--- /dev/null
+++ b/doc/1_KC3/1.03_Block.en.md
@@ -0,0 +1,45 @@
+# 1.3 Block
+
+A KC3 block is a source code block. It starts with `do` or `{` and
+ends with `end` or `}` respectively.
+It can be passed to a special operator or macro function to
+be evaluated explicitly in C with `env_eval_block` (see
+`libkc3/env_eval.c`).
+
+A block evaluates all its instructions in turn, and returns the value
+of the last expression.
+
+## 1.3.1 Examples
+
+```elixir
+ikc3> do
+ikc3> 1
+ikc3> 2
+ikc3> 3
+ikc3> end
+3
+ikc3> quote do
+ikc3> 1
+ikc3> 2
+ikc3> 3
+ikc3> end
+do
+ 1
+ 2
+ 3
+end
+ikc3> type(quote do
+ikc3> 1
+ikc3> 2
+ikc3> 3
+ikc3> end)
+Block
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.02 Array](1.02_Array)
+
+Next : [1.04 Bool](1.04_Bool)
diff --git a/doc/1_KC3/1.03_Str.en.md b/doc/1_KC3/1.03_Str.en.md
deleted file mode 100644
index 4bc04af..0000000
--- a/doc/1_KC3/1.03_Str.en.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# 1.03 Str type.
-
-Read-only string of bytes. Use `Str.size` to get the size in bytes
-of the string (without NUL terminator). All KC3 strings are bound-
-checked according to their size and are NUL terminated.
-
-## 1.03.1 String litterals and interpolation
-
-A string litteral starts and ends with double quotes `"`
-or triple quotes `"""` and inside of a string litteral you can use
-the `#{expr}` syntax to evaluate `expr` to a `Str` inside of the
-litteral. The string litteral is then parsed as a `Call` to `KC3.str`
-and not an actual `Str`. At evaluation the arguments to the call
-and `KC3.str` gets called concatenating at once all the parts to a
-brand new `Str`.
-
-## 1.03.2 Examples
-
-```elixir
-ikc3> "123"
-"123"
-ikc3> type("123")
-Str
-ikc3> b = 2
-2
-ikc3> "1#{b}3"
-"123"
-ikc3> type("1#{b}3")
-Str
-ikc3> quote "1#{b}3"
-"1#{b}3"
-ikc3> type(quote "1#{b}3")
-Call
-ikc3> type(quote quote "1#{b}3")
-Quote
-```
diff --git a/doc/1_KC3/1.04_Bool.en.md b/doc/1_KC3/1.04_Bool.en.md
new file mode 100644
index 0000000..ff9b807
--- /dev/null
+++ b/doc/1_KC3/1.04_Bool.en.md
@@ -0,0 +1,45 @@
+# 1.4 Bool
+
+Booleans can have only two values : `false` or `true`.
+
+They can be casted to integer types, `false` being `0` and
+true being `1`.
+
+You can cast any type to a boolean : integers `0` and character NUL
+being `false` and everything else being `true`. This is useful for
+boolean operations : accept any tag as a condition and if it
+evaluates to `true` after a cast then proceed. This is how
+`if_then_else` and `while` and many KC3 operators are implemented.
+
+## 1.4.1 Examples
+
+```
+ikc3> true && true
+true
+ikc3> true && false
+false
+ikc3> if "" do "ok" else "ko" end
+"ok"
+ikc3> if 1 do "ok" else "ko" end
+"ok"
+ikc3> if 0 do "ko" else "ok" end
+"ok"
+ikc3> (Bool) ""
+true
+ikc3> (Bool) 1
+true
+ikc3> (Bool) 0
+false
+ikc3> "ok" == "ok"
+true
+ikc3> "ok" == "ko"
+false
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.03 Block](1.03_Block)
+
+Next : [1.05 Callable](1.05_Callable)
diff --git a/doc/1_KC3/1.04_Ratio.en.md b/doc/1_KC3/1.04_Ratio.en.md
deleted file mode 100644
index d24db32..0000000
--- a/doc/1_KC3/1.04_Ratio.en.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# 1.4 Ratio
-
-Ratios are made with a couple of large integers : the numerator
-which can be any number, and the denominator which has to be positive.
-They represent fractions of integral numbers.
-They are written with a slash and no space.
-
-```elixir
-ikc3> 1/2 + 2/3
-7/6
-ikc3> 1/2 * 2/3
-1/3
-ikc3> 1/2 / 2/3
-3/4
-ikc3> 1/2 - 2/3
--1/6
-```
-
----
-
-Top : [KC3 documentation](/doc/)
-
-Previous : [1.3 Map](1.3_Map)
-
-Next : [1.5 List](1.5_List)
diff --git a/doc/1_KC3/1.05_Callable.en.md b/doc/1_KC3/1.05_Callable.en.md
new file mode 100644
index 0000000..76bd58e
--- /dev/null
+++ b/doc/1_KC3/1.05_Callable.en.md
@@ -0,0 +1,14 @@
+# 1.5 Callable
+
+The KC3 `Callable` type is an or-type of `Cfn` and `Fn`.
+
+In any case where you accept a `Fn` or `Cfn` as an argument
+you should use `Callable` as the type.
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.04 Bool](1.04_Bool)
+
+Next : [1.06 Call](1.06_Call)
diff --git a/doc/1_KC3/1.05_List.en.md b/doc/1_KC3/1.05_List.en.md
deleted file mode 100644
index c5ad99a..0000000
--- a/doc/1_KC3/1.05_List.en.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# 1.5 List
-
-Linked lists owning the data (each node contains a couple of tags :
-one for data and one for next pointer.
-
-Regular lists can be :
- - multiple elements : `[1, 2, 3]`
- - an element and a list : `[1 | [2, 3]]`
- - multiple elements and a list : `[1, 2 | [3]]`
- - the empty list : `[]`
-
-Regular lists end with the empty list : `[1] == [1 | []]`.
-
-You can also contruct dotted lists like in Common Lisp where
-the next list pointer is an arbitrary form. E.g. :
- - an element and an element : `[1 | 2]`
- - multiple elements and an element : `[1, 2, 3 | 4]`
- - the empty list and an element : `[[] | 1]`
-
-All these list formats are supported in pattern matching.
-
-## 1.5.1 Functions
-
-```elixir
-List List.map (List, Fn)
-```
-
-```elixir
-List List.reverse (List)
-```
-
----
-
-Top : [KC3 documentation](/doc/)
-
-Previous : [1.4 Ratio](1.4_Ratio)
-
-Next : [1.6 Variable](1.6_Variable)
diff --git a/doc/1_KC3/1.06_Call.en.md b/doc/1_KC3/1.06_Call.en.md
new file mode 100644
index 0000000..df34ae1
--- /dev/null
+++ b/doc/1_KC3/1.06_Call.en.md
@@ -0,0 +1,22 @@
+# 1.6 Call
+
+A function or operator call has type `Call` in KC3. To produce it
+you need to quote a call or call a cfn that returns a `Call`, like
+`Tag.from_str`.
+
+## 1.6.1 Examples
+
+```elixir
+ikc3> type(quote 1 + 1)
+Call
+ikc3> type(quote List.count(1000))
+Call
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.05 Callable](1.05_Callable)
+
+Next : [1.07 Character](1.07_Character)
diff --git a/doc/1_KC3/1.06_Variable.en.md b/doc/1_KC3/1.06_Variable.en.md
deleted file mode 100644
index e33520f..0000000
--- a/doc/1_KC3/1.06_Variable.en.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# 1.6 Variables
-
-Variables in KC3 can be defined using the litteral value for a variable
-which is always `?`. You can cast this litteral value and it will not
-really be casted but it will give you a typed variable litteral value.
-E.g. `(List) ?`.
-The typed variable litteral value will only accept to be set once to
-one value of the variable's type (in this example the type of a linked
-list).
-
-It's actually a syntax so you cannot rename `?` by mistake and
-so is an easy task to do static analysis of variable creation.
-
-The default type for a variable which you can also specify explicitly
-is `Tag` which is an enum-tagged union type of any other KC3 types
-currently defined in the environment. So `?` is exactly equivalent to
-`(Tag) ?` and they will both accept to be set once to one value of any
-type.
-
-A variable is settable once and cannot be changed afterwards (there is
-an exception if you write C code and link to it but it is not easy nor
-silent).
-
-This way you do not need to lock or trust any behaviour, once your
-variable is set to a value the value of the variable will never change,
-it really is read-only.
-
-You can also use the assignment operator which is `<-` which in turn calls
-`tag_init_copy`. It works like the C assignment operator (`=`).
-
-Examples :
-```elixir
-# Declare a unsigned byte 8 bits variable "x".
-x = (U8) ?
-# Set the variable "x" to zero.
-x <- 0
-# Allocate again for the same binding name "x"
-x = (U8) ?
-# Also set the new variable "x" to zero with just one Unicode symbol
-# that is AltGr+Y on my keyboard.
-x โ 0
-```
-
-
-## So how do I change anything if it is read-only ?
-
-You can always reset an existing binding at will to another variable
-litteral and another variable will be created for the same name and it
-will be in a different memory location, settable once and then
-read-only again so you can use it without locking.
-
----
-
-Top : [KC3 documentation](/doc/)
-
-Previous : [1.5 List](1.5_List)
-
-Next : [2 HTTPd](/doc/2_HTTPd)
diff --git a/doc/1_KC3/1.07_Character.en.md b/doc/1_KC3/1.07_Character.en.md
new file mode 100644
index 0000000..9f46591
--- /dev/null
+++ b/doc/1_KC3/1.07_Character.en.md
@@ -0,0 +1,29 @@
+# 1.7 Character
+
+KC3 characters are U32 encoded Unicode codepoints.
+They have a litteral syntax enclosed in simple quotes, just like in C.
+
+## 1.7.1 Examples
+
+```elixir
+ikc3> '๐
'
+'๐
'
+ikc3> type('๐
')
+Character
+ikc3> '๐ณ'
+'๐ณ'
+ikc3> '๐'
+'๐'
+ikc3> '๐ฃ'
+'๐ฃ'
+ikc3> '๐คฉ'
+'๐คฉ'
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.06 Call](1.06_Call)
+
+Next : [1.08 Complex](1.08_Complex)
diff --git a/doc/1_KC3/1.07_Struct.en.md b/doc/1_KC3/1.07_Struct.en.md
deleted file mode 100644
index be5504a..0000000
--- a/doc/1_KC3/1.07_Struct.en.md
+++ /dev/null
@@ -1,127 +0,0 @@
-# 1.7 Struct
-
-KC3 structs are a key value associative data structure with default
-values and arbitrary property order.
-
-They are compatible with C structs of the same type.
-
-```elixir
-ikc3> a = %KC3.Op{sym: :dot,
- precedence: 10,
- callable: fn (a, b) { a.x * b.y + a.y * b.y }}
-%KC3.Op{sym: :dot,
- arity: 2,
- special: false,
- precedence: 10,
- associativity: 1,
- callable: fn (a, b) { a.x * b.y + a.y * b.y }}
-```
-
-You can define one _struct type_ per module with `defstruct` for
-example in `vec2d.kc3` :
-
-```elixir
-defmodule Vec2D do
-
- defstruct [x: 0.0,
- y: 0.0]
-
-end
-```
-
-Destructuring works with structs to extract values :
-
-```elixir
-ikc3> %KC3.Op{sym: sym} = ^ a
-%KC3.Op{sym: :dot,
- arity: 2,
- special: false,
- precedence: 10,
- associativity: 1,
- callable: fn (a, b) { a.x * b.y + a.y * b.y }}
-ikc3> sym
-:dot
-```
-
-
-You can use the dot syntax to access struct values from a `Sym` key :
-
-```elixir
-ikc3> a = %KC3.Op{sym: :dot,
- precedence: 10,
- callable: fn (a, b) { a.x * b.y + a.y * b.y }}
-%KC3.Op{sym: :dot,
- arity: 2,
- special: false,
- precedence: 10,
- associativity: 1,
- callable: fn (a, b) { a.x * b.y + a.y * b.y }}
-ikc3> a.sym
-:dot
-ikc3> a.arity
-2
-ikc3> a.callable
-fn (a, b) { a.x * b.y + a.y * b.y }
-```
-
-The bracket syntax allows you to query structs the same as maps :
-
-```elixir
-ikc3> a[:sym]
-:dot
-ikc3> a[:arity]
-2
-ikc3> a[:callable]
-fn (a, b) { a.x * b.y + a.y * b.y }
-```
-
-You can also use the `KC3.access` function for the same result :
-
-```elixir
-ikc3> a = %KC3.Op{sym: :dot,
- precedence: 10,
- callable: fn (a, b) { a.x * b.y + a.y * b.y }}
-%KC3.Op{sym: :dot,
- arity: 2,
- special: false,
- precedence: 10,
- associativity: 1,
- callable: fn (a, b) { a.x * b.y + a.y * b.y }}
-ikc3> access(a, [:sym])
-:dot
-ikc3> access(a, [:arity])
-2
-ikc3> access(a, [:callable])
-fn (a, b) { a.x * b.y + a.y * b.y }
-```
-
-To update an existing struct property you can use Struct.put, a new
-struct with modified properties will be returned. E.g. :
-
-```elixir
-ikc3> a = %KC3.Op{sym: :dot,
- precedence: 10,
- callable: fn (a, b) { a.x * b.y + a.y * b.y }}
-%KC3.Op{sym: :dot,
- arity: 2,
- special: false,
- precedence: 10,
- associativity: 1,
- callable: fn (a, b) { a.x * b.y + a.y * b.y }}
-b = Struct.put(a, :sym, :ยท)
-%KC3.Op{sym: :ยท,
- arity: 2,
- special: false,
- precedence: 10,
- associativity: 1,
- callable: fn (a, b) { a.x * b.y + a.y * b.y }}
-```
-
-
----
-
-Top : [KC3 documentation](/doc/)
-
-Previous : [1.2 Integer](1.2_Integer)
-
-Next : [1.4 Ratio](1.4_Ratio)
diff --git a/doc/1_KC3/1.08_Array.en.md b/doc/1_KC3/1.08_Array.en.md
deleted file mode 100644
index 3b5aeb4..0000000
--- a/doc/1_KC3/1.08_Array.en.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# 1.8 Array
-
-Arrays have an array type and are multidimensional like in C.
-
-Litteral values start with an array cast and are followed by a tuple.
-
-Use `List.to_array` to convert a `List` to an array type.
-
-## 1.8.1 Examples
-
-```
-ikc3> a = (U8[]) {0, 1, 2}
-(U8[]) {0, 1, 2}
-ikc3> type(a)
-U8[]
-ikc3> a[0]
-0
-ikc3> a[1]
-1
-ikc3> a[2]
-2
-ikc3> List.to_array
-cfn Array "kc3_list_to_array" (List, Sym, Result)
-ikc3> List.to_array([0, 1, 2], U8[])
-(U8[]) {0, 1, 2}
-```
diff --git a/doc/1_KC3/1.08_Complex.en.md b/doc/1_KC3/1.08_Complex.en.md
new file mode 100644
index 0000000..a2f9a3d
--- /dev/null
+++ b/doc/1_KC3/1.08_Complex.en.md
@@ -0,0 +1,25 @@
+# 1.8 Complex
+
+Complex numbers are supported in KC3 through the `Complex` type and
+the `+i` infix operator.
+
+## 1.8.1 Examples
+
+```elixir
+ikc3> i = 0 +i 1
+0 +i 1
+ikc3> ii = i * i
+-1 +i 0
+ikc3> iii = i +i i
+-1 +i 1
+ikc3> type(i)
+Complex
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.07 Character](1.07_Character)
+
+Next : [1.09 Cow](1.09_Cow)
diff --git a/doc/1_KC3/1.09_Block.en.md b/doc/1_KC3/1.09_Block.en.md
deleted file mode 100644
index 7133630..0000000
--- a/doc/1_KC3/1.09_Block.en.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# 1.9 Block
-
-A KC3 block is a source code block. It starts with `do` or `{` and
-ends with `end` or `}` respectively.
-It can be passed to a special operator or macro function to
-be evaluated explicitly in C with `env_eval_block` (see
-`libkc3/env_eval.c`).
-
-A block evaluates all its instructions in turn, and returns the value
-of the last expression.
-
-## 1.9.1 Examples
-
-```elixir
-ikc3> do
-ikc3> 1
-ikc3> 2
-ikc3> 3
-ikc3> end
-3
-ikc3> quote do
-ikc3> 1
-ikc3> 2
-ikc3> 3
-ikc3> end
-do
- 1
- 2
- 3
-end
-ikc3> type(quote do
-ikc3> 1
-ikc3> 2
-ikc3> 3
-ikc3> end)
-Block
-```
diff --git a/doc/1_KC3/1.09_Cow.en.md b/doc/1_KC3/1.09_Cow.en.md
new file mode 100644
index 0000000..e5c032b
--- /dev/null
+++ b/doc/1_KC3/1.09_Cow.en.md
@@ -0,0 +1,19 @@
+# 1.9 Cow
+
+`Cow` is a copy on write data structure based on `List`.
+
+## 1.9.1 Examples
+
+```elixir
+ikc3> c = cow %{a: 1, b: 2}
+cow %{a: 1,
+ b: 2}
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.08 Complex](1.08_Complex)
+
+Next : [1.10 F32](1.10_F32)
diff --git a/doc/1_KC3/1.10_Bool.en.md b/doc/1_KC3/1.10_Bool.en.md
deleted file mode 100644
index dd9588e..0000000
--- a/doc/1_KC3/1.10_Bool.en.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# 1.10 Bool
-
-Booleans can have only two values : `false` or `true`.
-
-They can be casted to integer types, `false` being `0` and
-true being `1`.
-
-You can cast any type to a boolean : integers `0` and character NUL
-being `false` and everything else being `true`. This is useful for
-boolean operations : accept any tag as a condition and if it
-evaluates to `true` after a cast then proceed. This is how
-`if_then_else` and `while` and many KC3 operators are implemented.
-
-## 1.10.1 Examples
-
-```
-ikc3> true && true
-true
-ikc3> true && false
-false
-ikc3> if "" do "ok" else "ko" end
-"ok"
-ikc3> if 1 do "ok" else "ko" end
-"ok"
-ikc3> if 0 do "ko" else "ok" end
-"ok"
-ikc3> (Bool) ""
-true
-ikc3> (Bool) 1
-true
-ikc3> (Bool) 0
-false
-ikc3> "ok" == "ok"
-true
-ikc3> "ok" == "ko"
-false
-```
diff --git a/doc/1_KC3/1.10_F32.en.md b/doc/1_KC3/1.10_F32.en.md
new file mode 100644
index 0000000..ddf698f
--- /dev/null
+++ b/doc/1_KC3/1.10_F32.en.md
@@ -0,0 +1,19 @@
+# 1.10 F32
+
+The KC3 `F32` type is a C-compatible IEEE 754 floating point number
+on 32 bits.
+
+## 1.10.1 Examples
+
+```elixir
+ikc3> (F32) 0.1 + (F32) 0.001
+(F32) 1.009999e-1
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.09 Cow](1.09_Cow)
+
+Next : [1.11 F64](1.11_F64)
diff --git a/doc/1_KC3/1.11_Call.en.md b/doc/1_KC3/1.11_Call.en.md
deleted file mode 100644
index bed3c2e..0000000
--- a/doc/1_KC3/1.11_Call.en.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# 1.11 Call
-
-A function or operator call has type `Call` in KC3. To produce it
-you need to quote a call or call a cfn that returns a `Call`, like
-`Tag.from_str`.
-
-## 1.11.1 Examples
-
-```elixir
-ikc3> type(quote 1 + 1)
-Call
-ikc3> type(quote List.count(1000))
-Call
-```
diff --git a/doc/1_KC3/1.11_Character.en.md b/doc/1_KC3/1.11_Character.en.md
deleted file mode 100644
index faade0c..0000000
--- a/doc/1_KC3/1.11_Character.en.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# 1.11 Character
-
-KC3 characters are U32 encoded Unicode codepoints.
-They have a litteral syntax enclosed in simple quotes, just like in C.
-```elixir
-ikc3> '๐
'
-'๐
'
-ikc3> type('๐
')
-Character
-ikc3> '๐ณ'
-'๐ณ'
-ikc3> '๐'
-'๐'
-ikc3> '๐ฃ'
-'๐ฃ'
-ikc3> '๐คฉ'
-'๐คฉ'
-```
diff --git a/doc/1_KC3/1.11_F64.en.md b/doc/1_KC3/1.11_F64.en.md
new file mode 100644
index 0000000..595f099
--- /dev/null
+++ b/doc/1_KC3/1.11_F64.en.md
@@ -0,0 +1,19 @@
+# 1.11 F64
+
+The KC3 `F64` type is a C-compatible IEEE 754 floating point number
+on 64 bits.
+
+## 1.11.1 Examples
+
+```elixir
+ikc3> (F64) 1 + (F64) 0.001
+(F64) 1.00099999999999
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.10 F32](1.10_F32)
+
+Next : [1.12 F128](1.12_F128)
diff --git a/doc/1_KC3/1.12_Complex.en.md b/doc/1_KC3/1.12_Complex.en.md
deleted file mode 100644
index c35baf4..0000000
--- a/doc/1_KC3/1.12_Complex.en.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# 1.12 Complex
-
-Complex numbers are supported in KC3 through the `Complex` type and
-the `+i` infix operator.
-
-## 1.12.1 Examples
-
-```elixir
-ikc3> i = 0 +i 1
-0 +i 1
-ikc3> ii = i * i
--1 +i 0
-ikc3> iii = i +i i
--1 +i 1
-ikc3> type(i)
-Complex
diff --git a/doc/1_KC3/1.12_F128.en.md b/doc/1_KC3/1.12_F128.en.md
new file mode 100644
index 0000000..1db4f02
--- /dev/null
+++ b/doc/1_KC3/1.12_F128.en.md
@@ -0,0 +1,19 @@
+# 1.12 F128
+
+The KC3 `F128` type is a C-compatible IEEE 754 floating point number
+on 128 bits.
+
+## 1.12.1 Examples
+
+```elixir
+ikc3> (F128) 1 - (F128) 0.001
+(F128) 9.989999999999999999791833182882783e-1
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.11 F64](1.11_F64)
+
+Next : [1.13 Ident](1.13_Ident)
diff --git a/doc/1_KC3/1.13_Cow.en.md b/doc/1_KC3/1.13_Cow.en.md
deleted file mode 100644
index 62a28f7..0000000
--- a/doc/1_KC3/1.13_Cow.en.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# 1.13 Cow
-
-`Cow` is a copy on write data structure based on `List`.
-
-## 1.13.1 Examples
-
-```elixir
-ikc3> c = cow Array.init(Uw[], Uw[]{1024, 1024, 1024})
-(Uw[]) {...}
-```
diff --git a/doc/1_KC3/1.13_Ident.en.md b/doc/1_KC3/1.13_Ident.en.md
new file mode 100644
index 0000000..53a27ba
--- /dev/null
+++ b/doc/1_KC3/1.13_Ident.en.md
@@ -0,0 +1,53 @@
+# 1.13 Ident
+
+The KC3 `Ident` type is an identifier. An identifier evaluates to its
+bound value in the current environnement, that is in local and global
+frames and then in the triple store.
+
+## 1.13.1 Examples
+
+To get an `Ident` you can use quote :
+
+```elixir
+ikc3> quote List.reverse
+List.reverse
+ikc3> type(quote List.reverse)
+Ident
+```
+
+To bind a value to an ident you can use pattern matching :
+
+```elixir
+ikc3> [one, two, three | rest] = List.count(5)
+[1, 2, 3, 4, 5]
+ikc3> type(quote one)
+Ident
+ikc3> one
+1
+ikc3> two
+2
+ikc3> three
+3
+ikc3> rest
+[4, 5]
+```
+
+Otherwise you can use `KC3.def` and it will store the value in the
+graph database (facts) :
+
+```elixir
+ikc3> def one = 1
+1
+ikc3> def two = one + one
+2
+ikc3> two
+2
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.12 F128](1.12_F128)
+
+Next : [1.14 Integer](1.14_Integer)
diff --git a/doc/1_KC3/1.14_F32.en.md b/doc/1_KC3/1.14_F32.en.md
deleted file mode 100644
index a2e0144..0000000
--- a/doc/1_KC3/1.14_F32.en.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# 1.14 F32
-
-The KC3 `F32` type is a C-compatible IEEE 754 floating point number
-on 32 bits.
-
-## 1.14.1 Examples
-
-```elixir
-ikc3> (F32) 0.1 + (F32) 0.001
-(F32) 1.009999e-1
-```
\ No newline at end of file
diff --git a/doc/1_KC3/1.14_Integer.en.md b/doc/1_KC3/1.14_Integer.en.md
new file mode 100644
index 0000000..7a5f275
--- /dev/null
+++ b/doc/1_KC3/1.14_Integer.en.md
@@ -0,0 +1,136 @@
+# 1.14 Integer
+
+## 1.14.1 Small integers
+
+IKC3 supports all C integer type sizes from `U8` (matching the C type `uint8_t`)
+to `U64` (matching the C type `uint64_t`) for unsigned integers,
+and from `S8` to `S64` for signed integers.
+
+In addition to these 8 basic integer types there are 2 pointer-sized
+integer types :
+`Uw` for unsigned pointer-sized integers,
+and `Sw` for signed pointer-sized integers.
+
+Small integers take little space, are static, they are passed directly and
+not as a pointer, and for these reasons are fast.
+
+They do not need to be cleaned after use and thus can be used in arrays like
+is usually done in C.
+
+```elixir
+ikc3> type(-1)
+S8
+ikc3> type(-128)
+S16
+ikc3> type(-32768)
+S32
+ikc3> type(-2147483648)
+S64
+ikc3> type(-9223372036854775807)
+S64
+ikc3> type(0)
+U8
+ikc3> type(256)
+U16
+ikc3> type(65536)
+U32
+ikc3> type(4294967296)
+U64
+ikc3> type(18446744073709551615)
+U64
+```
+
+## 1.14.2 Large integers
+
+IKC3 supports large integers and they are compatible with small integers.
+Their type is `Integer` and can support numbers as large as memory allows.
+They are slow because they are allocated dynamically on the heap
+using malloc.
+
+```elixir
+ikc3> type(1000000000000000000000000000000)
+Integer
+```
+
+
+## 1.14.3 Operations on integers
+
+### 1.14.3.1 Operator `~`
+
+Binary not.
+
+```elixir
+ikc3> ~ 1
+254
+ikc3> ~ -1
+0
+ikc3> ~ 0
+255
+ikc3> ~ 255
+0
+ikc3> ~ (U16) 1
+65534
+ikc3> ~ (S16) 1
+-2
+```
+
+### 1.14.3.2 Operator `+`
+
+Integer addition.
+
+All positive integers can be defined in terms of addition of :
+zero or a positive integer, and one. E.g.
+
+```elixir
+1 = 0 + 1
+2 = 0 + 1 + 1
+3 = 0 + 1 + 1 + 1
+etc.
+```
+
+### 1.14.3.3 Operator `-`
+
+Integer subtraction. Take an integer and remove another integer from it.
+
+### 1.14.3.4 Operator `*`
+
+Integer multiplication. Init result to zero, add an integer `a` and
+repeat `b` times.
+
+### 1.14.3.5 Operator `/`
+
+Integer division. The inverse of multiplication :
+for all integers `a` and `b` there is a couple `q` and `r` that satisfies
+`a = b * q + r`. Integer division returns `q`.
+
+### 1.14.3.6 Operator `mod`
+
+Integer modulo. Returns `r` in the previous equation (see Operator `/`)
+
+### 1.14.3.7 Operator `<<`
+
+Left shift
+
+
+## 1.14.4 Examples
+
+```elixir
+ikc3> type(1)
+U8
+ikc3> type(1000000000000000000000000000000)
+Integer
+ikc3> a = 1 + 100000000000000000000000000000000
+100000000000000000000000000000001
+ikc3> a * a
+10000000000000000000000000000000200000000000000000000000000000001
+ikc3> a * a / 1000000000000000000000000000000000000000000000000000
+10000000000000
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.13 Ident](1.13_Ident)
+
+Next : [1.15 List](1.15_List)
diff --git a/doc/1_KC3/1.15_F64.en.md b/doc/1_KC3/1.15_F64.en.md
deleted file mode 100644
index 9cfa1de..0000000
--- a/doc/1_KC3/1.15_F64.en.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# 1.15 F64
-
-The KC3 `F64` type is a C-compatible IEEE 754 floating point number
-on 64 bits.
-
-## 1.15.1 Examples
-
-```elixir
-ikc3> (F64) 1 + (F64) 0.001
-(F64) 1.00099999999999
-```
\ No newline at end of file
diff --git a/doc/1_KC3/1.15_List.en.md b/doc/1_KC3/1.15_List.en.md
new file mode 100644
index 0000000..3ef40d6
--- /dev/null
+++ b/doc/1_KC3/1.15_List.en.md
@@ -0,0 +1,38 @@
+# 1.15 List
+
+Linked lists owning the data (each node contains a couple of tags :
+one for data and one for next pointer.
+
+Regular lists can be :
+ - multiple elements : `[1, 2, 3]`
+ - an element and a list : `[1 | [2, 3]]`
+ - multiple elements and a list : `[1, 2 | [3]]`
+ - the empty list : `[]`
+
+Regular lists end with the empty list : `[1] == [1 | []]`.
+
+You can also contruct dotted lists like in Common Lisp where
+the next list pointer is an arbitrary form. E.g. :
+ - an element and an element : `[1 | 2]`
+ - multiple elements and an element : `[1, 2, 3 | 4]`
+ - the empty list and an element : `[[] | 1]`
+
+All these list formats are supported in pattern matching.
+
+## 1.15.1 Functions
+
+```elixir
+List List.map (List, Fn)
+```
+
+```elixir
+List List.reverse (List)
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.14 Integer](1.14_Integer)
+
+Next : [1.16 Map](1.16_Map)
diff --git a/doc/1_KC3/1.16_F128.en.md b/doc/1_KC3/1.16_F128.en.md
deleted file mode 100644
index c0053ac..0000000
--- a/doc/1_KC3/1.16_F128.en.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# 1.16 F128
-
-The KC3 `F128` type is a C-compatible IEEE 754 floating point number
-on 128 bits.
-
-## 1.16.1 Examples
-
-```elixir
-ikc3> (F128) 1 - (F128) 0.001
-(F128) 9.989999999999999999791833182882783e-1
-```
\ No newline at end of file
diff --git a/doc/1_KC3/1.16_Map.en.md b/doc/1_KC3/1.16_Map.en.md
new file mode 100644
index 0000000..94635da
--- /dev/null
+++ b/doc/1_KC3/1.16_Map.en.md
@@ -0,0 +1,79 @@
+# 1.16 Map
+
+KC3 maps are like Elixir maps, they are key-values enclosed in `%{}` :
+
+```elixir
+ikc3> a = %{id: 1, title: "My title", message: "Hello, world !"}
+%{id: 1,
+ title: "My title",
+ message: "Hello, world !"}
+```
+
+Destructuring works with maps to extract values :
+
+```elixir
+ikc3> %{id: id, title: "My title", message: message} = ^ a
+%{id: 1,
+ title: "My title",
+ message: "Hello, world !"}
+ikc3> id
+1
+ikc3> message
+"Hello, world !"
+```
+
+
+You can use the dot syntax to access map values from a `Sym` key :
+
+```elixir
+ikc3> a = %{id: 1, title: "My title", message: "Hello, world !"}
+%{id: 1,
+ title: "My title",
+ message: "Hello, world !"}
+ikc3> a.id
+1
+ikc3> a.message
+"Hello, world !"
+```
+
+The bracket syntax allows you to query any key type :
+
+```elixir
+ikc3> a[:id]
+1
+ikc3> a[:message]
+"Hello, world !"
+```
+
+You can also use the `KC3.access` function for the same result :
+
+```elixir
+ikc3> a = %{id: 1, title: "My title", message: "Hello, world !"}
+%{id: 1,
+ title: "My title",
+ message: "Hello, world !"}
+ikc3> access(a, [:id])
+1
+ikc3> access(a, [:message])
+"Hello, world !"
+```
+
+To update an existing map you can use Map.put like this :
+
+```elixir
+ikc3> a = %{id: 1, title: "My title"}
+%{id: 1,
+ title: "My title"}
+ikc3> a = Map.put(a, :message, "Hello, world !")
+%{id: 1,
+ title: "My title",
+ message: "Hello, world !"}
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.15 List](1.15_List)
+
+Next : [1.17 Ptr](1.17_Ptr)
diff --git a/doc/1_KC3/1.17_Ident.en.md b/doc/1_KC3/1.17_Ident.en.md
deleted file mode 100644
index 7f28cd6..0000000
--- a/doc/1_KC3/1.17_Ident.en.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# 1.17 Ident
-
-The KC3 `Ident` type is an identifier. An identifier evaluates to its
-bound value in the current environnement, that is in local and global
-frames and then in the triple store.
-
-## 1.17.1 Examples
-
-To get an `Ident` you can use quote :
-
-```elixir
-ikc3> quote List.reverse
-List.reverse
-ikc3> type(quote List.reverse)
-Ident
-```
-
-To bind a value to an ident you can use pattern matching :
-
-```elixir
-ikc3> [one, two, three | rest] = List.count(5)
-[1, 2, 3, 4, 5]
-ikc3> type(quote one)
-Ident
-ikc3> one
-1
-ikc3> two
-2
-ikc3> three
-3
-ikc3> rest
-[4, 5]
-```
-
-Otherwise you can use `KC3.def` and it will store the value in the
-graph database (facts) :
-
-```elixir
-ikc3> def one = 1
-1
-ikc3> def two = one + one
-2
-ikc3> two
-2
-```
diff --git a/doc/1_KC3/1.17_Ptr.en.md b/doc/1_KC3/1.17_Ptr.en.md
new file mode 100644
index 0000000..2f51c01
--- /dev/null
+++ b/doc/1_KC3/1.17_Ptr.en.md
@@ -0,0 +1,22 @@
+# 1.17 Ptr
+
+In KC3 there should be no use for Ptr type but it's here to stay
+compatible with C's `void *` type.
+
+You can cast from and to a pointer but be careful about correctly
+chaining casts from the same type to the same type.
+
+The only parsable pointer is the NULL pointer :
+
+```elixir
+ikc3> (Ptr) 0
+(Ptr) 0
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.16 Map](1.16_Map)
+
+Next : [1.18 Quote](1.18_Quote)
diff --git a/doc/1_KC3/1.18_Callable.en.md b/doc/1_KC3/1.18_Callable.en.md
deleted file mode 100644
index 957dc94..0000000
--- a/doc/1_KC3/1.18_Callable.en.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# 1.18 Callable
-
-The KC3 `Callable` type is an or-type of `Cfn` and `Fn`.
-
-In any case where you accept a `Fn` or `Cfn` as an argument
-you should use `Callable` as the type.
diff --git a/doc/1_KC3/1.18_Quote.en.md b/doc/1_KC3/1.18_Quote.en.md
new file mode 100644
index 0000000..2fd28e9
--- /dev/null
+++ b/doc/1_KC3/1.18_Quote.en.md
@@ -0,0 +1,28 @@
+# 1.18 Quote
+
+The KC3 `Quote` type allows you for partial quotes. See `Unquote`.
+
+Quoting is necessary for meta-programming where you want to return
+a quoted value that will not be evaluated except the quote will be
+removed.
+
+## 1.18.1 Examples
+
+```elixir
+ikc3> quote 1 + 1
+1 + 1
+ikc3> quote quote 1 + 1
+quote 1 + 1
+ikc3> type(quote 1 + 1)
+Call
+ikc3> type(quote quote 1 + 1)
+Quote
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.17 Ptr](1.17_Ptr)
+
+Next : [1.19 Ratio](1.19_Ratio)
diff --git a/doc/1_KC3/1.19_Ptr.en.md b/doc/1_KC3/1.19_Ptr.en.md
deleted file mode 100644
index ed38c8b..0000000
--- a/doc/1_KC3/1.19_Ptr.en.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# 1.19 Ptr
-
-In KC3 there should be no use for Ptr type but it's here to stay
-compatible with C's `void *` type.
-
-You can cast from and to a pointer but be careful about correctly
-chaining casts from the same type to the same type.
-
-The only parsable pointer is the NULL pointer :
-
-```elixir
-ikc3> (Ptr) 0
-(Ptr) 0
-```
diff --git a/doc/1_KC3/1.19_Quote.en.md b/doc/1_KC3/1.19_Quote.en.md
deleted file mode 100644
index 2025996..0000000
--- a/doc/1_KC3/1.19_Quote.en.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# 1.19 Quote
-
-The KC3 `Quote` type allows you for partial quotes. See `Unquote`.
-
-Quoting is necessary for meta-programming where you want to return
-a quoted value that will not be evaluated except the quote will be
-removed.
-
-## 1.19.1 Examples
-
-```elixir
-ikc3> quote 1 + 1
-1 + 1
-ikc3> quote quote 1 + 1
-quote 1 + 1
-ikc3> type(quote 1 + 1)
-Call
-ikc3> type(quote quote 1 + 1)
-Quote
-```
diff --git a/doc/1_KC3/1.19_Ratio.en.md b/doc/1_KC3/1.19_Ratio.en.md
new file mode 100644
index 0000000..ba07c9f
--- /dev/null
+++ b/doc/1_KC3/1.19_Ratio.en.md
@@ -0,0 +1,25 @@
+# 1.19 Ratio
+
+Ratios are made with a couple of large integers : the numerator
+which can be any number, and the denominator which has to be positive.
+They represent fractions of integral numbers.
+They are written with a slash and no space.
+
+```elixir
+ikc3> 1/2 + 2/3
+7/6
+ikc3> 1/2 * 2/3
+1/3
+ikc3> 1/2 / 2/3
+3/4
+ikc3> 1/2 - 2/3
+-1/6
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.18 Quote](1.18_Quote)
+
+Next : [1.20 Str](1.20_Str)
diff --git a/doc/1_KC3/1.20_Str.en.md b/doc/1_KC3/1.20_Str.en.md
new file mode 100644
index 0000000..cd64df5
--- /dev/null
+++ b/doc/1_KC3/1.20_Str.en.md
@@ -0,0 +1,44 @@
+# 1.20 Str type.
+
+Read-only string of bytes. Use `Str.size` to get the size in bytes
+of the string (without NUL terminator). All KC3 strings are bound-
+checked according to their size and are NUL terminated.
+
+## 1.20.1 String litterals and interpolation
+
+A string litteral starts and ends with double quotes `"`
+or triple quotes `"""` and inside of a string litteral you can use
+the `#{expr}` syntax to evaluate `expr` to a `Str` inside of the
+litteral. The string litteral is then parsed as a `Call` to `KC3.str`
+and not an actual `Str`. At evaluation the arguments to the call
+and `KC3.str` gets called concatenating at once all the parts to a
+brand new `Str`.
+
+## 1.20.2 Examples
+
+```elixir
+ikc3> "123"
+"123"
+ikc3> type("123")
+Str
+ikc3> b = 2
+2
+ikc3> "1#{b}3"
+"123"
+ikc3> type("1#{b}3")
+Str
+ikc3> quote "1#{b}3"
+"1#{b}3"
+ikc3> type(quote "1#{b}3")
+Call
+ikc3> type(quote quote "1#{b}3")
+Quote
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.19 Ratio](1.19_Ratio)
+
+Next : [1.21 Struct](1.21_Struct)
diff --git a/doc/1_KC3/1.20_Sym.en.md b/doc/1_KC3/1.20_Sym.en.md
deleted file mode 100644
index 0e3ae96..0000000
--- a/doc/1_KC3/1.20_Sym.en.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# 1.20 Sym
-
-The KC3 type `Sym` is used everywhere in KC3. This is symbolic
-computing : the triple store and data rely on interned strings
-which are easy to compare for equality.
-
-Sorting still relies on Sym's string representation so is slower
-than just comparing pointers.
-
-Symbols either start with a capital letter character, in which
-case this symbol also is a package name (see Packages).
-Otherwise symbols start with `:` and if the symbol string contains
-reserved characters then the symbol is quoted.
-
-## 1.20.1 Examples
-
-```elixir
-ikc3> :"123"
-:123
-ikc3> type(:123)
-Sym
-ikc3> MyModule
-MyModule
-ikc3> type(MyModule)
-Sym
-```
diff --git a/doc/1_KC3/1.21_Map.en.md b/doc/1_KC3/1.21_Map.en.md
deleted file mode 100644
index adc0b95..0000000
--- a/doc/1_KC3/1.21_Map.en.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# 1.21 Map
-
-KC3 maps are like Elixir maps, they are key-values enclosed in `%{}` :
-
-```elixir
-ikc3> a = %{id: 1, title: "My title", message: "Hello, world !"}
-%{id: 1,
- title: "My title",
- message: "Hello, world !"}
-```
-
-Destructuring works with maps to extract values :
-
-```elixir
-ikc3> %{id: id, title: "My title", message: message} = ^ a
-%{id: 1,
- title: "My title",
- message: "Hello, world !"}
-ikc3> id
-1
-ikc3> message
-"Hello, world !"
-```
-
-
-You can use the dot syntax to access map values from a `Sym` key :
-
-```elixir
-ikc3> a = %{id: 1, title: "My title", message: "Hello, world !"}
-%{id: 1,
- title: "My title",
- message: "Hello, world !"}
-ikc3> a.id
-1
-ikc3> a.message
-"Hello, world !"
-```
-
-The bracket syntax allows you to query any key type :
-
-```elixir
-ikc3> a[:id]
-1
-ikc3> a[:message]
-"Hello, world !"
-```
-
-You can also use the `KC3.access` function for the same result :
-
-```elixir
-ikc3> a = %{id: 1, title: "My title", message: "Hello, world !"}
-%{id: 1,
- title: "My title",
- message: "Hello, world !"}
-ikc3> access(a, [:id])
-1
-ikc3> access(a, [:message])
-"Hello, world !"
-```
-
-To update an existing map you can use Map.put like this :
-
-```elixir
-ikc3> a = %{id: 1, title: "My title"}
-%{id: 1,
- title: "My title"}
-ikc3> a = Map.put(a, :message, "Hello, world !")
-%{id: 1,
- title: "My title",
- message: "Hello, world !"}
-```
-
----
-
-Top : [KC3 documentation](/doc/)
diff --git a/doc/1_KC3/1.21_Struct.en.md b/doc/1_KC3/1.21_Struct.en.md
new file mode 100644
index 0000000..01751a6
--- /dev/null
+++ b/doc/1_KC3/1.21_Struct.en.md
@@ -0,0 +1,126 @@
+# 1.21 Struct
+
+KC3 structs are a key value associative data structure with default
+values and arbitrary property order.
+
+They are compatible with C structs of the same type.
+
+```elixir
+ikc3> a = %KC3.Op{sym: :dot,
+ precedence: 10,
+ callable: fn (a, b) { a.x * b.y + a.y * b.y }}
+%KC3.Op{sym: :dot,
+ arity: 2,
+ special: false,
+ precedence: 10,
+ associativity: 1,
+ callable: fn (a, b) { a.x * b.y + a.y * b.y }}
+```
+
+You can define one _struct type_ per module with `defstruct` for
+example in `vec2d.kc3` :
+
+```elixir
+defmodule Vec2D do
+
+ defstruct [x: 0.0,
+ y: 0.0]
+
+end
+```
+
+Destructuring works with structs to extract values :
+
+```elixir
+ikc3> %KC3.Op{sym: sym} = ^ a
+%KC3.Op{sym: :dot,
+ arity: 2,
+ special: false,
+ precedence: 10,
+ associativity: 1,
+ callable: fn (a, b) { a.x * b.y + a.y * b.y }}
+ikc3> sym
+:dot
+```
+
+
+You can use the dot syntax to access struct values from a `Sym` key :
+
+```elixir
+ikc3> a = %KC3.Op{sym: :dot,
+ precedence: 10,
+ callable: fn (a, b) { a.x * b.y + a.y * b.y }}
+%KC3.Op{sym: :dot,
+ arity: 2,
+ special: false,
+ precedence: 10,
+ associativity: 1,
+ callable: fn (a, b) { a.x * b.y + a.y * b.y }}
+ikc3> a.sym
+:dot
+ikc3> a.arity
+2
+ikc3> a.callable
+fn (a, b) { a.x * b.y + a.y * b.y }
+```
+
+The bracket syntax allows you to query structs the same as maps :
+
+```elixir
+ikc3> a[:sym]
+:dot
+ikc3> a[:arity]
+2
+ikc3> a[:callable]
+fn (a, b) { a.x * b.y + a.y * b.y }
+```
+
+You can also use the `KC3.access` function for the same result :
+
+```elixir
+ikc3> a = %KC3.Op{sym: :dot,
+ precedence: 10,
+ callable: fn (a, b) { a.x * b.y + a.y * b.y }}
+%KC3.Op{sym: :dot,
+ arity: 2,
+ special: false,
+ precedence: 10,
+ associativity: 1,
+ callable: fn (a, b) { a.x * b.y + a.y * b.y }}
+ikc3> access(a, [:sym])
+:dot
+ikc3> access(a, [:arity])
+2
+ikc3> access(a, [:callable])
+fn (a, b) { a.x * b.y + a.y * b.y }
+```
+
+To update an existing struct property you can use Struct.put, a new
+struct with modified properties will be returned. E.g. :
+
+```elixir
+ikc3> a = %KC3.Op{sym: :dot,
+ precedence: 10,
+ callable: fn (a, b) { a.x * b.y + a.y * b.y }}
+%KC3.Op{sym: :dot,
+ arity: 2,
+ special: false,
+ precedence: 10,
+ associativity: 1,
+ callable: fn (a, b) { a.x * b.y + a.y * b.y }}
+b = Struct.put(a, :sym, :ยท)
+%KC3.Op{sym: :ยท,
+ arity: 2,
+ special: false,
+ precedence: 10,
+ associativity: 1,
+ callable: fn (a, b) { a.x * b.y + a.y * b.y }}
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.20 Str](1.20_Str)
+
+Next : [1.22 Sym](1.22_Sym)
diff --git a/doc/1_KC3/1.22_Sym.en.md b/doc/1_KC3/1.22_Sym.en.md
new file mode 100644
index 0000000..ec6d6cc
--- /dev/null
+++ b/doc/1_KC3/1.22_Sym.en.md
@@ -0,0 +1,34 @@
+# 1.22 Sym
+
+The KC3 type `Sym` is used everywhere in KC3. This is symbolic
+computing : the triple store and data rely on interned strings
+which are easy to compare for equality.
+
+Sorting still relies on Sym's string representation so is slower
+than just comparing pointers.
+
+Symbols either start with a capital letter character, in which
+case this symbol also is a package name (see Packages).
+Otherwise symbols start with `:` and if the symbol string contains
+reserved characters then the symbol is quoted.
+
+## 1.22.1 Examples
+
+```elixir
+ikc3> :"123"
+:123
+ikc3> type(:123)
+Sym
+ikc3> MyModule
+MyModule
+ikc3> type(MyModule)
+Sym
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.21 Struct](1.21_Struct)
+
+Next : [1.23 Tuple](1.23_Tuple)
diff --git a/doc/1_KC3/1.22_Tuple.en.md b/doc/1_KC3/1.22_Tuple.en.md
deleted file mode 100644
index 132244e..0000000
--- a/doc/1_KC3/1.22_Tuple.en.md
+++ /dev/null
@@ -1,51 +0,0 @@
-# 1.22 Tuple
-
-KC3 tuples are immutable arrays of `Tag`. They contain a fixed number of
-constant values of any type. Tuple access is very fast.
-
-Tuples can be used to return more than one value from a function.
-For example a successful function call might result in a
-`{:ok, result}` tuple, while an error might produce the
-`{:error, "Message", data, trace}` tuple.
-
-## 1.22.1 Examples
-
-```elixir
-ikc3> a = {:ok, "My title", "Hello, world !"}
-{:ok, "My title", "Hello, world !"}
-```
-
-Destructuring works with tuples to extract values :
-
-```elixir
-ikc3> {:ok, title, message} = ^ a
-{:ok, "My title", "Hello, world !"}
-ikc3> title
-"My title"
-ikc3> message
-"Hello, world !"
-```
-
-The bracket syntax allows you to query the tag at a tuple position :
-
-```elixir
-ikc3> a[0]
-:ok
-ikc3> a[1]
-"My title"
-ikc3> a[2]
-"Hello, world !"
-```
-
-You can also use the `KC3.access` function for the same result :
-
-```elixir
-ikc3> a = {:ok, "My title", "Hello, world !"}
-{:ok, "My title", "Hello, world !"}
-ikc3> access(a, [0])
-:ok
-ikc3> access(a, [1])
-"My title"
-ikc3> access(a, [2])
-"Hello, world !"
-```
diff --git a/doc/1_KC3/1.23_Tuple.en.md b/doc/1_KC3/1.23_Tuple.en.md
new file mode 100644
index 0000000..5a12651
--- /dev/null
+++ b/doc/1_KC3/1.23_Tuple.en.md
@@ -0,0 +1,59 @@
+# 1.23 Tuple
+
+KC3 tuples are immutable arrays of `Tag`. They contain a fixed number of
+constant values of any type. Tuple access is very fast.
+
+Tuples can be used to return more than one value from a function.
+For example a successful function call might result in a
+`{:ok, result}` tuple, while an error might produce the
+`{:error, "Message", data, trace}` tuple.
+
+## 1.23.1 Examples
+
+```elixir
+ikc3> a = {:ok, "My title", "Hello, world !"}
+{:ok, "My title", "Hello, world !"}
+```
+
+Destructuring works with tuples to extract values :
+
+```elixir
+ikc3> {:ok, title, message} = ^ a
+{:ok, "My title", "Hello, world !"}
+ikc3> title
+"My title"
+ikc3> message
+"Hello, world !"
+```
+
+The bracket syntax allows you to query the tag at a tuple position :
+
+```elixir
+ikc3> a[0]
+:ok
+ikc3> a[1]
+"My title"
+ikc3> a[2]
+"Hello, world !"
+```
+
+You can also use the `KC3.access` function for the same result :
+
+```elixir
+ikc3> a = {:ok, "My title", "Hello, world !"}
+{:ok, "My title", "Hello, world !"}
+ikc3> access(a, [0])
+:ok
+ikc3> access(a, [1])
+"My title"
+ikc3> access(a, [2])
+"Hello, world !"
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.22 Sym](1.22_Sym)
+
+Next : [1.24 Var](1.24_)
diff --git a/doc/1_KC3/1.24_Variable.en.md b/doc/1_KC3/1.24_Variable.en.md
new file mode 100644
index 0000000..1ebfc77
--- /dev/null
+++ b/doc/1_KC3/1.24_Variable.en.md
@@ -0,0 +1,51 @@
+# 1.24 Variables
+
+Variables in KC3 can be defined using the litteral value for a variable
+which is always `?`. You can cast this litteral value and it will not
+really be casted but it will give you a typed variable litteral value.
+E.g. `(List) ?`.
+The typed variable litteral value will only accept to be set once to
+one value of the variable's type (in this example the type of a linked
+list).
+
+It's actually a syntax so you cannot rename `?` by mistake and
+so is an easy task to do static analysis of variable creation.
+
+The default type for a variable which you can also specify explicitly
+is `Tag` which is an enum-tagged union type of any other KC3 types
+currently defined in the environment. So `?` is exactly equivalent to
+`(Tag) ?` and they will both accept to be set once to one value of any
+type.
+
+A variable is settable once and cannot be changed afterwards (there is
+an exception if you write C code and link to it but it is not easy nor
+silent).
+
+This way you do not need to lock or trust any behaviour, once your
+variable is set to a value the value of the variable will never change,
+it really is read-only.
+
+You can also use the assignment operator which is `<-` which in turn calls
+`tag_init_copy`. It works like the C assignment operator (`=`).
+
+## 1.24.1 Examples
+
+```elixir
+# Declare a unsigned byte 8 bits variable "x".
+x = (U8) ?
+# Set the variable "x" to zero.
+x <- 0
+# Allocate again for the same binding name "x"
+x = (U8) ?
+# Also set the new variable "x" to zero with just one Unicode symbol
+# that is AltGr+Y on my keyboard.
+x โ 0
+```
+
+---
+
+Top : [KC3 documentation](/doc/)
+
+Previous : [1.23 Tuple](1.23_Tuple)
+
+Next : [2 HTTPd](2_HTTPd)