diff --git a/doc/userdoc.org b/doc/userdoc.org
index 960c47d9f3e8a732c33fb1a4e1510ac9d3a857b9..dcc8742d1e735a165ed4af818a4d65cf464d669d 100644
--- a/doc/userdoc.org
+++ b/doc/userdoc.org
@@ -557,40 +557,6 @@ A practical example is
 which produces the result
 #+results: simple-definition-example
 
-**** Compound declarations and affectations
-We shall now see some weird constructions that are not useful by
-themselves but which are important when dealing with builtin functions.
-
-We just give an example which should be enough to explain the syntax.
-
-#+NAME: compound-definition-example
-#+BEGIN_SRC pugs :exports both :results output
-  let (a, b, x):N*N*R;
-  (x,b) = (2.3, 12);
-  a = 3;
-
-  cout << "a = " << a << " b = " << b << " x = " << x << "\n";
-
-  let (c,y,d) : N*R*N, (c, y, d) = (8, 1e-3, 2);
-
-  cout << "c = " << c << " d = " << d << " y = " << y << "\n";
-#+END_SRC
-which produces the result
-#+results: compound-definition-example
-
-The only potential mistake with this construction, is that variables
-must appear in the same order in the declaration part and in the
-affectation part of a definition. For instance, the following code is
-invalid.
-
-#+NAME: invalid-compound-definition
-#+BEGIN_SRC pugs-error :exports both :results output
-  let (x,y):R*R, (y,x) = (0,1);
-#+END_SRC
-It produces the following error
-#+results: invalid-compound-definition
-which is easy to fix.
-
 *** Blocks and lifetime of variables<<blocks-and-life-time>>
 
 In pugs scripts, variables have a precise lifetime. They are defined
@@ -1647,7 +1613,100 @@ types. This is transparent to the user and provides the intuitive
 (similar) behavior since data of high-level variables are constant. To
 illustrate this, let us consider the following example.
 
-*** TODO Lists
+*** Compound types
+
+The ~pugs~ language allow to deal with compound types. The idea is to
+define lists variables as a member of a product space (each variable
+belongs to one of them, each variable has a simple type: basic or
+high-level).
+
+**** Compound declaration
+
+Let us provide an example to fix ideas.
+#+NAME: compound-declaration
+#+BEGIN_SRC pugs :exports both :results output
+  let (A,x,n): R^2x2*R^3*N;
+  A = (1,2,3,4);
+  x = (2,4,6);
+  n = 2;
+
+  cout << "A = " << A << "\nx = " << x << "\nn = " << n << "\n";
+#+END_SRC
+the output is
+#+RESULTS: compound-declaration
+
+This is completely equivalent to declaring the variables one after the
+other.
+
+**** Compound definition
+
+One can also use the following definition instruction
+#+NAME: compound-definition
+#+BEGIN_SRC pugs :exports both :results output
+  let (A,x,n): R^2x2*R^3*N, (A,x,n) = ((1,2,3,4), (2,4,6), 2);
+
+  cout << "A = " << A << "\nx = " << x << "\nn = " << n << "\n";
+#+END_SRC
+which gives the same result
+#+RESULTS: compound-definition
+
+A potential mistake with this construction, is that variables
+must appear in the same order in the declaration part and in the
+affectation part of a definition. For instance, the following code is
+invalid.
+
+#+NAME: invalid-compound-definition
+#+BEGIN_SRC pugs-error :exports both :results output
+  let (x,y):R*R, (y,x) = (0,1);
+#+END_SRC
+It produces the following error
+#+results: invalid-compound-definition
+which is easy to fix.
+
+Another potential mistake is that all variables are marked to be
+defined at the same time. Thus one cannot use construction like this:
+#+NAME: undeclared-compound-definition
+#+BEGIN_SRC pugs-error :exports both :results output
+  let (x,y):R*R, (x,y) = (0,2+x);
+#+END_SRC
+It produces the following error
+#+results: undeclared-compound-definition
+While the variable ~x~ is defined *before* ~y~, this kind of construction is
+forbidden. From a technical point of view, this behavior would be easy
+to change (allow to use the fresh value of ~x~ in the definition of ~y~),
+but this make the code unclear and this is not the purpose of compound
+types.
+
+**** Compound affectation
+
+The last way to use compound types is illustrated by the following
+example.
+#+NAME: compound-affectation
+#+BEGIN_SRC pugs :exports both :results output
+  let A: R^2x2;
+  let x: R^3;
+  let n: N;
+
+  (A,x,n) = ((1,2,3,4), (2,4,6), 2);
+
+  cout << "A = " << A << "\nx = " << x << "\nn = " << n << "\n";
+#+END_SRC
+It produces again
+#+results: compound-affectation
+
+#+BEGIN_note
+Observe that the only operator allowed for this kind of construction
+is the operator ~=~.
+#+END_note
+
+**** Use of compound types
+
+Actually using compound types the way it is presented in this
+paragraph is not recommend. The purpose of compounds types and
+compound affectations is related to functions. As one will see in
+section [[functions]], functions can return compound values, thus compound
+affectations (or definitions) are needed to get returned values in
+that case.
 
 *** TODO Tuples types