diff --git a/src/language/ast/ASTNodeDataTypeBuilder.cpp b/src/language/ast/ASTNodeDataTypeBuilder.cpp
index 404a351b5c46e946f155b25f358a18a2e94acb1d..96ff62bfc20cd9a6526f140d14a4cee7218e241d 100644
--- a/src/language/ast/ASTNodeDataTypeBuilder.cpp
+++ b/src/language/ast/ASTNodeDataTypeBuilder.cpp
@@ -65,11 +65,13 @@ ASTNodeDataTypeBuilder::_buildDeclarationNodeDataTypes(ASTNode& type_node, ASTNo
       } else if (content_node->is_type<language::R_set>()) {
         content_node->m_data_type = ASTNodeDataType::double_t;
       } else if (content_node->is_type<language::vector_type>()) {
-        content_node->m_data_type = getVectorDataType(type_node);
+        content_node->m_data_type = getVectorDataType(*type_node.children[0]);
       } else if (content_node->is_type<language::string_type>()) {
         content_node->m_data_type = ASTNodeDataType::string_t;
       } else {
+        // LCOV_EXCL_START
         throw UnexpectedError("unexpected content type in tuple");
+        // LCOV_EXCL_STOP
       }
 
       data_type = ASTNodeDataType{ASTNodeDataType::tuple_t, content_node->m_data_type};
diff --git a/src/language/node_processor/AffectationProcessor.hpp b/src/language/node_processor/AffectationProcessor.hpp
index 4c79bb5783abb2ed1c312c2ed7f68817287f0ec2..ae06f5153a7e0c70b78fe1f99ff06c972e9cba57 100644
--- a/src/language/node_processor/AffectationProcessor.hpp
+++ b/src/language/node_processor/AffectationProcessor.hpp
@@ -472,10 +472,39 @@ class AffectationToTupleFromListProcessor final : public INodeProcessor
               os << child_value << std::ends;
               tuple_value[i] = os.str();
             }
-
+          } else if constexpr (is_tiny_vector_v<ValueT>) {
+            if constexpr (std::is_same_v<T, AggregateDataVariant>) {
+              ValueT& v = tuple_value[i];
+              Assert(ValueT::Dimension == child_value.size());
+              for (size_t j = 0; j < ValueT::Dimension; ++j) {
+                std::visit(
+                  [&](auto&& vj) {
+                    using Ti = std::decay_t<decltype(vj)>;
+                    if constexpr (std::is_convertible_v<Ti, typename ValueT::data_type>) {
+                      v[j] = vj;
+                    } else {
+                      // LCOV_EXCL_START
+                      throw parse_error("unexpected error: unexpected right hand side type in affectation",
+                                        m_node.children[1]->children[i]->begin());
+                      // LCOV_EXCL_STOP
+                    }
+                  },
+                  child_value[j]);
+              }
+            } else if constexpr (std::is_same_v<T, int64_t>) {
+              // in this case a 0 is given
+              Assert(child_value == 0);
+              tuple_value[i] = ZeroType{};
+            } else {
+              // LCOV_EXCL_START
+              throw parse_error("unexpected error: unexpected right hand side type in affectation",
+                                m_node.children[1]->children[i]->begin());
+              // LCOV_EXCL_STOP
+            }
           } else {
             // LCOV_EXCL_START
-            throw parse_error("unexpected error: unexpected right hand side type in affectation", m_node.begin());
+            throw parse_error("unexpected error: unexpected right hand side type in affectation",
+                              m_node.children[1]->children[i]->begin());
             // LCOV_EXCL_STOP
           }
         },
diff --git a/tests/test_ASTNodeDataTypeBuilder.cpp b/tests/test_ASTNodeDataTypeBuilder.cpp
index 96eb27f4627bf01d98f2a640966f647ee761aee3..9e44625e1ef31b116954e7b6859b1409873b6e11 100644
--- a/tests/test_ASTNodeDataTypeBuilder.cpp
+++ b/tests/test_ASTNodeDataTypeBuilder.cpp
@@ -3,7 +3,10 @@
 #include <language/ast/ASTBuilder.hpp>
 #include <language/ast/ASTNodeDataTypeBuilder.hpp>
 #include <language/ast/ASTSymbolTableBuilder.hpp>
+#include <language/utils/ASTNodeDataTypeTraits.hpp>
 #include <language/utils/ASTPrinter.hpp>
+#include <language/utils/TypeDescriptor.hpp>
+#include <utils/Exceptions.hpp>
 
 #include <pegtl/string_input.hpp>
 
@@ -24,6 +27,39 @@
     REQUIRE(ast_output.str() == expected_output);                                                   \
   }
 
