diff --git a/doc/userdoc.org b/doc/userdoc.org
index 3f8ae8f9c04cba5b031d033b2c00e6be4e2b4b0d..203404c7c29e148df6479d5a0a21ddfcbb55f283 100644
--- a/doc/userdoc.org
+++ b/doc/userdoc.org
@@ -2047,18 +2047,46 @@ changes the output to
 
 Obviously the behavior is the same using ~do...while~ or ~while~ loops.
 
-** TODO Functions<<functions>>
+** Functions<<functions>>
+
+The ~pugs~ language allow the manipulation and definition of
+functions. These are *mathematical functions* and are not functions as
+functions in ~C++~. The functions in the ~pugs~ language are *not
+subroutines*.
+
+To be more precise, a function $f$ follows the following structure
+\begin{align*}
+    \mbox{let }f:& X_1\times \cdots \times X_n \to Y_1\times \cdots \times Y_m,\\
+                 & (x_1,\ldots,x_n)\mapsto (y_1,\ldots,y_m)=f(x_1,\ldots,x_n),
+\end{align*}
+where $n,m\in\mathbb{N}$, and where ${(X_i)}_{0\le i\le n}$ and ${(Y_i)}_{0\le
+i\le m}$ are /simple/ types. Actually $X_1\times \cdots \times X_n$ and
+$Y_1\times \cdots \times Y_m$ are /compound/ types.
+
+
+Thus assuming that the function $f$ is defined in the language as ~f~,
+one can use the following syntax to evaluate it. This is a
+pseudo-code, real examples will follow. Assuming that ~(x1...,xn)~ has
+been properly defined in ~X1*...*Xn~ one can write
+#+BEGIN_SRC pugs :exports code
+  let (y1,...,ym):Y1*...*Ym, (y1,...,ym) = f(x1,...,xn);
+#+END_SRC
+or if ~(y1,...,ym)~ has already been defined in  ~Y1*...*Ym~
+#+BEGIN_SRC pugs :exports code
+  (y1,...,ym) = f(x1,...,xn);
+#+END_SRC
 
 *** Pure functions
 
-*** Implicit type conversion for parameters and returned values
+*** TODO Implicit type conversion for parameters and returned values
 
-*** User-defined functions
+*** TODO User-defined functions
+
+*** TODO Builtin functions
+
+** TODO modules
 
-*** Builtin functions
 
 [fn:pugs-def] ~pugs~: Parallel Unstructured Grid Solvers
 [fn:MPI-def] ~MPI~: Message Passing Interface
 [fn:DSL-def] ~DSL~: Domain Specific Language
-
-** TODO modules