diff --git a/src/language/modules/BuiltinModule.hpp b/src/language/modules/BuiltinModule.hpp
index 3dd9ad1dbb9895f3f79ba04ec2702cc7ee0bd15f..33afb27d718be626cad0e14da1736761e5f8a624 100644
--- a/src/language/modules/BuiltinModule.hpp
+++ b/src/language/modules/BuiltinModule.hpp
@@ -4,10 +4,17 @@
 #include <language/modules/IModule.hpp>
 #include <language/utils/ASTNodeDataType.hpp>
 
+#include <utils/Exceptions.hpp>
+
+#include <sstream>
+
 class IBuiltinFunctionEmbedder;
 class TypeDescriptor;
 class ValueDescriptor;
 
+template <typename FX, typename... Args>
+class BuiltinFunctionEmbedder;
+
 class BuiltinModule : public IModule
 {
  protected:
@@ -15,9 +22,27 @@ class BuiltinModule : public IModule
   NameTypeMap m_name_type_map;
   NameValueMap m_name_value_map;
 
+  template <typename FX, typename... Args>
+  void
+  _addBuiltinFunction(const std::string& name, std::function<FX(Args...)>&& f)
+  {
+    try {
+      this->_addBuiltinFunction(name, std::make_shared<BuiltinFunctionEmbedder<FX(Args...)>>(
+                                        std::forward<std::function<FX(Args...)>>(f)));
+    }
+    catch (std::invalid_argument& e) {
+      std::ostringstream os;
+      os << "while defining builtin function '" << rang::fgB::yellow << name << rang::fg::reset << "'\n";
+      os << e.what();
+      throw UnexpectedError(os.str());
+    }
+  }
+
+ private:
   void _addBuiltinFunction(const std::string& name,
                            std::shared_ptr<IBuiltinFunctionEmbedder> builtin_function_embedder);
 
+ protected:
   void _addTypeDescriptor(const ASTNodeDataType& type);
 
   void _addNameValue(const std::string& name, const ASTNodeDataType& type, const DataVariant& data);
diff --git a/src/language/modules/CoreModule.cpp b/src/language/modules/CoreModule.cpp
index 966953add590740830226aaf16c447f25ed57672..ff07fc9da15f52f67a03e632503c4d62bf9af439 100644
--- a/src/language/modules/CoreModule.cpp
+++ b/src/language/modules/CoreModule.cpp
@@ -37,19 +37,19 @@
 
 CoreModule::CoreModule() : BuiltinModule(true)
 {
-  this->_addBuiltinFunction("getPugsVersion", std::make_shared<BuiltinFunctionEmbedder<std::string(void)>>(
+  this->_addBuiltinFunction("getPugsVersion", std::function(
 
                                                 []() -> std::string { return pugsVersion(); }
 
                                                 ));
 
-  this->_addBuiltinFunction("getPugsBuildInfo", std::make_shared<BuiltinFunctionEmbedder<std::string(void)>>(
+  this->_addBuiltinFunction("getPugsBuildInfo", std::function(
 
                                                   []() -> std::string { return pugsBuildInfo(); }
 
                                                   ));
 
-  this->_addBuiltinFunction("getAvailableModules", std::make_shared<BuiltinFunctionEmbedder<std::string()>>(
+  this->_addBuiltinFunction("getAvailableModules", std::function(
 
                                                      []() -> std::string {
                                                        const ModuleRepository& repository =
@@ -60,7 +60,7 @@ CoreModule::CoreModule() : BuiltinModule(true)
 
                                                      ));
 
-  this->_addBuiltinFunction("getModuleInfo", std::make_shared<BuiltinFunctionEmbedder<std::string(const std::string&)>>(
+  this->_addBuiltinFunction("getModuleInfo", std::function(
 
                                                [](const std::string& module_name) -> std::string {
                                                  const ModuleRepository& repository =
@@ -71,7 +71,7 @@ CoreModule::CoreModule() : BuiltinModule(true)
 
                                                ));
 
-  this->_addBuiltinFunction("setRandomSeed", std::make_shared<BuiltinFunctionEmbedder<void(const int64_t&)>>(
+  this->_addBuiltinFunction("setRandomSeed", std::function(
 
                                                [](const int64_t& random_seed) -> void {
                                                  RandomEngine::instance().setRandomSeed(random_seed);
@@ -79,21 +79,21 @@ CoreModule::CoreModule() : BuiltinModule(true)
 
                                                ));
 
-  this->_addBuiltinFunction("resetRandomSeed", std::make_shared<BuiltinFunctionEmbedder<void(void)>>(
+  this->_addBuiltinFunction("resetRandomSeed", std::function(
 
-                                                 []() { RandomEngine::instance().resetRandomSeed(); }
+                                                 []() -> void { RandomEngine::instance().resetRandomSeed(); }
 
                                                  ));
 
   this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const OStream>>);
 
-  this
-    ->_addBuiltinFunction("ofstream",
-                          std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const OStream>(const std::string&)>>(
+  this->_addBuiltinFunction("ofstream", std::function(
 
-                            [](const std::string& filename) { return std::make_shared<const OFStream>(filename); }
+                                          [](const std::string& filename) -> std::shared_ptr<const OStream> {
+                                            return std::make_shared<const OFStream>(filename);
+                                          }
 
-                            ));
+                                          ));
 
   this->_addNameValue("cout", ast_node_data_type_from<std::shared_ptr<const OStream>>,
                       EmbeddedData{std::make_shared<DataHandler<const OStream>>(std::make_shared<OStream>(std::cout))});
diff --git a/src/language/modules/DevUtilsModule.cpp b/src/language/modules/DevUtilsModule.cpp
index f0d0d31f35f1a85213a71feb0a6feda79fa61728..2dace9adffa8c18482043fe7a4f154b7ec15abbb 100644
--- a/src/language/modules/DevUtilsModule.cpp
+++ b/src/language/modules/DevUtilsModule.cpp
@@ -10,7 +10,7 @@
 
 DevUtilsModule::DevUtilsModule()
 {
-  this->_addBuiltinFunction("getAST", std::make_shared<BuiltinFunctionEmbedder<std::string(void)>>(
+  this->_addBuiltinFunction("getAST", std::function(
 
                                         []() -> std::string {
                                           const auto& root_node = ASTExecutionInfo::current().rootNode();
@@ -23,7 +23,7 @@ DevUtilsModule::DevUtilsModule()
 
                                         ));
 
-  this->_addBuiltinFunction("saveASTDot", std::make_shared<BuiltinFunctionEmbedder<void(const std::string&)>>(
+  this->_addBuiltinFunction("saveASTDot", std::function(
 
                                             [](const std::string& dot_filename) -> void {
                                               const auto& root_node = ASTExecutionInfo::current().rootNode();
@@ -48,22 +48,21 @@ DevUtilsModule::DevUtilsModule()
 
                                             ));
 
-  this->_addBuiltinFunction("getFunctionAST",
-                            std::make_shared<BuiltinFunctionEmbedder<std::string(const FunctionSymbolId&)>>(
+  this->_addBuiltinFunction("getFunctionAST", std::function(
 
-                              [](const FunctionSymbolId& function_symbol_id) -> std::string {
-                                const auto& function_descriptor = function_symbol_id.descriptor();
+                                                [](const FunctionSymbolId& function_symbol_id) -> std::string {
+                                                  const auto& function_descriptor = function_symbol_id.descriptor();
 
-                                std::ostringstream os;
-                                os << function_descriptor.name() << ": domain mapping\n";
-                                os << ASTPrinter(function_descriptor.domainMappingNode());
-                                os << function_descriptor.name() << ": definition\n";
-                                os << ASTPrinter(function_descriptor.definitionNode());
+                                                  std::ostringstream os;
+                                                  os << function_descriptor.name() << ": domain mapping\n";
+                                                  os << ASTPrinter(function_descriptor.domainMappingNode());
+                                                  os << function_descriptor.name() << ": definition\n";
+                                                  os << ASTPrinter(function_descriptor.definitionNode());
 
-                                return os.str();
-                              }
+                                                  return os.str();
+                                                }
 
-                              ));
+                                                ));
 }
 
 void
diff --git a/src/language/modules/LinearSolverModule.cpp b/src/language/modules/LinearSolverModule.cpp
index 5dafbadcfedec464b83d7d20ce798e81518e073d..123a930073dfb0735dd30df1893613b5cb30a292 100644
--- a/src/language/modules/LinearSolverModule.cpp
+++ b/src/language/modules/LinearSolverModule.cpp
@@ -6,7 +6,7 @@
 
 LinearSolverModule::LinearSolverModule()
 {
-  this->_addBuiltinFunction("setLSVerbosity", std::make_shared<BuiltinFunctionEmbedder<void(const bool&)>>(
+  this->_addBuiltinFunction("setLSVerbosity", std::function(
 
                                                 [](const bool& verbose) -> void {
                                                   LinearSolverOptions::default_options.verbose() = verbose;
@@ -14,7 +14,7 @@ LinearSolverModule::LinearSolverModule()
 
                                                 ));
 
-  this->_addBuiltinFunction("setLSEpsilon", std::make_shared<BuiltinFunctionEmbedder<void(const double&)>>(
+  this->_addBuiltinFunction("setLSEpsilon", std::function(
 
                                               [](const double& epsilon) -> void {
                                                 LinearSolverOptions::default_options.epsilon() = epsilon;
@@ -22,7 +22,7 @@ LinearSolverModule::LinearSolverModule()
 
                                               ));
 
-  this->_addBuiltinFunction("setLSMaxIter", std::make_shared<BuiltinFunctionEmbedder<void(const uint64_t&)>>(
+  this->_addBuiltinFunction("setLSMaxIter", std::function(
 
                                               [](const uint64_t& max_iter) -> void {
                                                 LinearSolverOptions::default_options.maximumIteration() = max_iter;
@@ -30,7 +30,7 @@ LinearSolverModule::LinearSolverModule()
 
                                               ));
 
-  this->_addBuiltinFunction("setLSLibrary", std::make_shared<BuiltinFunctionEmbedder<void(const std::string&)>>(
+  this->_addBuiltinFunction("setLSLibrary", std::function(
 
                                               [](const std::string& library_name) -> void {
                                                 LinearSolverOptions::default_options.library() =
@@ -39,7 +39,7 @@ LinearSolverModule::LinearSolverModule()
 
                                               ));
 
-  this->_addBuiltinFunction("setLSMethod", std::make_shared<BuiltinFunctionEmbedder<void(const std::string&)>>(
+  this->_addBuiltinFunction("setLSMethod", std::function(
 
                                              [](const std::string& method_name) -> void {
                                                LinearSolverOptions::default_options.method() =
@@ -48,7 +48,7 @@ LinearSolverModule::LinearSolverModule()
 
                                              ));
 
-  this->_addBuiltinFunction("setLSPrecond", std::make_shared<BuiltinFunctionEmbedder<void(const std::string&)>>(
+  this->_addBuiltinFunction("setLSPrecond", std::function(
 
                                               [](const std::string& precond_name) -> void {
                                                 LinearSolverOptions::default_options.precond() =
@@ -57,7 +57,7 @@ LinearSolverModule::LinearSolverModule()
 
                                               ));
 
-  this->_addBuiltinFunction("getLSOptions", std::make_shared<BuiltinFunctionEmbedder<std::string()>>(
+  this->_addBuiltinFunction("getLSOptions", std::function(
 
                                               []() -> std::string {
                                                 std::ostringstream os;
@@ -69,7 +69,7 @@ LinearSolverModule::LinearSolverModule()
 
                                               ));
 
-  this->_addBuiltinFunction("getLSAvailable", std::make_shared<BuiltinFunctionEmbedder<std::string()>>(
+  this->_addBuiltinFunction("getLSAvailable", std::function(
 
                                                 []() -> std::string {
                                                   std::ostringstream os;
diff --git a/src/language/modules/MathFunctionRegisterForVh.cpp b/src/language/modules/MathFunctionRegisterForVh.cpp
index 22f7866bddd9a0539d9d2cb669c69d69c0be23a8..b15e9796f39f71c266741616db2afe1df2d5b0e1 100644
--- a/src/language/modules/MathFunctionRegisterForVh.cpp
+++ b/src/language/modules/MathFunctionRegisterForVh.cpp
@@ -8,342 +8,380 @@
 
 MathFunctionRegisterForVh::MathFunctionRegisterForVh(SchemeModule& scheme_module)
 {
-  scheme_module._addBuiltinFunction("sqrt",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return sqrt(a); }));
-
-  scheme_module._addBuiltinFunction("abs",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return abs(a); }));
-
-  scheme_module._addBuiltinFunction("sin",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return sin(a); }));
-
-  scheme_module._addBuiltinFunction("cos",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return cos(a); }));
-
-  scheme_module._addBuiltinFunction("tan",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return tan(a); }));
-
-  scheme_module._addBuiltinFunction("asin",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return asin(a); }));
-
-  scheme_module._addBuiltinFunction("acos",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return acos(a); }));
-
-  scheme_module._addBuiltinFunction("atan",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return atan(a); }));
-
-  scheme_module
-    ._addBuiltinFunction("atan2",
-                         std::make_shared<BuiltinFunctionEmbedder<
-                           std::shared_ptr<const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>,
-                                                                    std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a, std::shared_ptr<const IDiscreteFunction> b)
-                             -> std::shared_ptr<const IDiscreteFunction> { return atan2(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("atan2",
-                         std::make_shared<BuiltinFunctionEmbedder<
-                           std::shared_ptr<const IDiscreteFunction>(double, std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](double a, std::shared_ptr<const IDiscreteFunction> b)
-                             -> std::shared_ptr<const IDiscreteFunction> { return atan2(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("atan2",
-                         std::make_shared<BuiltinFunctionEmbedder<
-                           std::shared_ptr<const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>, double)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a,
-                              double b) -> std::shared_ptr<const IDiscreteFunction> { return atan2(a, b); }));
-
-  scheme_module._addBuiltinFunction("sinh",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return sinh(a); }));
-
-  scheme_module._addBuiltinFunction("cosh",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return cosh(a); }));
-
-  scheme_module._addBuiltinFunction("tanh",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return tanh(a); }));
-
-  scheme_module._addBuiltinFunction("asinh",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return asinh(a); }));
-
-  scheme_module._addBuiltinFunction("acosh",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return acosh(a); }));
-
-  scheme_module._addBuiltinFunction("atanh",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return atanh(a); }));
-
-  scheme_module._addBuiltinFunction("exp",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return exp(a); }));
-
-  scheme_module._addBuiltinFunction("log",
-                                    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                                      std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a)
-                                        -> std::shared_ptr<const IDiscreteFunction> { return log(a); }));
-
-  scheme_module
-    ._addBuiltinFunction("pow",
-                         std::make_shared<BuiltinFunctionEmbedder<
-                           std::shared_ptr<const IDiscreteFunction>(double, std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](double a, std::shared_ptr<const IDiscreteFunction> b)
-                             -> std::shared_ptr<const IDiscreteFunction> { return pow(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("pow",
-                         std::make_shared<BuiltinFunctionEmbedder<
-                           std::shared_ptr<const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>, double)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a,
-                              double b) -> std::shared_ptr<const IDiscreteFunction> { return pow(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("pow",
-                         std::make_shared<BuiltinFunctionEmbedder<
-                           std::shared_ptr<const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>,
-                                                                    std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a, std::shared_ptr<const IDiscreteFunction> b)
-                             -> std::shared_ptr<const IDiscreteFunction> { return pow(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("dot",
-                         std::make_shared<BuiltinFunctionEmbedder<
-                           std::shared_ptr<const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>,
-                                                                    std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a, std::shared_ptr<const IDiscreteFunction> b)
-                             -> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("dot",
-                         std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                           const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>, const TinyVector<1>)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a, const TinyVector<1> b)
-                             -> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("dot",
-                         std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                           const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>, const TinyVector<2>)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a, const TinyVector<2> b)
-                             -> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("dot",
-                         std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                           const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>, const TinyVector<3>&)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a, const TinyVector<3>& b)
-                             -> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("dot",
-                         std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                           const IDiscreteFunction>(const TinyVector<1>, std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](const TinyVector<1> a, std::shared_ptr<const IDiscreteFunction> b)
-                             -> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("dot",
-                         std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                           const IDiscreteFunction>(const TinyVector<2>, std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](const TinyVector<2> a, std::shared_ptr<const IDiscreteFunction> b)
-                             -> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("dot",
-                         std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                           const IDiscreteFunction>(const TinyVector<3>&, std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](const TinyVector<3>& a, std::shared_ptr<const IDiscreteFunction> b)
-                             -> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("min",
-                         std::make_shared<BuiltinFunctionEmbedder<double(std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a) -> double { return min(a); }));
-
-  scheme_module
-    ._addBuiltinFunction("min",
-                         std::make_shared<BuiltinFunctionEmbedder<
-                           std::shared_ptr<const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>,
-                                                                    std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a, std::shared_ptr<const IDiscreteFunction> b)
-                             -> std::shared_ptr<const IDiscreteFunction> { return min(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("min",
-                         std::make_shared<BuiltinFunctionEmbedder<
-                           std::shared_ptr<const IDiscreteFunction>(double, std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](double a, std::shared_ptr<const IDiscreteFunction> b)
-                             -> std::shared_ptr<const IDiscreteFunction> { return min(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("min",
-                         std::make_shared<BuiltinFunctionEmbedder<
-                           std::shared_ptr<const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>, double)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a,
-                              double b) -> std::shared_ptr<const IDiscreteFunction> { return min(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("max",
-                         std::make_shared<BuiltinFunctionEmbedder<double(std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a) -> double { return max(a); }));
-
-  scheme_module
-    ._addBuiltinFunction("max",
-                         std::make_shared<BuiltinFunctionEmbedder<
-                           std::shared_ptr<const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>,
-                                                                    std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a, std::shared_ptr<const IDiscreteFunction> b)
-                             -> std::shared_ptr<const IDiscreteFunction> { return max(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("max",
-                         std::make_shared<BuiltinFunctionEmbedder<
-                           std::shared_ptr<const IDiscreteFunction>(double, std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](double a, std::shared_ptr<const IDiscreteFunction> b)
-                             -> std::shared_ptr<const IDiscreteFunction> { return max(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("max",
-                         std::make_shared<BuiltinFunctionEmbedder<
-                           std::shared_ptr<const IDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>, double)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a,
-                              double b) -> std::shared_ptr<const IDiscreteFunction> { return max(a, b); }));
-
-  scheme_module
-    ._addBuiltinFunction("sum_of_R",
-                         std::make_shared<BuiltinFunctionEmbedder<double(std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a) -> double { return sum_of<double>(a); }));
-
-  scheme_module._addBuiltinFunction("sum_of_R1",
-                                    std::make_shared<
-                                      BuiltinFunctionEmbedder<TinyVector<1>(std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a) -> TinyVector<1> {
-                                        return sum_of<TinyVector<1>>(a);
-                                      }));
+  scheme_module._addBuiltinFunction("sqrt", std::function(
 
-  scheme_module._addBuiltinFunction("sum_of_R2",
-                                    std::make_shared<
-                                      BuiltinFunctionEmbedder<TinyVector<2>(std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a) -> TinyVector<2> {
-                                        return sum_of<TinyVector<2>>(a);
-                                      }));
+                                              [](std::shared_ptr<const IDiscreteFunction> a)
+                                                -> std::shared_ptr<const IDiscreteFunction> { return sqrt(a); }
 
-  scheme_module._addBuiltinFunction("sum_of_R3",
-                                    std::make_shared<
-                                      BuiltinFunctionEmbedder<TinyVector<3>(std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a) -> TinyVector<3> {
-                                        return sum_of<TinyVector<3>>(a);
-                                      }));
+                                              ));
 
-  scheme_module._addBuiltinFunction("sum_of_R1x1",
-                                    std::make_shared<
-                                      BuiltinFunctionEmbedder<TinyMatrix<1>(std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a) -> TinyMatrix<1> {
-                                        return sum_of<TinyMatrix<1>>(a);
-                                      }));
+  scheme_module._addBuiltinFunction("abs", std::function(
 
-  scheme_module._addBuiltinFunction("sum_of_R2x2",
-                                    std::make_shared<
-                                      BuiltinFunctionEmbedder<TinyMatrix<2>(std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a) -> TinyMatrix<2> {
-                                        return sum_of<TinyMatrix<2>>(a);
-                                      }));
+                                             [](std::shared_ptr<const IDiscreteFunction> a)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return abs(a); }
 
-  scheme_module._addBuiltinFunction("sum_of_R3x3",
-                                    std::make_shared<
-                                      BuiltinFunctionEmbedder<TinyMatrix<3>(std::shared_ptr<const IDiscreteFunction>)>>(
-                                      [](std::shared_ptr<const IDiscreteFunction> a) -> TinyMatrix<3> {
-                                        return sum_of<TinyMatrix<3>>(a);
-                                      }));
-  scheme_module
-    ._addBuiltinFunction("integral_of_R",
-                         std::make_shared<BuiltinFunctionEmbedder<double(std::shared_ptr<const IDiscreteFunction>)>>(
-                           [](std::shared_ptr<const IDiscreteFunction> a) -> double {
-                             return integral_of<double>(a);
-                           }));
+                                             ));
+
+  scheme_module._addBuiltinFunction("sin", std::function(
+
+                                             [](std::shared_ptr<const IDiscreteFunction> a)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return sin(a); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("cos", std::function(
+
+                                             [](std::shared_ptr<const IDiscreteFunction> a)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return cos(a); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("tan", std::function(
+
+                                             [](std::shared_ptr<const IDiscreteFunction> a)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return tan(a); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("asin", std::function(
+
+                                              [](std::shared_ptr<const IDiscreteFunction> a)
+                                                -> std::shared_ptr<const IDiscreteFunction> { return asin(a); }
+
+                                              ));
+
+  scheme_module._addBuiltinFunction("acos", std::function(
+
+                                              [](std::shared_ptr<const IDiscreteFunction> a)
+                                                -> std::shared_ptr<const IDiscreteFunction> { return acos(a); }
+
+                                              ));
+
+  scheme_module._addBuiltinFunction("atan", std::function(
+
+                                              [](std::shared_ptr<const IDiscreteFunction> a)
+                                                -> std::shared_ptr<const IDiscreteFunction> { return atan(a); }
+
+                                              ));
+
+  scheme_module._addBuiltinFunction("atan2", std::function(
+
+                                               [](std::shared_ptr<const IDiscreteFunction> a,
+                                                  std::shared_ptr<const IDiscreteFunction> b)
+                                                 -> std::shared_ptr<const IDiscreteFunction> { return atan2(a, b); }
+
+                                               ));
+
+  scheme_module._addBuiltinFunction("atan2", std::function(
+
+                                               [](double a, std::shared_ptr<const IDiscreteFunction> b)
+                                                 -> std::shared_ptr<const IDiscreteFunction> { return atan2(a, b); }
+
+                                               ));
+
+  scheme_module._addBuiltinFunction("atan2",
+                                    std::function(
+
+                                      [](std::shared_ptr<const IDiscreteFunction> a,
+                                         double b) -> std::shared_ptr<const IDiscreteFunction> { return atan2(a, b); }
+
+                                      ));
+
+  scheme_module._addBuiltinFunction("sinh", std::function(
+
+                                              [](std::shared_ptr<const IDiscreteFunction> a)
+                                                -> std::shared_ptr<const IDiscreteFunction> { return sinh(a); }
+
+                                              ));
+
+  scheme_module._addBuiltinFunction("std::function", std::function(
+
+                                                       [](std::shared_ptr<const IDiscreteFunction> a)
+                                                         -> std::shared_ptr<const IDiscreteFunction> { return tanh(a); }
+
+                                                       ));
+
+  scheme_module._addBuiltinFunction("asinh", std::function(
+
+                                               [](std::shared_ptr<const IDiscreteFunction> a)
+                                                 -> std::shared_ptr<const IDiscreteFunction> { return asinh(a); }
+
+                                               ));
+
+  scheme_module._addBuiltinFunction("acosh", std::function(
+
+                                               [](std::shared_ptr<const IDiscreteFunction> a)
+                                                 -> std::shared_ptr<const IDiscreteFunction> { return acosh(a); }
+
+                                               ));
+
+  scheme_module._addBuiltinFunction("atanh", std::function(
+
+                                               [](std::shared_ptr<const IDiscreteFunction> a)
+                                                 -> std::shared_ptr<const IDiscreteFunction> { return atanh(a); }
+
+                                               ));
+
+  scheme_module._addBuiltinFunction("exp", std::function(
+
+                                             [](std::shared_ptr<const IDiscreteFunction> a)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return exp(a); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("log", std::function(
+
+                                             [](std::shared_ptr<const IDiscreteFunction> a)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return log(a); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("pow", std::function(
+
+                                             [](double a, std::shared_ptr<const IDiscreteFunction> b)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return pow(a, b); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("pow",
+                                    std::function(
+
+                                      [](std::shared_ptr<const IDiscreteFunction> a,
+                                         double b) -> std::shared_ptr<const IDiscreteFunction> { return pow(a, b); }
+
+                                      ));
+
+  scheme_module._addBuiltinFunction("pow", std::function(
+
+                                             [](std::shared_ptr<const IDiscreteFunction> a,
+                                                std::shared_ptr<const IDiscreteFunction> b)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return pow(a, b); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("dot", std::function(
+
+                                             [](std::shared_ptr<const IDiscreteFunction> a,
+                                                std::shared_ptr<const IDiscreteFunction> b)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("dot", std::function(
+
+                                             [](std::shared_ptr<const IDiscreteFunction> a, const TinyVector<1> b)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("dot", std::function(
+
+                                             [](std::shared_ptr<const IDiscreteFunction> a, const TinyVector<2> b)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("dot", std::function(
+
+                                             [](std::shared_ptr<const IDiscreteFunction> a, const TinyVector<3>& b)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("dot", std::function(
+
+                                             [](const TinyVector<1> a, std::shared_ptr<const IDiscreteFunction> b)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("dot", std::function(
+
+                                             [](const TinyVector<2> a, std::shared_ptr<const IDiscreteFunction> b)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("dot", std::function(
+
+                                             [](const TinyVector<3>& a, std::shared_ptr<const IDiscreteFunction> b)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return dot(a, b); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("min", std::function(
+
+                                             [](std::shared_ptr<const IDiscreteFunction> a) -> double { return min(a); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("min", std::function(
+
+                                             [](std::shared_ptr<const IDiscreteFunction> a,
+                                                std::shared_ptr<const IDiscreteFunction> b)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return min(a, b); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("min", std::function(
+
+                                             [](double a, std::shared_ptr<const IDiscreteFunction> b)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return min(a, b); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("min",
+                                    std::function(
+
+                                      [](std::shared_ptr<const IDiscreteFunction> a,
+                                         double b) -> std::shared_ptr<const IDiscreteFunction> { return min(a, b); }
+
+                                      ));
+
+  scheme_module._addBuiltinFunction("max", std::function(
+
+                                             [](std::shared_ptr<const IDiscreteFunction> a) -> double { return max(a); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("max", std::function(
+
+                                             [](std::shared_ptr<const IDiscreteFunction> a,
+                                                std::shared_ptr<const IDiscreteFunction> b)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return max(a, b); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("max", std::function(
+
+                                             [](double a, std::shared_ptr<const IDiscreteFunction> b)
+                                               -> std::shared_ptr<const IDiscreteFunction> { return max(a, b); }
+
+                                             ));
+
+  scheme_module._addBuiltinFunction("max",
+                                    std::function(
+
+                                      [](std::shared_ptr<const IDiscreteFunction> a,
+                                         double b) -> std::shared_ptr<const IDiscreteFunction> { return max(a, b); }
+
+                                      ));
+
+  scheme_module._addBuiltinFunction("sum_of_R", std::function(
+
+                                                  [](std::shared_ptr<const IDiscreteFunction> a) -> double {
+                                                    return sum_of<double>(a);
+                                                  }
+
+                                                  ));
+
+  scheme_module._addBuiltinFunction("sum_of_R1", std::function(
+
+                                                   [](std::shared_ptr<const IDiscreteFunction> a) -> TinyVector<1> {
+                                                     return sum_of<TinyVector<1>>(a);
+                                                   }
+
+                                                   ));
+
+  scheme_module._addBuiltinFunction("sum_of_R2", std::function(
+
+                                                   [](std::shared_ptr<const IDiscreteFunction> a) -> TinyVector<2> {
+                                                     return sum_of<TinyVector<2>>(a);
+                                                   }
+
+                                                   ));
+
+  scheme_module._addBuiltinFunction("sum_of_R3", std::function(
+
+                                                   [](std::shared_ptr<const IDiscreteFunction> a) -> TinyVector<3> {
+                                                     return sum_of<TinyVector<3>>(a);
+                                                   }
+
+                                                   ));
+
+  scheme_module._addBuiltinFunction("sum_of_R1x1", std::function(
+
+                                                     [](std::shared_ptr<const IDiscreteFunction> a) -> TinyMatrix<1> {
+                                                       return sum_of<TinyMatrix<1>>(a);
+                                                     }
+
+                                                     ));
+
+  scheme_module._addBuiltinFunction("sum_of_R2x2", std::function(
+
+                                                     [](std::shared_ptr<const IDiscreteFunction> a) -> TinyMatrix<2> {
+                                                       return sum_of<TinyMatrix<2>>(a);
+                                                     }
+
+                                                     ));
+
+  scheme_module._addBuiltinFunction("sum_of_R3x3", std::function(
+
+                                                     [](std::shared_ptr<const IDiscreteFunction> a) -> TinyMatrix<3> {
+                                                       return sum_of<TinyMatrix<3>>(a);
+                                                     }
+
+                                                     ));
+
+  scheme_module._addBuiltinFunction("integral_of_R", std::function(
+
+                                                       [](std::shared_ptr<const IDiscreteFunction> a) -> double {
+                                                         return integral_of<double>(a);
+                                                       }
+
+                                                       ));
 
   scheme_module._addBuiltinFunction("integral_of_R1",
-                                    std::make_shared<
-                                      BuiltinFunctionEmbedder<TinyVector<1>(std::shared_ptr<const IDiscreteFunction>)>>(
+                                    std::function(
+
                                       [](std::shared_ptr<const IDiscreteFunction> a) -> TinyVector<1> {
                                         return integral_of<TinyVector<1>>(a);
-                                      }));
+                                      }
+
+                                      ));
 
   scheme_module._addBuiltinFunction("integral_of_R2",
-                                    std::make_shared<
-                                      BuiltinFunctionEmbedder<TinyVector<2>(std::shared_ptr<const IDiscreteFunction>)>>(
+                                    std::function(
+
                                       [](std::shared_ptr<const IDiscreteFunction> a) -> TinyVector<2> {
                                         return integral_of<TinyVector<2>>(a);
-                                      }));
+                                      }
+
+                                      ));
 
   scheme_module._addBuiltinFunction("integral_of_R3",
-                                    std::make_shared<
-                                      BuiltinFunctionEmbedder<TinyVector<3>(std::shared_ptr<const IDiscreteFunction>)>>(
+                                    std::function(
+
                                       [](std::shared_ptr<const IDiscreteFunction> a) -> TinyVector<3> {
                                         return integral_of<TinyVector<3>>(a);
-                                      }));
+                                      }
+
+                                      ));
 
   scheme_module._addBuiltinFunction("integral_of_R1x1",
-                                    std::make_shared<
-                                      BuiltinFunctionEmbedder<TinyMatrix<1>(std::shared_ptr<const IDiscreteFunction>)>>(
+                                    std::function(
+
                                       [](std::shared_ptr<const IDiscreteFunction> a) -> TinyMatrix<1> {
                                         return integral_of<TinyMatrix<1>>(a);
-                                      }));
+                                      }
+
+                                      ));
 
   scheme_module._addBuiltinFunction("integral_of_R2x2",
-                                    std::make_shared<
-                                      BuiltinFunctionEmbedder<TinyMatrix<2>(std::shared_ptr<const IDiscreteFunction>)>>(
+                                    std::function(
+
                                       [](std::shared_ptr<const IDiscreteFunction> a) -> TinyMatrix<2> {
                                         return integral_of<TinyMatrix<2>>(a);
-                                      }));
+                                      }
+
+                                      ));
 
   scheme_module._addBuiltinFunction("integral_of_R3x3",
-                                    std::make_shared<
-                                      BuiltinFunctionEmbedder<TinyMatrix<3>(std::shared_ptr<const IDiscreteFunction>)>>(
+                                    std::function(
+
                                       [](std::shared_ptr<const IDiscreteFunction> a) -> TinyMatrix<3> {
                                         return integral_of<TinyMatrix<3>>(a);
-                                      }));
+                                      }
+
+                                      ));
 }
diff --git a/src/language/modules/MathModule.cpp b/src/language/modules/MathModule.cpp
index e73bfc4f5654f0864774ee2be8e1ada4b9d73927..4e8e10d1534f55f8c02cccb2f3f48974fdc944d2 100644
--- a/src/language/modules/MathModule.cpp
+++ b/src/language/modules/MathModule.cpp
@@ -7,99 +7,69 @@
 
 MathModule::MathModule()
 {
-  this->_addBuiltinFunction("sqrt", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                      [](double x) -> double { return std::sqrt(x); }));
+  this->_addBuiltinFunction("sqrt", std::function([](double x) -> double { return std::sqrt(x); }));
 
-  this->_addBuiltinFunction("abs", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                     [](double x) -> double { return std::abs(x); }));
+  this->_addBuiltinFunction("abs", std::function([](double x) -> double { return std::abs(x); }));
 
-  this->_addBuiltinFunction("abs", std::make_shared<BuiltinFunctionEmbedder<uint64_t(int64_t)>>(
-                                     [](int64_t x) -> uint64_t { return std::abs(x); }));
+  this->_addBuiltinFunction("abs", std::function([](int64_t x) -> uint64_t { return std::abs(x); }));
 
-  this->_addBuiltinFunction("sin", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                     [](double x) -> double { return std::sin(x); }));
+  this->_addBuiltinFunction("sin", std::function([](double x) -> double { return std::sin(x); }));
 
-  this->_addBuiltinFunction("cos", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                     [](double x) -> double { return std::cos(x); }));
+  this->_addBuiltinFunction("cos", std::function([](double x) -> double { return std::cos(x); }));
 
-  this->_addBuiltinFunction("tan", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                     [](double x) -> double { return std::tan(x); }));
+  this->_addBuiltinFunction("tan", std::function([](double x) -> double { return std::tan(x); }));
 
-  this->_addBuiltinFunction("asin", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                      [](double x) -> double { return std::asin(x); }));
+  this->_addBuiltinFunction("asin", std::function([](double x) -> double { return std::asin(x); }));
 
-  this->_addBuiltinFunction("acos", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                      [](double x) -> double { return std::acos(x); }));
+  this->_addBuiltinFunction("acos", std::function([](double x) -> double { return std::acos(x); }));
 
-  this->_addBuiltinFunction("atan", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                      [](double x) -> double { return std::atan(x); }));
+  this->_addBuiltinFunction("atan", std::function([](double x) -> double { return std::atan(x); }));
 
-  this->_addBuiltinFunction("atan2", std::make_shared<BuiltinFunctionEmbedder<double(double, double)>>(
-                                       [](double x, double y) -> double { return std::atan2(x, y); }));
+  this->_addBuiltinFunction("atan2", std::function([](double x, double y) -> double { return std::atan2(x, y); }));
 
-  this->_addBuiltinFunction("sinh", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                      [](double x) -> double { return std::sinh(x); }));
+  this->_addBuiltinFunction("sinh", std::function([](double x) -> double { return std::sinh(x); }));
 
-  this->_addBuiltinFunction("cosh", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                      [](double x) -> double { return std::cosh(x); }));
+  this->_addBuiltinFunction("cosh", std::function([](double x) -> double { return std::cosh(x); }));
 
-  this->_addBuiltinFunction("tanh", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                      [](double x) -> double { return std::tanh(x); }));
+  this->_addBuiltinFunction("tanh", std::function([](double x) -> double { return std::tanh(x); }));
 
-  this->_addBuiltinFunction("asinh", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                       [](double x) -> double { return std::asinh(x); }));
+  this->_addBuiltinFunction("asinh", std::function([](double x) -> double { return std::asinh(x); }));
 
-  this->_addBuiltinFunction("acosh", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                       [](double x) -> double { return std::acosh(x); }));
+  this->_addBuiltinFunction("acosh", std::function([](double x) -> double { return std::acosh(x); }));
 
-  this->_addBuiltinFunction("atanh", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                       [](double x) -> double { return std::atanh(x); }));
+  this->_addBuiltinFunction("atanh", std::function([](double x) -> double { return std::atanh(x); }));
 
-  this->_addBuiltinFunction("exp", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                     [](double x) -> double { return std::exp(x); }));
+  this->_addBuiltinFunction("exp", std::function([](double x) -> double { return std::exp(x); }));
 
-  this->_addBuiltinFunction("log", std::make_shared<BuiltinFunctionEmbedder<double(double)>>(
-                                     [](double x) -> double { return std::log(x); }));
+  this->_addBuiltinFunction("log", std::function([](double x) -> double { return std::log(x); }));
 
-  this->_addBuiltinFunction("pow", std::make_shared<BuiltinFunctionEmbedder<double(double, double)>>(
-                                     [](double x, double y) -> double { return std::pow(x, y); }));
+  this->_addBuiltinFunction("pow", std::function([](double x, double y) -> double { return std::pow(x, y); }));
 
-  this->_addBuiltinFunction("ceil", std::make_shared<BuiltinFunctionEmbedder<int64_t(double)>>(
-                                      [](double x) -> int64_t { return std::ceil(x); }));
+  this->_addBuiltinFunction("ceil", std::function([](double x) -> int64_t { return std::ceil(x); }));
 
-  this->_addBuiltinFunction("floor", std::make_shared<BuiltinFunctionEmbedder<int64_t(double)>>(
-                                       [](double x) -> int64_t { return std::floor(x); }));
+  this->_addBuiltinFunction("floor", std::function([](double x) -> int64_t { return std::floor(x); }));
 
-  this->_addBuiltinFunction("trunc", std::make_shared<BuiltinFunctionEmbedder<int64_t(double)>>(
-                                       [](double x) -> int64_t { return std::trunc(x); }));
+  this->_addBuiltinFunction("trunc", std::function([](double x) -> int64_t { return std::trunc(x); }));
 
-  this->_addBuiltinFunction("round", std::make_shared<BuiltinFunctionEmbedder<int64_t(double)>>(
-                                       [](double x) -> int64_t { return std::lround(x); }));
+  this->_addBuiltinFunction("round", std::function([](double x) -> int64_t { return std::lround(x); }));
 
-  this->_addBuiltinFunction("min", std::make_shared<BuiltinFunctionEmbedder<double(double, double)>>(
-                                     [](double x, double y) -> double { return std::min(x, y); }));
+  this->_addBuiltinFunction("min", std::function([](double x, double y) -> double { return std::min(x, y); }));
 
-  this->_addBuiltinFunction("min", std::make_shared<BuiltinFunctionEmbedder<int64_t(int64_t, int64_t)>>(
-                                     [](int64_t x, int64_t y) -> int64_t { return std::min(x, y); }));
+  this->_addBuiltinFunction("min", std::function([](int64_t x, int64_t y) -> int64_t { return std::min(x, y); }));
 
-  this->_addBuiltinFunction("max", std::make_shared<BuiltinFunctionEmbedder<double(double, double)>>(
-                                     [](double x, double y) -> double { return std::max(x, y); }));
+  this->_addBuiltinFunction("max", std::function([](double x, double y) -> double { return std::max(x, y); }));
 
-  this->_addBuiltinFunction("max", std::make_shared<BuiltinFunctionEmbedder<int64_t(int64_t, int64_t)>>(
-                                     [](int64_t x, int64_t y) -> int64_t { return std::max(x, y); }));
+  this->_addBuiltinFunction("max", std::function([](int64_t x, int64_t y) -> int64_t { return std::max(x, y); }));
 
-  this->_addBuiltinFunction("dot",
-                            std::make_shared<BuiltinFunctionEmbedder<double(const TinyVector<1>, const TinyVector<1>)>>(
-                              [](const TinyVector<1> x, const TinyVector<1> y) -> double { return dot(x, y); }));
+  this->_addBuiltinFunction("dot", std::function(
+                                     [](const TinyVector<1> x, const TinyVector<1> y) -> double { return dot(x, y); }));
 
-  this->_addBuiltinFunction("dot",
-                            std::make_shared<BuiltinFunctionEmbedder<double(const TinyVector<2>, const TinyVector<2>)>>(
-                              [](const TinyVector<2> x, const TinyVector<2> y) -> double { return dot(x, y); }));
+  this->_addBuiltinFunction("dot", std::function(
+                                     [](const TinyVector<2> x, const TinyVector<2> y) -> double { return dot(x, y); }));
 
-  this
-    ->_addBuiltinFunction("dot",
-                          std::make_shared<BuiltinFunctionEmbedder<double(const TinyVector<3>&, const TinyVector<3>&)>>(
-                            [](const TinyVector<3>& x, const TinyVector<3>& y) -> double { return dot(x, y); }));
+  this->_addBuiltinFunction("dot", std::function([](const TinyVector<3>& x, const TinyVector<3>& y) -> double {
+                              return dot(x, y);
+                            }));
 }
 
 void
diff --git a/src/language/modules/MeshModule.cpp b/src/language/modules/MeshModule.cpp
index 485886fdc9721f27dbb0180a2875bb6272cbeda5..4fc75f4f2b61058b339c748f822720107c92dd1a 100644
--- a/src/language/modules/MeshModule.cpp
+++ b/src/language/modules/MeshModule.cpp
@@ -32,19 +32,17 @@ MeshModule::MeshModule()
   this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const IBoundaryDescriptor>>);
   this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const IZoneDescriptor>>);
 
-  this->_addBuiltinFunction("readGmsh",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IMesh>(const std::string&)>>(
+  this->_addBuiltinFunction("readGmsh", std::function(
 
-                              [](const std::string& file_name) -> std::shared_ptr<const IMesh> {
-                                GmshReader gmsh_reader(file_name);
-                                return gmsh_reader.mesh();
-                              }
+                                          [](const std::string& file_name) -> std::shared_ptr<const IMesh> {
+                                            GmshReader gmsh_reader(file_name);
+                                            return gmsh_reader.mesh();
+                                          }
 
-                              ));
+                                          ));
 
   this->_addBuiltinFunction("boundaryName",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<std::shared_ptr<const IBoundaryDescriptor>(const std::string&)>>(
+                            std::function(
 
                               [](const std::string& boundary_name) -> std::shared_ptr<const IBoundaryDescriptor> {
                                 return std::make_shared<NamedBoundaryDescriptor>(boundary_name);
@@ -52,62 +50,51 @@ MeshModule::MeshModule()
 
                               ));
 
-  this->_addBuiltinFunction("zoneTag",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IZoneDescriptor>(int64_t)>>(
+  this->_addBuiltinFunction("zoneTag", std::function(
 
-                              [](int64_t zone_tag) -> std::shared_ptr<const IZoneDescriptor> {
-                                return std::make_shared<NumberedZoneDescriptor>(zone_tag);
-                              }
+                                         [](int64_t zone_tag) -> std::shared_ptr<const IZoneDescriptor> {
+                                           return std::make_shared<NumberedZoneDescriptor>(zone_tag);
+                                         }
 
-                              ));
+                                         ));
 
-  this->_addBuiltinFunction("zoneName",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<std::shared_ptr<const IZoneDescriptor>(const std::string&)>>(
+  this->_addBuiltinFunction("zoneName", std::function(
 
-                              [](const std::string& zone_name) -> std::shared_ptr<const IZoneDescriptor> {
-                                return std::make_shared<NamedZoneDescriptor>(zone_name);
-                              }
+                                          [](const std::string& zone_name) -> std::shared_ptr<const IZoneDescriptor> {
+                                            return std::make_shared<NamedZoneDescriptor>(zone_name);
+                                          }
 
-                              ));
+                                          ));
 
-  this->_addBuiltinFunction("boundaryTag",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<std::shared_ptr<const IBoundaryDescriptor>(int64_t)>>(
+  this->_addBuiltinFunction("boundaryTag", std::function(
 
-                              [](int64_t boundary_tag) -> std::shared_ptr<const IBoundaryDescriptor> {
-                                return std::make_shared<NumberedBoundaryDescriptor>(boundary_tag);
-                              }
+                                             [](int64_t boundary_tag) -> std::shared_ptr<const IBoundaryDescriptor> {
+                                               return std::make_shared<NumberedBoundaryDescriptor>(boundary_tag);
+                                             }
 
-                              ));
+                                             ));
 
-  this->_addBuiltinFunction("transform",
-                            std::make_shared<BuiltinFunctionEmbedder<
-                              std::shared_ptr<const IMesh>(std::shared_ptr<const IMesh>, const FunctionSymbolId&)>>(
+  this->_addBuiltinFunction("transform", std::function(
 
-                              [](std::shared_ptr<const IMesh> p_mesh,
-                                 const FunctionSymbolId& function_id) -> std::shared_ptr<const IMesh> {
-                                return MeshTransformer{}.transform(function_id, p_mesh);
-                              }
+                                           [](std::shared_ptr<const IMesh> p_mesh,
+                                              const FunctionSymbolId& function_id) -> std::shared_ptr<const IMesh> {
+                                             return MeshTransformer{}.transform(function_id, p_mesh);
+                                           }
 
-                              ));
+                                           ));
 
-  this->_addBuiltinFunction("relax",
-                            std::make_shared<BuiltinFunctionEmbedder<
-                              std::shared_ptr<const IMesh>(const std::shared_ptr<const IMesh>&,
-                                                           const std::shared_ptr<const IMesh>&, const double&)>>(
+  this->_addBuiltinFunction("relax", std::function(
 
-                              [](const std::shared_ptr<const IMesh>& source_mesh,
-                                 const std::shared_ptr<const IMesh>& destination_mesh,
-                                 const double& theta) -> std::shared_ptr<const IMesh> {
-                                return MeshRelaxer{}.relax(source_mesh, destination_mesh, theta);
-                              }
+                                       [](const std::shared_ptr<const IMesh>& source_mesh,
+                                          const std::shared_ptr<const IMesh>& destination_mesh,
+                                          const double& theta) -> std::shared_ptr<const IMesh> {
+                                         return MeshRelaxer{}.relax(source_mesh, destination_mesh, theta);
+                                       }
 
-                              ));
+                                       ));
 
   this->_addBuiltinFunction("cartesianMesh",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                              const IMesh>(const TinyVector<1>, const TinyVector<1>, const std::vector<uint64_t>&)>>(
+                            std::function(
 
                               [](const TinyVector<1> a, const TinyVector<1> b,
                                  const std::vector<uint64_t>& box_sizes) -> std::shared_ptr<const IMesh> {
@@ -133,8 +120,7 @@ MeshModule::MeshModule()
                               ));
 
   this->_addBuiltinFunction("cartesianMesh",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                              const IMesh>(const TinyVector<2>, const TinyVector<2>, const std::vector<uint64_t>&)>>(
+                            std::function(
 
                               [](const TinyVector<2> a, const TinyVector<2> b,
                                  const std::vector<uint64_t>& box_sizes) -> std::shared_ptr<const IMesh> {
@@ -160,8 +146,7 @@ MeshModule::MeshModule()
                               ));
 
   this->_addBuiltinFunction("cartesianMesh",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                              const IMesh>(const TinyVector<3>&, const TinyVector<3>&, const std::vector<uint64_t>&)>>(
+                            std::function(
 
                               [](const TinyVector<3>& a, const TinyVector<3>& b,
                                  const std::vector<uint64_t>& box_sizes) -> std::shared_ptr<const IMesh> {
@@ -187,8 +172,7 @@ MeshModule::MeshModule()
                               ));
 
   this->_addBuiltinFunction("diamondDual",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IMesh>(
-                              const std::shared_ptr<const IMesh>&)>>(
+                            std::function(
 
                               [](const std::shared_ptr<const IMesh>& i_mesh) -> std::shared_ptr<const IMesh> {
                                 switch (i_mesh->dimension()) {
@@ -219,8 +203,7 @@ MeshModule::MeshModule()
                               ));
 
   this->_addBuiltinFunction("medianDual",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IMesh>(
-                              const std::shared_ptr<const IMesh>&)>>(
+                            std::function(
 
                               [](const std::shared_ptr<const IMesh>& i_mesh) -> std::shared_ptr<const IMesh> {
                                 switch (i_mesh->dimension()) {
diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp
index bc744e4d3318a6c5eda1981dccf4709430fbde35..01dcc66eb23da733c9b5d5922d8bdb55156d73ca 100644
--- a/src/language/modules/SchemeModule.cpp
+++ b/src/language/modules/SchemeModule.cpp
@@ -48,56 +48,49 @@ SchemeModule::SchemeModule()
 
   this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const IBoundaryConditionDescriptor>>);
 
-  this->_addBuiltinFunction("P0", std::make_shared<
-                                    BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunctionDescriptor>()>>(
+  this->_addBuiltinFunction("P0", std::function(
+
                                     []() -> std::shared_ptr<const IDiscreteFunctionDescriptor> {
                                       return std::make_shared<DiscreteFunctionDescriptorP0>();
                                     }
 
                                     ));
 
-  this->_addBuiltinFunction("P0Vector",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunctionDescriptor>()>>(
-                              []() -> std::shared_ptr<const IDiscreteFunctionDescriptor> {
-                                return std::make_shared<DiscreteFunctionDescriptorP0Vector>();
-                              }
+  this->_addBuiltinFunction("P0Vector", std::function(
 
-                              ));
+                                          []() -> std::shared_ptr<const IDiscreteFunctionDescriptor> {
+                                            return std::make_shared<DiscreteFunctionDescriptorP0Vector>();
+                                          }
+
+                                          ));
+
+  this->_addBuiltinFunction("Gauss", std::function(
 
-  this->_addBuiltinFunction("Gauss", std::make_shared<
-                                       BuiltinFunctionEmbedder<std::shared_ptr<const IQuadratureDescriptor>(uint64_t)>>(
                                        [](uint64_t degree) -> std::shared_ptr<const IQuadratureDescriptor> {
                                          return std::make_shared<GaussQuadratureDescriptor>(degree);
                                        }
 
                                        ));
 
-  this->_addBuiltinFunction("GaussLobatto",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<std::shared_ptr<const IQuadratureDescriptor>(uint64_t)>>(
-                              [](uint64_t degree) -> std::shared_ptr<const IQuadratureDescriptor> {
-                                return std::make_shared<GaussLobattoQuadratureDescriptor>(degree);
-                              }
+  this->_addBuiltinFunction("GaussLobatto", std::function(
 
-                              ));
+                                              [](uint64_t degree) -> std::shared_ptr<const IQuadratureDescriptor> {
+                                                return std::make_shared<GaussLobattoQuadratureDescriptor>(degree);
+                                              }
 
-  this->_addBuiltinFunction("GaussLegendre",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<std::shared_ptr<const IQuadratureDescriptor>(uint64_t)>>(
-                              [](uint64_t degree) -> std::shared_ptr<const IQuadratureDescriptor> {
-                                return std::make_shared<GaussLegendreQuadratureDescriptor>(degree);
-                              }
+                                              ));
 
-                              ));
+  this->_addBuiltinFunction("GaussLegendre", std::function(
+
+                                               [](uint64_t degree) -> std::shared_ptr<const IQuadratureDescriptor> {
+                                                 return std::make_shared<GaussLegendreQuadratureDescriptor>(degree);
+                                               }
+
+                                               ));
 
   this->_addBuiltinFunction("integrate",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                              const IDiscreteFunction>(std::shared_ptr<const IMesh>,
-                                                       const std::vector<std::shared_ptr<const IZoneDescriptor>>&,
-                                                       std::shared_ptr<const IQuadratureDescriptor>,
-                                                       std::shared_ptr<const IDiscreteFunctionDescriptor>,
-                                                       const std::vector<FunctionSymbolId>&)>>(
+                            std::function(
+
                               [](std::shared_ptr<const IMesh> mesh,
                                  const std::vector<std::shared_ptr<const IZoneDescriptor>>& integration_zone_list,
                                  std::shared_ptr<const IQuadratureDescriptor> quadrature_descriptor,
@@ -112,30 +105,25 @@ SchemeModule::SchemeModule()
 
                               ));
 
-  this
-    ->_addBuiltinFunction("integrate",
-                          std::make_shared<BuiltinFunctionEmbedder<
-                            std::shared_ptr<const IDiscreteFunction>(std::shared_ptr<const IMesh>,
-                                                                     std::shared_ptr<const IQuadratureDescriptor>,
-                                                                     std::shared_ptr<const IDiscreteFunctionDescriptor>,
-                                                                     const std::vector<FunctionSymbolId>&)>>(
-                            [](std::shared_ptr<const IMesh> mesh,
-                               std::shared_ptr<const IQuadratureDescriptor> quadrature_descriptor,
-                               std::shared_ptr<const IDiscreteFunctionDescriptor> discrete_function_descriptor,
-                               const std::vector<FunctionSymbolId>& function_id_list)
-                              -> std::shared_ptr<const IDiscreteFunction> {
-                              return DiscreteFunctionVectorIntegrator{mesh, quadrature_descriptor,
-                                                                      discrete_function_descriptor, function_id_list}
-                                .integrate();
-                            }
+  this->_addBuiltinFunction("integrate",
+                            std::function(
 
-                            ));
+                              [](std::shared_ptr<const IMesh> mesh,
+                                 std::shared_ptr<const IQuadratureDescriptor> quadrature_descriptor,
+                                 std::shared_ptr<const IDiscreteFunctionDescriptor> discrete_function_descriptor,
+                                 const std::vector<FunctionSymbolId>& function_id_list)
+                                -> std::shared_ptr<const IDiscreteFunction> {
+                                return DiscreteFunctionVectorIntegrator{mesh, quadrature_descriptor,
+                                                                        discrete_function_descriptor, function_id_list}
+                                  .integrate();
+                              }
+
+                              ));
 
   this->_addBuiltinFunction(
     "integrate",
-    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-      const IDiscreteFunction>(std::shared_ptr<const IMesh>, const std::vector<std::shared_ptr<const IZoneDescriptor>>&,
-                               std::shared_ptr<const IQuadratureDescriptor>, const FunctionSymbolId&)>>(
+    std::function(
+
       [](std::shared_ptr<const IMesh> mesh,
          const std::vector<std::shared_ptr<const IZoneDescriptor>>& integration_zone_list,
          std::shared_ptr<const IQuadratureDescriptor> quadrature_descriptor,
@@ -146,10 +134,8 @@ SchemeModule::SchemeModule()
       ));
 
   this->_addBuiltinFunction("integrate",
-                            std::make_shared<BuiltinFunctionEmbedder<
-                              std::shared_ptr<const IDiscreteFunction>(std::shared_ptr<const IMesh>,
-                                                                       std::shared_ptr<const IQuadratureDescriptor>,
-                                                                       const FunctionSymbolId&)>>(
+                            std::function(
+
                               [](std::shared_ptr<const IMesh> mesh,
                                  std::shared_ptr<const IQuadratureDescriptor> quadrature_descriptor,
                                  const FunctionSymbolId& function_id) -> std::shared_ptr<const IDiscreteFunction> {
@@ -159,11 +145,8 @@ SchemeModule::SchemeModule()
                               ));
 
   this->_addBuiltinFunction("interpolate",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                              const IDiscreteFunction>(std::shared_ptr<const IMesh>,
-                                                       const std::vector<std::shared_ptr<const IZoneDescriptor>>&,
-                                                       std::shared_ptr<const IDiscreteFunctionDescriptor>,
-                                                       const std::vector<FunctionSymbolId>&)>>(
+                            std::function(
+
                               [](std::shared_ptr<const IMesh> mesh,
                                  const std::vector<std::shared_ptr<const IZoneDescriptor>>& interpolation_zone_list,
                                  std::shared_ptr<const IDiscreteFunctionDescriptor> discrete_function_descriptor,
@@ -194,9 +177,8 @@ SchemeModule::SchemeModule()
 
   this->_addBuiltinFunction(
     "interpolate",
-    std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-      const IDiscreteFunction>(std::shared_ptr<const IMesh>, std::shared_ptr<const IDiscreteFunctionDescriptor>,
-                               const std::vector<FunctionSymbolId>&)>>(
+    std::function(
+
       [](std::shared_ptr<const IMesh> mesh,
          std::shared_ptr<const IDiscreteFunctionDescriptor> discrete_function_descriptor,
          const std::vector<FunctionSymbolId>& function_id_list) -> std::shared_ptr<const IDiscreteFunction> {
@@ -219,9 +201,7 @@ SchemeModule::SchemeModule()
       ));
 
   this->_addBuiltinFunction("randomizeMesh",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                              const IMesh>(std::shared_ptr<const IMesh>,
-                                           const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&)>>(
+                            std::function(
 
                               [](std::shared_ptr<const IMesh> p_mesh,
                                  const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&
@@ -233,10 +213,7 @@ SchemeModule::SchemeModule()
                               ));
 
   this->_addBuiltinFunction("randomizeMesh",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                              const IMesh>(std::shared_ptr<const IMesh>,
-                                           const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&,
-                                           const FunctionSymbolId&)>>(
+                            std::function(
 
                               [](std::shared_ptr<const IMesh> p_mesh,
                                  const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&
@@ -248,74 +225,59 @@ SchemeModule::SchemeModule()
 
                               ));
 
-  this
-    ->_addBuiltinFunction("fixed",
-                          std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IBoundaryConditionDescriptor>(
-                            std::shared_ptr<const IBoundaryDescriptor>)>>(
+  this->_addBuiltinFunction("fixed", std::function(
 
-                            [](std::shared_ptr<const IBoundaryDescriptor> boundary)
-                              -> std::shared_ptr<const IBoundaryConditionDescriptor> {
-                              return std::make_shared<FixedBoundaryConditionDescriptor>(boundary);
-                            }
+                                       [](std::shared_ptr<const IBoundaryDescriptor> boundary)
+                                         -> std::shared_ptr<const IBoundaryConditionDescriptor> {
+                                         return std::make_shared<FixedBoundaryConditionDescriptor>(boundary);
+                                       }
 
-                            ));
+                                       ));
 
-  this
-    ->_addBuiltinFunction("axis",
-                          std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IBoundaryConditionDescriptor>(
-                            std::shared_ptr<const IBoundaryDescriptor>)>>(
+  this->_addBuiltinFunction("axis", std::function(
 
-                            [](std::shared_ptr<const IBoundaryDescriptor> boundary)
-                              -> std::shared_ptr<const IBoundaryConditionDescriptor> {
-                              return std::make_shared<AxisBoundaryConditionDescriptor>(boundary);
-                            }
+                                      [](std::shared_ptr<const IBoundaryDescriptor> boundary)
+                                        -> std::shared_ptr<const IBoundaryConditionDescriptor> {
+                                        return std::make_shared<AxisBoundaryConditionDescriptor>(boundary);
+                                      }
 
-                            ));
+                                      ));
 
-  this
-    ->_addBuiltinFunction("symmetry",
-                          std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IBoundaryConditionDescriptor>(
-                            std::shared_ptr<const IBoundaryDescriptor>)>>(
+  this->_addBuiltinFunction("symmetry", std::function(
 
-                            [](std::shared_ptr<const IBoundaryDescriptor> boundary)
-                              -> std::shared_ptr<const IBoundaryConditionDescriptor> {
-                              return std::make_shared<SymmetryBoundaryConditionDescriptor>(boundary);
-                            }
+                                          [](std::shared_ptr<const IBoundaryDescriptor> boundary)
+                                            -> std::shared_ptr<const IBoundaryConditionDescriptor> {
+                                            return std::make_shared<SymmetryBoundaryConditionDescriptor>(boundary);
+                                          }
 
-                            ));
+                                          ));
 
-  this->_addBuiltinFunction("pressure",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                              const IBoundaryConditionDescriptor>(std::shared_ptr<const IBoundaryDescriptor>,
-                                                                  const FunctionSymbolId&)>>(
+  this->_addBuiltinFunction("pressure", std::function(
 
-                              [](std::shared_ptr<const IBoundaryDescriptor> boundary,
-                                 const FunctionSymbolId& pressure_id)
-                                -> std::shared_ptr<const IBoundaryConditionDescriptor> {
-                                return std::make_shared<DirichletBoundaryConditionDescriptor>("pressure", boundary,
-                                                                                              pressure_id);
-                              }
+                                          [](std::shared_ptr<const IBoundaryDescriptor> boundary,
+                                             const FunctionSymbolId& pressure_id)
+                                            -> std::shared_ptr<const IBoundaryConditionDescriptor> {
+                                            return std::make_shared<DirichletBoundaryConditionDescriptor>("pressure",
+                                                                                                          boundary,
+                                                                                                          pressure_id);
+                                          }
 
-                              ));
+                                          ));
 
-  this->_addBuiltinFunction("velocity",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                              const IBoundaryConditionDescriptor>(std::shared_ptr<const IBoundaryDescriptor>,
-                                                                  const FunctionSymbolId&)>>(
+  this->_addBuiltinFunction("velocity", std::function(
 
-                              [](std::shared_ptr<const IBoundaryDescriptor> boundary,
-                                 const FunctionSymbolId& velocity_id)
-                                -> std::shared_ptr<const IBoundaryConditionDescriptor> {
-                                return std::make_shared<DirichletBoundaryConditionDescriptor>("velocity", boundary,
-                                                                                              velocity_id);
-                              }
+                                          [](std::shared_ptr<const IBoundaryDescriptor> boundary,
+                                             const FunctionSymbolId& velocity_id)
+                                            -> std::shared_ptr<const IBoundaryConditionDescriptor> {
+                                            return std::make_shared<DirichletBoundaryConditionDescriptor>("velocity",
+                                                                                                          boundary,
+                                                                                                          velocity_id);
+                                          }
 
-                              ));
+                                          ));
 
   this->_addBuiltinFunction("external_fsi_velocity",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
-                              const IBoundaryConditionDescriptor>(std::shared_ptr<const IBoundaryDescriptor>,
-                                                                  const std::shared_ptr<const Socket>&)>>(
+                            std::function(
 
                               [](std::shared_ptr<const IBoundaryDescriptor> boundary,
                                  const std::shared_ptr<const Socket>& socket)
@@ -327,17 +289,7 @@ SchemeModule::SchemeModule()
                               ));
 
   this->_addBuiltinFunction("glace_solver",
-                            std::make_shared<BuiltinFunctionEmbedder<std::tuple<
-                              std::shared_ptr<const IMesh>, std::shared_ptr<const IDiscreteFunction>,
-                              std::shared_ptr<const IDiscreteFunction>,
-                              std::shared_ptr<const IDiscreteFunction>>(const std::shared_ptr<const IDiscreteFunction>&,
-                                                                        const std::shared_ptr<const IDiscreteFunction>&,
-                                                                        const std::shared_ptr<const IDiscreteFunction>&,
-                                                                        const std::shared_ptr<const IDiscreteFunction>&,
-                                                                        const std::shared_ptr<const IDiscreteFunction>&,
-                                                                        const std::vector<std::shared_ptr<
-                                                                          const IBoundaryConditionDescriptor>>&,
-                                                                        const double&)>>(
+                            std::function(
 
                               [](const std::shared_ptr<const IDiscreteFunction>& rho,
                                  const std::shared_ptr<const IDiscreteFunction>& u,
@@ -363,17 +315,7 @@ SchemeModule::SchemeModule()
                               ));
 
   this->_addBuiltinFunction("eucclhyd_solver",
-                            std::make_shared<BuiltinFunctionEmbedder<std::tuple<
-                              std::shared_ptr<const IMesh>, std::shared_ptr<const IDiscreteFunction>,
-                              std::shared_ptr<const IDiscreteFunction>,
-                              std::shared_ptr<const IDiscreteFunction>>(const std::shared_ptr<const IDiscreteFunction>&,
-                                                                        const std::shared_ptr<const IDiscreteFunction>&,
-                                                                        const std::shared_ptr<const IDiscreteFunction>&,
-                                                                        const std::shared_ptr<const IDiscreteFunction>&,
-                                                                        const std::shared_ptr<const IDiscreteFunction>&,
-                                                                        const std::vector<std::shared_ptr<
-                                                                          const IBoundaryConditionDescriptor>>&,
-                                                                        const double&)>>(
+                            std::function(
 
                               [](const std::shared_ptr<const IDiscreteFunction>& rho,
                                  const std::shared_ptr<const IDiscreteFunction>& u,
@@ -398,21 +340,17 @@ SchemeModule::SchemeModule()
 
                               ));
 
-  this
-    ->_addBuiltinFunction("lagrangian",
-                          std::make_shared<BuiltinFunctionEmbedder<
-                            std::shared_ptr<const IDiscreteFunction>(const std::shared_ptr<const IMesh>&,
-                                                                     const std::shared_ptr<const IDiscreteFunction>&)>>(
+  this->_addBuiltinFunction("lagrangian",
+                            std::function(
 
-                            [](const std::shared_ptr<const IMesh>& mesh,
-                               const std::shared_ptr<const IDiscreteFunction>& v)
-                              -> std::shared_ptr<const IDiscreteFunction> { return shallowCopy(mesh, v); }
+                              [](const std::shared_ptr<const IMesh>& mesh,
+                                 const std::shared_ptr<const IDiscreteFunction>& v)
+                                -> std::shared_ptr<const IDiscreteFunction> { return shallowCopy(mesh, v); }
 
-                            ));
+                              ));
 
   this->_addBuiltinFunction("acoustic_dt",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<double(const std::shared_ptr<const IDiscreteFunction>&)>>(
+                            std::function(
 
                               [](const std::shared_ptr<const IDiscreteFunction>& c) -> double { return acoustic_dt(c); }
 
@@ -420,8 +358,7 @@ SchemeModule::SchemeModule()
 
   this
     ->_addBuiltinFunction("cell_volume",
-                          std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunction>(
-                            const std::shared_ptr<const IMesh>&)>>(
+                          std::function(
 
                             [](const std::shared_ptr<const IMesh>& i_mesh) -> std::shared_ptr<const IDiscreteFunction> {
                               switch (i_mesh->dimension()) {
diff --git a/src/language/modules/SocketModule.cpp b/src/language/modules/SocketModule.cpp
index 0540af2b60553c33f61ccaeeed049d9696f6ba5e..426a561372289256182d0a5d981eaeaf00de2e08 100644
--- a/src/language/modules/SocketModule.cpp
+++ b/src/language/modules/SocketModule.cpp
@@ -11,7 +11,7 @@ SocketModule::SocketModule()
   this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const Socket>>);
 
   this->_addBuiltinFunction("createSocketServer",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const Socket>(const uint64_t&)>>(
+                            std::function(
 
                               [](const uint64_t& port_number) -> std::shared_ptr<const Socket> {
                                 return std::make_shared<const Socket>(createServerSocket(port_number));
@@ -20,8 +20,7 @@ SocketModule::SocketModule()
                               ));
 
   this->_addBuiltinFunction("acceptSocketClient",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<std::shared_ptr<const Socket>(std::shared_ptr<const Socket>)>>(
+                            std::function(
 
                               [](std::shared_ptr<const Socket> server_socket) -> std::shared_ptr<const Socket> {
                                 return std::make_shared<const Socket>(acceptClientSocket(*server_socket));
@@ -30,8 +29,7 @@ SocketModule::SocketModule()
                               ));
 
   this->_addBuiltinFunction("connectSocketServer",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const Socket>(const std::string&,
-                                                                                                   const uint64_t&)>>(
+                            std::function(
 
                               [](const std::string& hostname,
                                  const uint64_t& port_number) -> std::shared_ptr<const Socket> {
@@ -40,88 +38,74 @@ SocketModule::SocketModule()
 
                               ));
 
-  this->_addBuiltinFunction("write",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<void(const std::shared_ptr<const Socket>&, const bool&)>>(
+  this->_addBuiltinFunction("write", std::function(
 
-                              [](const std::shared_ptr<const Socket>& socket, const bool& value) -> void {
-                                write(*socket, value);
-                              }
+                                       [](const std::shared_ptr<const Socket>& socket, const bool& value) -> void {
+                                         write(*socket, value);
+                                       }
 
-                              ));
+                                       ));
 
-  this->_addBuiltinFunction("write",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<void(const std::shared_ptr<const Socket>&, const uint64_t&)>>(
+  this->_addBuiltinFunction("write", std::function(
 
-                              [](const std::shared_ptr<const Socket>& socket, const uint64_t& value) -> void {
-                                write(*socket, value);
-                              }
+                                       [](const std::shared_ptr<const Socket>& socket, const uint64_t& value) -> void {
+                                         write(*socket, value);
+                                       }
 
-                              ));
+                                       ));
 
-  this->_addBuiltinFunction("write",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<void(const std::shared_ptr<const Socket>&, const int64_t&)>>(
+  this->_addBuiltinFunction("write", std::function(
 
-                              [](const std::shared_ptr<const Socket>& socket, const int64_t& value) -> void {
-                                write(*socket, value);
-                              }
+                                       [](const std::shared_ptr<const Socket>& socket, const int64_t& value) -> void {
+                                         write(*socket, value);
+                                       }
 
-                              ));
+                                       ));
 
-  this->_addBuiltinFunction("write",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<void(const std::shared_ptr<const Socket>&, const double&)>>(
+  this->_addBuiltinFunction("write", std::function(
 
-                              [](const std::shared_ptr<const Socket>& socket, const double& value) -> void {
-                                write(*socket, value);
-                              }
+                                       [](const std::shared_ptr<const Socket>& socket, const double& value) -> void {
+                                         write(*socket, value);
+                                       }
 
-                              ));
+                                       ));
 
-  this->_addBuiltinFunction("write", std::make_shared<BuiltinFunctionEmbedder<void(const std::shared_ptr<const Socket>&,
-                                                                                   const TinyVector<1>&)>>(
+  this->_addBuiltinFunction("write", std::function(
 
                                        [](const std::shared_ptr<const Socket>& socket,
                                           const TinyVector<1>& value) -> void { write(*socket, value); }
 
                                        ));
 
-  this->_addBuiltinFunction("write", std::make_shared<BuiltinFunctionEmbedder<void(const std::shared_ptr<const Socket>&,
-                                                                                   const TinyVector<2>&)>>(
+  this->_addBuiltinFunction("write", std::function(
 
                                        [](const std::shared_ptr<const Socket>& socket,
                                           const TinyVector<2>& value) -> void { write(*socket, value); }
 
                                        ));
 
-  this->_addBuiltinFunction("write", std::make_shared<BuiltinFunctionEmbedder<void(const std::shared_ptr<const Socket>&,
-                                                                                   const TinyVector<3>&)>>(
+  this->_addBuiltinFunction("write", std::function(
 
                                        [](const std::shared_ptr<const Socket>& socket,
                                           const TinyVector<3>& value) -> void { write(*socket, value); }
 
                                        ));
 
-  this->_addBuiltinFunction("write", std::make_shared<BuiltinFunctionEmbedder<void(const std::shared_ptr<const Socket>&,
-                                                                                   const TinyMatrix<1>&)>>(
+  this->_addBuiltinFunction("write", std::function(
 
                                        [](const std::shared_ptr<const Socket>& socket,
                                           const TinyMatrix<1>& value) -> void { write(*socket, value); }
 
                                        ));
 
-  this->_addBuiltinFunction("write", std::make_shared<BuiltinFunctionEmbedder<void(const std::shared_ptr<const Socket>&,
-                                                                                   const TinyMatrix<2>&)>>(
+  this->_addBuiltinFunction("write", std::function(
 
                                        [](const std::shared_ptr<const Socket>& socket,
                                           const TinyMatrix<2>& value) -> void { write(*socket, value); }
 
                                        ));
 
-  this->_addBuiltinFunction("write", std::make_shared<BuiltinFunctionEmbedder<void(const std::shared_ptr<const Socket>&,
-                                                                                   const TinyMatrix<3>&)>>(
+  this->_addBuiltinFunction("write", std::function(
 
                                        [](const std::shared_ptr<const Socket>& socket,
                                           const TinyMatrix<3>& value) -> void { write(*socket, value); }
@@ -129,8 +113,7 @@ SocketModule::SocketModule()
                                        ));
 
   this->_addBuiltinFunction("write",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<void(const std::shared_ptr<const Socket>&, const std::string&)>>(
+                            std::function(
 
                               [](const std::shared_ptr<const Socket>& socket, const std::string& value) -> void {
                                 write(*socket, value.size());
@@ -139,56 +122,51 @@ SocketModule::SocketModule()
 
                               ));
 
-  this->_addBuiltinFunction("read_B",
-                            std::make_shared<BuiltinFunctionEmbedder<bool(const std::shared_ptr<const Socket>&)>>(
+  this->_addBuiltinFunction("read_B", std::function(
 
-                              [](const std::shared_ptr<const Socket>& socket) -> bool {
-                                bool value;
-                                read(*socket, value);
+                                        [](const std::shared_ptr<const Socket>& socket) -> bool {
+                                          bool value;
+                                          read(*socket, value);
 
-                                return value;
-                              }
+                                          return value;
+                                        }
 
-                              ));
+                                        ));
 
-  this->_addBuiltinFunction("read_N",
-                            std::make_shared<BuiltinFunctionEmbedder<uint64_t(const std::shared_ptr<const Socket>&)>>(
+  this->_addBuiltinFunction("read_N", std::function(
 
-                              [](const std::shared_ptr<const Socket>& socket) -> uint64_t {
-                                uint64_t value;
-                                read(*socket, value);
+                                        [](const std::shared_ptr<const Socket>& socket) -> uint64_t {
+                                          uint64_t value;
+                                          read(*socket, value);
 
-                                return value;
-                              }
+                                          return value;
+                                        }
 
-                              ));
+                                        ));
 
-  this->_addBuiltinFunction("read_Z",
-                            std::make_shared<BuiltinFunctionEmbedder<int64_t(const std::shared_ptr<const Socket>&)>>(
+  this->_addBuiltinFunction("read_Z", std::function(
 
-                              [](const std::shared_ptr<const Socket>& socket) -> int64_t {
-                                int64_t value;
-                                read(*socket, value);
+                                        [](const std::shared_ptr<const Socket>& socket) -> int64_t {
+                                          int64_t value;
+                                          read(*socket, value);
 
-                                return value;
-                              }
+                                          return value;
+                                        }
 
-                              ));
+                                        ));
 
-  this->_addBuiltinFunction("read_R",
-                            std::make_shared<BuiltinFunctionEmbedder<double(const std::shared_ptr<const Socket>&)>>(
+  this->_addBuiltinFunction("read_R", std::function(
 
-                              [](const std::shared_ptr<const Socket>& socket) -> double {
-                                double value;
-                                read(*socket, value);
+                                        [](const std::shared_ptr<const Socket>& socket) -> double {
+                                          double value;
+                                          read(*socket, value);
 
-                                return value;
-                              }
+                                          return value;
+                                        }
 
-                              ));
+                                        ));
 
-  this->_addBuiltinFunction("read_R1", std::make_shared<
-                                         BuiltinFunctionEmbedder<TinyVector<1>(const std::shared_ptr<const Socket>&)>>(
+  this->_addBuiltinFunction("read_R1", std::function(
 
                                          [](const std::shared_ptr<const Socket>& socket) -> TinyVector<1> {
                                            TinyVector<1> value;
@@ -199,8 +177,7 @@ SocketModule::SocketModule()
 
                                          ));
 
-  this->_addBuiltinFunction("read_R2", std::make_shared<
-                                         BuiltinFunctionEmbedder<TinyVector<2>(const std::shared_ptr<const Socket>&)>>(
+  this->_addBuiltinFunction("read_R2", std::function(
 
                                          [](const std::shared_ptr<const Socket>& socket) -> TinyVector<2> {
                                            TinyVector<2> value;
@@ -211,8 +188,7 @@ SocketModule::SocketModule()
 
                                          ));
 
-  this->_addBuiltinFunction("read_R3", std::make_shared<
-                                         BuiltinFunctionEmbedder<TinyVector<3>(const std::shared_ptr<const Socket>&)>>(
+  this->_addBuiltinFunction("read_R3", std::function(
 
                                          [](const std::shared_ptr<const Socket>& socket) -> TinyVector<3> {
                                            TinyVector<3> value;
@@ -223,61 +199,53 @@ SocketModule::SocketModule()
 
                                          ));
 
-  this->_addBuiltinFunction("read_R1x1",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<TinyMatrix<1>(const std::shared_ptr<const Socket>&)>>(
+  this->_addBuiltinFunction("read_R1x1", std::function(
 
-                              [](const std::shared_ptr<const Socket>& socket) -> TinyMatrix<1> {
-                                TinyMatrix<1> value;
-                                read(*socket, value);
+                                           [](const std::shared_ptr<const Socket>& socket) -> TinyMatrix<1> {
+                                             TinyMatrix<1> value;
+                                             read(*socket, value);
 
-                                return value;
-                              }
+                                             return value;
+                                           }
 
-                              ));
+                                           ));
 
-  this->_addBuiltinFunction("read_R2x2",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<TinyMatrix<2>(const std::shared_ptr<const Socket>&)>>(
+  this->_addBuiltinFunction("read_R2x2", std::function(
 
-                              [](const std::shared_ptr<const Socket>& socket) -> TinyMatrix<2> {
-                                TinyMatrix<2> value;
-                                read(*socket, value);
+                                           [](const std::shared_ptr<const Socket>& socket) -> TinyMatrix<2> {
+                                             TinyMatrix<2> value;
+                                             read(*socket, value);
 
-                                return value;
-                              }
+                                             return value;
+                                           }
 
-                              ));
+                                           ));
 
-  this->_addBuiltinFunction("read_R3x3",
-                            std::make_shared<
-                              BuiltinFunctionEmbedder<TinyMatrix<3>(const std::shared_ptr<const Socket>&)>>(
+  this->_addBuiltinFunction("read_R3x3", std::function(
 
-                              [](const std::shared_ptr<const Socket>& socket) -> TinyMatrix<3> {
-                                TinyMatrix<3> value;
-                                read(*socket, value);
+                                           [](const std::shared_ptr<const Socket>& socket) -> TinyMatrix<3> {
+                                             TinyMatrix<3> value;
+                                             read(*socket, value);
 
-                                return value;
-                              }
+                                             return value;
+                                           }
 
-                              ));
+                                           ));
 
-  this
-    ->_addBuiltinFunction("read_string",
-                          std::make_shared<BuiltinFunctionEmbedder<std::string(const std::shared_ptr<const Socket>&)>>(
-
-                            [](const std::shared_ptr<const Socket>& socket) -> std::string {
-                              size_t size;
-                              read(*socket, size);
-                              std::string value;
-                              if (size > 0) {
-                                value.resize(size);
-                                read(*socket, value);
-                              }
-                              return value;
-                            }
+  this->_addBuiltinFunction("read_string", std::function(
+
+                                             [](const std::shared_ptr<const Socket>& socket) -> std::string {
+                                               size_t size;
+                                               read(*socket, size);
+                                               std::string value;
+                                               if (size > 0) {
+                                                 value.resize(size);
+                                                 read(*socket, value);
+                                               }
+                                               return value;
+                                             }
 
-                            ));
+                                             ));
 }
 
 void
diff --git a/src/language/modules/WriterModule.cpp b/src/language/modules/WriterModule.cpp
index a1eebb3ed74df078eabaebeaa440c7bcb2446cdb..89d25001b6f70ceaec5c8465718cbd01da32a928 100644
--- a/src/language/modules/WriterModule.cpp
+++ b/src/language/modules/WriterModule.cpp
@@ -20,64 +20,59 @@ WriterModule::WriterModule()
 
   this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const IWriter>>);
 
-  this
-    ->_addBuiltinFunction("vtk_writer",
-                          std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IWriter>(const std::string&)>>(
+  this->_addBuiltinFunction("vtk_writer", std::function(
 
-                            [](const std::string& filename) { return std::make_shared<VTKWriter>(filename); }
+                                            [](const std::string& filename) -> std::shared_ptr<const IWriter> {
+                                              return std::make_shared<VTKWriter>(filename);
+                                            }
 
-                            ));
+                                            ));
 
   this->_addBuiltinFunction("vtk_writer",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IWriter>(const std::string&,
-                                                                                                    const double&)>>(
+                            std::function(
 
-                              [](const std::string& filename, const double& period) {
+                              [](const std::string& filename, const double& period) -> std::shared_ptr<const IWriter> {
                                 return std::make_shared<VTKWriter>(filename, period);
                               }
 
                               ));
 
-  this
-    ->_addBuiltinFunction("gnuplot_writer",
-                          std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IWriter>(const std::string&)>>(
+  this->_addBuiltinFunction("gnuplot_writer", std::function(
 
-                            [](const std::string& filename) { return std::make_shared<GnuplotWriter>(filename); }
+                                                [](const std::string& filename) -> std::shared_ptr<const IWriter> {
+                                                  return std::make_shared<GnuplotWriter>(filename);
+                                                }
 
-                            ));
+                                                ));
 
   this->_addBuiltinFunction("gnuplot_writer",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IWriter>(const std::string&,
-                                                                                                    const double&)>>(
+                            std::function(
 
-                              [](const std::string& filename, const double& period) {
+                              [](const std::string& filename, const double& period) -> std::shared_ptr<const IWriter> {
                                 return std::make_shared<GnuplotWriter>(filename, period);
                               }
 
                               ));
 
-  this
-    ->_addBuiltinFunction("gnuplot_1d_writer",
-                          std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IWriter>(const std::string&)>>(
+  this->_addBuiltinFunction("gnuplot_1d_writer", std::function(
 
-                            [](const std::string& filename) { return std::make_shared<GnuplotWriter1D>(filename); }
+                                                   [](const std::string& filename) -> std::shared_ptr<const IWriter> {
+                                                     return std::make_shared<GnuplotWriter1D>(filename);
+                                                   }
 
-                            ));
+                                                   ));
 
   this->_addBuiltinFunction("gnuplot_1d_writer",
-                            std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IWriter>(const std::string&,
-                                                                                                    const double&)>>(
+                            std::function(
 
-                              [](const std::string& filename, const double& period) {
+                              [](const std::string& filename, const double& period) -> std::shared_ptr<const IWriter> {
                                 return std::make_shared<GnuplotWriter1D>(filename, period);
                               }
 
                               ));
 
   this->_addBuiltinFunction("name_output",
-                            std::make_shared<BuiltinFunctionEmbedder<
-                              std::shared_ptr<const NamedDiscreteFunction>(std::shared_ptr<const IDiscreteFunction>,
-                                                                           const std::string&)>>(
+                            std::function(
 
                               [](std::shared_ptr<const IDiscreteFunction> discrete_function,
                                  const std::string& name) -> std::shared_ptr<const NamedDiscreteFunction> {
@@ -87,8 +82,7 @@ WriterModule::WriterModule()
                               ));
 
   this->_addBuiltinFunction("write_mesh",
-                            std::make_shared<BuiltinFunctionEmbedder<void(std::shared_ptr<const IWriter>,
-                                                                          std::shared_ptr<const IMesh>)>>(
+                            std::function(
 
                               [](std::shared_ptr<const IWriter> writer, std::shared_ptr<const IMesh> p_mesh) -> void {
                                 writer->writeMesh(p_mesh);
@@ -96,9 +90,7 @@ WriterModule::WriterModule()
 
                               ));
 
-  this->_addBuiltinFunction("write", std::make_shared<BuiltinFunctionEmbedder<
-                                       void(std::shared_ptr<const IWriter>,
-                                            const std::vector<std::shared_ptr<const NamedDiscreteFunction>>&)>>(
+  this->_addBuiltinFunction("write", std::function(
 
                                        [](std::shared_ptr<const IWriter> writer,
                                           const std::vector<std::shared_ptr<const NamedDiscreteFunction>>&
@@ -108,33 +100,27 @@ WriterModule::WriterModule()
 
                                        ));
 
-  this->_addBuiltinFunction("write",
-                            std::make_shared<BuiltinFunctionEmbedder<
-                              void(std::shared_ptr<const IWriter>,
-                                   const std::vector<std::shared_ptr<const NamedDiscreteFunction>>&, const double&)>>(
+  this->_addBuiltinFunction("write", std::function(
 
-                              [](std::shared_ptr<const IWriter> writer,
-                                 const std::vector<std::shared_ptr<const NamedDiscreteFunction>>&
-                                   named_discrete_function_list,
-                                 const double& time) -> void {
-                                writer->writeIfNeeded(named_discrete_function_list, time);
-                              }
+                                       [](std::shared_ptr<const IWriter> writer,
+                                          const std::vector<std::shared_ptr<const NamedDiscreteFunction>>&
+                                            named_discrete_function_list,
+                                          const double& time) -> void {
+                                         writer->writeIfNeeded(named_discrete_function_list, time);
+                                       }
 
-                              ));
+                                       ));
 
-  this->_addBuiltinFunction("force_write",
-                            std::make_shared<BuiltinFunctionEmbedder<
-                              void(std::shared_ptr<const IWriter>,
-                                   const std::vector<std::shared_ptr<const NamedDiscreteFunction>>&, const double&)>>(
+  this->_addBuiltinFunction("force_write", std::function(
 
-                              [](std::shared_ptr<const IWriter> writer,
-                                 const std::vector<std::shared_ptr<const NamedDiscreteFunction>>&
-                                   named_discrete_function_list,
-                                 const double& time) -> void {
-                                writer->writeForced(named_discrete_function_list, time);
-                              }
+                                             [](std::shared_ptr<const IWriter> writer,
+                                                const std::vector<std::shared_ptr<const NamedDiscreteFunction>>&
+                                                  named_discrete_function_list,
+                                                const double& time) -> void {
+                                               writer->writeForced(named_discrete_function_list, time);
+                                             }
 
-                              ));
+                                             ));
 }
 
 void
diff --git a/src/language/utils/BuiltinFunctionEmbedder.hpp b/src/language/utils/BuiltinFunctionEmbedder.hpp
index ac3ba21fe241f8ea9416192fc0ce97f865bb0883..c3f015c5b61fbdfda66ee78bbf928fe3a24f3de0 100644
--- a/src/language/utils/BuiltinFunctionEmbedder.hpp
+++ b/src/language/utils/BuiltinFunctionEmbedder.hpp
@@ -33,6 +33,122 @@ class IBuiltinFunctionEmbedder
   virtual ~IBuiltinFunctionEmbedder() = default;
 };
 
+template <typename FX, typename... Args>
+class BuiltinFunctionEmbedderBase;
+
+template <typename FX, typename... Args>
+class BuiltinFunctionEmbedderBase<FX(Args...)> : public IBuiltinFunctionEmbedder
+{
+ protected:
+  template <size_t I>
+  PUGS_INLINE void constexpr _check_value() const
+  {
+    using ValueN_T = std::tuple_element_t<I, FX>;
+    if constexpr (std::is_lvalue_reference_v<ValueN_T>) {
+      static_assert(std::is_const_v<std::remove_reference_t<ValueN_T>>,
+                    "builtin function return values are non mutable use 'const' when passing references");
+    }
+
+    if constexpr (is_std_ptr_v<ValueN_T>) {
+      static_assert(std::is_const_v<typename ValueN_T::element_type>,
+                    "builtin function return values are non mutable. For instance use std::shared_ptr<const T>");
+    }
+
+    if (ast_node_data_type_from<std::remove_cv_t<std::remove_reference_t<ValueN_T>>> == ASTNodeDataType::undefined_t) {
+      throw std::invalid_argument(std::string{"cannot bind C++ to language.\nnote: return value number "} +
+                                  std::to_string(I + 1) + std::string{" has no associated language type: "} +
+                                  demangle<ValueN_T>());
+    }
+  }
+
+  template <size_t... I>
+  PUGS_INLINE void constexpr _check_tuple_value(std::index_sequence<I...>) const
+  {
+    (_check_value<I>(), ...);
+  }
+
+  PUGS_INLINE void constexpr _check_return_type()
+  {
+    if constexpr (is_std_tuple_v<FX>) {
+      constexpr size_t N  = std::tuple_size_v<FX>;
+      using IndexSequence = std::make_index_sequence<N>;
+      _check_tuple_value(IndexSequence{});
+    } else {
+      if (ast_node_data_type_from<std::remove_cv_t<std::remove_reference_t<FX>>> == ASTNodeDataType::undefined_t) {
+        throw std::invalid_argument(
+          std::string{"cannot bind C++ to language.\nnote: return value has no associated language type: "} +
+          demangle<FX>());
+      }
+    }
+  }
+
+  template <typename T>
+  PUGS_INLINE ASTNodeDataType
+  _getDataType() const
+  {
+    Assert(ast_node_data_type_from<T> != ASTNodeDataType::undefined_t);
+    return ast_node_data_type_from<T>;
+  }
+
+  template <typename TupleT, size_t I>
+  PUGS_INLINE ASTNodeDataType
+  _getOneElementDataType() const
+  {
+    using ArgN_T = std::decay_t<decltype(std::get<I>(TupleT{}))>;
+    return this->template _getDataType<ArgN_T>();
+  }
+
+  template <size_t... I>
+  PUGS_INLINE std::vector<std::shared_ptr<const ASTNodeDataType>>
+  _getCompoundDataTypes(std::index_sequence<I...>) const
+  {
+    std::vector<std::shared_ptr<const ASTNodeDataType>> compound_type_list;
+    (compound_type_list.push_back(std::make_shared<ASTNodeDataType>(this->_getOneElementDataType<FX, I>())), ...);
+    return compound_type_list;
+  }
+
+  template <typename T>
+  PUGS_INLINE std::shared_ptr<IDataHandler>
+  _createHandler(std::shared_ptr<T> data) const
+  {
+    return std::make_shared<DataHandler<T>>(data);
+  }
+
+  template <typename ResultT>
+  PUGS_INLINE DataVariant
+  _resultToDataVariant(ResultT&& result) const
+  {
+    if constexpr (is_data_variant_v<std::decay_t<ResultT>>) {
+      return std::move(result);
+    } else {
+      return EmbeddedData(_createHandler(std::move(result)));
+    }
+  }
+
+ public:
+  PUGS_INLINE ASTNodeDataType
+  getReturnDataType() const final
+  {
+    if constexpr (is_std_tuple_v<FX>) {
+      constexpr size_t N  = std::tuple_size_v<FX>;
+      using IndexSequence = std::make_index_sequence<N>;
+      return ASTNodeDataType::build<ASTNodeDataType::list_t>(this->_getCompoundDataTypes(IndexSequence{}));
+    } else {
+      return this->_getDataType<FX>();
+    }
+  }
+
+  BuiltinFunctionEmbedderBase()
+  {
+    this->_check_return_type();
+  }
+
+  BuiltinFunctionEmbedderBase(const BuiltinFunctionEmbedderBase&) = delete;
+  BuiltinFunctionEmbedderBase(BuiltinFunctionEmbedderBase&&)      = delete;
+
+  virtual ~BuiltinFunctionEmbedderBase() = default;
+};
+
 template <typename FX, typename... Args>
 class BuiltinFunctionEmbedder
 {
@@ -45,12 +161,39 @@ inline constexpr bool is_const_ref_or_non_ref = (std::is_const_v<T> and std::is_
                                                 (not std::is_lvalue_reference_v<T>);
 
 template <typename FX, typename... Args>
-class BuiltinFunctionEmbedder<FX(Args...)> : public IBuiltinFunctionEmbedder
+class BuiltinFunctionEmbedder<FX(Args...)> : public BuiltinFunctionEmbedderBase<FX(Args...)>
 {
  private:
   std::function<FX(Args...)> m_f;
   using ArgsTuple = std::tuple<std::decay_t<Args>...>;
 
+  template <size_t I>
+  PUGS_INLINE void constexpr _check_arg() const
+  {
+    using ArgN_T = std::tuple_element_t<I, std::tuple<Args...>>;
+    if constexpr (std::is_lvalue_reference_v<ArgN_T>) {
+      static_assert(std::is_const_v<std::remove_reference_t<ArgN_T>>,
+                    "builtin function arguments are non mutable use 'const' when passing references");
+    }
+
+    if constexpr (is_std_ptr_v<ArgN_T>) {
+      static_assert(std::is_const_v<typename ArgN_T::element_type>,
+                    "builtin function arguments are non mutable. For instance use std::shared_ptr<const T>");
+    }
+
+    if (ast_node_data_type_from<std::remove_cv_t<std::remove_reference_t<ArgN_T>>> == ASTNodeDataType::undefined_t) {
+      throw std::invalid_argument(std::string{"cannot bind C++ to language.\nnote: argument number "} +
+                                  std::to_string(I + 1) + std::string{" has no associated language type: "} +
+                                  demangle<ArgN_T>());
+    }
+  }
+
+  template <size_t... I>
+  PUGS_INLINE void constexpr _check_arg_list(std::index_sequence<I...>) const
+  {
+    (_check_arg<I>(), ...);
+  }
+
   template <size_t I>
   PUGS_INLINE void
   _copyValue(ArgsTuple& t, const std::vector<DataVariant>& v) const
@@ -122,77 +265,15 @@ class BuiltinFunctionEmbedder<FX(Args...)> : public IBuiltinFunctionEmbedder
     (_copyValue<I>(t, v), ...);
   }
 
-  template <typename T>
-  PUGS_INLINE ASTNodeDataType
-  _getDataType() const
-  {
-    Assert(ast_node_data_type_from<T> != ASTNodeDataType::undefined_t);
-    return ast_node_data_type_from<T>;
-  }
-
-  template <typename TupleT, size_t I>
-  PUGS_INLINE ASTNodeDataType
-  _getOneParameterDataType() const
-  {
-    using ArgN_T = std::decay_t<decltype(std::get<I>(TupleT{}))>;
-    return _getDataType<ArgN_T>();
-  }
-
   template <size_t... I>
-  PUGS_INLINE std::vector<ASTNodeDataType> _getParameterDataTypes(std::index_sequence<I...>) const
+  PUGS_INLINE std::vector<ASTNodeDataType>
+  _getParameterDataTypes(std::index_sequence<I...>) const
   {
     std::vector<ASTNodeDataType> parameter_type_list;
-    (parameter_type_list.push_back(this->_getOneParameterDataType<ArgsTuple, I>()), ...);
+    (parameter_type_list.push_back(this->template _getOneElementDataType<ArgsTuple, I>()), ...);
     return parameter_type_list;
   }
 
-  template <size_t... I>
-  PUGS_INLINE std::vector<std::shared_ptr<const ASTNodeDataType>> _getCompoundDataTypes(std::index_sequence<I...>) const
-  {
-    std::vector<std::shared_ptr<const ASTNodeDataType>> compound_type_list;
-    (compound_type_list.push_back(std::make_shared<ASTNodeDataType>(this->_getOneParameterDataType<FX, I>())), ...);
-    return compound_type_list;
-  }
-
-  template <typename T>
-  PUGS_INLINE std::shared_ptr<IDataHandler>
-  _createHandler(std::shared_ptr<T> data) const
-  {
-    return std::make_shared<DataHandler<T>>(data);
-  }
-
-  template <size_t I>
-  PUGS_INLINE void constexpr _check_arg() const
-  {
-    using ArgN_T = std::tuple_element_t<I, std::tuple<Args...>>;
-    if constexpr (std::is_lvalue_reference_v<ArgN_T>) {
-      static_assert(std::is_const_v<std::remove_reference_t<ArgN_T>>,
-                    "builtin function arguments are non mutable use 'const' when passing references");
-    }
-
-    if constexpr (is_std_ptr_v<ArgN_T>) {
-      static_assert(std::is_const_v<typename ArgN_T::element_type>,
-                    "builtin function arguments are non mutable. For instance use std::shared_ptr<const T>");
-    }
-  }
-
-  template <size_t... I>
-  PUGS_INLINE void constexpr _check_arg_list(std::index_sequence<I...>) const
-  {
-    (_check_arg<I>(), ...);
-  }
-
-  template <typename ResultT>
-  PUGS_INLINE DataVariant
-  _resultToDataVariant(ResultT&& result) const
-  {
-    if constexpr (is_data_variant_v<std::decay_t<ResultT>>) {
-      return std::move(result);
-    } else {
-      return EmbeddedData(_createHandler(std::move(result)));
-    }
-  }
-
   PUGS_INLINE
   AggregateDataVariant
   _applyToAggregate(const ArgsTuple& t) const
@@ -201,26 +282,14 @@ class BuiltinFunctionEmbedder<FX(Args...)> : public IBuiltinFunctionEmbedder
     std::vector<DataVariant> vector_result;
     vector_result.reserve(std::tuple_size_v<decltype(tuple_result)>);
 
-    std::apply([&](auto&&... result) { ((vector_result.emplace_back(_resultToDataVariant(result))), ...); },
-               tuple_result);
+    std::
+      apply([&](auto&&... result) { ((vector_result.emplace_back(this->template _resultToDataVariant(result))), ...); },
+            tuple_result);
 
     return AggregateDataVariant{std::move(vector_result)};
   }
 
  public:
-  PUGS_INLINE ASTNodeDataType
-  getReturnDataType() const final
-  {
-    if constexpr (is_std_tuple_v<FX>) {
-      constexpr size_t N  = std::tuple_size_v<FX>;
-      using IndexSequence = std::make_index_sequence<N>;
-
-      return ASTNodeDataType::build<ASTNodeDataType::list_t>(this->_getCompoundDataTypes(IndexSequence{}));
-    } else {
-      return this->_getDataType<FX>();
-    }
-  }
-
   PUGS_INLINE std::vector<ASTNodeDataType>
   getParameterDataTypes() const final
   {
@@ -253,7 +322,7 @@ class BuiltinFunctionEmbedder<FX(Args...)> : public IBuiltinFunctionEmbedder
       std::apply(m_f, t);
       return {};
     } else {
-      return EmbeddedData(_createHandler(std::apply(m_f, t)));
+      return EmbeddedData(this->template _createHandler(std::apply(m_f, t)));
     }
   }
 
@@ -261,8 +330,6 @@ class BuiltinFunctionEmbedder<FX(Args...)> : public IBuiltinFunctionEmbedder
   {
     using IndexSequence = std::make_index_sequence<std::tuple_size_v<ArgsTuple>>;
     this->_check_arg_list(IndexSequence{});
-
-    static_assert((std::is_same_v<Args, Args> and ...));
   }
 
   BuiltinFunctionEmbedder(const BuiltinFunctionEmbedder&) = delete;
@@ -279,53 +346,11 @@ class BuiltinFunctionEmbedder<FX, void>
 };
 
 template <typename FX>
-class BuiltinFunctionEmbedder<FX(void)> : public IBuiltinFunctionEmbedder
+class BuiltinFunctionEmbedder<FX(void)> : public BuiltinFunctionEmbedderBase<FX(void)>
 {
  private:
   std::function<FX(void)> m_f;
 
-  template <typename TupleT, size_t I>
-  PUGS_INLINE ASTNodeDataType
-  _getOneParameterDataType() const
-  {
-    using ArgN_T = std::decay_t<decltype(std::get<I>(TupleT{}))>;
-    return _getDataType<ArgN_T>();
-  }
-
-  template <size_t... I>
-  PUGS_INLINE std::vector<std::shared_ptr<const ASTNodeDataType>> _getCompoundDataTypes(std::index_sequence<I...>) const
-  {
-    std::vector<std::shared_ptr<const ASTNodeDataType>> compound_type_list;
-    (compound_type_list.push_back(std::make_shared<ASTNodeDataType>(this->_getOneParameterDataType<FX, I>())), ...);
-    return compound_type_list;
-  }
-
-  template <typename T>
-  PUGS_INLINE std::shared_ptr<IDataHandler>
-  _createHandler(std::shared_ptr<T> data) const
-  {
-    return std::make_shared<DataHandler<T>>(data);
-  }
-
-  template <typename T>
-  PUGS_INLINE ASTNodeDataType
-  _getDataType() const
-  {
-    Assert(ast_node_data_type_from<T> != ASTNodeDataType::undefined_t);
-    return ast_node_data_type_from<T>;
-  }
-
-  template <typename ResultT>
-  PUGS_INLINE DataVariant
-  _resultToDataVariant(ResultT&& result) const
-  {
-    if constexpr (is_data_variant_v<std::decay_t<ResultT>>) {
-      return std::move(result);
-    } else {
-      return EmbeddedData(_createHandler(std::move(result)));
-    }
-  }
-
   PUGS_INLINE
   AggregateDataVariant
   _applyToAggregate() const
@@ -334,25 +359,14 @@ class BuiltinFunctionEmbedder<FX(void)> : public IBuiltinFunctionEmbedder
     std::vector<DataVariant> vector_result;
     vector_result.reserve(std::tuple_size_v<decltype(tuple_result)>);
 
-    std::apply([&](auto&&... result) { ((vector_result.emplace_back(_resultToDataVariant(result))), ...); },
-               tuple_result);
+    std::
+      apply([&](auto&&... result) { ((vector_result.emplace_back(this->template _resultToDataVariant(result))), ...); },
+            tuple_result);
 
     return AggregateDataVariant{std::move(vector_result)};
   }
 
  public:
-  PUGS_INLINE ASTNodeDataType
-  getReturnDataType() const final
-  {
-    if constexpr (is_std_tuple_v<FX>) {
-      constexpr size_t N  = std::tuple_size_v<FX>;
-      using IndexSequence = std::make_index_sequence<N>;
-      return ASTNodeDataType::build<ASTNodeDataType::list_t>(this->_getCompoundDataTypes(IndexSequence{}));
-    } else {
-      return this->_getDataType<FX>();
-    }
-  }
-
   PUGS_INLINE std::vector<ASTNodeDataType>
   getParameterDataTypes() const final
   {
@@ -377,7 +391,7 @@ class BuiltinFunctionEmbedder<FX(void)> : public IBuiltinFunctionEmbedder
       m_f();
       return {};
     } else {
-      return EmbeddedData(_createHandler(m_f()));
+      return EmbeddedData(this->template _createHandler(m_f()));
     }
   }
 
diff --git a/tests/test_BuiltinFunctionEmbedder.cpp b/tests/test_BuiltinFunctionEmbedder.cpp
index 51b2462b44a696e9b5214678b17e96d888c6dd27..7fd481e163a77f73b32a0d08fba3f49224cdc130 100644
--- a/tests/test_BuiltinFunctionEmbedder.cpp
+++ b/tests/test_BuiltinFunctionEmbedder.cpp
@@ -293,7 +293,7 @@ TEST_CASE("BuiltinFunctionEmbedder", "[language]")
     };
 
     std::unique_ptr<IBuiltinFunctionEmbedder> i_embedded_c = std::make_unique<
-      BuiltinFunctionEmbedder<std::tuple<double, TinyVector<2>, std::shared_ptr<double>>(double, double)>>(c);
+      BuiltinFunctionEmbedder<std::tuple<double, TinyVector<2>, std::shared_ptr<const double>>(double, double)>>(c);
 
     const double a = 3.2;
     const double b = 1.5;
@@ -323,7 +323,7 @@ TEST_CASE("BuiltinFunctionEmbedder", "[language]")
     };
 
     std::unique_ptr<IBuiltinFunctionEmbedder> i_embedded_c =
-      std::make_unique<BuiltinFunctionEmbedder<std::tuple<uint64_t, double, std::shared_ptr<double>>(void)>>(c);
+      std::make_unique<BuiltinFunctionEmbedder<std::tuple<uint64_t, double, std::shared_ptr<const double>>(void)>>(c);
 
     REQUIRE(1ul == std::get<0>(c()));
     REQUIRE(3.5 == std::get<1>(c()));
@@ -339,7 +339,7 @@ TEST_CASE("BuiltinFunctionEmbedder", "[language]")
 
     REQUIRE(*data_type.contentTypeList()[0] == ASTNodeDataType::unsigned_int_t);
     REQUIRE(*data_type.contentTypeList()[1] == ASTNodeDataType::double_t);
-    REQUIRE(*data_type.contentTypeList()[2] == ast_node_data_type_from<std::shared_ptr<double>>);
+    REQUIRE(*data_type.contentTypeList()[2] == ast_node_data_type_from<std::shared_ptr<const double>>);
   }
 
   SECTION("void(void) BuiltinFunctionEmbedder")
@@ -375,15 +375,71 @@ TEST_CASE("BuiltinFunctionEmbedder", "[language]")
 
   SECTION("error")
   {
-    std::function positive = [](double x) -> bool { return x >= 0; };
-
-    BuiltinFunctionEmbedder<bool(double)> embedded_positive{positive};
-
-    std::string arg = std::string{"2.3"};
-
-    std::vector<DataVariant> args;
-    args.push_back(arg);
-
-    REQUIRE_THROWS(embedded_positive.apply(args));
+    SECTION("invalid cast")
+    {
+      std::function positive = [](double x) -> bool { return x >= 0; };
+
+      BuiltinFunctionEmbedder<bool(double)> embedded_positive{positive};
+
+      std::string arg = std::string{"2.3"};
+
+      std::vector<DataVariant> args;
+      args.push_back(arg);
+
+      std::ostringstream error_msg;
+      error_msg << "unexpected error: unexpected argument types while casting \"" << demangle<std::string>()
+                << "\" to \"" << demangle<double>() << "\"";
+
+      REQUIRE_THROWS_WITH(embedded_positive.apply(args), error_msg.str());
+    }
+
+    SECTION("invalid arg type")
+    {
+      std::ostringstream error_msg;
+      error_msg << "cannot bind C++ to language.\n"
+                << "note: argument number 1 has no associated language type: ";
+      error_msg << demangle<int>();
+      REQUIRE_THROWS_WITH(BuiltinFunctionEmbedder<bool(int)>{[](int) -> bool { return 1; }}, error_msg.str());
+    }
+
+    SECTION("invalid arg type")
+    {
+      std::ostringstream error_msg;
+      error_msg << "cannot bind C++ to language.\n"
+                << "note: argument number 2 has no associated language type: ";
+      error_msg << demangle<int>();
+      REQUIRE_THROWS_WITH(BuiltinFunctionEmbedder<bool(double, int)>{[](int, int) -> bool { return 1; }},
+                          error_msg.str());
+    }
+
+    SECTION("invalid return type")
+    {
+      std::ostringstream error_msg;
+      error_msg << "cannot bind C++ to language.\n"
+                << "note: return value has no associated language type: ";
+      error_msg << demangle<std::shared_ptr<const int>>();
+
+      std::function f = [](double) -> std::shared_ptr<const int> { return std::make_shared<int>(1); };
+
+      REQUIRE_THROWS_WITH(BuiltinFunctionEmbedder<std::shared_ptr<const int>(double)>(f), error_msg.str());
+    }
+
+    SECTION("invalid return type in compound")
+    {
+      std::ostringstream error_msg;
+      error_msg << "cannot bind C++ to language.\n"
+                << "note: return value number 2 has no associated language type: ";
+      error_msg << demangle<std::shared_ptr<const int>>();
+
+      std::function f = [](double) -> std::tuple<double, std::shared_ptr<const int>> {
+        return std::make_tuple(double{1.3}, std::make_shared<const int>(1));
+      };
+
+      REQUIRE_THROWS_WITH((BuiltinFunctionEmbedder<std::tuple<double, std::shared_ptr<const int>>(double)>{
+                            [](double) -> std::tuple<double, std::shared_ptr<const int>> {
+                              return std::make_tuple(2.3, std::make_shared<const int>(1));
+                            }}),
+                          error_msg.str());
+    }
   }
 }
diff --git a/tests/test_BuiltinFunctionEmbedderTable.cpp b/tests/test_BuiltinFunctionEmbedderTable.cpp
index e0787552686a0d15672967ff43d58a53df20a7a7..17a51370cefd36f9c713b2f67a9aff2f96babfbf 100644
--- a/tests/test_BuiltinFunctionEmbedderTable.cpp
+++ b/tests/test_BuiltinFunctionEmbedderTable.cpp
@@ -21,7 +21,8 @@ TEST_CASE("BuiltinFunctionEmbedderTable", "[language]")
   REQUIRE(table.size() == 1);
 
   std::shared_ptr<IBuiltinFunctionEmbedder> embedded_greater =
-    std::make_shared<BuiltinFunctionEmbedder<bool(int, int)>>([](int i, int j) -> bool { return i > j; });
+    std::make_shared<BuiltinFunctionEmbedder<bool(int64_t, int64_t)>>(
+      [](int64_t i, int64_t j) -> bool { return i > j; });
   table.add(embedded_greater);
 
   REQUIRE(table.size() == 2);