/**
  * Set a named constant (constants names are not case-sensitive). Constants are like variables but
  * are not cleared by clear(). Variables of the same name have precedence over constants.
  */
 public MathEval setConstant(String nam, Double val) {
   if (constants.get(nam) != null) {
     throw new IllegalArgumentException("Constants may not be redefined");
   }
   validateName(nam);
   constants.put(nam, val);
   return this;
 }
 /**
  * Set a named variable (variables names are not case-sensitive). If the value is null, the
  * variable is removed.
  */
 public MathEval setVariable(String nam, Double val) {
   validateName(nam);
   if (val == null) {
     variables.remove(nam);
   } else {
     variables.put(nam, val);
   }
   return this;
 }
 /**
  * Set a function handler for the specific named function optionally tagging the function as
  * impure, replacing any existing handler for the given name; if the handler is null the function
  * handler is removed.
  *
  * <p>Pure functions have results which depend purely on their arguments; given constant arguments
  * they will have a constant result. Impure functions are rare.
  */
 public MathEval setFunctionHandler(String nam, FunctionHandler hdl, boolean impure) {
   validateName(nam);
   if (hdl == null) {
     pureFunctions.remove(nam);
     impureFunctions.remove(nam);
   } else if (impure) {
     pureFunctions.remove(nam);
     impureFunctions.put(nam, hdl);
   } else {
     pureFunctions.put(nam, hdl);
     impureFunctions.remove(nam);
   }
   return this;
 }