diff --git a/src/Bytecode.cc b/src/Bytecode.cc
index 510141697ec8d02eadf7b06b7cd6306cd3d5ff6f..ffbbf217bc839cc79b94a54cbe44e7757b26e6bc 100644
--- a/src/Bytecode.cc
+++ b/src/Bytecode.cc
@@ -46,7 +46,7 @@ operator<<(BytecodeWriter &code_file, const FCALL_ &instr)
   code_file.write(reinterpret_cast<const char *>(&instr.add_input_arguments), sizeof instr.add_input_arguments);
   code_file.write(reinterpret_cast<const char *>(&instr.row), sizeof instr.row);
   code_file.write(reinterpret_cast<const char *>(&instr.col), sizeof instr.col);
-  code_file.write(reinterpret_cast<const char *>(&instr.function_type), sizeof instr.function_type);
+  code_file.write(reinterpret_cast<const char *>(&instr.call_type), sizeof instr.call_type);
 
   int size = static_cast<int>(instr.func_name.size());
   code_file.write(reinterpret_cast<char *>(&size), sizeof size);
diff --git a/src/Bytecode.hh b/src/Bytecode.hh
index 6d179a5984147ef4339530ac184462d73f93c9dc..c7bef351aad70cf35f758c801a11395ec7caa34b 100644
--- a/src/Bytecode.hh
+++ b/src/Bytecode.hh
@@ -100,6 +100,17 @@ enum class ExpressionType
    FirstExodetDerivative,
   };
 