+template <>
+inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const double>> = {ASTNodeDataType::type_id_t,
+                                                                                 "builtin_t"};
+const auto builtin_data_type = ast_node_data_type_from<std::shared_ptr<const double>>;
+
+#define CHECK_AST_WITH_BUILTIN(data, expected_output)                                                         \
+  {                                                                                                           \
+    static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>);                            \
+    static_assert(std::is_same_v<std::decay_t<decltype(expected_output)>, std::string_view>);                 \
+                                                                                                              \
+    string_input input{data, "test.pgs"};                                                                     \
+    auto ast = ASTBuilder::build(input);                                                                      \
+                                                                                                              \
+    SymbolTable& symbol_table = *ast->m_symbol_table;                                                         \
+    auto [i_symbol, success]  = symbol_table.add(builtin_data_type.nameOfTypeId(), ast->begin());             \
+    if (not success) {                                                                                        \
+      throw UnexpectedError("cannot add '" + builtin_data_type.nameOfTypeId() + "' type for testing");        \
+    }                                                                                                         \
+                                                                                                              \
+    i_symbol->attributes().setDataType(ASTNodeDataType::type_name_id_t);                                      \
+    i_symbol->attributes().setIsInitialized();                                                                \
+    i_symbol->attributes().value() = symbol_table.typeEmbedderTable().size();                                 \
+    symbol_table.typeEmbedderTable().add(std::make_shared<TypeDescriptor>(builtin_data_type.nameOfTypeId())); \
+                                                                                                              \
+    ASTSymbolTableBuilder{*ast};                                                                              \
+    ASTNodeDataTypeBuilder{*ast};                                                                             \
+                                                                                                              \
+    std::stringstream ast_output;                                                                             \
+    ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::data_type}};           \
+                                                                                                              \
+    REQUIRE(ast_output.str() == expected_output);                                                             \
+  }
+
 // clazy:excludeall=non-pod-global-static
 
 TEST_CASE("ASTNodeDataTypeBuilder", "[language]")
