diff --git a/examples/w1_2.rs b/examples/w1_2.rs
index fcf5cd9b46e5caa9bef00d11d71cb40be9a40ba6..83df078f15614ee705964a5a906c5eaded20f218 100644
--- a/examples/w1_2.rs
+++ b/examples/w1_2.rs
@@ -16,12 +16,11 @@ fn c(x: i32, y: i32) -> i32 {
     -a - (-b) * y // here we have prefix operator "-"
 }
 
-
 // More advanced statements
 
 // a function taking two bool arguments returning the bool type
 // with some let statements and function calls
-fn a(x: bool, y: bool) -> bool {
+fn a1(x: bool, y: bool) -> bool {
     if x && y {
         let a: bool = true;
         y || a
@@ -32,8 +31,8 @@ fn a(x: bool, y: bool) -> bool {
 
 // a function taking two bool arguments returning the i32 type
 // with some let statements and function calls
-fn b(x: bool, y: bool) -> i32 {
-    let a: bool = a(x, y || false);
+fn b1(x: bool, y: bool) -> i32 {
+    let a: bool = a1(x, y || false);
     let mut b: i32 = 0;
     if a && y {
         let a: bool = true; // shadowing
@@ -50,7 +49,7 @@ fn b(x: bool, y: bool) -> i32 {
 
 // a function taking two bool arguments returning the i32 type
 // while
-fn c(x: bool, y: bool) -> i32 {
+fn c1(x: bool, y: bool) -> i32 {
     let mut b: i32 = 0;
     let mut c: i32 = 1;
     while (b < 10) {
diff --git a/src/check.rs b/src/check.rs
index 46c2d2a53031e18148408a3bdef1c4a6eb9c6486..9bda67bcb1d3e2d533caa7953d73887c318ca018 100644
--- a/src/check.rs
+++ b/src/check.rs
@@ -45,6 +45,8 @@ fn expr_type(
 ) -> Result<Type, Error> {
     use Expr::*;
     trace!("expr_type {}", e);
+    trace!("var_env {:?}", var_env);
+
     match e {
         Num(_) => Ok(Type::I32),
         Bool(_) => Ok(Type::Bool),
@@ -57,15 +59,16 @@ fn expr_type(
 
             use Op::*;
             match op {
-                // Arithmetic and Boolean
+                // Arithmetic and Boolen
                 Add | Mul | Div | Sub | And | Or => {
-                    // check if op and args are of i32
-                    if lt == Type::I32 && rt == Type::I32 {
-                        Ok(Type::I32)
+                    // check if op and args are compliant
+                    let opt = op.get_type();
+                    if lt == opt && rt == opt {
+                        Ok(opt)
                     } else {
                         Err(format!(
-                            "Num operation requires i32, left {}  right {}",
-                            lt, rt
+                            "Expected type {}, found, left {}: {}, {:?}  right {}: {}, {:?}",
+                            opt, l, lt, lt, r, rt, rt
                         ))
                     }
                 }
@@ -373,7 +376,7 @@ pub fn check(p: &Program) -> Result<(), Error> {
     trace!("Input program \n{}", &p);
 
     for fd in p.fn_decls.iter() {
-        trace!("function id {}", fd.id);
+        trace!("check function\n{}", fd);
         let mut var_env = VarEnv::new();
 
         // build a scope for the arguments
@@ -390,9 +393,9 @@ pub fn check(p: &Program) -> Result<(), Error> {
         var_env.push_param_scope(arg_ty);
 
         let stmt_type = check_stmts(&fd.body, &fn_env, &type_env, &mut var_env);
-        trace!("function id {}: {:?}", fd.id, &stmt_type);
+        trace!("result {}: {:?}", fd.id, &stmt_type);
 
-        let stmt_type = stmt_type?;
+        let stmt_type = strip_mut(stmt_type?);
 
         if stmt_type != fd.result {
             Err(format!(
diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop
index eaa7f05cf4e83f96426974bccaac937f55ae7b40..239904f84072360ccac9c4d528e1e4c75f93bf86 100644
--- a/src/grammar.lalrpop
+++ b/src/grammar.lalrpop
@@ -150,9 +150,10 @@ Stmt : Stmt = {
 
 
 Type : Type = {
-    Id => Type::Named(<>),
+    "bool" => Type::Bool,
     "()" => Type::Unit,
     "i32" => Type::I32, // this should likely be a paratrized Num type later
+    Id => Type::Named(<>),
     "&" <Type> => Type::Ref(Box::new(<>)),
     "&" "mut" <Type> => Type::Ref(Box::new(Type::Mut(Box::new(<>)))),
 }