+enum class ExternalFunctionCallType
+  {
+   levelWithoutDerivative,
+   levelWithFirstDerivative,
+   levelWithFirstAndSecondDerivative,
+   separatelyProvidedFirstDerivative,
+   numericalFirstDerivative,
+   separatelyProvidedSecondDerivative,
+   numericalSecondDerivative
+  };
+
 struct Block_contain_type
 {
   int Equation, Variable, Own_Derivative;
@@ -672,9 +683,6 @@ public:
 class FLDV_ : public TagWithThreeArguments<SymbolType, int, int>
 {
 public:
-  FLDV_(SymbolType type_arg, int pos_arg) : TagWithThreeArguments::TagWithThreeArguments{Tags::FLDV, type_arg, pos_arg, 0}
-  {
-  };
   FLDV_(SymbolType type_arg, int pos_arg, int lead_lag_arg) :
     TagWithThreeArguments::TagWithThreeArguments{Tags::FLDV, type_arg, pos_arg, lead_lag_arg}
   {
@@ -699,10 +707,6 @@ public:
 class FSTPV_ : public TagWithThreeArguments<SymbolType, int, int>
 {
 public:
-  FSTPV_(SymbolType type_arg, int pos_arg) :
-    TagWithThreeArguments::TagWithThreeArguments{Tags::FSTPV, type_arg, pos_arg, 0}
-  {
-  };
   FSTPV_(SymbolType type_arg, int pos_arg, int lead_lag_arg) :
     TagWithThreeArguments::TagWithThreeArguments{Tags::FSTPV, type_arg, pos_arg, lead_lag_arg}
   {
@@ -733,17 +737,18 @@ private:
   string func_name;
   string arg_func_name;
   int add_input_arguments{0}, row{0}, col{0};
-  ExternalFunctionType function_type{ExternalFunctionType::withoutDerivative};
+  ExternalFunctionCallType call_type;
 public:
   FCALL_() : BytecodeInstruction{Tags::FCALL}
   {
   };
-  FCALL_(int nb_output_arguments_arg, int nb_input_arguments_arg, string func_name_arg, int indx_arg) :
+  FCALL_(int nb_output_arguments_arg, int nb_input_arguments_arg, string func_name_arg, int indx_arg, ExternalFunctionCallType call_type_arg) :
     BytecodeInstruction{Tags::FCALL},
     nb_output_arguments{nb_output_arguments_arg},
     nb_input_arguments{nb_input_arguments_arg},
     indx{indx_arg},
-    func_name{move(func_name_arg)}
+    func_name{move(func_name_arg)},
+    call_type{call_type_arg}
   {
   };
   string
@@ -807,15 +812,10 @@ public:
   {
     return col;
   };
-  void
-  set_function_type(ExternalFunctionType arg_function_type)
-  {
-    function_type = arg_function_type;
-  };
-  ExternalFunctionType
-  get_function_type()
+  ExternalFunctionCallType
+  get_call_type()
   {
-    return function_type;
+    return call_type;
   }
 #ifdef BYTECODE_MEX
 
@@ -829,7 +829,7 @@ public:
     memcpy(&add_input_arguments, code, sizeof(add_input_arguments)); code += sizeof(add_input_arguments);
     memcpy(&row, code, sizeof(row)); code += sizeof(row);
     memcpy(&col, code, sizeof(col)); code += sizeof(col);
-    memcpy(&function_type, code, sizeof(function_type)); code += sizeof(function_type);
+    memcpy(&call_type, code, sizeof(call_type)); code += sizeof(call_type);
     int size;
     memcpy(&size, code, sizeof(size)); code += sizeof(size);
     char *name = static_cast<char *>(mxMalloc((size+1)*sizeof(char)));
diff --git a/src/CommonEnums.hh b/src/CommonEnums.hh
index 84c5495dfe5389e71572f7c8ce21f81117a72685..4aef8f8e56ff22b64134cb7b442cb75fde8754a1 100644
--- a/src/CommonEnums.hh
+++ b/src/CommonEnums.hh
@@ -103,17 +103,6 @@ enum class TrinaryOpcode
    normpdf
   };
 
-enum class ExternalFunctionType
-  {
-   withoutDerivative,
-   withFirstDerivative,
-   withFirstAndSecondDerivative,
-   numericalFirstDerivative,
-   firstDerivative,
-   numericalSecondDerivative,
-   secondDerivative
-  };
-
 enum class PriorDistributions
   {
    noShape = 0,
diff --git a/src/ExprNode.cc b/src/ExprNode.cc
index 82eb4c7119d56dca9e104edc74169d8604b9b406..5197436e15f87b39d6f2841312acabeeaf14b985 100644
--- a/src/ExprNode.cc
+++ b/src/ExprNode.cc
@@ -1321,10 +1321,7 @@ VariableNode::writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOut
       switch (output_type)
         {
         case ExprNodeBytecodeOutputType::dynamicModel:
-          if (type == SymbolType::parameter)
-            code_file << FLDV_{type, tsid};
-          else
-            code_file << FLDV_{type, tsid, lag};
+          code_file << FLDV_{type, tsid, lag};
           break;
         case ExprNodeBytecodeOutputType::staticModel:
           code_file << FLDSV_{type, tsid};
@@ -1333,10 +1330,7 @@ VariableNode::writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOut
           code_file << FLDVS_{type, tsid};
           break;
         case ExprNodeBytecodeOutputType::dynamicAssignmentLHS:
-          if (type == SymbolType::parameter)
-            code_file << FSTPV_{type, tsid};
-          else
-            code_file << FSTPV_{type, tsid, lag};
+          code_file << FSTPV_{type, tsid, lag};
           break;
         case ExprNodeBytecodeOutputType::staticAssignmentLHS:
           code_file << FSTPSV_{type, tsid};
@@ -6688,7 +6682,7 @@ AbstractExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map<int
   return composeDerivatives(dargs);
 }
 
-int
+void
 AbstractExternalFunctionNode::writeBytecodeExternalFunctionArguments(BytecodeWriter &code_file,
                                                                      ExprNodeBytecodeOutputType output_type,
                                                                      const temporary_terms_t &temporary_terms,
@@ -6698,7 +6692,6 @@ AbstractExternalFunctionNode::writeBytecodeExternalFunctionArguments(BytecodeWri
   for (auto argument : arguments)
     argument->writeBytecodeOutput(code_file, output_type, temporary_terms,
                                   temporary_terms_idxs, tef_terms);
-  return static_cast<int>(arguments.size());
 }
 
 void
@@ -7286,31 +7279,30 @@ ExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_f
       int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id);
       assert(second_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided);
 
-      int nb_output_arguments{0};
+      writeBytecodeExternalFunctionArguments(code_file, output_type, temporary_terms,
+                                             temporary_terms_idxs, tef_terms);
+
+      int nb_output_arguments;
+      ExternalFunctionCallType call_type;
       if (symb_id == first_deriv_symb_id
           && symb_id == second_deriv_symb_id)
-        nb_output_arguments = 3;
+        {
+          nb_output_arguments = 3;
+          call_type = ExternalFunctionCallType::levelWithFirstAndSecondDerivative;
+        }
       else if (symb_id == first_deriv_symb_id)
-        nb_output_arguments = 2;
+        {
+          nb_output_arguments = 2;
+          call_type = ExternalFunctionCallType::levelWithFirstDerivative;
+        }
       else
-        nb_output_arguments = 1;
-      int nb_input_arguments{writeBytecodeExternalFunctionArguments(code_file, output_type, temporary_terms,
-                                                                    temporary_terms_idxs, tef_terms)};
-
-      FCALL_ fcall{nb_output_arguments, nb_input_arguments, datatree.symbol_table.getName(symb_id), indx};
-      switch (nb_output_arguments)
         {
-        case 1:
-          fcall.set_function_type(ExternalFunctionType::withoutDerivative);
-          break;
-        case 2:
-          fcall.set_function_type(ExternalFunctionType::withFirstDerivative);
-          break;
-        case 3:
-          fcall.set_function_type(ExternalFunctionType::withFirstAndSecondDerivative);
-          break;
+          nb_output_arguments = 1;
+          call_type = ExternalFunctionCallType::levelWithoutDerivative;
         }
-      code_file << fcall << FSTPTEF_{indx};
+
+      code_file << FCALL_{nb_output_arguments, static_cast<int>(arguments.size()), datatree.symbol_table.getName(symb_id), indx, call_type}
+        << FSTPTEF_{indx};
     }
 }
 
@@ -7807,32 +7799,31 @@ FirstDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWrit
   if (alreadyWrittenAsTefTerm(first_deriv_symb_id, tef_terms))
     return;
 
-  int nb_add_input_arguments{writeBytecodeExternalFunctionArguments(code_file, output_type, temporary_terms,
-                                                                    temporary_terms_idxs, tef_terms)};
-  if (first_deriv_symb_id == ExternalFunctionsTable::IDNotSet)
+  writeBytecodeExternalFunctionArguments(code_file, output_type, temporary_terms,
+                                         temporary_terms_idxs, tef_terms);
+
+  if (int indx = getIndxInTefTerms(symb_id, tef_terms);
+      first_deriv_symb_id == ExternalFunctionsTable::IDNotSet)
     {
       int nb_input_arguments{0};
       int nb_output_arguments{1};
-      int indx = getIndxInTefTerms(symb_id, tef_terms);
-      FCALL_ fcall{nb_output_arguments, nb_input_arguments, "jacob_element", indx};
+      FCALL_ fcall{nb_output_arguments, nb_input_arguments, "jacob_element", indx,
+        ExternalFunctionCallType::numericalFirstDerivative};
       fcall.set_arg_func_name(datatree.symbol_table.getName(symb_id));
       fcall.set_row(inputIndex);
-      fcall.set_nb_add_input_arguments(nb_add_input_arguments);
-      fcall.set_function_type(ExternalFunctionType::numericalFirstDerivative);
+      fcall.set_nb_add_input_arguments(static_cast<int>(arguments.size()));
       code_file << fcall << FSTPTEFD_{indx, inputIndex};
     }
   else
     {
       tef_terms[{ first_deriv_symb_id, arguments }] = static_cast<int>(tef_terms.size());
-      int indx = getIndxInTefTerms(symb_id, tef_terms);
       int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id);
       assert(second_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided);
 
       int nb_output_arguments{1};
 
-      FCALL_ fcall{nb_output_arguments, nb_add_input_arguments, datatree.symbol_table.getName(first_deriv_symb_id), indx};
-      fcall.set_function_type(ExternalFunctionType::firstDerivative);
-      code_file << fcall << FSTPTEFD_{indx, inputIndex};
+      code_file << FCALL_{nb_output_arguments, static_cast<int>(arguments.size()), datatree.symbol_table.getName(first_deriv_symb_id), indx, ExternalFunctionCallType::separatelyProvidedFirstDerivative}
+        << FSTPTEFD_{indx, inputIndex};
     }
 }
 
@@ -8212,31 +8203,25 @@ SecondDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWri
   if (alreadyWrittenAsTefTerm(second_deriv_symb_id, tef_terms))
     return;
 
-  int nb_add_input_arguments{writeBytecodeExternalFunctionArguments(code_file, output_type, temporary_terms,
-                                                                    temporary_terms_idxs, tef_terms)};
-  if (second_deriv_symb_id == ExternalFunctionsTable::IDNotSet)
+  writeBytecodeExternalFunctionArguments(code_file, output_type, temporary_terms,
+                                         temporary_terms_idxs, tef_terms);
+
+  if (int indx = getIndxInTefTerms(symb_id, tef_terms);
+      second_deriv_symb_id == ExternalFunctionsTable::IDNotSet)
     {
-      int nb_input_arguments{0};
-      int nb_output_arguments{1};
-      int indx = getIndxInTefTerms(symb_id, tef_terms);
-      FCALL_ fcall{nb_output_arguments, nb_input_arguments, "hess_element", indx};
+      FCALL_ fcall{1, 0, "hess_element", indx, ExternalFunctionCallType::numericalSecondDerivative};
       fcall.set_arg_func_name(datatree.symbol_table.getName(symb_id));
       fcall.set_row(inputIndex1);
       fcall.set_col(inputIndex2);
-      fcall.set_nb_add_input_arguments(nb_add_input_arguments);
-      fcall.set_function_type(ExternalFunctionType::numericalSecondDerivative);
+      fcall.set_nb_add_input_arguments(static_cast<int>(arguments.size()));
       code_file << fcall << FSTPTEFDD_{indx, inputIndex1, inputIndex2};
     }
   else
     {
       tef_terms[{ second_deriv_symb_id, arguments }] = static_cast<int>(tef_terms.size());
-      int indx = getIndxInTefTerms(symb_id, tef_terms);
 
-      int nb_output_arguments{1};
-
-      FCALL_ fcall{nb_output_arguments, nb_add_input_arguments, datatree.symbol_table.getName(second_deriv_symb_id), indx};
-      fcall.set_function_type(ExternalFunctionType::secondDerivative);
-      code_file << fcall << FSTPTEFDD_{indx, inputIndex1, inputIndex2};
+      code_file << FCALL_{1, static_cast<int>(arguments.size()), datatree.symbol_table.getName(second_deriv_symb_id), indx, ExternalFunctionCallType::separatelyProvidedSecondDerivative}
+        << FSTPTEFDD_{indx, inputIndex1, inputIndex2};
     }
 }
 