@@ -330,6 +366,253 @@ let square : R -> R^3, x -> (x, x*x);
 
   SECTION("let declaration")
   {
+    SECTION("tuples")
+    {
+      SECTION("B tuples")
+      {
+        std::string_view data = R"(
+let t : (B), t = (true, false);
+)";
+
+        std::string_view result = R"(
+(root:void)
+ `-(language::var_declaration:tuple(B))
+     +-(language::name:t:tuple(B))
+     +-(language::tuple_type_specifier:tuple(B))
+     |   `-(language::B_set:typename)
+     +-(language::name:t:tuple(B))
+     `-(language::expression_list:list)
+         +-(language::true_kw:B)
+         `-(language::false_kw:B)
+)";
+
+        CHECK_AST(data, result);
+      }
+
+      SECTION("N tuples")
+      {
+        std::string_view data = R"(
+let t : (N), t = (1, 2, 3, 5);
+)";
+
+        std::string_view result = R"(
+(root:void)
+ `-(language::var_declaration:tuple(N))
+     +-(language::name:t:tuple(N))
+     +-(language::tuple_type_specifier:tuple(N))
+     |   `-(language::N_set:typename)
+     +-(language::name:t:tuple(N))
+     `-(language::expression_list:list)
+         +-(language::integer:1:Z)
+         +-(language::integer:2:Z)
+         +-(language::integer:3:Z)
+         `-(language::integer:5:Z)
+)";
+
+        CHECK_AST(data, result);
+      }
+
+      SECTION("Z tuples")
+      {
+        std::string_view data = R"(
+let n : N, n = 3;
+let t : (Z), t = (2, n, true);
+)";
+
+        std::string_view result = R"(
+(root:void)
+ +-(language::var_declaration:N)
+ |   +-(language::name:n:N)
+ |   +-(language::N_set:typename)
+ |   +-(language::name:n:N)
+ |   `-(language::integer:3:Z)
+ `-(language::var_declaration:tuple(Z))
+     +-(language::name:t:tuple(Z))
+     +-(language::tuple_type_specifier:tuple(Z))
+     |   `-(language::Z_set:typename)
+     +-(language::name:t:tuple(Z))
+     `-(language::expression_list:list)
+         +-(language::integer:2:Z)
+         +-(language::name:n:N)
+         `-(language::true_kw:B)
+)";
+
+        CHECK_AST(data, result);
+      }
+
+      SECTION("R tuples")
+      {
+        std::string_view data = R"(
+let t : (R), t = (2, 3.1, 5);
+)";
+
+        std::string_view result = R"(
+(root:void)
+ `-(language::var_declaration:tuple(R))
+     +-(language::name:t:tuple(R))
+     +-(language::tuple_type_specifier:tuple(R))
+     |   `-(language::R_set:typename)
+     +-(language::name:t:tuple(R))
+     `-(language::expression_list:list)
+         +-(language::integer:2:Z)
+         +-(language::real:3.1:R)
+         `-(language::integer:5:Z)
+)";
+
+        CHECK_AST(data, result);
+      }
+
+      SECTION("R^d tuples")
+      {
+        std::string_view data = R"(
+let a : R^2, a = (2,3.1);
+let t1 : (R^2), t1 = (a, (1,2), 0);
+let t2 : (R^3), t2 = (0, 0);
+)";
+
+        std::string_view result = R"(
+(root:void)
+ +-(language::var_declaration:R^2)
+ |   +-(language::name:a:R^2)
+ |   +-(language::vector_type:typename)
+ |   |   +-(language::R_set:typename)
+ |   |   `-(language::integer:2:Z)
+ |   +-(language::name:a:R^2)
+ |   `-(language::expression_list:list)
+ |       +-(language::integer:2:Z)
+ |       `-(language::real:3.1:R)
+ +-(language::var_declaration:tuple(R^2))
+ |   +-(language::name:t1:tuple(R^2))
+ |   +-(language::tuple_type_specifier:tuple(R^2))
+ |   |   `-(language::vector_type:typename)
+ |   |       +-(language::R_set:typename)
+ |   |       `-(language::integer:2:Z)
+ |   +-(language::name:t1:tuple(R^2))
+ |   `-(language::expression_list:list)
+ |       +-(language::name:a:R^2)
+ |       +-(language::tuple_expression:list)
+ |       |   +-(language::integer:1:Z)
+ |       |   `-(language::integer:2:Z)
+ |       `-(language::integer:0:Z)
+ `-(language::var_declaration:tuple(R^3))
+     +-(language::name:t2:tuple(R^3))
+     +-(language::tuple_type_specifier:tuple(R^3))
+     |   `-(language::vector_type:typename)
+     |       +-(language::R_set:typename)
+     |       `-(language::integer:3:Z)
+     +-(language::name:t2:tuple(R^3))
+     `-(language::expression_list:list)
+         +-(language::integer:0:Z)
+         `-(language::integer:0:Z)
+)";
+
+        CHECK_AST(data, result);
+      }
+
+      SECTION("string tuples")
+      {
+        std::string_view data = R"(
+let t : (string), t = ("foo", "bar");
+)";
+
+        std::string_view result = R"(
+(root:void)
+ `-(language::var_declaration:tuple(string))
+     +-(language::name:t:tuple(string))
+     +-(language::tuple_type_specifier:tuple(string))
+     |   `-(language::string_type:typename)
+     +-(language::name:t:tuple(string))
+     `-(language::expression_list:list)
+         +-(language::literal:"foo":string)
+         `-(language::literal:"bar":string)
+)";
+
+        CHECK_AST(data, result);
+      }
+
+      SECTION("type_id tuples")
+      {
+        std::string_view data = R"(
+// invalid conversion just checking grammar
+let t : (builtin_t), t= (1,2,3);
+)";
+
+        std::string_view result = R"(
+(root:void)
+ `-(language::var_declaration:tuple(builtin_t))
+     +-(language::name:t:tuple(builtin_t))
+     +-(language::tuple_type_specifier:tuple(builtin_t))
+     |   `-(language::type_name_id:typename)
+     +-(language::name:t:tuple(builtin_t))
+     `-(language::expression_list:list)
+         +-(language::integer:1:Z)
+         +-(language::integer:2:Z)
+         `-(language::integer:3:Z)
+)";
+
+        CHECK_AST_WITH_BUILTIN(data, result);
+      }
+
+      SECTION("errors")
+      {
+        SECTION("type_id")
+        {
+          std::string_view data = R"(
+let t : builtin_t;
+)";
+
+          string_input input{data, "test.pgs"};
+          auto ast = ASTBuilder::build(input);
+          ASTSymbolTableBuilder{*ast};
+
+          REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast}, "undefined type identifier");
+        }
+
+        SECTION("type_id 2")
+        {
+          std::string_view data = R"(
+let a: R, a = 3;
+let t : a;
+)";
+
+          string_input input{data, "test.pgs"};
+          auto ast = ASTBuilder::build(input);
+          ASTSymbolTableBuilder{*ast};
+
+          REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast},
+                              "invalid type identifier, 'a' was previously defined as a 'R'");
+        }
+
+        SECTION("type_id tuples")
+        {
+          std::string_view data = R"(
+let t : (builtin_t);
+)";
+
+          string_input input{data, "test.pgs"};
+          auto ast = ASTBuilder::build(input);
+          ASTSymbolTableBuilder{*ast};
+
+          REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast}, "undefined type identifier");
+        }
+
+        SECTION("type_id tuples 2")
+        {
+          std::string_view data = R"(
+let a: R, a = 3;
+let t : (a);
+)";
+
+          string_input input{data, "test.pgs"};
+          auto ast = ASTBuilder::build(input);
+          ASTSymbolTableBuilder{*ast};
+
+          REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast},
+                              "invalid type identifier, 'a' was previously defined as a 'R'");
+        }
+      }
+    }
+
     SECTION("R^d-functions")
     {
       SECTION("vector function")
@@ -942,6 +1225,25 @@ let s: string;
     CHECK_AST(data, result);
   }
 
+  SECTION("type_id")
+  {
+    std::string_view data = R"(
+// invalid conversion just checking grammar
+let t : builtin_t, t= 1;
+)";
+
+    std::string_view result = R"(
+(root:void)
+ `-(language::var_declaration:builtin_t)
+     +-(language::name:t:builtin_t)
+     +-(language::type_name_id:typename)
+     +-(language::name:t:builtin_t)
+     `-(language::integer:1:Z)
+)";
+
+    CHECK_AST_WITH_BUILTIN(data, result);
+  }
+
   SECTION("continue")
   {
     std::string_view data = R"(