diff --git a/src/language/ASTNodeDataTypeBuilder.cpp b/src/language/ASTNodeDataTypeBuilder.cpp
index 0f23059f4ddc5057116fb83a5555746911169262..5bac1b114a07489581af98f60e5abec7016315ac 100644
--- a/src/language/ASTNodeDataTypeBuilder.cpp
+++ b/src/language/ASTNodeDataTypeBuilder.cpp
@@ -220,13 +220,14 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
             ASTNodeDataType image_type = getVectorDataType(image_domain_node);
             if (image_type.dimension() != nb_image_expressions) {
               std::ostringstream message;
-              message << "note: expecting " << image_domain_node.m_data_type.dimension() << " expressions found "
-                      << nb_image_expressions << std::ends;
+              message << "expecting " << image_type.dimension() << " scalar expressions or an "
+                      << dataTypeName(image_type) << ", found " << nb_image_expressions << " scalar expressions"
+                      << std::ends;
               throw parse_error(message.str(), image_domain_node.begin());
             }
           } else {
             std::ostringstream message;
-            message << "note: number of image spaces (" << nb_image_domains << ") " << rang::fgB::yellow
+            message << "number of image spaces (" << nb_image_domains << ") " << rang::fgB::yellow
                     << image_domain_node.string() << rang::style::reset << rang::style::bold
                     << " differs from number of expressions (" << nb_image_expressions << ") " << rang::fgB::yellow
                     << image_expression_node.string() << rang::style::reset << std::ends;
diff --git a/tests/test_ASTNodeDataTypeBuilder.cpp b/tests/test_ASTNodeDataTypeBuilder.cpp
index 79c53a57f71387cd9e9f15daeaea14ec340f5916..496cd68cdbe43adcf8e551284f03c2641705967b 100644
--- a/tests/test_ASTNodeDataTypeBuilder.cpp
+++ b/tests/test_ASTNodeDataTypeBuilder.cpp
@@ -255,6 +255,19 @@ R*B*N*string (x,b,n,s);
 
     SECTION("errors")
     {
+      SECTION("invalid array subscript")
+      {
+        std::string_view data = R"(
+R x; x[2];
+)";
+
+        string_input input{data, "test.pgs"};
+        auto ast = ASTBuilder::build(input);
+        ASTSymbolTableBuilder{*ast};
+
+        REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast}, "invalid types 'R[Z]' for array subscript");
+      }
+
       SECTION("too many variables")
       {
         std::string_view data = R"(
@@ -295,13 +308,75 @@ R (x,y);
 
         REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast}, "unexpected variable list for single space");
       }
+
+      SECTION("invalid R-list -> R^d")
+      {
+        std::string_view data = R"(
+let square : R -> R^3, x -> (x, x*x);
+)";
+
+        string_input input{data, "test.pgs"};
+        auto ast = ASTBuilder::build(input);
+        ASTSymbolTableBuilder{*ast};
+
+        REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast},
+                            "expecting 3 scalar expressions or an R^3, found 2 scalar expressions");
+      }
     }
   }
 
   SECTION("let declaration")
   {
+    SECTION("R^d-functions")
+    {
+      SECTION("vector function")
+      {
+        std::string_view data = R"(
+let double : R^2 -> R^2, x -> 2*x;
+)";
+
+        std::string_view result = R"(
+(root:void)
+ `-(language::let_declaration:void)
+     `-(language::name:double:function)
+)";
+
+        CHECK_AST(data, result);
+      }
+
+      SECTION("R-list -> R^d")
+      {
+        std::string_view data = R"(
+let square : R -> R^2, x -> (x, x*x);
+)";
+
+        std::string_view result = R"(
+(root:void)
+ `-(language::let_declaration:void)
+     `-(language::name:square:function)
+)";
+
+        CHECK_AST(data, result);
+      }
+    }
+
     SECTION("R-functions")
     {
+      SECTION("multiple variable")
+      {
+        std::string_view data = R"(
+let weird : R^2*R -> R, (x,y) -> x[0]-y*x[1];
+)";
+
+        std::string_view result = R"(
+(root:void)
+ `-(language::let_declaration:void)
+     `-(language::name:weird:function)
+)";
+
+        CHECK_AST(data, result);
+      }
+
       SECTION("multiple variable")
       {
         std::string_view data = R"(
@@ -489,7 +564,7 @@ let f : R*Z -> B, (x,z) -> (3, x);
         ASTSymbolTableBuilder{*ast};
 
         REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast},
-                            "note: number of image spaces (1) B differs from number of expressions (2) (3, x)");
+                            "number of image spaces (1) B differs from number of expressions (2) (3, x)");
       }
 
       SECTION("wrong image size 2")
@@ -502,13 +577,46 @@ let f : R -> R*R, x -> x*x*x;
         ASTSymbolTableBuilder{*ast};
 
         REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast},
-                            "note: number of image spaces (2) R*R differs from number of expressions (1) x*x*x");
+                            "number of image spaces (2) R*R differs from number of expressions (1) x*x*x");
       }
     }
   }
 
   SECTION("function evaluation")
   {
+    SECTION("R^d-functions")
+    {
+      SECTION("single argument")
+      {
+        std::string_view data = R"(
+let f : R^2 -> R^2, x -> (x[0]+1, x[1]-2);
+R^2 x = (1,2);
+x = f(x);
+)";
+
+        std::string_view result = R"(
+(root:void)
+ +-(language::let_declaration:void)
+ |   `-(language::name:f:function)
+ +-(language::declaration:R^2)
+ |   +-(language::vector_type:typename)
+ |   |   +-(language::R_set:typename)
+ |   |   `-(language::integer:2:Z)
+ |   +-(language::name:x:R^2)
+ |   `-(language::expression_list:list)
+ |       +-(language::integer:1:Z)
+ |       `-(language::integer:2:Z)
+ `-(language::eq_op:R^2)
+     +-(language::name:x:R^2)
+     `-(language::function_evaluation:R^2)
+         +-(language::name:f:function)
+         `-(language::name:x:R^2)
+)";
+
+        CHECK_AST(data, result);
+      }
+    }
+
     SECTION("R-functions")
     {
       SECTION("single argument")