diff --git a/src/language/ASTNodeBuiltinFunctionExpressionBuilder.cpp b/src/language/ASTNodeBuiltinFunctionExpressionBuilder.cpp
index 5b324f104a2a9c4906250281986adb65be67921d..4bb46ce18210f0d4458dd611c98c7fd3cebac026 100644
--- a/src/language/ASTNodeBuiltinFunctionExpressionBuilder.cpp
+++ b/src/language/ASTNodeBuiltinFunctionExpressionBuilder.cpp
@@ -64,6 +64,20 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData
     }
   };
 
+  auto get_function_argument_to_type_id_converter = [&]() -> std::unique_ptr<IFunctionArgumentConverter> {
+    switch (argument_node_sub_data_type.m_data_type) {
+    case ASTNodeDataType::type_id_t: {
+      return std::make_unique<FunctionArgumentConverter<EmbeddedData, EmbeddedData>>(argument_number);
+    }
+      // LCOV_EXCL_START
+    default: {
+      throw parse_error("unexpected error: invalid argument type for function",
+                        std::vector{argument_node_sub_data_type.m_parent_node.begin()});
+    }
+      // LCOV_EXCL_STOP
+    }
+  };
+
   auto get_function_argument_converter_for_argument_type = [&]() {
     switch (parameter_type) {
     case ASTNodeDataType::bool_t: {
@@ -80,6 +94,9 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData
     }
     case ASTNodeDataType::string_t: {
       return get_function_argument_to_string_converter();
+    }
+    case ASTNodeDataType::type_id_t: {
+      return get_function_argument_to_type_id_converter();
     }
       // LCOV_EXCL_START
     default: {
diff --git a/src/language/BuiltinFunctionEmbedder.hpp b/src/language/BuiltinFunctionEmbedder.hpp
index 1aacffed7ed797f47b5232aeb79abfa62e76dd00..d6040f7be2e1f71621b1297bfe080f3cdd8b5584 100644
--- a/src/language/BuiltinFunctionEmbedder.hpp
+++ b/src/language/BuiltinFunctionEmbedder.hpp
@@ -12,6 +12,7 @@
 #include <vector>
 
 #include <Demangle.hpp>
+#include <PugsTraits.hpp>
 
 template <typename T>
 inline ASTNodeDataType ast_node_data_type_from = ASTNodeDataType::undefined_t;
@@ -62,6 +63,9 @@ class BuiltinFunctionEmbedder : public IBuiltinFunctionEmbedder
         } else if constexpr ((std::is_arithmetic_v<Vi_Type>)and(std::is_arithmetic_v<Ti_Type> or
                                                                 std::is_same_v<Ti_Type, std::string>)) {
           std::get<I>(t) = v_i;
+        } else if constexpr (is_shared_ptr_v<Ti_Type> and std::is_same_v<Vi_Type, EmbeddedData>) {
+          auto data_handler = static_cast<const DataHandler<typename Ti_Type::element_type>&>(v_i.get());
+          std::get<I>(t)    = data_handler.data_ptr();
         } else {
           std::ostringstream os;
           os << "unexpected argument types while casting " << demangle<Vi_Type>() << " -> " << demangle<Ti_Type>()
@@ -139,6 +143,9 @@ class BuiltinFunctionEmbedder : public IBuiltinFunctionEmbedder
     this->_copy_from_vector(t, x, IndexSequence{});
     if constexpr (std::is_arithmetic_v<FX>) {
       return {std::apply(m_f, t)};
+    } else if constexpr (std::is_same_v<FX, void>) {
+      std::apply(m_f, t);
+      return {};
     } else {
       return EmbeddedData(_createHandler(std::apply(m_f, t)));
     }
diff --git a/src/language/DataHandler.hpp b/src/language/DataHandler.hpp
index 9a62a233ff57955c365b00db02b3e5dc9e2c7619..214c889f420111ea1c7b314d31f52fa32745fda9 100644
--- a/src/language/DataHandler.hpp
+++ b/src/language/DataHandler.hpp
@@ -20,17 +20,9 @@ class DataHandler : public IDataHandler
   std::shared_ptr<DataT> m_data;
 
  public:
-  DataT&
-  data()
+  std::shared_ptr<DataT>
+  data_ptr() const
   {
-    Assert(m_data);
-    return m_data;
-  }
-
-  const DataT&
-  data() const
-  {
-    Assert(m_data);
     return m_data;
   }
 
diff --git a/src/utils/PugsTraits.hpp b/src/utils/PugsTraits.hpp
index 3184f5b6ef7685c7997ca2f43674a1a792926d35..30283afa80efdde9110ce9cf8bbba548934224a6 100644
--- a/src/utils/PugsTraits.hpp
+++ b/src/utils/PugsTraits.hpp
@@ -1,6 +1,7 @@
 #ifndef PUGS_TRAITS_HPP
 #define PUGS_TRAITS_HPP
 
+#include <memory>
 #include <type_traits>
 
 template <size_t N, typename T>
@@ -28,4 +29,12 @@ inline constexpr bool is_trivially_castable<const TinyMatrix<N, T>> = is_trivial
 template <typename T>
 inline constexpr bool is_false_v = false;
 
+// Traits is_shared_ptr
+
+template <typename T>
+inline constexpr bool is_shared_ptr_v = false;
+
+template <typename T>
+inline constexpr bool is_shared_ptr_v<std::shared_ptr<T>> = true;
+
 #endif   // PUGS_TRAITS_HPP