diff --git a/src/language/modules/UtilsModule.cpp b/src/language/modules/UtilsModule.cpp
index 8b2271158c1548d05b39c379782abb3cc4754d66..b74ddc54eaab21ebf44dd53dbb585f4d0111c3fe 100644
--- a/src/language/modules/UtilsModule.cpp
+++ b/src/language/modules/UtilsModule.cpp
@@ -52,9 +52,7 @@ UtilsModule::UtilsModule()
                             std::make_shared<BuiltinFunctionEmbedder<std::string(const FunctionSymbolId&)>>(
 
                               [](const FunctionSymbolId& function_symbol_id) -> std::string {
-                                auto& function_table = function_symbol_id.symbolTable().functionTable();
-
-                                const auto& function_descriptor = function_table[function_symbol_id.id()];
+                                const auto& function_descriptor = function_symbol_id.descriptor();
 
                                 std::ostringstream os;
                                 os << function_descriptor.name() << ": domain mapping\n";
diff --git a/src/language/utils/CMakeLists.txt b/src/language/utils/CMakeLists.txt
index 22c0ae52f184a7f18d852057cbe9b0616f1905e3..32a75c66f0dd73cc10c09ca2c6aecf640962c45c 100644
--- a/src/language/utils/CMakeLists.txt
+++ b/src/language/utils/CMakeLists.txt
@@ -22,6 +22,7 @@ add_library(PugsLanguageUtils
   BinaryOperatorRegisterForZ.cpp
   DataVariant.cpp
   EmbeddedData.cpp
+  FunctionSymbolId.cpp
   IncDecOperatorRegisterForN.cpp
   IncDecOperatorRegisterForR.cpp
   IncDecOperatorRegisterForZ.cpp
diff --git a/src/language/utils/FunctionSymbolId.cpp b/src/language/utils/FunctionSymbolId.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d45c35c2d3e71311128026c8779094e370eee22d
--- /dev/null
+++ b/src/language/utils/FunctionSymbolId.cpp
@@ -0,0 +1,8 @@
+#include <language/utils/FunctionSymbolId.hpp>
+#include <language/utils/SymbolTable.hpp>
+
+const FunctionDescriptor&
+FunctionSymbolId::descriptor() const
+{
+  return m_symbol_table->functionTable()[m_function_id];
+}
diff --git a/src/language/utils/FunctionSymbolId.hpp b/src/language/utils/FunctionSymbolId.hpp
index f96b783fa5bf3853507f4c650e02972faa5d6ebb..21496cb0e56e49f9c5a5d58d407a927f3d32cfd3 100644
--- a/src/language/utils/FunctionSymbolId.hpp
+++ b/src/language/utils/FunctionSymbolId.hpp
@@ -8,7 +8,9 @@
 #include <iostream>
 #include <memory>
 
+class FunctionDescriptor;
 class SymbolTable;
+
 class FunctionSymbolId
 {
  private:
@@ -29,6 +31,8 @@ class FunctionSymbolId
     return *m_symbol_table;
   }
 
+  [[nodiscard]] const FunctionDescriptor& descriptor() const;
+
   friend std::ostream&
   operator<<(std::ostream& os, const FunctionSymbolId& function_symbol_id)
   {
diff --git a/src/language/utils/PugsFunctionAdapter.hpp b/src/language/utils/PugsFunctionAdapter.hpp
index 7fef84f2d7bd0b8934c3e6e41583de3b540666b2..b6d3a259dbb676d5f1259c058e0ea1f36fb925fd 100644
--- a/src/language/utils/PugsFunctionAdapter.hpp
+++ b/src/language/utils/PugsFunctionAdapter.hpp
@@ -119,10 +119,10 @@ class PugsFunctionAdapter<OutputType(InputType...)>
   [[nodiscard]] PUGS_INLINE static auto&
   getFunctionExpression(const FunctionSymbolId& function_symbol_id)
   {
-    auto& function = function_symbol_id.symbolTable().functionTable()[function_symbol_id.id()];
-    _checkFunction(function);
+    auto& function_descriptor = function_symbol_id.descriptor();
+    _checkFunction(function_descriptor);
 
-    return *function.definitionNode().children[1];
+    return *function_descriptor.definitionNode().children[1];
   }
 
   [[nodiscard]] PUGS_INLINE static auto
@@ -209,7 +209,7 @@ class PugsFunctionAdapter<OutputType(InputType...)>
           };
         } else {
           // If this point is reached must be a 0 vector
-          return [](DataVariant &&) -> OutputType { return OutputType{ZeroType{}}; };
+          return [](DataVariant&&) -> OutputType { return OutputType{ZeroType{}}; };
         }
       }
       case ASTNodeDataType::double_t: {
@@ -288,7 +288,7 @@ class PugsFunctionAdapter<OutputType(InputType...)>
           };
         } else {
           // If this point is reached must be a 0 matrix
-          return [](DataVariant &&) -> OutputType { return OutputType{ZeroType{}}; };
+          return [](DataVariant&&) -> OutputType { return OutputType{ZeroType{}}; };
         }
       }
       case ASTNodeDataType::double_t: {