public void setParameterDefs(ArrayList<Attribute> paramDefs) throws Exception {
    if (paramDefs.size() != m_parameters.size()) {
      throw new Exception("[DefineFunction] number of parameter definitions does not match "
          + "number of parameters!");
    }
    
    // check these defs against the optypes of the parameters
    for (int i = 0; i < m_parameters.size(); i++) {
      if (m_parameters.get(i).getOptype() == FieldMetaInfo.Optype.CONTINUOUS) {
        if (!paramDefs.get(i).isNumeric()) {
          throw new Exception("[DefineFunction] parameter "
              + m_parameters.get(i).getFieldName() + " is continuous, but corresponding "
              + "supplied parameter def " + paramDefs.get(i).name() + " is not!");
        }
      } else {
        if (!paramDefs.get(i).isNominal() && !paramDefs.get(i).isString()) {
          throw new Exception("[DefineFunction] parameter "
              + m_parameters.get(i).getFieldName() + " is categorical/ordinal, but corresponding "
              + "supplied parameter def " + paramDefs.get(i).name() + " is not!");
        }
      }
    }
    
    // now we need to rename these argument definitions to match the names of
    // the actual parameters
    ArrayList<Attribute> newParamDefs = new ArrayList<Attribute>();
    for (int i = 0; i < paramDefs.size(); i++) {
      Attribute a = paramDefs.get(i);
      newParamDefs.add(a.copy(m_parameters.get(i).getFieldName()));
    }
    
    m_parameterDefs = newParamDefs;
    
    // update the Expression
    m_expression.setFieldDefs(m_parameterDefs);
  }