diff --git a/src/ExprNode.hh b/src/ExprNode.hh
index 39b2781d22de55453684da1efebeb50792e304fd..5f5b6bfc11af11ea2c8aa9d8fc85c33a2dc70d46 100644
--- a/src/ExprNode.hh
+++ b/src/ExprNode.hh
@@ -1320,11 +1320,11 @@ protected:
   void writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const;
   void writeJsonASTExternalFunctionArguments(ostream &output) const;
   void writeJsonExternalFunctionArguments(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const;
-  int writeBytecodeExternalFunctionArguments(BytecodeWriter &code_file,
-                                             ExprNodeBytecodeOutputType output_type,
-                                             const temporary_terms_t &temporary_terms,
-                                             const temporary_terms_idxs_t &temporary_terms_idxs,
-                                             const deriv_node_temp_terms_t &tef_terms) const;
+  void writeBytecodeExternalFunctionArguments(BytecodeWriter &code_file,
+                                              ExprNodeBytecodeOutputType output_type,
+                                              const temporary_terms_t &temporary_terms,
+                                              const temporary_terms_idxs_t &temporary_terms_idxs,
+                                              const deriv_node_temp_terms_t &tef_terms) const;
   /*! Returns a predicate that tests whether an other ExprNode is an external
     function which is computed by the same external function call (i.e. it has
     the same so-called "Tef" index) */