spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
[Formulas] reserving '...values' for special cases, convering all others to normal arguments
author
Ben Vogt <[email protected]>
date
2017-05-13 22:18:26
stats
16 file(s) changed, 1062 insertions(+), 1017 deletions(-)
files
README.md
src/Formulas/Date.ts
src/Formulas/Engineering.ts
src/Formulas/Financial.ts
src/Formulas/Logical.ts
src/Formulas/Math.ts
src/Formulas/Statistical.ts
src/Formulas/Text.ts
tests/Formulas/DateFormulasTest.ts
tests/Formulas/DateFormulasTestTimeOverride.ts
tests/Formulas/EngineeringTest.ts
tests/Formulas/FinancialTest.ts
tests/Formulas/LogicalTest.ts
tests/Formulas/MathTest.ts
tests/Formulas/StatisticalTest.ts
tests/Formulas/TextTest.ts
   1diff --git a/README.md b/README.md
   2index a045a04..7d8cde8 100644
   3--- a/README.md
   4+++ b/README.md
   5@@ -68,10 +68,6 @@ TypeConverter.
   6 ### Test CriteriaFunctionFactory
   7 
   8 
   9-### Use `arguments` instead of `...values` for performance reasons.
  10-And use `.call()` when testing with weird param numbers.
  11-
  12-
  13 ### Pull static functions outside of formulas, declare once.
  14 
  15 
  16diff --git a/src/Formulas/Date.ts b/src/Formulas/Date.ts
  17index 2835662..f495474 100644
  18--- a/src/Formulas/Date.ts
  19+++ b/src/Formulas/Date.ts
  20@@ -14,18 +14,18 @@ import {
  21 
  22 /**
  23  * Converts a provided year, month, and day into a date.
  24- * @param values[0] year - The year component of the date.
  25- * @param values[1] month - The month component of the date.
  26- * @param values[2] day - The day component of the date.
  27+ * @param year - The year component of the date.
  28+ * @param month - The month component of the date.
  29+ * @param day - The day component of the date.
  30  * @returns {number} newly created date.
  31  * @constructor
  32  */
  33-var DATE = function (...values) : number {
  34+var DATE = function (year, month, day) : number {
  35   const FIRST_YEAR = 1900;
  36-  ArgsChecker.checkLength(values, 3, "DATE");
  37-  var year = Math.abs(Math.floor(TypeConverter.firstValueAsNumber(values[0]))); // No negative values for year
  38-  var month = Math.floor(TypeConverter.firstValueAsNumber(values[1])) - 1; // Months are between 0 and 11.
  39-  var day = Math.floor(TypeConverter.firstValueAsNumber(values[2])) - 1; // Days are also zero-indexed.
  40+  ArgsChecker.checkLength(arguments, 3, "DATE");
  41+  year = Math.abs(Math.floor(TypeConverter.firstValueAsNumber(year))); // No negative values for year
  42+  month = Math.floor(TypeConverter.firstValueAsNumber(month)) - 1; // Months are between 0 and 11.
  43+  day = Math.floor(TypeConverter.firstValueAsNumber(day)) - 1; // Days are also zero-indexed.
  44   var m = moment.utc(TypeConverter.ORIGIN_MOMENT)
  45     .add(2, "days")
  46     .add(year < FIRST_YEAR ? year : year - FIRST_YEAR, 'years') // If the value is less than 1900, assume 1900 as start index for year
  47@@ -41,15 +41,15 @@ var DATE = function (...values) : number {
  48 
  49 /**
  50  * Converts a provided date string in a known format to a date value.
  51- * @param values[0] date_string - The string representing the date. Understood formats include any date format which is
  52+ * @param dateString - The string representing the date. Understood formats include any date format which is
  53  * normally auto-converted when entered, without quotation marks, directly into a cell. Understood formats may depend on
  54  * region and language settings.
  55  * @returns {number} of days since 1900/1/1, inclusively.
  56  * @constructor
  57  */
  58-var DATEVALUE = function (...values) : number {
  59-  ArgsChecker.checkLength(values, 1, "DATEVALUE");
  60-  var dateString = TypeConverter.firstValueAsString(values[0]);
  61+var DATEVALUE = function (dateString) : number {
  62+  ArgsChecker.checkLength(arguments, 1, "DATEVALUE");
  63+  dateString = TypeConverter.firstValueAsString(dateString);
  64   var dateAsNumber;
  65   try {
  66     dateAsNumber = TypeConverter.stringToDateNumber(dateString);
  67@@ -64,18 +64,18 @@ var DATEVALUE = function (...values) : number {
  68 
  69 /**
  70  * Returns a date a specified number of months before or after another date.
  71- * @param values[0] start_date - The date from which to calculate the result.
  72- * @param values[1] months - The number of months before (negative) or after (positive) start_date to calculate.
  73+ * @param startDate - The date from which to calculate the result.
  74+ * @param months - The number of months before (negative) or after (positive) start_date to calculate.
  75  * @returns {number} date a specified number of months before or after another date
  76  * @constructor
  77  */
  78-var EDATE = function (...values) : number {
  79-  ArgsChecker.checkLength(values, 2, "EDATE");
  80-  var startDateNumber = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
  81+var EDATE = function (startDate, months) : number {
  82+  ArgsChecker.checkLength(arguments, 2, "EDATE");
  83+  var startDateNumber = TypeConverter.firstValueAsDateNumber(startDate, true); // tell firstValueAsDateNumber to coerce boolean
  84   if (startDateNumber < 0) {
  85     throw new NumError("Function EDATE parameter 1 value is " + startDateNumber+ ". It should be greater than or equal to 0.");
  86   }
  87-  var months = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
  88+  months = Math.floor(TypeConverter.firstValueAsNumber(months));
  89   // While momentToDayNumber will return an inclusive count of days since 1900/1/1, moment.Moment.add assumes exclusive
  90   // count of days.
  91   return TypeConverter.momentToDayNumber(moment.utc(TypeConverter.ORIGIN_MOMENT).add(startDateNumber, "days").add(months, "months"));
  92@@ -85,19 +85,19 @@ var EDATE = function (...values) : number {
  93 /**
  94  * Returns a date representing the last day of a month which falls a specified number of months before or after another
  95  * date.
  96- * @param values[0] start_date - The date from which to calculate the the result.
  97- * @param values[1] months - The number of months before (negative) or after (positive) start_date to consider. The last
  98+ * @param startDate - The date from which to calculate the the result.
  99+ * @param months - The number of months before (negative) or after (positive) start_date to consider. The last
 100  * calendar day of the calculated month is returned.
 101  * @returns {number} the last day of a month
 102  * @constructor
 103  */
 104-var EOMONTH = function (...values) : number {
 105-  ArgsChecker.checkLength(values, 2, "EOMONTH");
 106-  var startDateNumber = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
 107+var EOMONTH = function (startDate, months) : number {
 108+  ArgsChecker.checkLength(arguments, 2, "EOMONTH");
 109+  var startDateNumber = TypeConverter.firstValueAsDateNumber(startDate, true); // tell firstValueAsDateNumber to coerce boolean
 110   if (startDateNumber < 0) {
 111     throw new NumError("Function EOMONTH parameter 1 value is " + startDateNumber + ". It should be greater than or equal to 0.");
 112   }
 113-  var months = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
 114+  months = Math.floor(TypeConverter.firstValueAsNumber(months));
 115   return TypeConverter.momentToDayNumber(moment.utc(TypeConverter.ORIGIN_MOMENT)
 116     .add(startDateNumber, "days")
 117     .add(months, "months")
 118@@ -107,43 +107,43 @@ var EOMONTH = function (...values) : number {
 119 
 120 /**
 121  * Returns the day of the month that a specific date falls on, in numeric format.
 122- * @param values[0] date - The date from which to extract the day. Must be a reference to a cell containing a date, a
 123+ * @param date - The date from which to extract the day. Must be a reference to a cell containing a date, a
 124  * function returning a date type, or a number.
 125  * @returns {number} day of the month
 126  * @constructor
 127  */
 128-var DAY = function (...values) : number {
 129-  ArgsChecker.checkLength(values, 1, "DAY");
 130-  var dateNumber = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
 131-  if (dateNumber < 0) {
 132-    throw new NumError("Function DAY parameter 1 value is " + dateNumber + ". It should be greater than or equal to 0.");
 133+var DAY = function (date) : number {
 134+  ArgsChecker.checkLength(arguments, 1, "DAY");
 135+  date = TypeConverter.firstValueAsDateNumber(date, true); // tell firstValueAsDateNumber to coerce boolean
 136+  if (date < 0) {
 137+    throw new NumError("Function DAY parameter 1 value is " + date + ". It should be greater than or equal to 0.");
 138   }
 139-  return TypeConverter.numberToMoment(dateNumber).date();
 140+  return TypeConverter.numberToMoment(date).date();
 141 };
 142 
 143 
 144 /**
 145  * Returns the number of days between two dates.
 146- * @param values[0] end_date most recently occurring
 147- * @param values[1] start_date not most recently occurring
 148+ * @param endDate most recently occurring
 149+ * @param startDate not most recently occurring
 150  * @returns {number} of days between start_date and end_date
 151  * @constructor
 152  */
 153-var DAYS = function (...values) : number {
 154-  ArgsChecker.checkLength(values, 2, "DAYS");
 155-  var end = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
 156-  var start = TypeConverter.firstValueAsDateNumber(values[1], true); // tell firstValueAsDateNumber to coerce boolean
 157-  return end - start;
 158+var DAYS = function (endDate, startDate) : number {
 159+  ArgsChecker.checkLength(arguments, 2, "DAYS");
 160+  endDate = TypeConverter.firstValueAsDateNumber(endDate, true); // tell firstValueAsDateNumber to coerce boolean
 161+  startDate = TypeConverter.firstValueAsDateNumber(startDate, true); // tell firstValueAsDateNumber to coerce boolean
 162+  return endDate - startDate;
 163 };
 164 
 165 
 166 /**
 167  * Returns the difference between two days based on the 360 day year used in some financial interest calculations.
 168- * @param values[0] start_date - The start date to consider in the calculation. Must be a reference to a cell containing
 169+ * @param startDate - The start date to consider in the calculation. Must be a reference to a cell containing
 170  * a date, a function returning a date type, or a number.
 171- * @param values[1] end_date - The end date to consider in the calculation. Must be a reference to a cell containing a
 172+ * @param endDate - The end date to consider in the calculation. Must be a reference to a cell containing a
 173  * date, a function returning a date type, or a number.
 174- * @param values[2] method - [ OPTIONAL - 0 by default ] - An indicator of what day count method to use.
 175+ * @param methodToUse - [ OPTIONAL - 0 by default ] - An indicator of what day count method to use.
 176  * 0 indicates the US method - Under the US method, if start_date is the last day of a month, the day of month of
 177  * start_date is changed to 30 for the purposes of the calculation. Furthermore if end_date is the last day of a month
 178  * and the day of the month of start_date is earlier than the 30th, end_date is changed to the first day of the month
 179@@ -153,48 +153,45 @@ var DAYS = function (...values) : number {
 180  * @returns {number} of days between two dates
 181  * @constructor
 182  */
 183-var DAYS360 = function (...values) : number {
 184-  ArgsChecker.checkLengthWithin(values, 2, 3, "DAYS360");
 185-  var start = TypeConverter.numberToMoment(TypeConverter.firstValueAsDateNumber(values[0], true)); // tell firstValueAsDateNumber to coerce boolean
 186-  var end = TypeConverter.numberToMoment(TypeConverter.firstValueAsDateNumber(values[1], true)); // tell firstValueAsDateNumber to coerce boolean
 187-  var methodToUse = false;
 188-  if (values.length === 3) {
 189-    methodToUse = TypeConverter.firstValueAsBoolean(values[2]);
 190-  }
 191+var DAYS360 = function (startDate, endDate, methodToUse?) : number {
 192+  ArgsChecker.checkLengthWithin(arguments, 2, 3, "DAYS360");
 193+  startDate = TypeConverter.numberToMoment(TypeConverter.firstValueAsDateNumber(startDate, true)); // tell firstValueAsDateNumber to coerce boolean
 194+  endDate = TypeConverter.numberToMoment(TypeConverter.firstValueAsDateNumber(endDate, true)); // tell firstValueAsDateNumber to coerce boolean
 195+  methodToUse = methodToUse ? TypeConverter.firstValueAsBoolean(methodToUse) : false;
 196   var smd = 31;
 197   var emd = 31;
 198-  var sd = start.date();
 199-  var ed = end.date();
 200+  var sd = startDate.date();
 201+  var ed = endDate.date();
 202   if (methodToUse) {
 203     sd = (sd === 31) ? 30 : sd;
 204     ed = (ed === 31) ? 30 : ed;
 205   }
 206   else {
 207-    if (start.month() === 1) {
 208-      smd = start.daysInMonth();
 209+    if (startDate.month() === 1) {
 210+      smd = startDate.daysInMonth();
 211     }
 212-    if (end.month() === 1) {
 213-      emd = end.daysInMonth();
 214+    if (endDate.month() === 1) {
 215+      emd = endDate.daysInMonth();
 216     }
 217     sd = (sd === smd) ? 30 : sd;
 218     if (sd === 30 || sd === smd) {
 219       ed = (ed === emd) ? 30 : ed;
 220     }
 221   }
 222-  return 360 * (end.year() - start.year()) + 30 * (end.month() - start.month()) + (ed - sd);
 223+  return 360 * (endDate.year() - startDate.year()) + 30 * (endDate.month() - startDate.month()) + (ed - sd);
 224 };
 225 
 226 
 227 /**
 228  * Returns the month of the year a specific date falls in, in numeric format.
 229- * @param values[0] date - The date from which to extract the month. Must be a reference to a cell containing a date, a
 230+ * @param date - The date from which to extract the month. Must be a reference to a cell containing a date, a
 231  * function returning a date type, or a number.
 232  * @returns {number} month of the year that the input date falls on.
 233  * @constructor
 234  */
 235-var MONTH = function (...values) : number {
 236-  ArgsChecker.checkLength(values, 1, "MONTH");
 237-  var date = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
 238+var MONTH = function (date) : number {
 239+  ArgsChecker.checkLength(arguments, 1, "MONTH");
 240+  date = TypeConverter.firstValueAsDateNumber(date, true); // tell firstValueAsDateNumber to coerce boolean
 241   if (date < 0) {
 242     throw new NumError("Function MONTH parameter 1 value is " + date + ". It should be greater than or equal to 0.");
 243   }
 244@@ -204,14 +201,14 @@ var MONTH = function (...values) : number {
 245 
 246 /**
 247  * Returns the year specified by a given date.
 248- * @param values[0] date - The date from which to calculate the year. Must be a cell reference to a cell containing a
 249+ * @param date - The date from which to calculate the year. Must be a cell reference to a cell containing a
 250  * date, a function returning a date type, or a number.
 251  * @returns {number} year of the input date
 252  * @constructor
 253  */
 254-var YEAR = function (...values) : number {
 255-  ArgsChecker.checkLength(values, 1, "YEAR");
 256-  var date = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
 257+var YEAR = function (date) : number {
 258+  ArgsChecker.checkLength(arguments, 1, "YEAR");
 259+  date = TypeConverter.firstValueAsDateNumber(date, true); // tell firstValueAsDateNumber to coerce boolean
 260   if (date < 0) {
 261     throw new NumError("Function YEAR parameter 1 value is " + date + ". It should be greater than or equal to 0.");
 262   }
 263@@ -221,9 +218,9 @@ var YEAR = function (...values) : number {
 264 
 265 /**
 266  * Returns a number representing the day of the week of the date provided.
 267- * @param values[0] date - The date for which to determine the day of the week. Must be a reference to a cell containing
 268+ * @param date - The date for which to determine the day of the week. Must be a reference to a cell containing
 269  * a date, a function returning a date type, or a number.
 270- * @param values[1] type - [ OPTIONAL - 1 by default ] - A number indicating which numbering system to use to represent
 271+ * @param offsetType - [ OPTIONAL - 1 by default ] - A number indicating which numbering system to use to represent
 272  * weekdays. By default counts starting with Sunday = 1. If type is 1, days are counted from Sunday and the value of
 273  * Sunday is 1, therefore the value of Saturday is 7. If type is 2, days are counted from Monday and the value of Monday
 274  * is 1, therefore the value of Sunday is 7. If type is 3, days are counted from Monday and the value of Monday is 0,
 275@@ -231,10 +228,10 @@ var YEAR = function (...values) : number {
 276  * @returns {number} day of week
 277  * @constructor
 278  */
 279-var WEEKDAY = function (...values) : number {
 280-  ArgsChecker.checkLengthWithin(values, 1, 2, "WEEKDAY");
 281-  var date = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
 282-  var offsetType = values.length === 2 ? TypeConverter.firstValueAsNumber(values[1]) : 1;
 283+var WEEKDAY = function (date, offsetType?) : number {
 284+  ArgsChecker.checkLengthWithin(arguments, 1, 2, "WEEKDAY");
 285+  date = TypeConverter.firstValueAsDateNumber(date, true); // tell firstValueAsDateNumber to coerce boolean
 286+  offsetType = offsetType ? TypeConverter.firstValueAsNumber(offsetType) : 1;
 287   if (date < 0) {
 288     throw new NumError("Function WEEKDAY parameter 1 value is " + date + ". It should be greater than or equal to 0.");
 289   }
 290@@ -283,17 +280,17 @@ function calculateWeekNum(dm : moment.Moment, shifterArray : Array<number>) : nu
 291  * year is considered to be the week containing the first Thursday of the year, which is numbered as week 1. System 2 is
 292  * the approach specified in ISO 8601, also known as the European system for numbering weeks.
 293  *
 294- * @param values[0] date - The date for which to determine the week number. Must be a reference to a cell containing a
 295+ * @param date - The date for which to determine the week number. Must be a reference to a cell containing a
 296  * date, a function returning a date type, or a number.
 297- * @param values[1] type - [ OPTIONAL - default is 1 ] - A number representing the day that a week starts on as well as
 298+ * @param shiftType - [ OPTIONAL - default is 1 ] - A number representing the day that a week starts on as well as
 299  * the system used for determining the first week of the year (1=Sunday, 2=Monday).
 300  * @returns {number} representing week number of year.
 301  * @constructor
 302  */
 303-var WEEKNUM = function (...values) : number {
 304-  ArgsChecker.checkLengthWithin(values, 1, 2, "WEEKNUM");
 305-  var date = TypeConverter.firstValueAsDateNumber(values[0], true); // tell firstValueAsDateNumber to coerce boolean
 306-  var shiftType = values.length === 2 ? TypeConverter.firstValueAsNumber(values[1]) : 1;
 307+var WEEKNUM = function (date, shiftType?) : number {
 308+  ArgsChecker.checkLengthWithin(arguments, 1, 2, "WEEKNUM");
 309+  date = TypeConverter.firstValueAsDateNumber(date, true); // tell firstValueAsDateNumber to coerce boolean
 310+  shiftType = shiftType ? TypeConverter.firstValueAsNumber(shiftType) : 1;
 311   if (date < 0) {
 312     throw new NumError("Function YEAR parameter 1 value is " + date + ". It should be greater than or equal to 0.");
 313   }
 314@@ -349,11 +346,11 @@ var WEEKNUM = function (...values) : number {
 315 
 316 /**
 317  * Calculates the number of days, months, or years between two dates.
 318- * @param values[0] start_date - The start date to consider in the calculation. Must be a reference to a cell containing
 319+ * @param startDate - The start date to consider in the calculation. Must be a reference to a cell containing
 320  * a DATE, a function returning a DATE type, or a number.
 321- * @param values[1] end_date - The end date to consider in the calculation. Must be a reference to a cell containing a
 322+ * @param endDate - The end date to consider in the calculation. Must be a reference to a cell containing a
 323  * DATE, a function returning a DATE type, or a number.
 324- * @param values[2] unit - A text abbreviation for unit of time. For example,"M" for month. Accepted values are "Y": the
 325+ * @param unit - A text abbreviation for unit of time. For example,"M" for month. Accepted values are "Y": the
 326  * number of whole years between start_date and end_date, "M": the number of whole months between start_date and
 327  * end_date, "D": the number of days between start_date and end_date, "MD": the number of days between start_date and
 328  * end_date after subtracting whole months, "YM": the number of whole months between start_date and end_date after
 329@@ -362,18 +359,18 @@ var WEEKNUM = function (...values) : number {
 330  * @returns {number} number of days, months, or years between two dates.
 331  * @constructor
 332  */
 333-var DATEDIF = function (...values) : number {
 334-  ArgsChecker.checkLength(values, 3, "DATEDIF");
 335-  var start = TypeConverter.firstValueAsDateNumber(values[0], true);
 336-  var end = TypeConverter.firstValueAsDateNumber(values[1], true);
 337-  var unit = TypeConverter.firstValueAsString(values[2]);
 338+var DATEDIF = function (startDate, endDate, unit) : number {
 339+  ArgsChecker.checkLength(arguments, 3, "DATEDIF");
 340+  startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
 341+  endDate = TypeConverter.firstValueAsDateNumber(endDate, true);
 342+  unit = TypeConverter.firstValueAsString(unit);
 343   var unitClean = unit.toUpperCase();
 344-  var startMoment = TypeConverter.numberToMoment(start);
 345-  var endMoment = TypeConverter.numberToMoment(end);
 346+  var startMoment = TypeConverter.numberToMoment(startDate);
 347+  var endMoment = TypeConverter.numberToMoment(endDate);
 348 
 349-  if (start > end) {
 350-    throw new NumError("Function DATEDIF parameter 1 (" + start.toString() +
 351-      ") should be on or before Function DATEDIF parameter 2 (" + end.toString() + ").");
 352+  if (startDate > endDate) {
 353+    throw new NumError("Function DATEDIF parameter 1 (" + startDate.toString() +
 354+      ") should be on or before Function DATEDIF parameter 2 (" + endDate.toString() + ").");
 355   }
 356 
 357   if (unitClean === "Y") {
 358@@ -381,7 +378,7 @@ var DATEDIF = function (...values) : number {
 359   } else if (unitClean === "M") {
 360     return Math.floor(endMoment.diff(startMoment, "months"));
 361   } else if (unitClean === "D") {
 362-    return end - start;
 363+    return endDate - startDate;
 364   } else if (unitClean === "MD") {
 365     var s = startMoment;
 366     while(s.isBefore(endMoment)) {
 367@@ -422,23 +419,23 @@ var DATEDIF = function (...values) : number {
 368  *
 369  * * http://finmath.net/finmath-lib/
 370  *
 371- * @param values[0] start_date - The start date to consider in the calculation. Must be a reference to a cell
 372+ * @param startDate - The start date to consider in the calculation. Must be a reference to a cell
 373  * containing a date, a function returning a date type, or a number.
 374- * @param values[1] end_date - The end date to consider in the calculation. Must be a reference to a cell containing
 375+ * @param endDate - The end date to consider in the calculation. Must be a reference to a cell containing
 376  * a date, a function returning a date type, or a number.
 377- * @param values[2] day_count_convention - [ OPTIONAL - 0 by default ] - An indicator of what day count method to
 378+ * @param dayCountConvention - [ OPTIONAL - 0 by default ] - An indicator of what day count method to
 379  * use.
 380  * @returns {number}the number of years, including fractional years, between two dates
 381  * @constructor
 382  */
 383-var YEARFRAC = function (...values) : number {
 384-  ArgsChecker.checkLengthWithin(values, 2, 3, "YEARFRAC");
 385-  var start = TypeConverter.firstValueAsDateNumber(values[0], true);
 386-  var end = TypeConverter.firstValueAsDateNumber(values[1], true);
 387-  var basis = values.length === 2 ? 0 : TypeConverter.firstValueAsNumber(values[2]);
 388-
 389-  var s = TypeConverter.numberToMoment(start);
 390-  var e = TypeConverter.numberToMoment(end);
 391+var YEARFRAC = function (startDate, endDate, dayCountConvention?) : number {
 392+  ArgsChecker.checkLengthWithin(arguments, 2, 3, "YEARFRAC");
 393+  startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
 394+  endDate = TypeConverter.firstValueAsDateNumber(endDate, true);
 395+  dayCountConvention = dayCountConvention ? TypeConverter.firstValueAsNumber(dayCountConvention) : 0;
 396+
 397+  var s = TypeConverter.numberToMoment(startDate);
 398+  var e = TypeConverter.numberToMoment(endDate);
 399   if (e.isBefore(s)) {
 400     var me = moment.utc(e);
 401     e = moment.utc(s);
 402@@ -468,7 +465,7 @@ var YEARFRAC = function (...values) : number {
 403     return false;
 404   };
 405 
 406-  switch (basis) {
 407+  switch (dayCountConvention) {
 408     // US (NASD) 30/360
 409     case 0:
 410       // Note: if eday == 31, it stays 31 if sday < 30
 411@@ -495,12 +492,12 @@ var YEARFRAC = function (...values) : number {
 412         } else if (feb29Between(s, e) || (emonth === 1 && eday === 29)) {
 413           ylength = 366;
 414         }
 415-        return Math.abs((end - start) / ylength);
 416+        return Math.abs((endDate - startDate) / ylength);
 417       } else {
 418         var years = (eyear - syear) + 1;
 419         var days = moment.utc([eyear+1]).startOf("year").diff(moment.utc([syear]).startOf("year"), 'days');
 420         var average = days / years;
 421-        return Math.abs((end - start) / average);
 422+        return Math.abs((endDate - startDate) / average);
 423       }
 424     // Actual/360
 425     case 2:
 426@@ -515,20 +512,20 @@ var YEARFRAC = function (...values) : number {
 427       // Remarkably, do NOT change February 28 or February 29 at ALL
 428       return Math.abs(((eday + emonth * 30 + eyear * 360) - (sday + smonth * 30 + syear * 360)) / 360);
 429   }
 430-  throw new NumError("Function YEARFRAC parameter 3 value is " + basis + ". Valid values are between 0 and 4 inclusive.");
 431+  throw new NumError("Function YEARFRAC parameter 3 value is " + dayCountConvention + ". Valid values are between 0 and 4 inclusive.");
 432 };
 433 
 434 
 435 /**
 436  * Returns the fraction of a 24-hour day the time represents.
 437- * @param values[1] time_string - The string that holds the time representation. Eg: "10am", "10:10", "10:10am",
 438- * "10:10:11", or "10:10:11am".
 439+ * @param timeString - The string that holds the time representation. Eg: "10am", "10:10", "10:10am", "10:10:11",
 440+ * or "10:10:11am".
 441  * @returns {number} representing the fraction of a 24-hour day
 442  * @constructor
 443  */
 444-var TIMEVALUE = function (...values) : number {
 445-  ArgsChecker.checkLength(values, 1, "TIMEVALUE");
 446-  var timeString = TypeConverter.firstValueAsString(values[0]);
 447+var TIMEVALUE = function (timeString) : number {
 448+  ArgsChecker.checkLength(arguments, 1, "TIMEVALUE");
 449+  timeString = TypeConverter.firstValueAsString(timeString);
 450   try {
 451     return TypeConverter.stringToTimeNumber(timeString);
 452   } catch (e) {
 453@@ -540,14 +537,14 @@ const MILLISECONDS_IN_DAY = 86400000;
 454 
 455 /**
 456  * Returns the hour component of a specific time, in numeric format.
 457- * @param values[0] time - The time from which to calculate the hour component. Must be a reference to a cell containing
 458+ * @param time - The time from which to calculate the hour component. Must be a reference to a cell containing
 459  * a date/time, a function returning a date/time type, or a number.
 460  * @returns {number}
 461  * @constructor
 462  */
 463-var HOUR = function (...values) : number {
 464-  ArgsChecker.checkLength(values, 1, "HOUR");
 465-  var time = TypeConverter.firstValueAsTimestampNumber(values[0]);
 466+var HOUR = function (time) : number {
 467+  ArgsChecker.checkLength(arguments, 1, "HOUR");
 468+  time = TypeConverter.firstValueAsTimestampNumber(time);
 469   if (time % 1 === 0) {
 470     return 0;
 471   }
 472@@ -558,14 +555,14 @@ var HOUR = function (...values) : number {
 473 
 474 /**
 475  * Returns the minute component of a specific time, in numeric format.
 476- * @param values[0] time - The time from which to calculate the minute component. Must be a reference to a cell
 477+ * @param time - The time from which to calculate the minute component. Must be a reference to a cell
 478  * containing a date/time, a function returning a date/time type, or a number.
 479  * @returns {number} minute of the time passed in.
 480  * @constructor
 481  */
 482-var MINUTE = function (...values) : number {
 483-  ArgsChecker.checkLength(values, 1, "MINUTE");
 484-  var time = TypeConverter.firstValueAsTimestampNumber(values[0]);
 485+var MINUTE = function (time) : number {
 486+  ArgsChecker.checkLength(arguments, 1, "MINUTE");
 487+  time = TypeConverter.firstValueAsTimestampNumber(time);
 488   if (time % 1 === 0) {
 489     return 0;
 490   }
 491@@ -575,14 +572,14 @@ var MINUTE = function (...values) : number {
 492 
 493 /**
 494  * Returns the second component of a specific time, in numeric format.
 495- * @param values[0] time - The time from which to calculate the second component. Must be a reference to a cell
 496+ * @param time - The time from which to calculate the second component. Must be a reference to a cell
 497  * containing a date/time, a function returning a date/time type, or a number.
 498  * @returns {number} second component of a specific time.
 499  * @constructor
 500  */
 501-var SECOND = function (...values) : number {
 502-  ArgsChecker.checkLength(values, 1, "SECOND");
 503-  var time = TypeConverter.firstValueAsTimestampNumber(values[0]);
 504+var SECOND = function (time) : number {
 505+  ArgsChecker.checkLength(arguments, 1, "SECOND");
 506+  time = TypeConverter.firstValueAsTimestampNumber(time);
 507   if (time % 1 === 0) {
 508     return 0;
 509   }
 510@@ -593,28 +590,29 @@ var SECOND = function (...values) : number {
 511 
 512 /**
 513  * Returns the number of net working days between two provided days.
 514- * @param values[0] start_date - The start date of the period from which to calculate the number of net working days.
 515- * @param values[1] end_date - The end date of the period from which to calculate the number of net working days.
 516- * @param values[1] holidays - [ OPTIONAL ] - A range or array constant containing the date serial numbers to consider
 517+ * @param startDate - The start date of the period from which to calculate the number of net working days.
 518+ * @param endDate - The end date of the period from which to calculate the number of net working days.
 519+ * @param holidays - [ OPTIONAL ] - A range or array constant containing the date serial numbers to consider
 520  * holidays. The values provided within an array for holidays must be date serial number values, as returned by N or
 521  * date values, as returned by DATE, DATEVALUE or TO_DATE. Values specified by a range should be standard date values or
 522  * date serial numbers.
 523  * @returns {number} the number of net working days between two provided dates.
 524  * @constructor
 525  */
 526-var NETWORKDAYS = function (...values) : number {
 527-  ArgsChecker.checkLengthWithin(values, 2, 3, "NETWORKDAYS");
 528-  var start = TypeConverter.firstValueAsDateNumber(values[0], true);
 529-  var end = TypeConverter.firstValueAsDateNumber(values[1], true);
 530-  var hasHolidays = values.length === 3;
 531-  var holidays = [];
 532+var NETWORKDAYS = function (startDate, endDate, holidays?) : number {
 533+  ArgsChecker.checkLengthWithin(arguments, 2, 3, "NETWORKDAYS");
 534+  startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
 535+  endDate = TypeConverter.firstValueAsDateNumber(endDate, true);
 536+  var hasHolidays = (holidays !== undefined);
 537+  var cleanHolidays = [];
 538   if (hasHolidays) {
 539-    if (values[2].length === 0) {
 540+    holidays = (holidays instanceof Array) ? holidays : [holidays];
 541+    if (holidays.length === 0) {
 542       throw new RefError("Reference does not exist.");
 543     }
 544-    for (var holidayDateValue of values[2]) {
 545+    for (var holidayDateValue of holidays) {
 546       if (typeof holidayDateValue === "number") {
 547-        holidays.push(holidayDateValue);
 548+        cleanHolidays.push(holidayDateValue);
 549       } else {
 550         throw new ValueError("NETWORKDAYS expects number values. But '" + holidayDateValue + "' is a " +
 551             (typeof holidayDateValue) + " and cannot be coerced to a number.")
 552@@ -622,22 +620,22 @@ var NETWORKDAYS = function (...values) : number {
 553     }
 554   }
 555   // Handle cases in which the start date is not before the end date.
 556-  var didSwap = start > end;
 557+  var didSwap = startDate > endDate;
 558   if (didSwap) {
 559-    var swap = end;
 560-    end = start;
 561-    start = swap;
 562+    var swap = endDate;
 563+    endDate = startDate;
 564+    startDate = swap;
 565   }
 566 
 567-  var countMoment = moment.utc(TypeConverter.numberToMoment(start));
 568+  var countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
 569   var weekendDays = [6, 0]; // Default weekend_days.
 570-  var days = end - start + 1;
 571+  var days = endDate - startDate + 1;
 572   var networkDays = days;
 573   var j = 0;
 574   while (j < days) {
 575     if (weekendDays.indexOf(countMoment.day()) >= 0) {
 576       networkDays--;
 577-    } else if (hasHolidays && holidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) > -1) {
 578+    } else if (hasHolidays && cleanHolidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) > -1) {
 579       networkDays--;
 580     }
 581     countMoment.add(1, 'days');
 582@@ -652,29 +650,29 @@ var NETWORKDAYS = function (...values) : number {
 583 
 584 /**
 585  * Returns the number of networking days between two provided days excluding specified weekend days and holidays.
 586- * @param values[0] start_date - The start date of the period from which to calculate the number of net working days.
 587- * @param values[1] end_date - The end date of the period from which to calculate the number of net working days.
 588- * @param values[2] weekend - [ OPTIONAL - 1 by default ] - A number or string representing which days of the week are
 589+ * @param startDate - The start date of the period from which to calculate the number of net working days.
 590+ * @param endDate - The end date of the period from which to calculate the number of net working days.
 591+ * @param weekend - [ OPTIONAL - 1 by default ] - A number or string representing which days of the week are
 592  * considered weekends. String method: weekends can be specified using seven 0’s and 1’s, where the first number in the
 593  * set represents Monday and the last number is for Sunday. A zero means that the day is a work day, a 1 means that the
 594  * day is a weekend. For example, “0000011” would mean Saturday and Sunday are weekends. Number method: instead of using
 595  * the string method above, a single number can be used. 1 = Saturday/Sunday are weekends, 2 = Sunday/Monday, and this
 596  * pattern repeats until 7 = Friday/Saturday. 11 = Sunday is the only weekend, 12 = Monday is the only weekend, and this
 597  * pattern repeats until 17 = Saturday is the only weekend.
 598- * @param values[3] holidays - [ OPTIONAL ] - A range or array constant containing the dates to consider as holidays.
 599+ * @param holidays - [ OPTIONAL ] - A range or array constant containing the dates to consider as holidays.
 600  * The values provided within an array for holidays must be date serial number values, as returned by N or date values,
 601  * as returned by DATE, DATEVALUE or TO_DATE. Values specified by a range should be standard date values or date serial
 602  * numbers.
 603  * @returns {number} of networking days between two provided days
 604  * @constructor
 605  */
 606-var NETWORKDAYS$INTL = function (...values) : number {
 607-  ArgsChecker.checkLengthWithin(values, 2, 4, "NETWORKDAYS$INTL");
 608-  var start = TypeConverter.firstValueAsDateNumber(values[0], true);
 609-  var end = TypeConverter.firstValueAsDateNumber(values[1], true);
 610+var NETWORKDAYS$INTL = function (startDate, endDate, weekend?, holidays?) : number {
 611+  ArgsChecker.checkLengthWithin(arguments, 2, 4, "NETWORKDAYS$INTL");
 612+  startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
 613+  endDate = TypeConverter.firstValueAsDateNumber(endDate, true);
 614   var weekendDays = [];
 615-  if (values.length >= 3) {
 616-    var weekend = TypeConverter.firstValue(values[2]);
 617+  if (weekend !== undefined) {
 618+    weekend = TypeConverter.firstValue(weekend);
 619     if (typeof weekend === "string") {
 620       if (!/^[0-1]{6,}$/.test(weekend)) {
 621         throw new NumError("Function NETWORKDAYS.INTL parameter 3 requires a number in the format '0000011'. "
 622@@ -714,20 +712,20 @@ var NETWORKDAYS$INTL = function (...values) : number {
 623       }
 624     } else {
 625       throw new ValueError("Function NETWORKDAYS.INTL parameter 4 expects number values. But '" + weekend
 626-          + "' cannot be coerced to a number.")
 627+          + "' cannot be coerced to a number.");
 628     }
 629   } else {
 630     weekendDays = [0, 6];
 631   }
 632-  var hasHolidays = values.length === 4;
 633-  var holidays = [];
 634+  var hasHolidays = holidays !== undefined;
 635+  var cleanHolidays = [];
 636   if (hasHolidays) {
 637-    if (values[3].length === 0) {
 638+    if (holidays === 0) {
 639       throw new RefError("Reference does not exist.");
 640     }
 641-    for (var holidayDateValue of values[3]) {
 642+    for (var holidayDateValue of holidays) {
 643       if (typeof holidayDateValue === "number") {
 644-        holidays.push(holidayDateValue);
 645+        cleanHolidays.push(holidayDateValue);
 646       } else {
 647         throw new ValueError("NETWORKDAYS.INTL expects number values. But '" + holidayDateValue + "' is a " +
 648           (typeof holidayDateValue) + " and cannot be coerced to a number.")
 649@@ -735,21 +733,21 @@ var NETWORKDAYS$INTL = function (...values) : number {
 650     }
 651   }
 652   // Handle cases in which the start date is not before the end date.
 653-  var didSwap = start > end;
 654+  var didSwap = startDate > endDate;
 655   if (didSwap) {
 656-    var swap = end;
 657-    end = start;
 658-    start = swap;
 659+    var swap = endDate;
 660+    endDate = startDate;
 661+    startDate = swap;
 662   }
 663 
 664-  var countMoment = moment.utc(TypeConverter.numberToMoment(start));
 665-  var days = end - start + 1;
 666+  var countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
 667+  var days = endDate - startDate + 1;
 668   var networkDays = days;
 669   var j = 0;
 670   while (j < days) {
 671     if (weekendDays.indexOf(countMoment.day()) >= 0) {
 672       networkDays--;
 673-    } else if (hasHolidays && holidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) > -1) {
 674+    } else if (hasHolidays && cleanHolidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) > -1) {
 675       networkDays--;
 676     }
 677     countMoment.add(1, 'days');
 678@@ -767,8 +765,8 @@ var NETWORKDAYS$INTL = function (...values) : number {
 679  * @returns {number} representing the current date and time.
 680  * @constructor
 681  */
 682-var NOW = function (...values) : number {
 683-  ArgsChecker.checkLength(values, 0, "NOW");
 684+var NOW = function () : number {
 685+  ArgsChecker.checkLength(arguments, 0, "NOW");
 686   return TypeConverter.momentToNumber(moment.utc());
 687 };
 688 
 689@@ -777,8 +775,8 @@ var NOW = function (...values) : number {
 690  * @returns {number} today
 691  * @constructor
 692  */
 693-var TODAY = function (...values) : number {
 694-  ArgsChecker.checkLength(values, 0, "TODAY");
 695+var TODAY = function () : number {
 696+  ArgsChecker.checkLength(arguments, 0, "TODAY");
 697   return TypeConverter.momentToNumber(moment.utc().startOf("day"));
 698 };
 699 
 700@@ -786,17 +784,17 @@ var TODAY = function (...values) : number {
 701 /**
 702  * Converts a provided hour, minute, and second into a time. Will silently recalculate numeric time values which fall
 703  * outside of valid ranges. Eg: TIME(24, 0, 0) is the same as TIME(0, 0, 0).
 704- * @param values[0] hour - The hour component of the time.
 705- * @param values[1] minute - The minute component of the time.
 706- * @param values[2] second - The second component of the time.
 707+ * @param hours - The hour component of the time.
 708+ * @param minutes - The minute component of the time.
 709+ * @param seconds - The second component of the time.
 710  * @returns {number} time of day
 711  * @constructor
 712  */
 713-var TIME = function (...values) : number {
 714-  ArgsChecker.checkLength(values, 3, "TIME");
 715-  var hours = Math.floor(TypeConverter.firstValueAsNumber(values[0]));
 716-  var minutes = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
 717-  var seconds = Math.floor(TypeConverter.firstValueAsNumber(values[2]));
 718+var TIME = function (hours, minutes, seconds) : number {
 719+  ArgsChecker.checkLength(arguments, 3, "TIME");
 720+  hours = Math.floor(TypeConverter.firstValueAsNumber(hours));
 721+  minutes = Math.floor(TypeConverter.firstValueAsNumber(minutes));
 722+  seconds = Math.floor(TypeConverter.firstValueAsNumber(seconds));
 723   var e = TypeConverter.unitsToTimeNumber(hours, minutes, seconds);
 724   if (e < 0) {
 725     throw new NumError("TIME evaluates to an out of range value " + e + ". It should be greater than or equal to 0.");
 726@@ -807,46 +805,46 @@ var TIME = function (...values) : number {
 727 
 728 /**
 729  * Calculates the end date after a specified number of working days.
 730- * @param values[0] start_date - The date from which to begin counting.
 731- * @param values[1] num_days - The number of working days to advance from start_date. If negative, counts backwards. If
 732+ * @param startDate - The date from which to begin counting.
 733+ * @param numberOfDays - The number of working days to advance from start_date. If negative, counts backwards. If
 734  * not an integer, truncate.
 735- * @param values[2] holidays - [ OPTIONAL ] - A range or array constant containing the dates to consider holidays. The
 736+ * @param holidays - [ OPTIONAL ] - A range or array constant containing the dates to consider holidays. The
 737  * values provided within an array for holidays must be date serial number values, as returned by N or date values, as
 738  * returned by DATE, DATEVALUE or TO_DATE. Values specified by a range should be standard date values or date serial
 739  * numbers.
 740  * @returns {number} end date after a specified number of working days.
 741  * @constructor
 742  */
 743-var WORKDAY = function (...values) : number {
 744-  ArgsChecker.checkLengthWithin(values, 2, 3, "WORKDAY");
 745-  var start = TypeConverter.firstValueAsDateNumber(values[0], true);
 746-  var days = TypeConverter.firstValueAsNumber(values[1]);
 747-  var hasHolidays = values.length === 3;
 748-  var holidays = [];
 749-  if (hasHolidays) {
 750-    if (values[2] instanceof Array) {
 751-      if (values[2].length === 0) {
 752+var WORKDAY = function (startDate, numberOfDays, holidays?) : number {
 753+  ArgsChecker.checkLengthWithin(arguments, 2, 3, "WORKDAY");
 754+  startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
 755+  numberOfDays = TypeConverter.firstValueAsNumber(numberOfDays);
 756+  var hasHolidays = (cleanHolidays !== undefined);
 757+  var cleanHolidays = [];
 758+  if (hasHolidays !== undefined) {
 759+    if (holidays instanceof Array) {
 760+      if (holidays.length === 0) {
 761         throw new RefError("Reference does not exist.");
 762       }
 763-      for (var holidayDateValue of values[2]) {
 764+      for (var holidayDateValue of holidays) {
 765         if (typeof holidayDateValue === "number") {
 766-          holidays.push(holidayDateValue);
 767+          cleanHolidays.push(holidayDateValue);
 768         } else {
 769           throw new ValueError("WORKDAY expects number values. But '" + holidayDateValue + "' is a " +
 770             (typeof holidayDateValue) + " and cannot be coerced to a number.")
 771         }
 772       }
 773     } else {
 774-      holidays.push(TypeConverter.valueToNumber(values[2]));
 775+      cleanHolidays.push(TypeConverter.valueToNumber(holidays));
 776     }
 777   }
 778 
 779   var weekendDays = [0, 6];
 780-  var countMoment = moment.utc(TypeConverter.numberToMoment(start));
 781+  var countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
 782   var j = 0;
 783-  while (j < days) {
 784+  while (j < numberOfDays) {
 785     countMoment.add(1, 'days');
 786-    if (weekendDays.indexOf(countMoment.day()) < 0 && holidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) < 0) {
 787+    if (weekendDays.indexOf(countMoment.day()) < 0 && cleanHolidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) < 0) {
 788       j++;
 789     }
 790   }
 791@@ -856,26 +854,26 @@ var WORKDAY = function (...values) : number {
 792 
 793 /**
 794  * Calculates the date after a specified number of workdays excluding specified weekend days and holidays.
 795- * @param values[0] start_date - The date from which to begin counting.
 796- * @param values[1] num_days - The number of working days to advance from start_date. If negative, counts backwards.
 797- * @param values[2] weekend - [ OPTIONAL - 1 by default ] - A number or string representing which days of the week are
 798+ * @param startDate - The date from which to begin counting.
 799+ * @param numberOfDays - The number of working days to advance from start_date. If negative, counts backwards.
 800+ * @param weekend - [ OPTIONAL - 1 by default ] - A number or string representing which days of the week are
 801  * considered weekends. String method: weekends can be specified using seven 0’s and 1’s, where the first number in the
 802  * set represents Monday and the last number is for Sunday. A zero means that the day is a work day, a 1 means that the
 803  * day is a weekend. For example, “0000011” would mean Saturday and Sunday are weekends. Number method: instead of using
 804  * the string method above, a single number can be used. 1 = Saturday/Sunday are weekends, 2 = Sunday/Monday, and this
 805  * pattern repeats until 7 = Friday/Saturday. 11 = Sunday is the only weekend, 12 = Monday is the only weekend, and this
 806  * pattern repeats until 17 = Saturday is the only weekend.
 807- * @param values[3] holidays - [ OPTIONAL ] - A range or array constant containing the dates to consider holidays.
 808+ * @param holidays - [ OPTIONAL ] - A range or array constant containing the dates to consider holidays.
 809  * @returns {number}
 810  * @constructor
 811  */
 812-var WORKDAY$INTL = function (...values) : number {
 813-  ArgsChecker.checkLengthWithin(values, 2, 3, "WORKDAY$INTL");
 814-  var start = TypeConverter.firstValueAsDateNumber(values[0], true);
 815-  var days = TypeConverter.firstValueAsNumber(values[1]);
 816+var WORKDAY$INTL = function (startDate, numberOfDays, weekend?, holidays?) : number {
 817+  ArgsChecker.checkLengthWithin(arguments, 2, 3, "WORKDAY$INTL");
 818+  startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
 819+  numberOfDays = TypeConverter.firstValueAsNumber(numberOfDays);
 820   var weekendDays = [];
 821-  if (values.length >= 3) {
 822-    var weekend = TypeConverter.firstValue(values[2]);
 823+  if (weekend !== undefined) {
 824+    weekend = TypeConverter.firstValue(weekend);
 825     if (typeof weekend === "string") {
 826       if (!/^[0-1]{6,}$/.test(weekend)) {
 827         throw new NumError("Function WORKDAY.INTL parameter 3 requires a number in the format '0000011'. "
 828@@ -915,35 +913,35 @@ var WORKDAY$INTL = function (...values) : number {
 829       }
 830     } else {
 831       throw new ValueError("Function WORKDAY.INTL parameter 4 expects number values. But '" + weekend
 832-        + "' cannot be coerced to a number.")
 833+        + "' cannot be coerced to a number.");
 834     }
 835   } else {
 836     weekendDays = [0, 6];
 837   }
 838-  var hasHolidays = values.length === 3;
 839-  var holidays = [];
 840+  var hasHolidays = (holidays !== undefined);
 841+  var cleanHolidays = [];
 842   if (hasHolidays) {
 843-    if (values[3] instanceof Array) {
 844-      if (values[3].length === 0) {
 845+    if (holidays instanceof Array) {
 846+      if (holidays.length === 0) {
 847         throw new RefError("Reference does not exist.");
 848       }
 849-      for (var holidayDateValue of values[3]) {
 850+      for (var holidayDateValue of holidays) {
 851         if (typeof holidayDateValue === "number") {
 852-          holidays.push(holidayDateValue);
 853+          cleanHolidays.push(holidayDateValue);
 854         } else {
 855           throw new ValueError("WORKDAY expects number values. But '" + holidayDateValue + "' is a " +
 856             (typeof holidayDateValue) + " and cannot be coerced to a number.")
 857         }
 858       }
 859     } else {
 860-      holidays.push(TypeConverter.valueToNumber(values[3]));
 861+      cleanHolidays.push(TypeConverter.valueToNumber(holidays));
 862     }
 863   }
 864-  var countMoment = moment.utc(TypeConverter.numberToMoment(start));
 865+  var countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
 866   var j = 0;
 867-  while (j < days) {
 868+  while (j < numberOfDays) {
 869     countMoment.add(1, 'days');
 870-    if (weekendDays.indexOf(countMoment.day()) < 0 && holidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) < 0) {
 871+    if (weekendDays.indexOf(countMoment.day()) < 0 && cleanHolidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) < 0) {
 872       j++;
 873     }
 874   }
 875diff --git a/src/Formulas/Engineering.ts b/src/Formulas/Engineering.ts
 876index b7e52d8..3c3e226 100644
 877--- a/src/Formulas/Engineering.ts
 878+++ b/src/Formulas/Engineering.ts
 879@@ -7,22 +7,22 @@ import {
 880 import {
 881   ValueError,
 882   NumError
 883-} from "../Errors"
 884+} from "../Errors";
 885 
 886 /**
 887  * Converts a signed binary number to decimal format.
 888- * @param values[0] signed_binary_number - The signed 10-bit binary value to be converted to decimal, provided as a
 889+ * @param signedBinaryNumber - The signed 10-bit binary value to be converted to decimal, provided as a
 890  * string. The most significant bit of signed_binary_number is the sign bit; that is, negative numbers are represented
 891  * in two's complement format.
 892  * @returns {number}
 893  * @constructor
 894  */
 895-var BIN2DEC = function (...values) : number {
 896-  ArgsChecker.checkLength(values, 1, "BIN2DEC");
 897-  if (typeof TypeConverter.firstValue(values[0]) === "boolean") {
 898-    throw new ValueError("Function BIN2DEC parameter 1 expects text values. But '" + values[0] + "' is a boolean and cannot be coerced to a text.");
 899+var BIN2DEC = function (signedBinaryNumber) : number {
 900+  ArgsChecker.checkLength(arguments, 1, "BIN2DEC");
 901+  if (typeof TypeConverter.firstValue(signedBinaryNumber) === "boolean") {
 902+    throw new ValueError("Function BIN2DEC parameter 1 expects text values. But '" + signedBinaryNumber + "' is a boolean and cannot be coerced to a text.");
 903   }
 904-  var n = TypeConverter.firstValueAsString(values[0]);
 905+  var n = TypeConverter.firstValueAsString(signedBinaryNumber);
 906   if (!(/^[01]{1,10}$/).test(n)) {
 907     throw new NumError("Input for BIN2DEC ('" + n + "') is not a valid binary representation.");
 908   }
 909@@ -36,22 +36,22 @@ var BIN2DEC = function (...values) : number {
 910 
 911 /**
 912  * Converts a signed binary number to signed hexadecimal format.
 913- * @param values[0] signed_binary_number - The signed 10-bit binary value to be converted to signed hexadecimal,
 914+ * @param signedBinaryNumber - The signed 10-bit binary value to be converted to signed hexadecimal,
 915  * provided as a string. The most significant bit of signed_binary_number is the sign bit; that is, negative numbers are
 916  * represented in two's complement format.
 917- * @param values[1] significant_digits - [ OPTIONAL ] - The number of significant digits to ensure in the result.
 918+ * @param significantDigits - [ OPTIONAL ] - The number of significant digits to ensure in the result.
 919  * @returns {string} string representation of a signed hexadecimal
 920  * @constructor
 921  */
 922-var BIN2HEX = function (...values) : string {
 923-  ArgsChecker.checkLengthWithin(values, 1, 2, "BIN2HEX");
 924-  if (typeof TypeConverter.firstValue(values[0]) === "boolean") {
 925-    throw new ValueError("Function BIN2HEX parameter 1 expects text values. But '" + values[0] + "' is a boolean and cannot be coerced to a text.");
 926+var BIN2HEX = function (signedBinaryNumber, significantDigits?) : string {
 927+  ArgsChecker.checkLengthWithin(arguments, 1, 2, "BIN2HEX");
 928+  if (typeof TypeConverter.firstValue(signedBinaryNumber) === "boolean") {
 929+    throw new ValueError("Function BIN2HEX parameter 1 expects text values. But '" + signedBinaryNumber + "' is a boolean and cannot be coerced to a text.");
 930   }
 931-  var n = TypeConverter.firstValueAsString(values[0]);
 932+  var n = TypeConverter.firstValueAsString(signedBinaryNumber);
 933   var p = 10;
 934-  if (values.length === 2) {
 935-    p = TypeConverter.firstValueAsNumber(values[1]);
 936+  if (significantDigits !== undefined) {
 937+    p = TypeConverter.firstValueAsNumber(significantDigits);
 938   }
 939   if (!(/^[01]{1,10}$/).test(n)) {
 940     throw new NumError("Input for BIN2HEX ('"+n+"') is not a valid binary representation.");
 941@@ -80,24 +80,24 @@ var BIN2HEX = function (...values) : string {
 942 
 943 /**
 944  * Converts a signed binary number to signed octal format.
 945- * @param values[0] signed_binary_number - The signed 10-bit binary value to be converted to signed octal, provided as a
 946+ * @param signedBinaryNumber - The signed 10-bit binary value to be converted to signed octal, provided as a
 947  * string. The most significant bit of signed_binary_number is the sign bit; that is, negative numbers are represented
 948  * in two's complement format.
 949- * @param values[1] significant_digits - [ OPTIONAL ] - The number of significant digits to ensure in the result. If
 950+ * @param significantDigits - [ OPTIONAL ] - The number of significant digits to ensure in the result. If
 951  * this is greater than the number of significant digits in the result, the result is left-padded with zeros until the
 952  * total number of digits reaches significant_digits.
 953  * @returns {string} number in octal format
 954  * @constructor
 955  */
 956-var BIN2OCT = function (...values) : string {
 957-  ArgsChecker.checkLengthWithin(values, 1, 2, "BIN2OCT");
 958-  if (typeof TypeConverter.firstValue(values[0]) === "boolean") {
 959-    throw new ValueError("Function BIN2OCT parameter 1 expects text values. But '" + values[0] + "' is a boolean and cannot be coerced to a text.");
 960+var BIN2OCT = function (signedBinaryNumber, significantDigits?) : string {
 961+  ArgsChecker.checkLengthWithin(arguments, 1, 2, "BIN2OCT");
 962+  if (typeof TypeConverter.firstValue(signedBinaryNumber) === "boolean") {
 963+    throw new ValueError("Function BIN2OCT parameter 1 expects text values. But '" + signedBinaryNumber + "' is a boolean and cannot be coerced to a text.");
 964   }
 965-  var n = TypeConverter.firstValueAsString(values[0]);
 966+  var n = TypeConverter.firstValueAsString(signedBinaryNumber);
 967   var p = 10;
 968-  if (values.length === 2) {
 969-    p = TypeConverter.firstValueAsNumber(values[1]);
 970+  if (significantDigits !== undefined) {
 971+    p = TypeConverter.firstValueAsNumber(significantDigits);
 972   }
 973   if (!(/^[01]{1,10}$/).test(n)) {
 974     throw new NumError("Input for BIN2OCT ('"+n+"') is not a valid binary representation.");
 975@@ -126,17 +126,17 @@ var BIN2OCT = function (...values) : string {
 976 
 977 /**
 978  * Converts a decimal number to signed octal format.
 979- * @param values[0] decimal_number - The decimal value to be converted to signed octal,provided as a string. For this
 980+ * @param decimalDumber - The decimal value to be converted to signed octal,provided as a string. For this
 981  * function, this value has a maximum of 536870911 if positive, and a minimum of -53687092 if negative.
 982- * @param values[1] significant_digits - [ OPTIONAL ] The number of significant digits to ensure in the result. If this
 983+ * @param significantDigits - [ OPTIONAL ] The number of significant digits to ensure in the result. If this
 984  * is greater than the number of significant digits in the result, the result is left-padded with zeros until the total
 985  * number of digits reaches significant_digits.
 986  * @returns {string} octal string representation of the decimal number
 987  * @constructor
 988  */
 989-var DEC2OCT = function (...values) : string {
 990-  ArgsChecker.checkLengthWithin(values, 1, 2, "DEC2OCT");
 991-  var n = TypeConverter.firstValueAsNumber(values[0]);
 992+var DEC2OCT = function (decimalDumber, significantDigits?) : string {
 993+  ArgsChecker.checkLengthWithin(arguments, 1, 2, "DEC2OCT");
 994+  var n = TypeConverter.firstValueAsNumber(decimalDumber);
 995   if (n < 0) {
 996     n = Math.ceil(n);
 997   }
 998@@ -145,8 +145,8 @@ var DEC2OCT = function (...values) : string {
 999   }
1000   var p = 10;
1001   var placesPresent = false;
1002-  if (values.length === 2) {
1003-    p = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
1004+  if (significantDigits !== undefined) {
1005+    p = Math.floor(TypeConverter.firstValueAsNumber(significantDigits));
1006     placesPresent = true;
1007   }
1008   if (n < -53687092 || n > 536870911) {
1009@@ -174,17 +174,17 @@ var DEC2OCT = function (...values) : string {
1010 
1011 /**
1012  * Converts a decimal number to signed hexadecimal format.
1013- * @param values[0] decimal_number - The decimal value to be converted to signed hexadecimal, provided as a string. This
1014+ * @param decimalDumber - The decimal value to be converted to signed hexadecimal, provided as a string. This
1015  * value has a maximum of 549755813887 if positive, and a minimum of -549755814888 if negative.
1016- * @param values[1] significant_digits - [ OPTIONAL ] - The number of significant digits to ensure in the result. If
1017+ * @param significantDigits - [ OPTIONAL ] - The number of significant digits to ensure in the result. If
1018  * this is greater than the number of significant digits in the result, the result is left-padded with zeros until the
1019  * total number of digits reaches significant_digits. This value is ignored if decimal_number is negative.
1020  * @returns {string} hexadecimal string representation of the decimal number
1021  * @constructor
1022  */
1023-var DEC2HEX = function (...values) : string {
1024-  ArgsChecker.checkLengthWithin(values, 1, 2, "DEC2HEX");
1025-  var n = TypeConverter.firstValueAsNumber(values[0]);
1026+var DEC2HEX = function (decimalDumber, significantDigits?) : string {
1027+  ArgsChecker.checkLengthWithin(arguments, 1, 2, "DEC2HEX");
1028+  var n = TypeConverter.firstValueAsNumber(decimalDumber);
1029   if (n < 0) {
1030     n = Math.ceil(n);
1031   }
1032@@ -193,8 +193,8 @@ var DEC2HEX = function (...values) : string {
1033   }
1034   var p = 10;
1035   var placesPresent = false;
1036-  if (values.length === 2) {
1037-    p = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
1038+  if (significantDigits !== undefined) {
1039+    p = Math.floor(TypeConverter.firstValueAsNumber(significantDigits));
1040     placesPresent = true;
1041   }
1042   if (n < -549755813888 || n > 549755813887) {
1043@@ -222,17 +222,17 @@ var DEC2HEX = function (...values) : string {
1044 
1045 /**
1046  * Converts a decimal number to signed binary format.
1047- * @param values[0] decimal_number - The decimal value to be converted to signed binary, provided as a string. For this
1048+ * @param decimalDumber - The decimal value to be converted to signed binary, provided as a string. For this
1049  * function, this value has a maximum of 511 if positive, and a minimum of -512 if negative.
1050- * @param values[1] significant_digits - [ OPTIONAL ] The number of significant digits to ensure in the result. If this
1051+ * @param significantDigits - [ OPTIONAL ] The number of significant digits to ensure in the result. If this
1052  * is greater than the number of significant digits in the result, the result is left-padded with zeros until the total
1053  * number of digits reaches significant_digits.
1054  * @returns {string} signed binary string representation of the input decimal number.
1055  * @constructor
1056  */
1057-var DEC2BIN = function (...values) : string {
1058-  ArgsChecker.checkLengthWithin(values, 1, 2, "DEC2BIN");
1059-  var n = TypeConverter.firstValueAsNumber(values[0]);
1060+var DEC2BIN = function (decimalDumber, significantDigits?) : string {
1061+  ArgsChecker.checkLengthWithin(arguments, 1, 2, "DEC2BIN");
1062+  var n = TypeConverter.firstValueAsNumber(decimalDumber);
1063   if (n < 0) {
1064     n = Math.ceil(n);
1065   }
1066@@ -244,8 +244,8 @@ var DEC2BIN = function (...values) : string {
1067   }
1068   var p = 10;
1069   var placesPresent = false;
1070-  if (values.length === 2) {
1071-    p = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
1072+  if (significantDigits !== undefined) {
1073+    p = Math.floor(TypeConverter.firstValueAsNumber(significantDigits));
1074     placesPresent = true;
1075   }
1076 
1077@@ -293,17 +293,17 @@ var DEC2BIN = function (...values) : string {
1078 
1079 /**
1080  * Compare two numeric values, returning 1 if they're equal.
1081- * @param values[0] The first number to compare.
1082- * @param values[1] The second number to compare.
1083+ * @param one - The first number to compare.
1084+ * @param two - The second number to compare.
1085  * @returns {number} 1 if they're equal, 0 if they're not equal.
1086  * @constructor
1087  */
1088-var DELTA = function (...values) : number {
1089-  ArgsChecker.checkLengthWithin(values, 1, 2, "DELTA");
1090-  if (values.length === 1) {
1091-    return TypeConverter.valueToNumber(values[0]) === 0 ? 1 : 0;
1092+var DELTA = function (one, two?) : number {
1093+  ArgsChecker.checkLengthWithin(arguments, 1, 2, "DELTA");
1094+  if (two === undefined) {
1095+    return TypeConverter.valueToNumber(one) === 0 ? 1 : 0;
1096   }
1097-  return TypeConverter.valueToNumber(values[0]) === TypeConverter.valueToNumber(values[1]) ? 1 : 0;
1098+  return TypeConverter.valueToNumber(one) === TypeConverter.valueToNumber(two) ? 1 : 0;
1099 };
1100 
1101 export {
1102diff --git a/src/Formulas/Financial.ts b/src/Formulas/Financial.ts
1103index c78b892..9ec430e 100644
1104--- a/src/Formulas/Financial.ts
1105+++ b/src/Formulas/Financial.ts
1106@@ -16,21 +16,21 @@ import {
1107 
1108 /**
1109  * Calculates the depreciation of an asset for a specified period using the double-declining balance method.
1110- * @param values[0] cost - The initial cost of the asset.
1111- * @param values[1] salvage - The value of the asset at the end of depreciation.
1112- * @param values[2] life - The number of periods over which the asset is depreciated.
1113- * @param values[3] period - The single period within life for which to calculate depreciation.
1114- * @param values[4] factor - [ OPTIONAL - 2 by default ] - The factor by which depreciation decreases.
1115+ * @param cost - The initial cost of the asset.
1116+ * @param salvage - The value of the asset at the end of depreciation.
1117+ * @param life - The number of periods over which the asset is depreciated.
1118+ * @param period - The single period within life for which to calculate depreciation.
1119+ * @param factor - [ OPTIONAL - 2 by default ] - The factor by which depreciation decreases.
1120  * @returns {number} depreciation of an asset for a specified period
1121  * @constructor
1122  */
1123-var DDB = function (...values) : number {
1124-  ArgsChecker.checkLengthWithin(values, 4, 5, "DDB");
1125-  var cost = TypeConverter.firstValueAsNumber(values[0]);
1126-  var salvage = TypeConverter.firstValueAsNumber(values[1]);
1127-  var life = TypeConverter.firstValueAsNumber(values[2]);
1128-  var period = TypeConverter.firstValueAsNumber(values[3]);
1129-  var factor = values.length === 5 ? TypeConverter.firstValueAsNumber(values[4]) : 2;
1130+var DDB = function (cost, salvage, life, period, factor?) : number {
1131+  ArgsChecker.checkLengthWithin(arguments, 4, 5, "DDB");
1132+  cost = TypeConverter.firstValueAsNumber(cost);
1133+  salvage = TypeConverter.firstValueAsNumber(salvage);
1134+  life = TypeConverter.firstValueAsNumber(life);
1135+  period = TypeConverter.firstValueAsNumber(period);
1136+  factor = factor === undefined ? 2 : TypeConverter.firstValueAsNumber(factor);
1137 
1138   if (cost < 0) {
1139     throw new NumError("Function DDB parameter 1 value is "
1140@@ -68,21 +68,21 @@ var DDB = function (...values) : number {
1141 
1142 /**
1143  * Calculates the depreciation of an asset for a specified period using the arithmetic declining balance method.
1144- * @param values[0] cost - The initial cost of the asset.
1145- * @param values[1] salvage - The value of the asset at the end of depreciation.
1146- * @param values[2] life - The number of periods over which the asset is depreciated.
1147- * @param values[3] period - The single period within life for which to calculate depreciation.
1148- * @param values[4] month - [ OPTIONAL - 12 by default ] - The number of months in the first year of depreciation.
1149+ * @param cost - The initial cost of the asset.
1150+ * @param salvage - The value of the asset at the end of depreciation.
1151+ * @param life - The number of periods over which the asset is depreciated.
1152+ * @param period - The single period within life for which to calculate depreciation.
1153+ * @param month - [ OPTIONAL - 12 by default ] - The number of months in the first year of depreciation.
1154  * @returns {number} depreciated value
1155  * @constructor
1156  */
1157-var DB = function (...values) : number {
1158-  ArgsChecker.checkLengthWithin(values, 4, 5, "DB");
1159-  var cost = TypeConverter.firstValueAsNumber(values[0]);
1160-  var salvage = TypeConverter.firstValueAsNumber(values[1]);
1161-  var life = TypeConverter.firstValueAsNumber(values[2]);
1162-  var period = TypeConverter.firstValueAsNumber(values[3]);
1163-  var month = values.length === 5 ? Math.floor(TypeConverter.firstValueAsNumber(values[4])) : 12;
1164+var DB = function (cost, salvage, life, period, month) : number {
1165+  ArgsChecker.checkLengthWithin(arguments, 4, 5, "DB");
1166+  cost = TypeConverter.firstValueAsNumber(cost);
1167+  salvage = TypeConverter.firstValueAsNumber(salvage);
1168+  life = TypeConverter.firstValueAsNumber(life);
1169+  period = TypeConverter.firstValueAsNumber(period);
1170+  month = month !== undefined ? Math.floor(TypeConverter.firstValueAsNumber(month)) : 12;
1171   if (cost < 0) {
1172     throw new NumError("Function DB parameter 1 value is "
1173       + cost + ". It should be greater than or equal to 0.");
1174@@ -134,15 +134,15 @@ var DB = function (...values) : number {
1175 /**
1176  * Formats a number into the locale-specific currency format. WARNING: Currently the equivalent of TRUNC, since this
1177  * returns numbers
1178- * @param values[0] number - The value to be formatted.
1179- * @param values[1] places - [ OPTIONAL - 2 by default ] - The number of decimal places to display.
1180+ * @param number - The value to be formatted.
1181+ * @param places - [ OPTIONAL - 2 by default ] - The number of decimal places to display.
1182  * @returns {number} dollars
1183  * @constructor
1184  */
1185-var DOLLAR = function (...values) : number {
1186-  ArgsChecker.checkLengthWithin(values, 1, 2, "DOLLAR");
1187-  var v = TypeConverter.firstValueAsNumber(values[0]);
1188-  var places = values.length === 2 ? TypeConverter.firstValueAsNumber(values[1]) : 2;
1189+var DOLLAR = function (number, places?) : number {
1190+  ArgsChecker.checkLengthWithin(arguments, 1, 2, "DOLLAR");
1191+  var v = TypeConverter.firstValueAsNumber(number);
1192+  places = places !== undefined ? TypeConverter.firstValueAsNumber(places) : 2;
1193   var sign = (v > 0) ? 1 : -1;
1194   var divisor = sign * (Math.floor(Math.abs(v) * Math.pow(10, places)));
1195   var pow = Math.pow(10, places);
1196@@ -155,15 +155,15 @@ var DOLLAR = function (...values) : number {
1197 
1198 /**
1199  * Converts a price quotation given as a decimal fraction into a decimal value.
1200- * @param values[0] fractional_price - The price quotation given using fractional decimal conventions.
1201- * @param values[1] unit - The units of the fraction, e.g. 8 for 1/8ths or 32 for 1/32nds.
1202+ * @param fractionalPrice - The price quotation given using fractional decimal conventions.
1203+ * @param unit - The units of the fraction, e.g. 8 for 1/8ths or 32 for 1/32nds.
1204  * @returns {number} decimal value.
1205  * @constructor
1206  */
1207-var DOLLARDE = function (...values) : number {
1208-  ArgsChecker.checkLength(values, 2, "DOLLARDE");
1209-  var dollar = TypeConverter.firstValueAsNumber(values[0]);
1210-  var fraction = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
1211+var DOLLARDE = function (fractionalPrice, unit) : number {
1212+  ArgsChecker.checkLength(arguments, 2, "DOLLARDE");
1213+  var dollar = TypeConverter.firstValueAsNumber(fractionalPrice);
1214+  var fraction = Math.floor(TypeConverter.firstValueAsNumber(unit));
1215   if (fraction === 0) {
1216     throw new DivZeroError("Function DOLLARDE parameter 2 cannot be zero.");
1217   }
1218@@ -180,35 +180,35 @@ var DOLLARDE = function (...values) : number {
1219 
1220 /**
1221  * Converts a price quotation given as a decimal value into a decimal fraction.
1222- * @param values[0] decimal_price - The price quotation given as a decimal value.
1223- * @param values[1] unit - The units of the desired fraction, e.g. 8 for 1/8ths or 32 for 1/32nds
1224+ * @param decimalPrice - The price quotation given as a decimal value.
1225+ * @param unit - The units of the desired fraction, e.g. 8 for 1/8ths or 32 for 1/32nds
1226  * @returns {number} price quotation as decimal fraction.
1227  * @constructor
1228  */
1229-var DOLLARFR = function (...values) : number {
1230-  ArgsChecker.checkLength(values, 2, "DOLLARFR");
1231-  var dollar = TypeConverter.firstValueAsNumber(values[0]);
1232-  var unit = Math.floor(TypeConverter.firstValueAsNumber(values[1]));
1233+var DOLLARFR = function (decimalPrice, unit) : number {
1234+  ArgsChecker.checkLength(arguments, 2, "DOLLARFR");
1235+  decimalPrice = TypeConverter.firstValueAsNumber(decimalPrice);
1236+  unit = Math.floor(TypeConverter.firstValueAsNumber(unit));
1237   if (unit === 0) {
1238     throw new DivZeroError("Function DOLLARFR parameter 2 cannot be zero.");
1239   }
1240-  var result = parseInt(dollar.toString(), 10);
1241-  result += (dollar % 1) * Math.pow(10, -Math.ceil(Math.log(unit) / Math.LN10)) * unit;
1242+  var result = parseInt(decimalPrice.toString(), 10);
1243+  result += (decimalPrice % 1) * Math.pow(10, -Math.ceil(Math.log(unit) / Math.LN10)) * unit;
1244   return result;
1245 };
1246 
1247 
1248 /**
1249  * Calculates the annual effective interest rate given the nominal rate and number of compounding periods per year.
1250- * @param values[0] nominal_rate - The nominal interest rate per year.
1251- * @param values[1] periods_per_year - The number of compounding periods per year.
1252+ * @param nominalRate - The nominal interest rate per year.
1253+ * @param periodsPerYear - The number of compounding periods per year.
1254  * @returns {number} annual effective interest rate
1255  * @constructor
1256  */
1257-var EFFECT = function (...values) : number {
1258-  ArgsChecker.checkLength(values, 2, "EFFECT");
1259-  var rate = TypeConverter.firstValueAsNumber(values[0]);
1260-  var periods = TypeConverter.firstValueAsNumber(values[1]);
1261+var EFFECT = function (nominalRate, periodsPerYear) : number {
1262+  ArgsChecker.checkLength(arguments, 2, "EFFECT");
1263+  var rate = TypeConverter.firstValueAsNumber(nominalRate);
1264+  var periods = TypeConverter.firstValueAsNumber(periodsPerYear);
1265   if (rate <= 0) {
1266     throw new NumError("Function EFFECT parameter 1 value is " + rate + ". It should be greater than to 0");
1267   }
1268@@ -272,34 +272,34 @@ function fv(rate, periods, payment, value, type) {
1269 /**
1270  * Calculates the cumulative principal paid over a range of payment periods for an investment based on constant-amount
1271  * periodic payments and a constant interest rate.
1272- * @param values[0] rate - The interest rate.
1273- * @param values[1] number_of_periods - The number of payments to be made.
1274- * @param values[2] present_value - The current value of the annuity.
1275- * @param values[3] first_period - The number of the payment period to begin the cumulative calculation. must be greater
1276+ * @param rate - The interest rate.
1277+ * @param numberOfPeriods - The number of payments to be made.
1278+ * @param presentValue - The current value of the annuity.
1279+ * @param firstPeriod - The number of the payment period to begin the cumulative calculation. must be greater
1280  * than or equal to 1.
1281- * @param values[4] last_period - The number of the payment period to end the cumulative calculation, must be greater
1282+ * @param lastPeriod - The number of the payment period to end the cumulative calculation, must be greater
1283  * than first_period.
1284- * @param values[5] end_or_beginning - Whether payments are due at the end (0) or beginning (1) of each period
1285+ * @param endOrBeginning - Whether payments are due at the end (0) or beginning (1) of each period
1286  * @returns {number} cumulative principal
1287  * @constructor
1288  */
1289-var CUMPRINC = function (...values) : number {
1290-  ArgsChecker.checkLength(values, 6, "CUMPRINC");
1291-  var rate = TypeConverter.firstValueAsNumber(values[0]);
1292-  var periods = TypeConverter.firstValueAsNumber(values[1]);
1293-  var value = TypeConverter.firstValueAsNumber(values[2]);
1294-  var start = TypeConverter.firstValueAsNumber(values[3]);
1295+var CUMPRINC = function (rate, numberOfPeriods, presentValue, firstPeriod, lastPeriod, endOrBeginning) : number {
1296+  ArgsChecker.checkLength(arguments, 6, "CUMPRINC");
1297+  rate = TypeConverter.firstValueAsNumber(rate);
1298+  var periods = TypeConverter.firstValueAsNumber(numberOfPeriods);
1299+  var value = TypeConverter.firstValueAsNumber(presentValue);
1300+  var start = TypeConverter.firstValueAsNumber(firstPeriod);
1301   if (start < 1) {
1302     throw new NumError("Function CUMPRINC parameter 4 value is " + start + ". It should be greater than or equal to 1.");
1303   }
1304-  var end = TypeConverter.firstValueAsNumber(values[4]);
1305+  var end = TypeConverter.firstValueAsNumber(lastPeriod);
1306   if (end < 1) {
1307     throw new NumError("Function CUMPRINC parameter 5 value is " + end + ". It should be greater than or equal to 1.");
1308   }
1309   if (end < start) {
1310     throw new NumError("Function CUMPRINC parameter 5 value is " + end + ". It should be greater than or equal to " + start + ".");
1311   }
1312-  var type = TypeConverter.firstValueAsBoolean(values[5]);
1313+  var type = TypeConverter.firstValueAsBoolean(endOrBeginning);
1314 
1315   var payment = PMT(rate, periods, value, 0, type);
1316   var principal = 0;
1317@@ -324,34 +324,34 @@ var CUMPRINC = function (...values) : number {
1318 /**
1319  * Calculates the cumulative interest over a range of payment periods for an investment based on constant-amount
1320  * periodic payments and a constant interest rate.
1321- * @param values[0] rate - The interest rate.
1322- * @param values[1] number_of_periods - The number of payments to be made.
1323- * @param values[2] present_value - The current value of the annuity.
1324- * @param values[3] first_period - The number of the payment period to begin the cumulative calculation, must be greater
1325+ * @param rate - The interest rate.
1326+ * @param numberOfPeriods - The number of payments to be made.
1327+ * @param presentValue - The current value of the annuity.
1328+ * @param firstPeriod - The number of the payment period to begin the cumulative calculation, must be greater
1329  * than or equal to 1.
1330- * @param values[4] last_period - The number of the payment period to end the cumulative calculation, must be greater
1331+ * @param lastPeriod - The number of the payment period to end the cumulative calculation, must be greater
1332  * than first_period.
1333- * @param values[5] end_or_beginning - Whether payments are due at the end (0) or beginning (1) of each period.
1334+ * @param endOrBeginning - Whether payments are due at the end (0) or beginning (1) of each period.
1335  * @returns {number} cumulative interest
1336  * @constructor
1337  */
1338-var CUMIPMT = function (...values) : number {
1339-  ArgsChecker.checkLength(values, 6, "CUMIPMT");
1340-  var rate = TypeConverter.firstValueAsNumber(values[0]);
1341-  var periods = TypeConverter.firstValueAsNumber(values[1]);
1342-  var value = TypeConverter.firstValueAsNumber(values[2]);
1343-  var start = TypeConverter.firstValueAsNumber(values[3]);
1344+var CUMIPMT = function (rate, numberOfPeriods, presentValue, firstPeriod, lastPeriod, endOrBeginning) : number {
1345+  ArgsChecker.checkLength(arguments, 6, "CUMIPMT");
1346+  rate = TypeConverter.firstValueAsNumber(rate);
1347+  var periods = TypeConverter.firstValueAsNumber(numberOfPeriods);
1348+  var value = TypeConverter.firstValueAsNumber(presentValue);
1349+  var start = TypeConverter.firstValueAsNumber(firstPeriod);
1350   if (start < 1) {
1351     throw new NumError("Function CUMPRINC parameter 4 value is " + start + ". It should be greater than or equal to 1.");
1352   }
1353-  var end = TypeConverter.firstValueAsNumber(values[4]);
1354+  var end = TypeConverter.firstValueAsNumber(lastPeriod);
1355   if (end < 1) {
1356     throw new NumError("Function CUMPRINC parameter 5 value is " + end + ". It should be greater than or equal to 1.");
1357   }
1358   if (end < start) {
1359     throw new NumError("Function CUMPRINC parameter 5 value is " + end + ". It should be greater than or equal to " + start + ".");
1360   }
1361-  var type = TypeConverter.firstValueAsBoolean(values[5]);
1362+  var type = TypeConverter.firstValueAsBoolean(endOrBeginning);
1363 
1364   var payment = PMT(rate, periods, value, 0, type);
1365   var interest = 0;
1366@@ -388,45 +388,47 @@ var CUMIPMT = function (...values) : number {
1367  * * https://quant.stackexchange.com/questions/7040/whats-the-algorithm-behind-excels-accrint
1368  *
1369  * * https://support.google.com/docs/answer/3093200
1370- * @param values[0] issue - The date the security was initially issued.
1371- * @param values[1] first_payment - The first date interest will be paid.
1372- * @param values[2] settlement - The settlement date of the security, the date after issuance when the security is
1373+ * @param issue - The date the security was initially issued.
1374+ * @param firstPayment - The first date interest will be paid.
1375+ * @param settlement - The settlement date of the security, the date after issuance when the security is
1376  * delivered to the buyer. Is the maturity date of the security if it is held until maturity rather than sold.
1377- * @param values[3] rate - The annualized rate of interest.
1378- * @param values[4] redemption - The redemption amount per 100 face value, or par.
1379- * @param values[5] frequency - The number of coupon payments per year. For annual payments, frequency = 1; for
1380+ * @param rate - The annualized rate of interest.
1381+ * @param redemption - The redemption amount per 100 face value, or par.
1382+ * @param frequency - The number of coupon payments per year. For annual payments, frequency = 1; for
1383  * semiannual, frequency = 2; for quarterly, frequency = 4.
1384- * @param values[6] day_count_convention - [ OPTIONAL - 0 by default ] - An indicator of what day count method to use.
1385+ * @param dayCountConvention - [ OPTIONAL - 0 by default ] - An indicator of what day count method to use.
1386  * 0 or omitted = US (NASD) 30/360, 1 = Actual/actual, 2 = Actual/360, 3 = Actual/365, 4 = European 30/360.
1387  * @returns {number}
1388  * @constructor
1389  * TODO: This function is based off of the open-source versions I was able to dig up online. We should implement a
1390  * TODO:     second version that is closer to what MSExcel does and is named something like `ACCRINT.MS`.
1391  */
1392-var ACCRINT = function (...values) {
1393-  ArgsChecker.checkLengthWithin(values, 6, 7, "ACCRINT");
1394-  var issue = TypeConverter.firstValueAsDateNumber(values[0]);
1395+var ACCRINT = function (issue, firstPayment, settlement, rate, redemption, frequency, dayCountConvention?) {
1396+  ArgsChecker.checkLengthWithin(arguments, 6, 7, "ACCRINT");
1397+  issue = TypeConverter.firstValueAsDateNumber(issue);
1398   // "firstPayment" param is only here to check for errors for GS implementation.
1399   // In MSE, there is a 7th (zero-indexed-6th) param that indicates the calculation-method to use, which indicates
1400   // weather the total accrued interest starting at the first_intrest date, instead of the issue date.
1401-  var firstPayment = TypeConverter.firstValueAsDateNumber(values[1]);
1402+  firstPayment = TypeConverter.firstValueAsDateNumber(firstPayment);
1403   if (firstPayment < 0) {
1404     throw new NumError("Function ACCRINT parameter 2 value is " + firstPayment
1405         + ". It should be greater than 0.");
1406   }
1407-  var settlement = TypeConverter.firstValueAsDateNumber(values[2]);
1408+  settlement = TypeConverter.firstValueAsDateNumber(settlement);
1409   if (issue > settlement) {
1410     throw new NumError("Function ACCRINT parameter 1 (" + issue.toString()
1411       + ") should be on or before Function ACCRINT parameter 3 (" + settlement.toString() + ").")
1412   }
1413-  var rate = TypeConverter.firstValueAsNumber(values[3]);
1414-  var redemption = TypeConverter.firstValueAsNumber(values[4]);// "par"
1415+  rate = TypeConverter.firstValueAsNumber(rate);
1416+  // redemption, aka "par"
1417+  redemption = TypeConverter.firstValueAsNumber(redemption);
1418   // The frequency parameter also does not affect the resulting value of the formula in the GS implementation.
1419   // In MSE, frequency is used to calculate a more accurate value, by breaking apart the year, and computing interest
1420   // on an on-going basis. In this implementation, we use YEARFRAC to get a numerical value that encompasses the
1421   // functionality of "frequency".
1422-  var frequency = TypeConverter.firstValueAsNumber(values[5]);
1423-  var dayCountConvention = values.length === 7 ? TypeConverter.firstValueAsNumber(values[6]) : 1;// "basis"
1424+  frequency = TypeConverter.firstValueAsNumber(frequency);
1425+  // dayCountConvention, aka "basis"
1426+  dayCountConvention = dayCountConvention !== undefined ? TypeConverter.firstValueAsNumber(dayCountConvention) : 1;
1427   var factor = YEARFRAC(issue, settlement, dayCountConvention);
1428   return redemption * rate * factor;
1429 };
1430diff --git a/src/Formulas/Logical.ts b/src/Formulas/Logical.ts
1431index 479b596..38aec2b 100644
1432--- a/src/Formulas/Logical.ts
1433+++ b/src/Formulas/Logical.ts
1434@@ -39,15 +39,15 @@ var AND = function (...values) {
1435 
1436 /**
1437  * Tests whether two strings are identical, returning true if they are.
1438- * @param values[0] The first string to compare
1439- * @param values[1] The second string to compare
1440+ * @param one - The first string to compare
1441+ * @param two - The second string to compare
1442  * @returns {boolean}
1443  * @constructor
1444  */
1445-var EXACT = function (...values) {
1446-  ArgsChecker.checkLength(values, 2, "EXACT");
1447-  var one = TypeConverter.firstValue(values[0]);
1448-  var two = TypeConverter.firstValue(values[1]);
1449+var EXACT = function (one, two) {
1450+  ArgsChecker.checkLength(arguments, 2, "EXACT");
1451+  one = TypeConverter.firstValue(one);
1452+  two = TypeConverter.firstValue(two);
1453   return one.toString() === two.toString();
1454 };
1455 
1456@@ -73,31 +73,30 @@ var FALSE = function () : boolean {
1457 
1458 /**
1459  * Returns the opposite of a logical value - NOT(TRUE) returns FALSE; NOT(FALSE) returns TRUE.
1460- * @param values[0] An expression or reference to a cell holding an expression that represents some logical value.
1461+ * @param value - An expression or reference to a cell holding an expression that represents some logical value.
1462  * @returns {boolean} opposite of a logical value input
1463  * @constructor
1464  */
1465-var NOT = function (...values) : boolean {
1466-  ArgsChecker.checkLength(values, 1, "NOT");
1467-  var X = values[0];
1468-  if (typeof(X) === "boolean") {
1469-    return !X;
1470+var NOT = function (value) : boolean {
1471+  ArgsChecker.checkLength(arguments, 1, "NOT");
1472+  if (typeof(value) === "boolean") {
1473+    return !value;
1474   }
1475-  if (typeof(X) === "string") {
1476-    if (X === "") {
1477+  if (typeof(value) === "string") {
1478+    if (value === "") {
1479       return true;
1480     }
1481-    throw new ValueError("Function NOT parameter 1 expects boolean values. But '" + X
1482+    throw new ValueError("Function NOT parameter 1 expects boolean values. But '" + value
1483         + "' is a text and cannot be coerced to a boolean.")
1484   }
1485-  if (typeof(X) === "number") {
1486-    return X === 0;
1487+  if (typeof(value) === "number") {
1488+    return value === 0;
1489   }
1490-  if (X instanceof Array) {
1491-    if (X.length === 0) {
1492+  if (value instanceof Array) {
1493+    if (value.length === 0) {
1494       throw new RefError("Reference does not exist.");
1495     }
1496-    return NOT(X[0]);
1497+    return NOT(value[0]);
1498   }
1499 };
1500 
1501diff --git a/src/Formulas/Math.ts b/src/Formulas/Math.ts
1502index 91deaaf..3528743 100644
1503--- a/src/Formulas/Math.ts
1504+++ b/src/Formulas/Math.ts
1505@@ -23,13 +23,13 @@ import {
1506 
1507 /**
1508  * Returns the absolute value of a number.
1509- * @param values[0] to get the absolute value of.
1510+ * @param value to get the absolute value of.
1511  * @returns {number} absolute value
1512  * @constructor
1513  */
1514-var ABS = function (...values) {
1515-  ArgsChecker.checkLength(values, 1, "ABS");
1516-  var v = TypeConverter.valueToNumber(values[0]);
1517+var ABS = function (value) {
1518+  ArgsChecker.checkLength(arguments, 1, "ABS");
1519+  var v = TypeConverter.valueToNumber(value);
1520   return Math.abs(v);
1521 };
1522 
1523@@ -39,7 +39,7 @@ var ABS = function (...values) {
1524  * @returns {number} inverse cosine of value
1525  * @constructor
1526  */
1527-var ACOS = function (value?) {
1528+var ACOS = function (value) {
1529   ArgsChecker.checkLength(arguments, 1, "ACOS");
1530   value = TypeConverter.valueToNumber(value);
1531   if (value === -1) {
1532@@ -56,7 +56,7 @@ var ACOS = function (value?) {
1533  * @returns {number} to find the inverse hyperbolic cosine for.
1534  * @constructor
1535  */
1536-var ACOSH = function (value?) {
1537+var ACOSH = function (value) {
1538   ArgsChecker.checkLength(arguments, 1, "ACOSH");
1539   value = TypeConverter.valueToNumber(value);
1540   if (value < 1) {
1541@@ -71,7 +71,7 @@ var ACOSH = function (value?) {
1542  * @returns {number} hyperbolic arc-cotangent
1543  * @constructor
1544  */
1545-var ACOTH = function (value?) {
1546+var ACOTH = function (value) {
1547   ArgsChecker.checkLength(arguments, 1, "ACOTH");
1548   value = TypeConverter.valueToNumber(value);
1549   if (value <= 1 && value >= -1) {
1550@@ -86,7 +86,7 @@ var ACOTH = function (value?) {
1551  * @returns {number} inverse sine of input value
1552  * @constructor
1553  */
1554-var ASIN = function (value?) {
1555+var ASIN = function (value) {
1556   ArgsChecker.checkLength(arguments, 1, "ASIN");
1557   value = TypeConverter.valueToNumber(value);
1558   if (value === -1) {
1559@@ -103,7 +103,7 @@ var ASIN = function (value?) {
1560  * @returns {number} inverse hyperbolic sine of input
1561  * @constructor
1562  */
1563-var ASINH = function (value?) {
1564+var ASINH = function (value) {
1565   ArgsChecker.checkLength(arguments, 1, "ASINH");
1566   value = TypeConverter.valueToNumber(value);
1567   return Math.log(value + Math.sqrt(value * value + 1));
1568@@ -116,7 +116,7 @@ var ASINH = function (value?) {
1569  * @returns {number} inverse tangent of input value
1570  * @constructor
1571  */
1572-var ATAN = function (value?) {
1573+var ATAN = function (value) {
1574   ArgsChecker.checkLength(arguments, 1, "ATAN");
1575   value = TypeConverter.valueToNumber(value);
1576   if (value === -1) {
1577@@ -152,7 +152,7 @@ var ATAN2 = function (x, y) {
1578  * @returns {number} inverse hyperbolic tangent of input
1579  * @constructor
1580  */
1581-var ATANH = function (value?) : number {
1582+var ATANH = function (value) : number {
1583   ArgsChecker.checkLength(arguments, 1, "ATANH");
1584   value = TypeConverter.valueToNumber(value);
1585   if (value >= 1 || value <= -1) {
1586@@ -166,33 +166,27 @@ var ATANH = function (value?) : number {
1587 
1588 /**
1589  * Rounds a number up to the nearest even integer.
1590- * @param values[0] The value to round to the next greatest even number.
1591+ * @param value The value to round to the next greatest even number.
1592  * @returns {number} next greatest even number
1593  * @constructor
1594  */
1595-var EVEN = function (...values) : number {
1596-  ArgsChecker.checkLength(values, 1, "EVEN");
1597-  if (values[0] instanceof Array) {
1598-    if (values[0].length === 0) {
1599-      throw new RefError("Reference does not exist.");
1600-    }
1601-    return EVEN(values[0][0]);
1602-  }
1603-  var X = TypeConverter.valueToNumber(values[0]);
1604+var EVEN = function (value) : number {
1605+  ArgsChecker.checkLength(arguments, 1, "EVEN");
1606+  var X = TypeConverter.firstValueAsNumber(value);
1607   return X % 2 === 1 ? X + 1 : X;
1608 };
1609 
1610 /**
1611  * Returns the result of the modulo operator, the remainder after a division operation.
1612- * @param values[0] The number to be divided to find the remainder.
1613- * @param values[1] The number to divide by.
1614+ * @param dividend The number to be divided to find the remainder.
1615+ * @param divisor The number to divide by.
1616  * @returns {number}
1617  * @constructor
1618  */
1619-var MOD = function (...values) : number {
1620-  ArgsChecker.checkLength(values, 2, "MOD");
1621-  var oneN = TypeConverter.valueToNumber(values[0]);
1622-  var twoN =  TypeConverter.valueToNumber(values[1]);
1623+var MOD = function (dividend, divisor) : number {
1624+  ArgsChecker.checkLength(arguments, 2, "MOD");
1625+  var oneN = TypeConverter.valueToNumber(dividend);
1626+  var twoN =  TypeConverter.valueToNumber(divisor);
1627   if (twoN === 0) {
1628     throw new DivZeroError("Function MOD parameter 2 cannot be zero.");
1629   }
1630@@ -202,33 +196,27 @@ var MOD = function (...values) : number {
1631 
1632 /**
1633  * Rounds a number up to the nearest odd integer.
1634- * @param values[0] The value to round to the next greatest odd number.
1635+ * @param value The value to round to the next greatest odd number.
1636  * @returns {number} value to round up to next greatest odd number.
1637  * @constructor
1638  */
1639-var ODD = function (...values) : number {
1640-  ArgsChecker.checkLength(values, 1, "ODD");
1641-  if (values[0] instanceof Array) {
1642-    if (values[0].length === 0) {
1643-      throw new RefError("Reference does not exist.");
1644-    }
1645-    return ODD(values[0][0]);
1646-  }
1647-  var X = TypeConverter.valueToNumber(values[0]);
1648+var ODD = function (value) : number {
1649+  ArgsChecker.checkLength(arguments, 1, "ODD");
1650+  var X = TypeConverter.firstValueAsNumber(value);
1651   return X % 2 === 1 ? X : X + 1;
1652 };
1653 
1654 /**
1655  * Returns a number raised to a power.
1656- * @param values[0] The number to raise to the exponent power.
1657- * @param values[1] The exponent to raise base to.
1658+ * @param base - The number to raise to the exponent power.
1659+ * @param exponent - The exponent to raise base to.
1660  * @returns {number} resulting number
1661  * @constructor
1662  */
1663-var POWER = function (...values) : number {
1664-  ArgsChecker.checkLength(values, 2, "POWER");
1665-  var n = TypeConverter.firstValueAsNumber(values[0]);
1666-  var p = TypeConverter.firstValueAsNumber(values[1]);
1667+var POWER = function (base, exponent) : number {
1668+  ArgsChecker.checkLength(arguments, 2, "POWER");
1669+  var n = TypeConverter.firstValueAsNumber(base);
1670+  var p = TypeConverter.firstValueAsNumber(exponent);
1671   return Math.pow(n, p);
1672 };
1673 
1674@@ -256,28 +244,28 @@ var SUM = function (...values) : number {
1675 
1676 /**
1677  * Returns the positive square root of a positive number.
1678- * @param values[0] The number for which to calculate the positive square root.
1679+ * @param value - The number for which to calculate the positive square root.
1680  * @returns {number} square root
1681  * @constructor
1682  */
1683-var SQRT = function (...values) : number {
1684-  ArgsChecker.checkLength(values, 1, "SQRT");
1685-  var x = TypeConverter.firstValueAsNumber(values[0]);
1686+var SQRT = function (value) : number {
1687+  ArgsChecker.checkLength(arguments, 1, "SQRT");
1688+  var x = TypeConverter.firstValueAsNumber(value);
1689   if (x < 0) {
1690-    throw new ValueError("Function SQRT parameter 1 expects number values. But '" + values[0] + "' is a text and cannot be coerced to a number.");
1691+    throw new ValueError("Function SQRT parameter 1 value is " + x + ". It should be greater than or equal to 0.");
1692   }
1693   return Math.sqrt(x);
1694 };
1695 
1696 /**
1697  * Returns the positive square root of the product of Pi and the given positive number.
1698- * @param values[0] value - The number which will be multiplied by Pi and have the product's square root returned
1699+ * @param value - The number which will be multiplied by Pi and have the product's square root returned
1700  * @returns {number} the positive square root of the product of Pi and the given positive number.
1701  * @constructor
1702  */
1703-var SQRTPI = function (...values) : number{
1704-  ArgsChecker.checkLength(values, 1, "SQRTPI");
1705-  var n = TypeConverter.firstValueAsNumber(values[0]);
1706+var SQRTPI = function (value) : number{
1707+  ArgsChecker.checkLength(arguments, 1, "SQRTPI");
1708+  var n = TypeConverter.firstValueAsNumber(value);
1709   if (n < 0) {
1710     throw new NumError("Function SQRTPI parameter 1 value is " + n + ". It should be greater than or equal to 0.");
1711   }
1712@@ -286,37 +274,37 @@ var SQRTPI = function (...values) : number{
1713 
1714 /**
1715  * Returns the cosine of an angle provided in radians.
1716- * @param values[0] The angle to find the cosine of, in radians.
1717+ * @param value - The angle to find the cosine of, in radians.
1718  * @returns {number} cosine of angle
1719  * @constructor
1720  */
1721-var COS = function (...values) : number {
1722-  ArgsChecker.checkLength(values, 1, "COS");
1723-  var r = TypeConverter.firstValueAsNumber(values[0]);
1724+var COS = function (value) : number {
1725+  ArgsChecker.checkLength(arguments, 1, "COS");
1726+  var r = TypeConverter.firstValueAsNumber(value);
1727   return Math.cos(r);
1728 };
1729 
1730 /**
1731  * Returns the hyperbolic cosine of any real number.
1732- * @param values[0] Any real value to calculate the hyperbolic cosine of.
1733+ * @param value - Any real value to calculate the hyperbolic cosine of.
1734  * @returns {number} the hyperbolic cosine of the input
1735  * @constructor
1736  */
1737-var COSH = function (...values) : number {
1738-  ArgsChecker.checkLength(values, 1, "COSH");
1739-  var r = TypeConverter.firstValueAsNumber(values[0]);
1740+var COSH = function (value) : number {
1741+  ArgsChecker.checkLength(arguments, 1, "COSH");
1742+  var r = TypeConverter.firstValueAsNumber(value);
1743   return Math["cosh"](r);
1744 };
1745 
1746 /**
1747  * Returns the cotangent of any real number. Defined as cot(x) = 1 / tan(x).
1748- * @param values[0] number to calculate the cotangent for
1749+ * @param value - number to calculate the cotangent for
1750  * @returns {number} cotangent
1751  * @constructor
1752  */
1753-var COT = function (...values) : number {
1754-  ArgsChecker.checkLength(values, 1, "COT");
1755-  var x = TypeConverter.firstValueAsNumber(values[0]);
1756+var COT = function (value) : number {
1757+  ArgsChecker.checkLength(arguments, 1, "COT");
1758+  var x = TypeConverter.firstValueAsNumber(value);
1759   if (x === 0) {
1760     throw new DivZeroError("Evaluation of function COT caused a divide by zero error.");
1761   }
1762@@ -325,13 +313,13 @@ var COT = function (...values) : number {
1763 
1764 /**
1765  * Return the hyperbolic cotangent of a value, defined as coth(x) = 1 / tanh(x).
1766- * @param values[0] value to calculate the hyperbolic cotangent value of
1767+ * @param value - value to calculate the hyperbolic cotangent value of
1768  * @returns {number} hyperbolic cotangent
1769  * @constructor
1770  */
1771-var COTH = function (...values) : number {
1772-  ArgsChecker.checkLength(values, 1, "COTH");
1773-  var x = TypeConverter.firstValueAsNumber(values[0]);
1774+var COTH = function (value) : number {
1775+  ArgsChecker.checkLength(arguments, 1, "COTH");
1776+  var x = TypeConverter.firstValueAsNumber(value);
1777   if (x === 0) {
1778     throw new DivZeroError("Evaluation of function COTH caused a divide by zero error.");
1779   }
1780@@ -340,69 +328,69 @@ var COTH = function (...values) : number {
1781 
1782 /**
1783  * Rounds a number down to the nearest integer that is less than or equal to it.
1784- * @param values[0] The value to round down to the nearest integer.
1785+ * @param value -  The value to round down to the nearest integer.
1786  * @returns {number} Rounded number
1787  * @constructor
1788  */
1789-var INT = function (...values) : number {
1790-  ArgsChecker.checkLength(values, 1, "INT");
1791-  var x = TypeConverter.firstValueAsNumber(values[0]);
1792+var INT = function (value) : number {
1793+  ArgsChecker.checkLength(arguments, 1, "INT");
1794+  var x = TypeConverter.firstValueAsNumber(value);
1795   return Math.floor(x);
1796 };
1797 
1798 
1799 /**
1800  * Checks whether the provided value is even.
1801- * @param values[0] The value to be verified as even.
1802+ * @param value - The value to be verified as even.
1803  * @returns {boolean} whether this value is even or not
1804  * @constructor
1805  */
1806-var ISEVEN = function (...values) : boolean {
1807-  ArgsChecker.checkLength(values, 1, "ISEVEN");
1808-  if (values[0] === "") {
1809-    throw new ValueError("Function ISEVEN parameter 1 expects boolean values. But '" + values[0] + "' is a text and cannot be coerced to a boolean.");
1810+var ISEVEN = function (value) : boolean {
1811+  ArgsChecker.checkLength(arguments, 1, "ISEVEN");
1812+  if (value === "") {
1813+    throw new ValueError("Function ISEVEN parameter 1 expects boolean values. But '" + value + "' is a text and cannot be coerced to a boolean.");
1814   }
1815-  var x = TypeConverter.firstValueAsNumber(values[0]);
1816+  var x = TypeConverter.firstValueAsNumber(value);
1817   return Math.floor(x) % 2 === 0;
1818 };
1819 
1820 
1821 /**
1822  * Checks whether the provided value is odd.
1823- * @param values[0] The value to be verified as odd.
1824+ * @param value - The value to be verified as odd.
1825  * @returns {boolean} whether this value is odd or not
1826  * @constructor
1827  */
1828-var ISODD = function (...values) : boolean {
1829-  ArgsChecker.checkLength(values, 1, "ISODD");
1830-  if (values[0] === "") {
1831-    throw new ValueError("Function ISODD parameter 1 expects boolean values. But '" + values[0] + "' is a text and cannot be coerced to a boolean.");
1832+var ISODD = function (value) : boolean {
1833+  ArgsChecker.checkLength(arguments, 1, "ISODD");
1834+  if (value === "") {
1835+    throw new ValueError("Function ISODD parameter 1 expects boolean values. But '" + value + "' is a text and cannot be coerced to a boolean.");
1836   }
1837-  var x = TypeConverter.firstValueAsNumber(values[0]);
1838+  var x = TypeConverter.firstValueAsNumber(value);
1839   return Math.floor(x) % 2 === 1;
1840 };
1841 
1842 /**
1843  * Returns the sine of an angle provided in radians.
1844- * @param values[0] The angle to find the sine of, in radians.
1845+ * @param value - The angle to find the sine of, in radians.
1846  * @returns {number} Sine of angle.
1847  * @constructor
1848  */
1849-var SIN = function (...values) {
1850-  ArgsChecker.checkLength(values, 1, "SIN");
1851-  var rad = TypeConverter.firstValueAsNumber(values[0]);
1852+var SIN = function (value) {
1853+  ArgsChecker.checkLength(arguments, 1, "SIN");
1854+  var rad = TypeConverter.firstValueAsNumber(value);
1855   return rad === Math.PI ? 0 : Math.sin(rad);
1856 };
1857 
1858 /**
1859  * Returns the hyperbolic sine of any real number.
1860- * @param values[0] real number to find the hyperbolic sine of
1861+ * @param value - real number to find the hyperbolic sine of
1862  * @returns {number} hyperbolic sine
1863  * @constructor
1864  */
1865-var SINH = function (...values) : number {
1866-  ArgsChecker.checkLength(values, 1, "SINH");
1867-  var rad = TypeConverter.firstValueAsNumber(values[0]);
1868+var SINH = function (value) : number {
1869+  ArgsChecker.checkLength(arguments, 1, "SINH");
1870+  var rad = TypeConverter.firstValueAsNumber(value);
1871   return Math["sinh"](rad);
1872 };
1873 
1874@@ -418,13 +406,13 @@ var PI = function () {
1875 
1876 /**
1877  * Returns the the logarithm of a number, base 10.
1878- * @param values[0] The value for which to calculate the logarithm, base 10.
1879+ * @param value - The value for which to calculate the logarithm, base 10.
1880  * @returns {number} logarithm of the number, in base 10.
1881  * @constructor
1882  */
1883-var LOG10 = function (...values) : number {
1884-  ArgsChecker.checkLength(values, 1, "LOG10");
1885-  var n = TypeConverter.firstValueAsNumber(values[0]);
1886+var LOG10 = function (value) : number {
1887+  ArgsChecker.checkLength(arguments, 1, "LOG10");
1888+  var n = TypeConverter.firstValueAsNumber(value);
1889   if (n < 1) {
1890     throw new NumError("Function LOG10 parameter 1 value is " + n + ". It should be greater than 0.");
1891   }
1892@@ -435,20 +423,17 @@ var LOG10 = function (...values) : number {
1893 
1894 /**
1895  * Returns the the logarithm of a number given a base.
1896- * @param values[0] The value for which to calculate the logarithm given base.
1897- * @param values[1] The base to use for calculation of the logarithm. Defaults to 10.
1898+ * @param value - The value for which to calculate the logarithm given base.
1899+ * @param base - The base to use for calculation of the logarithm. Defaults to 10.
1900  * @returns {number}
1901  * @constructor
1902  */
1903-var LOG = function (...values) : number {
1904-  ArgsChecker.checkAtLeastLength(values, 1, "LOG");
1905-  var n = TypeConverter.firstValueAsNumber(values[0]);
1906-  var b = 10;
1907-  if (values.length > 1) {
1908-    b = TypeConverter.firstValueAsNumber(values[1]);
1909-    if (b < 1) {
1910-      throw new NumError("Function LOG parameter 2 value is " + b + ". It should be greater than 0.");
1911-    }
1912+var LOG = function (value, base) : number {
1913+  ArgsChecker.checkAtLeastLength(arguments, 2, "LOG");
1914+  var n = TypeConverter.firstValueAsNumber(value);
1915+  var b = TypeConverter.firstValueAsNumber(base);
1916+  if (b < 1) {
1917+    throw new NumError("Function LOG parameter 2 value is " + b + ". It should be greater than 0.");
1918   }
1919   if (b < 2) {
1920     throw new DivZeroError("Evaluation of function LOG caused a divide by zero error.");
1921@@ -463,13 +448,13 @@ var LOG = function (...values) : number {
1922 
1923 /**
1924  * Returns the logarithm of a number, base e (Euler's number).
1925- * @param values[0] The value for which to calculate the logarithm, base e.
1926+ * @param value - The value for which to calculate the logarithm, base e.
1927  * @returns {number} logarithm calculated
1928  * @constructor
1929  */
1930-var LN = function (...values) : number {
1931-  ArgsChecker.checkLength(values, 1, "LN");
1932-  var n = TypeConverter.firstValueAsNumber(values[0]);
1933+var LN = function (value) : number {
1934+  ArgsChecker.checkLength(arguments, 1, "LN");
1935+  var n = TypeConverter.firstValueAsNumber(value);
1936   if (n < 1) {
1937     throw new NumError("Function LN parameter 1 value is " + n + ". It should be greater than 0.");
1938   }
1939@@ -478,42 +463,42 @@ var LN = function (...values) : number {
1940 
1941 /**
1942  * Returns the tangent of an angle provided in radians.
1943- * @param values The angle to find the tangent of, in radians.
1944+ * @param value - The angle to find the tangent of, in radians.
1945  * @returns {number} tangent in radians
1946  * @constructor
1947  */
1948-var TAN = function (...values) : number {
1949-  ArgsChecker.checkLength(values, 1, "TAN");
1950-  var rad = TypeConverter.firstValueAsNumber(values[0]);
1951+var TAN = function (value) : number {
1952+  ArgsChecker.checkLength(arguments, 1, "TAN");
1953+  var rad = TypeConverter.firstValueAsNumber(value);
1954   return rad === Math.PI ? 0 : Math.tan(rad);
1955 };
1956 
1957 /**
1958  * Returns the hyperbolic tangent of any real number.
1959- * @param values[0] Any real value to calculate the hyperbolic tangent of.
1960+ * @param value - Any real value to calculate the hyperbolic tangent of.
1961  * @returns {number} hyperbolic tangent
1962  * @constructor
1963  */
1964-var TANH = function (...values) : number {
1965-  ArgsChecker.checkLength(values, 1, "TANH");
1966-  var rad = TypeConverter.firstValueAsNumber(values[0]);
1967+var TANH = function (value) : number {
1968+  ArgsChecker.checkLength(arguments, 1, "TANH");
1969+  var rad = TypeConverter.firstValueAsNumber(value);
1970   return Math["tanh"](rad);
1971 };
1972 
1973 /**
1974  * Rounds a number up to the nearest integer multiple of specified significance.
1975- * @param values[0] The value to round up to the nearest integer multiple of factor.
1976- * @param values[1] The number to whose multiples value will be rounded.
1977+ * @param value The value to round up to the nearest integer multiple of factor.
1978+ * @param factor - [ OPTIONAL ] The number to whose multiples value will be rounded.
1979  * @returns {number}
1980  * @constructor
1981  */
1982-var CEILING = function (...values) : number {
1983-  ArgsChecker.checkLengthWithin(values, 1, 2, "CEILING");
1984-  var num = TypeConverter.firstValueAsNumber(values[0]);
1985-  if (values.length === 1) {
1986+var CEILING = function (value, factor?) : number {
1987+  ArgsChecker.checkLengthWithin(arguments, 1, 2, "CEILING");
1988+  var num = TypeConverter.firstValueAsNumber(value);
1989+  if (factor === undefined) {
1990     return Math.ceil(num);
1991   }
1992-  var significance = TypeConverter.firstValueAsNumber(values[1]);
1993+  var significance = TypeConverter.firstValueAsNumber(factor);
1994   if (significance === 0) {
1995     throw new DivZeroError("Function CEILING parameter 2 cannot be zero.");
1996   }
1997@@ -527,18 +512,18 @@ var CEILING = function (...values) : number {
1998 
1999 /**
2000  * Rounds a number down to the nearest integer multiple of specified significance.
2001- * @param values[0] The value to round down to the nearest integer multiple of factor.
2002- * @param values[1] The number to whose multiples value will be rounded.
2003+ * @param value - The value to round down to the nearest integer multiple of factor.
2004+ * @param factor - The number to whose multiples value will be rounded.
2005  * @returns {number}
2006  * @constructor
2007  */
2008-var FLOOR = function (...values) : number {
2009-  ArgsChecker.checkLengthWithin(values, 1, 2, "FLOOR");
2010-  var num = TypeConverter.firstValueAsNumber(values[0]);
2011-  if (values.length === 1) {
2012+var FLOOR = function (value, factor?) : number {
2013+  ArgsChecker.checkLengthWithin(arguments, 1, 2, "FLOOR");
2014+  var num = TypeConverter.firstValueAsNumber(value);
2015+  if (factor === undefined) {
2016     return Math.floor(num);
2017   }
2018-  var significance = TypeConverter.firstValueAsNumber(values[1]);
2019+  var significance = TypeConverter.firstValueAsNumber(factor);
2020   if (significance === 0) {
2021     throw new DivZeroError("Function FLOOR parameter 2 cannot be zero.");
2022   }
2023@@ -552,43 +537,41 @@ var FLOOR = function (...values) : number {
2024 
2025 /**
2026  * Returns one value if a logical expression is TRUE and another if it is FALSE.
2027- * @param values[0] An expression or reference to a cell containing an expression that represents some logical value, i.e. TRUE or FALSE.
2028- * @param values[1] The value the function returns if logical_expression is TRUE
2029- * @param values[2] The value the function returns if logical_expression is FALSE.
2030+ * @param logicalExpression - An expression or reference to a cell containing an expression that represents some logical value, i.e. TRUE or FALSE.
2031+ * @param valueIfTrue - The value the function returns if logical_expression is TRUE
2032+ * @param valueIfFalse - The value the function returns if logical_expression is FALSE.
2033  * @returns one value if a logical expression is TRUE and another if it is FALSE.
2034  * @constructor
2035  */
2036-var IF = function (...values) : any {
2037-  ArgsChecker.checkLength(values, 3, "IF");
2038-  if (values[0] instanceof Array) {
2039-    if (values[0].length === 0) {
2040+var IF = function (logicalExpression, valueIfTrue, valueIfFalse) : any {
2041+  ArgsChecker.checkLength(arguments, 3, "IF");
2042+  if (logicalExpression instanceof Array) {
2043+    if (logicalExpression.length === 0) {
2044       throw new RefError("Reference does not exist.");
2045     }
2046-    return IF(values[0][0], values[1], values[2]);
2047-  } else if (values[0] === "") {
2048-    return values[2];
2049+    return IF(logicalExpression[0], valueIfTrue, valueIfFalse);
2050+  } else if (logicalExpression === "") {
2051+    return valueIfFalse;
2052   }
2053-  return (TypeConverter.valueToBoolean(values[0])) ? values[1] : values[2];
2054+  return (TypeConverter.valueToBoolean(logicalExpression)) ? valueIfTrue : valueIfFalse;
2055 };
2056 
2057 
2058 /**
2059  * Returns a conditional count across a range.
2060- * @param values[0] range - The range that is tested against criterion., value[1];
2061- * @param values[1] criterion - The pattern or test to apply to range. If the range to check against contains text,
2062+ * @param range - The range that is tested against criterion., value[1];
2063+ * @param criteria - The pattern or test to apply to range. If the range to check against contains text,
2064  * this must be a string. It can be a comparison based string (e.g. "=1", "<1", ">=1") or it can be a wild-card string,
2065  * in which * matches any number of characters, and ? matches the next character. Both ? and * can be escaped by placing
2066  * a ~ in front of them. If it is neither, it will compared with values in the range using equality comparison.
2067  * @returns {number}
2068  * @constructor
2069  */
2070-var COUNTIF = function (...values) {
2071-  ArgsChecker.checkLength(values, 2, "COUNTIF");
2072-  var range = values[0];
2073+var COUNTIF = function (range, criteria) {
2074+  ArgsChecker.checkLength(arguments, 2, "COUNTIF");
2075   if (!(range instanceof Array)) {
2076     range = [range];
2077   }
2078-  var criteria = values[1];
2079   var criteriaEvaluation = CriteriaFunctionFactory.createCriteriaFunction(criteria);
2080 
2081   var count = 0;
2082@@ -656,74 +639,65 @@ var COUNTIFS = function (...values) {
2083 
2084 /**
2085  * Rounds a number to a certain number of decimal places according to standard rules.
2086- * @param values[0] The value to round to places number of places.
2087- * @param values[1] The number of decimal places to which to round.
2088+ * @param value - The value to round to places number of places.
2089+ * @param places - The number of decimal places to which to round.
2090  * @returns {number}
2091  * @constructor
2092  */
2093-var ROUND = function (...values) {
2094-  ArgsChecker.checkLengthWithin(values, 1, 2, "ROUND");
2095-  var n = TypeConverter.firstValueAsNumber(values[0]);
2096-  if (values.length === 1) {
2097-    return Math.round(n);
2098-  }
2099-  var d = TypeConverter.firstValueAsNumber(values[1]);
2100+var ROUND = function (value, places) {
2101+  ArgsChecker.checkLength(arguments, 2, "ROUND");
2102+  var n = TypeConverter.firstValueAsNumber(value);
2103+  var d = TypeConverter.firstValueAsNumber(places);
2104   return Math.round(n * Math.pow(10, d)) / Math.pow(10, d);
2105 };
2106 
2107 /**
2108  * Rounds a number to a certain number of decimal places, always rounding down to the next valid increment.
2109- * @param values[0] The value to round to places number of places, always rounding down.
2110- * @param values[1] (optional) The number of decimal places to which to round.
2111+ * @param value - The value to round to places number of places, always rounding down.
2112+ * @param places - (optional) The number of decimal places to which to round.
2113  * @returns {number}
2114  * @constructor
2115  */
2116-var ROUNDDOWN = function (...values) {
2117-  ArgsChecker.checkLengthWithin(values, 1, 2, "ROUNDDOWN");
2118-  var n = TypeConverter.firstValueAsNumber(values[0]);
2119-  if (values.length === 1) {
2120+var ROUNDDOWN = function (value, places?) {
2121+  ArgsChecker.checkLengthWithin(arguments, 1, 2, "ROUNDDOWN");
2122+  var n = TypeConverter.firstValueAsNumber(value);
2123+  if (places === undefined) {
2124     return Math.floor(n);
2125   }
2126-  var d = TypeConverter.firstValueAsNumber(values[1]);
2127+  var d = TypeConverter.firstValueAsNumber(places);
2128   return Math.floor(n * Math.pow(10, d)) / Math.pow(10, d);
2129 };
2130 
2131 /**
2132  * Rounds a number to a certain number of decimal places, always rounding up to the next valid increment.
2133- * @param values[0] The value to round to places number of places, always rounding up.
2134- * @param values[1] (optional) The number of decimal places to which to round.
2135+ * @param value - The value to round to places number of places, always rounding up.
2136+ * @param places - (optional) The number of decimal places to which to round.
2137  * @returns {number}
2138  * @constructor
2139  */
2140-var ROUNDUP = function (...values) {
2141-  ArgsChecker.checkLengthWithin(values, 1, 2, "ROUNDUP");
2142-  var n = TypeConverter.firstValueAsNumber(values[0]);
2143-  if (values.length === 1) {
2144+var ROUNDUP = function (value, places?) {
2145+  ArgsChecker.checkLengthWithin(arguments, 1, 2, "ROUNDUP");
2146+  var n = TypeConverter.firstValueAsNumber(value);
2147+  if (places === undefined) {
2148     return Math.ceil(n);
2149   }
2150-  var d = TypeConverter.firstValueAsNumber(values[1]);
2151+  var d = TypeConverter.firstValueAsNumber(places);
2152   return Math.ceil(n * Math.pow(10, d)) / Math.pow(10, d);
2153 };
2154 
2155 /**
2156  * Returns a conditional sum across a range.
2157- * @param values[0] The range which is tested against criterion.
2158- * @param values[1] The pattern or test to apply to range. If the range to check against contains text, this must be a
2159+ * @param range -  The range which is tested against criterion.
2160+ * @param criteria - The pattern or test to apply to range. If the range to check against contains text, this must be a
2161  * string. It can be a comparison based string (e.g. "=1", "<1", ">=1") or it can be a wild-card string, in which *
2162  * matches any number of characters, and ? matches the next character. Both ? and * can be escaped by placing a ~ in
2163  * front of them.
2164- * @param values[2] (optional) The range to be summed, if different from range.
2165+ * @param sumRange - (optional) The range to be summed, if different from range.
2166  * @returns {number}
2167  * @constructor
2168  */
2169-var SUMIF = function (...values) {
2170-  ArgsChecker.checkLengthWithin(values, 2, 3, "SUMIF");
2171-  var range = values[0];
2172-  var criteria = values[1];
2173-  var sumRange = null;
2174-  if (values.length === 3) {
2175-    sumRange = values[2];
2176-  }
2177+var SUMIF = function (range, criteria, sumRange?) {
2178+  ArgsChecker.checkLengthWithin(arguments, 2, 3, "SUMIF");
2179 
2180   var criteriaEvaluation = CriteriaFunctionFactory.createCriteriaFunction(criteria);
2181 
2182@@ -736,9 +710,9 @@ var SUMIF = function (...values) {
2183       if (sumRange && i > sumRange.length-1) {
2184         continue;
2185       }
2186-      if (values.length === 2 && TypeConverter.canCoerceToNumber(x) && criteriaEvaluation(x)) {
2187+      if (arguments.length === 2 && TypeConverter.canCoerceToNumber(x) && criteriaEvaluation(x)) {
2188         sum = sum + TypeConverter.valueToNumber(x);
2189-      } else if (values.length === 3 && TypeConverter.canCoerceToNumber(sumRange[i]) && criteriaEvaluation(x)) {
2190+      } else if (arguments.length === 3 && TypeConverter.canCoerceToNumber(sumRange[i]) && criteriaEvaluation(x)) {
2191         sum = sum + TypeConverter.valueToNumber(sumRange[i]);
2192       }
2193     }
2194@@ -772,8 +746,8 @@ var SUMSQ = function (...values) {
2195 
2196 /**
2197  * Truncates a number to a certain number of significant digits by omitting less significant digits.
2198- * @param values[0] The value to be truncated.
2199- * @param values[1]  [ OPTIONAL - 0 by default ] - The number of significant digits to the right of the decimal point to
2200+ * @param value - The value to be truncated.
2201+ * @param places - [ OPTIONAL - 0 by default ] - The number of significant digits to the right of the decimal point to
2202  * retain. If places is greater than the number of significant digits in value, value is returned without modification.
2203  * places may be negative, in which case the specified number of digits to the left of the decimal place are changed to
2204  * zero. All digits to the right of the decimal place are discarded. If all digits of value are changed to zero, TRUNC
2205@@ -781,12 +755,12 @@ var SUMSQ = function (...values) {
2206  * @returns {number} after truncation
2207  * @constructor
2208  */
2209-var TRUNC = function (...values) : number {
2210-  ArgsChecker.checkLengthWithin(values, 1, 2, "TRUNC");
2211-  var n = TypeConverter.firstValueAsNumber(values[0]);
2212+var TRUNC = function (value, places?) : number {
2213+  ArgsChecker.checkLengthWithin(arguments, 1, 2, "TRUNC");
2214+  var n = TypeConverter.firstValueAsNumber(value);
2215   var digits = 0;
2216-  if (values.length === 2) {
2217-    digits = TypeConverter.firstValueAsNumber(values[1]);
2218+  if (places !== undefined) {
2219+    digits = TypeConverter.firstValueAsNumber(places);
2220   }
2221   var sign = (n > 0) ? 1 : -1;
2222   return sign * (Math.floor(Math.abs(n) * Math.pow(10, digits))) / Math.pow(10, digits);
2223@@ -795,55 +769,55 @@ var TRUNC = function (...values) : number {
2224 
2225 /**
2226  * Converts an angle value in degrees to radians.
2227- * @param values[0] angle - The angle to convert from degrees to radians.
2228+ * @param angle - The angle to convert from degrees to radians.
2229  * @returns {number} radians
2230  * @constructor
2231  */
2232-var RADIANS = function (...values) {
2233-  ArgsChecker.checkLength(values, 1, "RADIANS");
2234-  var d = TypeConverter.firstValueAsNumber(values[0]);
2235+var RADIANS = function (angle) {
2236+  ArgsChecker.checkLength(arguments, 1, "RADIANS");
2237+  var d = TypeConverter.firstValueAsNumber(angle);
2238   return d * Math.PI / 180;
2239 };
2240 
2241 /**
2242  * Converts an angle value in radians to degrees.
2243- * @param values[0] angle - The angle to convert from radians to degrees.
2244+ * @param angle - The angle to convert from radians to degrees.
2245  * @returns {number} degrees
2246  * @constructor
2247  */
2248-var DEGREES = function (...values) {
2249-  ArgsChecker.checkLength(values, 1, "DEGREES");
2250-  var r = TypeConverter.firstValueAsNumber(values[0]);
2251+var DEGREES = function (angle) {
2252+  ArgsChecker.checkLength(arguments, 1, "DEGREES");
2253+  var r = TypeConverter.firstValueAsNumber(angle);
2254   return r * 180 / Math.PI;
2255 };
2256 
2257 
2258 /**
2259  * Returns the complementary Gauss error function of a value.
2260- * @param values[0] The number for which to calculate the complementary Gauss error function.
2261+ * @param value - The number for which to calculate the complementary Gauss error function.
2262  * @returns {number} complementary Gauss error function of a value
2263  * @constructor
2264  */
2265-var ERFC = function (...values) {
2266-  ArgsChecker.checkLength(values, 1, "ERFC");
2267-  var v = TypeConverter.firstValueAsNumber(values[0]);
2268+var ERFC = function (value) {
2269+  ArgsChecker.checkLength(arguments, 1, "ERFC");
2270+  var v = TypeConverter.firstValueAsNumber(value);
2271   return v === 0 ? 1 : 1 - erf(v);
2272 };
2273 
2274 
2275 /**
2276  * Returns the error function integrated between lower_limit and upper_limit.
2277- * @param values[0] lower_limit - The lower bound for integrating ERF.
2278- * @param values[1] upper_limit - [Optional]. The upper bound for integrating ERF. If omitted, ERF integrates between
2279+ * @param lowerLimit - The lower bound for integrating ERF.
2280+ * @param upperLimit - [Optional]. The upper bound for integrating ERF. If omitted, ERF integrates between
2281  * zero and lower_limit.
2282  * @returns {number} error function integrated between lower_limit and upper_limit
2283  * @constructor
2284  */
2285-var ERF = function (...values) : number {
2286-  ArgsChecker.checkLengthWithin(values, 1, 2, "ERF");
2287-  var lower = TypeConverter.firstValueAsNumber(values[0]);
2288-  var upper = values.length === 2 ? TypeConverter.firstValueAsNumber(values[1]) : 0;
2289-  return values.length === 1 ? erf(lower) : erf(upper) - erf(lower);
2290+var ERF = function (lowerLimit, upperLimit?) : number {
2291+  ArgsChecker.checkLengthWithin(arguments, 1, 2, "ERF");
2292+  var lower = TypeConverter.firstValueAsNumber(lowerLimit);
2293+  var upper = upperLimit !== undefined ? TypeConverter.firstValueAsNumber(upperLimit) : 0;
2294+  return upperLimit === undefined ? erf(lower) : erf(upper) - erf(lower);
2295 };
2296 
2297 
2298@@ -895,17 +869,17 @@ function erf(x) {
2299 
2300 /**
2301  * Calculates the sum of the sums of the squares of values in two arrays.
2302- * @param values[0] array_x - The array or range of values whose squares will be added to the squares of corresponding
2303- * entries in array_y and added together.
2304- * @param values[1] array_y - The array or range of values whose squares will be added to the squares of corresponding
2305- * entries in array_x and added together.
2306+ * @param arrayX - The array or range of values whose squares will be added to the squares of corresponding
2307+ * entries in arrayY and added together.
2308+ * @param arrayY - The array or range of values whose squares will be added to the squares of corresponding
2309+ * entries in arrayX and added together.
2310  * @returns {number} sum of the sums of the squares
2311  * @constructor
2312  */
2313-var SUMX2PY2 = function (...values) : number {
2314-  ArgsChecker.checkLength(values, 2, "SUMX2PY2");
2315-  var arrOne = Filter.flattenAndThrow(values[0]);
2316-  var arrTwo = Filter.flattenAndThrow(values[1]);
2317+var SUMX2PY2 = function (arrayX, arrayY) : number {
2318+  ArgsChecker.checkLength(arguments, 2, "SUMX2PY2");
2319+  var arrOne = Filter.flattenAndThrow(arrayX);
2320+  var arrTwo = Filter.flattenAndThrow(arrayY);
2321   if (arrOne.length !== arrTwo.length) {
2322     throw new NAError("Array arguments to SUMX2PY2 are of different size.");
2323   }
2324@@ -921,17 +895,17 @@ var SUMX2PY2 = function (...values) : number {
2325 
2326 /**
2327  * Calculates the sum of the differences of the squares of values in two arrays.
2328- * @param values[0] array_x - The array or range of values whose squares will be reduced by the squares of corresponding
2329+ * @param arrayX - The array or range of values whose squares will be reduced by the squares of corresponding
2330  * entries in array_y and added together.
2331- * @param values[1] array_y - The array or range of values whose squares will be subtracted from the squares of
2332+ * @param arrayY - The array or range of values whose squares will be subtracted from the squares of
2333  * corresponding entries in array_x and added together.
2334  * @returns {number} sum of the differences of the squares
2335  * @constructor
2336  */
2337-var SUMX2MY2 = function (...values) : number {
2338-  ArgsChecker.checkLength(values, 2, "SUMX2MY2");
2339-  var arrOne = Filter.flattenAndThrow(values[0]);
2340-  var arrTwo = Filter.flattenAndThrow(values[1]);
2341+var SUMX2MY2 = function (arrayX, arrayY) : number {
2342+  ArgsChecker.checkLength(arguments, 2, "SUMX2MY2");
2343+  var arrOne = Filter.flattenAndThrow(arrayX);
2344+  var arrTwo = Filter.flattenAndThrow(arrayY);
2345   if (arrOne.length !== arrTwo.length) {
2346     throw new NAError("Array arguments to SUMX2MY2 are of different size.");
2347   }
2348@@ -1022,13 +996,13 @@ var SUMPRODUCT = function (...values) : number {
2349 
2350 /**
2351  * Returns the number of ways to choose some number of objects from a pool of a given size of objects.
2352- * @param values[0] n - The size of the pool of objects to choose from.
2353- * @param values[1] k - The number of objects to choose.
2354+ * @param m - The size of the pool of objects to choose from.
2355+ * @param k - The number of objects to choose.
2356  * @returns {number} number of ways
2357  * @constructor
2358  */
2359-var COMBIN = function (...values) : number {
2360-  ArgsChecker.checkLength(values, 2, "COMBIN");
2361+var COMBIN = function (m, k) : number {
2362+  ArgsChecker.checkLength(arguments, 2, "COMBIN");
2363 
2364   var MEMOIZED_FACT = [];
2365   function fact(number) {
2366@@ -1042,8 +1016,8 @@ var COMBIN = function (...values) : number {
2367       return MEMOIZED_FACT[n];
2368     }
2369   }
2370-  var n = TypeConverter.firstValueAsNumber(values[0]);
2371-  var c = TypeConverter.firstValueAsNumber(values[1]);
2372+  var n = TypeConverter.firstValueAsNumber(m);
2373+  var c = TypeConverter.firstValueAsNumber(k);
2374   if (n < c) {
2375     throw new NumError("Function COMBIN parameter 2 value is "
2376       + c + ". It should be less than or equal to value of Function COMBIN parameter 1 with " + n + ".");
2377diff --git a/src/Formulas/Statistical.ts b/src/Formulas/Statistical.ts
2378index 840d42b..7e0a894 100644
2379--- a/src/Formulas/Statistical.ts
2380+++ b/src/Formulas/Statistical.ts
2381@@ -21,7 +21,7 @@ import {
2382 
2383 /**
2384  * Calculates the sum of squares of deviations based on a sample.
2385- * @param values The values or ranges of the sample.
2386+ * @param values - The values or ranges of the sample.
2387  * @returns {number} sum of squares of deviations
2388  * @constructor
2389  */
2390@@ -44,7 +44,7 @@ var DEVSQ = function (...values) : number {
2391 
2392 /**
2393  * Returns the median value in a numeric dataset.
2394- * @param values The value(s) or range(s) to consider when calculating the median value.
2395+ * @param values - The value(s) or range(s) to consider when calculating the median value.
2396  * @returns {number} the median value of the dataset
2397  * @constructor
2398  */
2399@@ -89,7 +89,7 @@ var MEDIAN = function (...values) : number {
2400 
2401 /**
2402  * Returns the numerical average value in a dataset, ignoring text.
2403- * @param values The values or ranges to consider when calculating the average value.
2404+ * @param values - The values or ranges to consider when calculating the average value.
2405  * @returns {number} the average value of this dataset.
2406  * @constructor
2407  */
2408@@ -115,7 +115,7 @@ var AVERAGE = function (...values) : number {
2409 
2410 /**
2411  * Calculates the average of the magnitudes of deviations of data from a dataset's mean.
2412- * @param values The value(s) or range(s)
2413+ * @param values - The value(s) or range(s)
2414  * @returns {number} average of the magnitudes of deviations of data from a dataset's mean
2415  * @constructor
2416  */
2417@@ -162,7 +162,7 @@ var AVEDEV = function (...values) {
2418 
2419 /**
2420  * Returns the numerical average value in a dataset, coercing text values in ranges to 0 values.
2421- * @param values value(s) or range(s) to consider when calculating the average value.
2422+ * @param values - value(s) or range(s) to consider when calculating the average value.
2423  * @returns {number} the numerical average value in a dataset
2424  * @constructor
2425  */
2426@@ -192,12 +192,12 @@ var AVERAGEA = function (...values) {
2427 /**
2428  * Calculates r, the Pearson product-moment correlation coefficient of a dataset. Any text encountered in the arguments
2429  * will be ignored. CORREL is synonymous with PEARSON.
2430- * @param values[0] data_y - The range representing the array or matrix of dependent data.
2431- * @param values[1] data_x - The range representing the array or matrix of independent data.
2432+ * @param dataY - The range representing the array or matrix of dependent data.
2433+ * @param dataX - The range representing the array or matrix of independent data.
2434  * @returns {number} the Pearson product-moment correlation coefficient.
2435  * @constructor
2436  */
2437-var CORREL = function (...values) : number {
2438+var CORREL = function (dataY, dataX) : number {
2439   /**
2440    * Return the standard deviation of a vector. By defaut, the population standard deviation is returned. Passing true
2441    * for the flag parameter returns the sample standard deviation. See http://jstat.github.io/vector.html#stdev for
2442@@ -272,18 +272,18 @@ var CORREL = function (...values) : number {
2443     }
2444     return sum(sq_dev) / (arr1Len - 1);
2445   }
2446-  ArgsChecker.checkLength(values, 2, "CORREL");
2447-  if (!Array.isArray(values[0])) {
2448-    values[0] = [values[0]];
2449+  ArgsChecker.checkLength(arguments, 2, "CORREL");
2450+  if (!Array.isArray(dataY)) {
2451+    dataY = [dataY];
2452   }
2453-  if (!Array.isArray(values[1])) {
2454-    values[1] = [values[1]];
2455+  if (!Array.isArray(dataX)) {
2456+    dataX = [dataX];
2457   }
2458-  if (values[0].length !== values[1].length) {
2459-    throw new NAError("CORREL has mismatched argument count " + values[0] + " vs " + values[1] + ".");
2460+  if (dataY.length !== dataX.length) {
2461+    throw new NAError("CORREL has mismatched argument count " + dataY + " vs " + dataX + ".");
2462   }
2463-  var arr1 = Filter.filterOutNonNumberValues(Filter.flattenAndThrow(values[0]));
2464-  var arr2 = Filter.filterOutNonNumberValues(Filter.flattenAndThrow(values[1]));
2465+  var arr1 = Filter.filterOutNonNumberValues(Filter.flattenAndThrow(dataY));
2466+  var arr2 = Filter.filterOutNonNumberValues(Filter.flattenAndThrow(dataX));
2467   var stdevArr1 = stdev(arr1, 1);
2468   var stdevArr2 = stdev(arr2, 1);
2469   if (stdevArr1 === 0 || stdevArr2 === 0) {
2470@@ -295,54 +295,54 @@ var CORREL = function (...values) : number {
2471 /**
2472  * Calculates r, the Pearson product-moment correlation coefficient of a dataset. Any text encountered in the arguments
2473  * will be ignored. PEARSON is synonymous with CORREL.
2474- * @param values[0] data_y - The range representing the array or matrix of dependent data.
2475- * @param values[1] data_x - The range representing the array or matrix of independent data.
2476+ * @param dataY - The range representing the array or matrix of dependent data.
2477+ * @param dataX - The range representing the array or matrix of independent data.
2478  * @returns {number} the Pearson product-moment correlation coefficient.
2479  * @constructor
2480  */
2481-var PEARSON = function (...values) {
2482-  ArgsChecker.checkLength(values, 2, "PEARSON");
2483-  return CORREL.apply(this, values);
2484+var PEARSON = function (dataY, dataX) {
2485+  ArgsChecker.checkLength(arguments, 2, "PEARSON");
2486+  return CORREL.apply(this, [dataY, dataX]);
2487 };
2488 
2489 /**
2490  * Returns the value of the exponential distribution function with a specified lambda at a specified value.
2491- * @param values[0] x - The input to the exponential distribution function. If cumulative is TRUE then EXPONDIST returns
2492+ * @param x - The input to the exponential distribution function. If cumulative is TRUE then EXPONDIST returns
2493  * the cumulative probability of all values up to x.
2494- * @param values[1] lambda - The lambda to specify the exponential distribution function.
2495- * @param values[2] cumulative - Whether to use the exponential cumulative distribution.
2496+ * @param lambda - The lambda to specify the exponential distribution function.
2497+ * @param cumulative - Whether to use the exponential cumulative distribution.
2498  * @returns {number} value of the exponential distribution function.
2499  * @constructor
2500  */
2501-var EXPONDIST = function (...values) : number {
2502-  ArgsChecker.checkLength(values, 3, "EXPONDIST");
2503+var EXPONDIST = function (x, lambda, cumulative) : number {
2504+  ArgsChecker.checkLength(arguments, 3, "EXPONDIST");
2505   function cdf(x, rate) {
2506     return x < 0 ? 0 : 1 - Math.exp(-rate * x);
2507   }
2508   function pdf(x, rate) {
2509     return x < 0 ? 0 : rate * Math.exp(-rate * x);
2510   }
2511-  var x = TypeConverter.firstValueAsNumber(values[0]);
2512-  var lambda = TypeConverter.firstValueAsNumber(values[1]);
2513-  var cumulative = TypeConverter.firstValueAsBoolean(values[2]);
2514+  x = TypeConverter.firstValueAsNumber(x);
2515+  lambda = TypeConverter.firstValueAsNumber(lambda);
2516+  cumulative = TypeConverter.firstValueAsBoolean(cumulative);
2517   return (cumulative) ? cdf(x, lambda) : pdf(x, lambda);
2518 };
2519 
2520 /**
2521  * Calculates the left-tailed F probability distribution (degree of diversity) for two data sets with given input x.
2522  * Alternately called Fisher-Snedecor distribution or Snecdor's F distribution.
2523- * @param values[0] x - The input to the F probability distribution function. The value at which to evaluate the function.
2524+ * @param x - The input to the F probability distribution function. The value at which to evaluate the function.
2525  * Must be a positive number.
2526- * @param values[1] degrees_freedom1 - The numerator degrees of freedom.
2527- * @param values[2] degrees_freedom2 - The denominator degrees of freedom.
2528- * @param values[3] cumulative - Logical value that determines the form of the function. If true returns the cumulative
2529+ * @param degreesFreedom1 - The numerator degrees of freedom.
2530+ * @param degreesFreedom2 - The denominator degrees of freedom.
2531+ * @param cumulative - Logical value that determines the form of the function. If true returns the cumulative
2532  * distribution function. If false returns the probability density function.
2533- * @returns {number|undefined|boolean} left-tailed F probability distribution
2534+ * @returns {number|boolean} left-tailed F probability distribution
2535  * @constructor
2536  * TODO: This function should be stricter in its return type.
2537  */
2538-var FDIST$LEFTTAILED = function (...values) : number|undefined|boolean {
2539-  ArgsChecker.checkLength(values, 4, "FDIST$LEFTTAILED");
2540+var FDIST$LEFTTAILED = function (x, degreesFreedom1, degreesFreedom2, cumulative) : number|undefined|boolean {
2541+  ArgsChecker.checkLength(arguments, 4, "FDIST$LEFTTAILED");
2542   /**
2543    * Returns the Log-Gamma function evaluated at x. See http://jstat.github.io/special-functions.html#gammaln for more
2544    * information.
2545@@ -515,27 +515,27 @@ var FDIST$LEFTTAILED = function (...values) : number|undefined|boolean {
2546     // make sure x + y doesn't exceed the upper limit of usable values
2547     return (x + y > 170) ? Math.exp(betaln(x, y)) : gammafn(x) * gammafn(y) / gammafn(x + y);
2548   }
2549-  var x = TypeConverter.firstValueAsNumber(values[0]);
2550+  x = TypeConverter.firstValueAsNumber(x);
2551   if (x < 0) {
2552     throw new NumError("Function F.DIST parameter 1 value is " + x + ". It should be greater than or equal to 0.");
2553   }
2554-  var d1 = TypeConverter.firstValueAsNumber(values[1]);
2555-  var d2 = TypeConverter.firstValueAsNumber(values[2]);
2556-  var cumulative = TypeConverter.firstValueAsBoolean(values[3]);
2557-  return (cumulative) ? cdf(x, d1, d2) : pdf(x, d1, d2);
2558+  var d1 = TypeConverter.firstValueAsNumber(degreesFreedom1);
2559+  var d2 = TypeConverter.firstValueAsNumber(degreesFreedom2);
2560+  var cum = TypeConverter.firstValueAsBoolean(cumulative);
2561+  return (cum) ? cdf(x, d1, d2) : pdf(x, d1, d2);
2562 };
2563 
2564 /**
2565  * Returns the inverse of the (right-tailed) F probability distribution. If p = FDIST(x,...), then FINV(p,...) = x. The
2566  * F distribution can be used in an F-test that compares the degree of variability in two data sets.
2567- * @param values[0] probability - A probability associated with the F cumulative distribution.
2568- * @param values[1] deg_freedom1 - Required. The numerator degrees of freedom.
2569- * @param values[2] deg_freedom2 - Required. The denominator degrees of freedom.
2570+ * @param probability - A probability associated with the F cumulative distribution.
2571+ * @param degFreedom1 - Required. The numerator degrees of freedom.
2572+ * @param degFreedom2 - Required. The denominator degrees of freedom.
2573  * @returns {number} inverse of the (right-tailed) F probability distribution
2574  * @constructor
2575  */
2576-var FINV = function (...values) : number {
2577-  ArgsChecker.checkLength(values, 3, "FINV");
2578+var FINV = function (probability, degFreedom1, degFreedom2) : number {
2579+  ArgsChecker.checkLength(arguments, 3, "FINV");
2580   /**
2581    * Returns the continued fraction for the incomplete Beta function with parameters a and b modified by Lentz's method
2582    * evaluated at x. For more information see http://jstat.github.io/special-functions.html#betacf
2583@@ -686,25 +686,25 @@ var FINV = function (...values) : number {
2584   function inv(x, df1, df2) {
2585     return df2 / (df1 * (1 / ibetainv(x, df1 / 2, df2 / 2) - 1));
2586   }
2587-  var probability = TypeConverter.firstValueAsNumber(values[0]);
2588+  probability = TypeConverter.firstValueAsNumber(probability);
2589   if (probability <= 0.0 || probability > 1.0) {
2590     throw new NumError("Function FINV parameter 1 value is " + probability
2591       + ". It should be greater than or equal to 0, and less than 1.")
2592   }
2593-  var d1 = TypeConverter.firstValueAsNumber(values[1]);
2594-  var d2 = TypeConverter.firstValueAsNumber(values[2]);
2595+  var d1 = TypeConverter.firstValueAsNumber(degFreedom1);
2596+  var d2 = TypeConverter.firstValueAsNumber(degFreedom2);
2597   return inv(1.0 - probability, d1, d2);
2598 };
2599 
2600 /**
2601  * Returns the Fisher transformation of a specified value.
2602- * @param values[0] value - The value for which to calculate the Fisher transformation.
2603+ * @param value - The value for which to calculate the Fisher transformation.
2604  * @returns {number} Fisher transformation
2605  * @constructor
2606  */
2607-var FISHER = function (...values) : number {
2608-  ArgsChecker.checkLength(values, 1, "FISHER");
2609-  var x = TypeConverter.firstValueAsNumber(values[0]);
2610+var FISHER = function (value) : number {
2611+  ArgsChecker.checkLength(arguments, 1, "FISHER");
2612+  var x = TypeConverter.firstValueAsNumber(value);
2613   if (x <= -1 || x >= 1) {
2614     throw new NumError("Function FISHER parameter 1 value is " + x + ". Valid values are between -1 and 1 exclusive.");
2615   }
2616@@ -713,20 +713,20 @@ var FISHER = function (...values) : number {
2617 
2618 /**
2619  * Returns the inverse Fisher transformation of a specified value.
2620- * @param values[0] value - The value for which to calculate the inverse Fisher transformation.
2621+ * @param value - The value for which to calculate the inverse Fisher transformation.
2622  * @returns {number} inverse Fisher transformation
2623  * @constructor
2624  */
2625-var FISHERINV = function (...values) : number {
2626-  ArgsChecker.checkLength(values, 1, "FISHERINV");
2627-  var y = TypeConverter.firstValueAsNumber(values[0]);
2628+var FISHERINV = function (value) : number {
2629+  ArgsChecker.checkLength(arguments, 1, "FISHERINV");
2630+  var y = TypeConverter.firstValueAsNumber(value);
2631   var e2y = Math.exp(2 * y);
2632   return (e2y - 1) / (e2y + 1);
2633 };
2634 
2635 /**
2636  * Returns the maximum value in a numeric dataset.
2637- * @param values The values or range(s) to consider when calculating the maximum value.
2638+ * @param values - The values or range(s) to consider when calculating the maximum value.
2639  * @returns {number} the maximum value of the dataset
2640  * @constructor
2641  */
2642@@ -751,7 +751,7 @@ var MAX = function (...values) {
2643 
2644 /**
2645  * Returns the maximum numeric value in a dataset.
2646- * @param values The value(s) or range(s) to consider when calculating the maximum value.
2647+ * @param values - The value(s) or range(s) to consider when calculating the maximum value.
2648  * @returns {number} maximum value of the dataset
2649  * @constructor
2650  */
2651@@ -763,7 +763,7 @@ var MAXA = function (...values) : number {
2652 
2653 /**
2654  * Returns the minimum value in a numeric dataset.
2655- * @param values The value(s) or range(s) to consider when calculating the minimum value.
2656+ * @param values - The value(s) or range(s) to consider when calculating the minimum value.
2657  * @returns {number} the minimum value of the dataset
2658  * @constructor
2659  */
2660@@ -789,7 +789,7 @@ var MIN = function (...values) {
2661 
2662 /**
2663  * Returns the minimum numeric value in a dataset.
2664- * @param values The value(s) or range(s) to consider when calculating the minimum value.
2665+ * @param values - The value(s) or range(s) to consider when calculating the minimum value.
2666  * @returns {number} the minimum value in the dataset
2667  * @constructor
2668  */
2669@@ -801,18 +801,18 @@ var MINA = function (...values) : number {
2670 
2671 /**
2672  * Returns the average of a range depending on criteria.
2673- * @param values[0] criteria_range - The range to check against criterion.
2674- * @param values[1] criterion - The pattern or test to apply to criteria_range.
2675- * @param values[2] average_range - [optional] The range to average. If not included, criteria_range is used for the
2676+ * @param criteriaRange - The range to check against criterion.
2677+ * @param criterion - The pattern or test to apply to criteria_range.
2678+ * @param averageRange - [optional] The range to average. If not included, criteria_range is used for the
2679  * average instead.
2680  * @returns {number}
2681  * @constructor
2682  * TODO: This needs to also accept a third parameter "average_range"
2683  */
2684-var AVERAGEIF = function (...values) {
2685-  ArgsChecker.checkLength(values, 2, "AVERAGEIF");
2686-  var range = Filter.flatten(values[0]);
2687-  var criteriaEvaluation = CriteriaFunctionFactory.createCriteriaFunction(values[1]);
2688+var AVERAGEIF = function (criteriaRange, criterion, averageRange?) {
2689+  ArgsChecker.checkLength(arguments, 2, "AVERAGEIF");
2690+  var range = Filter.flatten(criteriaRange);
2691+  var criteriaEvaluation = CriteriaFunctionFactory.createCriteriaFunction(criterion);
2692 
2693   var result = 0;
2694   var count = 0;
2695@@ -832,7 +832,7 @@ var AVERAGEIF = function (...values) {
2696 
2697 /**
2698  * Returns the a count of the number of numeric values in a dataset.
2699- * @param values The values or ranges to consider when counting.
2700+ * @param values - The values or ranges to consider when counting.
2701  * @returns {number} number of numeric values in a dataset.
2702  * @constructor
2703  */
2704@@ -853,7 +853,7 @@ var COUNT = function (...values) : number {
2705 
2706 /**
2707  * Returns the a count of the number of values in a dataset.
2708- * @param values The values or ranges to consider when counting.
2709+ * @param values - The values or ranges to consider when counting.
2710  * @returns {number} number of values in a dataset.
2711  * @constructor
2712  */
2713diff --git a/src/Formulas/Text.ts b/src/Formulas/Text.ts
2714index 01f99f6..93aef44 100644
2715--- a/src/Formulas/Text.ts
2716+++ b/src/Formulas/Text.ts
2717@@ -13,7 +13,7 @@ import {
2718 
2719 /**
2720  * Computes the value of a Roman numeral.
2721- * @param text The Roman numeral to format, whose value must be between 1 and 3999, inclusive.
2722+ * @param text - The Roman numeral to format, whose value must be between 1 and 3999, inclusive.
2723  * @returns {number} value in integer format
2724  * @constructor
2725  */
2726@@ -43,13 +43,13 @@ var ARABIC = function (text?) {
2727 
2728 /**
2729  * Convert a number into a character according to the current Unicode table.
2730- * @param values[0] The number of the character to look up from the current Unicode table in decimal format.
2731+ * @param value - The number of the character to look up from the current Unicode table in decimal format.
2732  * @returns {string} character corresponding to Unicode number
2733  * @constructor
2734  */
2735-var CHAR = function (...values) : string {
2736-  ArgsChecker.checkLength(values, 1, "CHAR");
2737-  var n = TypeConverter.firstValueAsNumber(values[0]);
2738+var CHAR = function (value) : string {
2739+  ArgsChecker.checkLength(arguments, 1, "CHAR");
2740+  var n = TypeConverter.firstValueAsNumber(value);
2741   if (n < 1 || n > 1114112) { //limit
2742     throw new NumError("Function CHAR parameter 1 value " + n + " is out of range.");
2743   }
2744@@ -58,13 +58,13 @@ var CHAR = function (...values) : string {
2745 
2746 /**
2747  * Returns the numeric Unicode map value of the first character in the string provided.
2748- * @param values[0] The string whose first character's Unicode map value will be returned.
2749+ * @param value - The string whose first character's Unicode map value will be returned.
2750  * @returns {number} number of the first character's Unicode value
2751  * @constructor
2752  */
2753-var CODE = function (...values) : number {
2754-  ArgsChecker.checkLength(values, 1, "CODE");
2755-  var text = TypeConverter.firstValueAsString(values[0]);
2756+var CODE = function (value) : number {
2757+  ArgsChecker.checkLength(arguments, 1, "CODE");
2758+  var text = TypeConverter.firstValueAsString(value);
2759   if (text === "") {
2760     throw new ValueError("Function CODE parameter 1 value should be non-empty.");
2761   }
2762@@ -73,22 +73,19 @@ var CODE = function (...values) : number {
2763 
2764 /**
2765  * Divides text around a specified character or string, and puts each fragment into a separate cell in the row.
2766- * @param values[0] text - The text to divide.
2767- * @param values[1] delimiter - The character or characters to use to split text.
2768- * @param values[2] split_by_each - [optional] Whether or not to divide text around each character contained in
2769+ * @param text - The text to divide.
2770+ * @param delimiter - The character or characters to use to split text.
2771+ * @param splitByEach - [optional] Whether or not to divide text around each character contained in
2772  * delimiter.
2773  * @returns {Array<string>} containing the split
2774  * @constructor
2775  * TODO: At some point this needs to return a more complex type than Array. Needs to return a type that has a dimension.
2776  */
2777-var SPLIT = function (...values) : Array<string> {
2778-  ArgsChecker.checkLengthWithin(values, 2, 3, "SPLIT");
2779-  var text = TypeConverter.firstValueAsString(values[0]);
2780-  var delimiter = TypeConverter.firstValueAsString(values[1]);
2781-  var splitByEach = false;
2782-  if (values.length === 3) {
2783-    splitByEach = TypeConverter.firstValueAsBoolean(values[2]);
2784-  }
2785+var SPLIT = function (text, delimiter, splitByEach?) : Array<string> {
2786+  ArgsChecker.checkLengthWithin(arguments, 2, 3, "SPLIT");
2787+  text = TypeConverter.firstValueAsString(text);
2788+  delimiter = TypeConverter.firstValueAsString(delimiter);
2789+  splitByEach = splitByEach === undefined ? false : TypeConverter.firstValueAsBoolean(splitByEach);
2790   if (splitByEach) {
2791     var result = [text];
2792     for (var i = 0; i < delimiter.length; i++) {
2793@@ -109,7 +106,7 @@ var SPLIT = function (...values) : Array<string> {
2794 
2795 /**
2796  * Appends strings to one another.
2797- * @param values to append to one another. Must contain at least one value
2798+ * @param values - to append to one another. Must contain at least one value
2799  * @returns {string} concatenated string
2800  * @constructor
2801  */
2802@@ -131,18 +128,18 @@ var CONCATENATE = function (...values) : string {
2803 
2804 /**
2805  * Converts a numeric value to a different unit of measure.
2806- * @param values[0] value - the numeric value in start_unit to convert to end_unit.
2807- * @param values[1] start_unit - The starting unit, the unit currently assigned to value.
2808- * @param values[2] end_unit - The unit of measure into which to convert value.
2809+ * @param value - the numeric value in start_unit to convert to end_unit.
2810+ * @param startUnit - The starting unit, the unit currently assigned to value.
2811+ * @param endUnit - The unit of measure into which to convert value.
2812  * @returns {number}
2813  * @constructor
2814  * TODO: Looking up units is not efficient at all. We should use an object instead of iterating through an array.
2815  */
2816-var CONVERT = function (...values) {
2817-  ArgsChecker.checkLength(values, 3, "CONVERT");
2818-  var n = TypeConverter.firstValueAsNumber(values[0]);
2819-  var fromUnit = TypeConverter.firstValueAsString(values[1]);
2820-  var toUnit = TypeConverter.firstValueAsString(values[2]);
2821+var CONVERT = function (value, startUnit, endUnit) {
2822+  ArgsChecker.checkLength(arguments, 3, "CONVERT");
2823+  var n = TypeConverter.firstValueAsNumber(value);
2824+  var fromUnit = TypeConverter.firstValueAsString(startUnit);
2825+  var toUnit = TypeConverter.firstValueAsString(endUnit);
2826 
2827   // NOTE: A lot of the code for this method is from https://github.com/sutoiku/formula.js. I'm relying on them to have
2828   // gotten it right, but I'm spot checking some of their work against GS, MSE, LibreOffice, OpenOffice.
2829diff --git a/tests/Formulas/DateFormulasTest.ts b/tests/Formulas/DateFormulasTest.ts
2830index b6e84e5..9b6bf39 100644
2831--- a/tests/Formulas/DateFormulasTest.ts
2832+++ b/tests/Formulas/DateFormulasTest.ts
2833@@ -43,10 +43,10 @@ test("WORKDAY.INTL", function () {
2834   assertEquals(WORKDAY$INTL(DATE(1945, 1, 14), 6000, "1110001"), DATE(1983, 5, 14));
2835   assertEquals(WORKDAY$INTL(DATE(1945, 1, 14), 6000, 6), DATE(1968, 1, 14));
2836   catchAndAssertEquals(function() {
2837-    WORKDAY$INTL(12, 12, [12], false, 1);
2838+    WORKDAY$INTL.apply(this, [12, 12, [12], false, 1]);
2839   }, ERRORS.NA_ERROR);
2840   catchAndAssertEquals(function() {
2841-    WORKDAY$INTL(12);
2842+    WORKDAY$INTL.apply(this, [12]);
2843   }, ERRORS.NA_ERROR);
2844   catchAndAssertEquals(function() {
2845     WORKDAY$INTL("1992-1-1", "str");
2846@@ -77,10 +77,10 @@ test("WORKDAY", function () {
2847   assertEquals(WORKDAY(DATE(2012, 5, 29), 1000, [41058, 41059, 41060, 41061, 41062]), DATE(2016, 4, 1));
2848   assertEquals(WORKDAY([DATE(1999, 2, 2)], [10]), DATE(1999, 2, 16));
2849   catchAndAssertEquals(function() {
2850-    WORKDAY();
2851+    WORKDAY.apply(this, []);
2852   }, ERRORS.NA_ERROR);
2853   catchAndAssertEquals(function() {
2854-    WORKDAY(DATE(2012, 5, 29), 1000, [10], 11);
2855+    WORKDAY.apply(this, [DATE(2012, 5, 29), 1000, [10], 11]);
2856   }, ERRORS.NA_ERROR);
2857 });
2858 
2859@@ -101,13 +101,13 @@ test("TIME", function () {
2860   assertEquals(TIME(3, 0, 0), 0.125);
2861   assertEquals(TIME("3", ["0"], false), 0.125);
2862   catchAndAssertEquals(function() {
2863-    TIME();
2864+    TIME.apply(this, []);
2865   }, ERRORS.NA_ERROR);
2866   catchAndAssertEquals(function() {
2867-    TIME(1, 1);
2868+    TIME.apply(this, [1, 1]);
2869   }, ERRORS.NA_ERROR);
2870   catchAndAssertEquals(function() {
2871-    TIME(1, 1, 1, 1);
2872+    TIME.apply(this, [1, 1, 1, 1]);
2873   }, ERRORS.NA_ERROR);
2874   catchAndAssertEquals(function() {
2875     TIME(-29, 10, 10);
2876@@ -160,10 +160,10 @@ test("NETWORKDAYS$INTL", function () {
2877   assertEquals(NETWORKDAYS$INTL(900, 12004), 7933);
2878   assertEquals(NETWORKDAYS$INTL(900, 12005), 7933);
2879   catchAndAssertEquals(function() {
2880-    NETWORKDAYS$INTL(12, 12, [12], false, 1);
2881+    NETWORKDAYS$INTL.apply(this, [12, 12, [12], false, 1]);
2882   }, ERRORS.NA_ERROR);
2883   catchAndAssertEquals(function() {
2884-    NETWORKDAYS$INTL(12);
2885+    NETWORKDAYS$INTL.apply(this, [12]);
2886   }, ERRORS.NA_ERROR);
2887   catchAndAssertEquals(function() {
2888     NETWORKDAYS$INTL("1992-1-1", "str");
2889@@ -219,10 +219,10 @@ test("NETWORKDAYS", function(){
2890   assertEquals(NETWORKDAYS(12, 12, [12]), 0);
2891   assertEquals(NETWORKDAYS(DATE(1998, 1, 1), DATE(1999, 1, 22), [DATE(1999, 1, 20)]), 276);
2892   catchAndAssertEquals(function() {
2893-    NETWORKDAYS(12, 12, [12], false);
2894+    NETWORKDAYS.apply(this, [12, 12, [12], false]);
2895   }, ERRORS.NA_ERROR);
2896   catchAndAssertEquals(function() {
2897-    NETWORKDAYS(12);
2898+    NETWORKDAYS.apply(this, [12]);
2899   }, ERRORS.NA_ERROR);
2900   catchAndAssertEquals(function() {
2901     NETWORKDAYS("1992-1-1", "str");
2902@@ -251,10 +251,10 @@ test("SECOND", function() {
2903   assertEquals(SECOND("1992-1-1 8:120:104"), 44);
2904   assertEquals(SECOND(0.511111111111), 0);
2905   catchAndAssertEquals(function() {
2906-    SECOND("8:10", 5);
2907+    SECOND.apply(this, ["8:10", 5]);
2908   }, ERRORS.NA_ERROR);
2909   catchAndAssertEquals(function() {
2910-    SECOND();
2911+    SECOND.apply(this, []);
2912   }, ERRORS.NA_ERROR);
2913   catchAndAssertEquals(function() {
2914     SECOND("str");
2915@@ -294,10 +294,10 @@ test("MINUTE", function() {
2916   assertEquals(MINUTE(99.5), 0);
2917   assertEquals(MINUTE("1969-7-6 5:05am"), 5);
2918   catchAndAssertEquals(function() {
2919-    MINUTE("8:10", 5);
2920+    MINUTE.apply(this, ["8:10", 5]);
2921   }, ERRORS.NA_ERROR);
2922   catchAndAssertEquals(function() {
2923-    MINUTE();
2924+    MINUTE.apply(this, []);
2925   }, ERRORS.NA_ERROR);
2926   catchAndAssertEquals(function() {
2927     MINUTE("str");
2928@@ -340,10 +340,10 @@ test("HOUR", function() {
2929   assertEquals(HOUR("0.0625"), 1);
2930   assertEquals(HOUR("1969-7-6 5am"), 5);
2931   catchAndAssertEquals(function() {
2932-    HOUR("8:10", 5);
2933+    HOUR.apply(this, ["8:10", 5]);
2934   }, ERRORS.NA_ERROR);
2935   catchAndAssertEquals(function() {
2936-    HOUR();
2937+    HOUR.apply(this, []);
2938   }, ERRORS.NA_ERROR);
2939   catchAndAssertEquals(function() {
2940     HOUR("str");
2941@@ -378,10 +378,10 @@ test("TIMEVALUE", function() {
2942   assertEquals(TIMEVALUE("11:21222:2111pm"), 0.7202662037037038);
2943   assertEquals(TIMEVALUE("11:21222:2111am"), 0.2202662037037037);
2944   catchAndAssertEquals(function() {
2945-    TIMEVALUE("8:10", 5);
2946+    TIMEVALUE.apply(this, ["8:10", 5]);
2947   }, ERRORS.NA_ERROR);
2948   catchAndAssertEquals(function() {
2949-    TIMEVALUE();
2950+    TIMEVALUE.apply(this, []);
2951   }, ERRORS.NA_ERROR);
2952   catchAndAssertEquals(function() {
2953     TIMEVALUE("str");
2954@@ -463,10 +463,10 @@ test("YEARFRAC", function(){
2955     YEARFRAC("1996-6-19", "1992-6-19", 5);
2956   }, ERRORS.NUM_ERROR);
2957   catchAndAssertEquals(function() {
2958-    YEARFRAC();
2959+    YEARFRAC.apply(this, []);
2960   }, ERRORS.NA_ERROR);
2961   catchAndAssertEquals(function() {
2962-    YEARFRAC("1992-6-19", "1995-6-19", 1, 0);
2963+    YEARFRAC.apply(this, ["1992-6-19", "1995-6-19", 1, 0]);
2964   }, ERRORS.NA_ERROR);
2965   catchAndAssertEquals(function() {
2966     YEARFRAC("str", "1995-6-19", 1);
2967@@ -542,10 +542,10 @@ test("DATEDIF", function(){
2968     DATEDIF("1992-6-19", "1995-6-19", "mm");
2969   }, ERRORS.NUM_ERROR);
2970   catchAndAssertEquals(function() {
2971-    DATEDIF();
2972+    DATEDIF.apply(this, []);
2973   }, ERRORS.NA_ERROR);
2974   catchAndAssertEquals(function() {
2975-    DATEDIF("1992-6-19", "1995-6-19", "mm", 0);
2976+    DATEDIF.apply(this, ["1992-6-19", "1995-6-19", "mm", 0]);
2977   }, ERRORS.NA_ERROR);
2978   catchAndAssertEquals(function() {
2979     DATEDIF("str", "1995-6-19", "mm");
2980@@ -1077,10 +1077,10 @@ test("WEEKNUM", function(){
2981   assertEquals(WEEKNUM(745, 21), 3);
2982   assertEquals(WEEKNUM(746, 21), 3);
2983   catchAndAssertEquals(function() {
2984-    WEEKNUM();
2985+    WEEKNUM.apply(this, []);
2986   }, ERRORS.NA_ERROR);
2987   catchAndAssertEquals(function() {
2988-    WEEKNUM(213123, 1, 1);
2989+    WEEKNUM.apply(this, [213123, 1, 1]);
2990   }, ERRORS.NA_ERROR);
2991   catchAndAssertEquals(function() {
2992     WEEKNUM("str");
2993@@ -1143,10 +1143,10 @@ test("WEEKDAY", function(){
2994   assertEquals(WEEKDAY(40915, 3), 5);
2995   assertEquals(WEEKDAY(40916, 3), 6);
2996   catchAndAssertEquals(function() {
2997-    WEEKDAY();
2998+    WEEKDAY.apply(this, []);
2999   }, ERRORS.NA_ERROR);
3000   catchAndAssertEquals(function() {
3001-    WEEKDAY(213123, 1, 1);
3002+    WEEKDAY.apply(this, [213123, 1, 1]);
3003   }, ERRORS.NA_ERROR);
3004   catchAndAssertEquals(function() {
3005     WEEKDAY("str");
3006@@ -1176,10 +1176,10 @@ test("YEAR", function(){
3007   assertEquals(YEAR(true), 1899);
3008   assertEquals(YEAR([1, "str"]), 1899);
3009   catchAndAssertEquals(function() {
3010-    YEAR();
3011+    YEAR.apply(this, []);
3012   }, ERRORS.NA_ERROR);
3013   catchAndAssertEquals(function() {
3014-    YEAR(213123, 123123);
3015+    YEAR.apply(this, [213123, 123123]);
3016   }, ERRORS.NA_ERROR);
3017   catchAndAssertEquals(function() {
3018     YEAR("str");
3019@@ -1198,10 +1198,10 @@ test("MONTH", function(){
3020   assertEquals(MONTH(1312212), 9);
3021   assertEquals(MONTH(13122121), 2);
3022   catchAndAssertEquals(function() {
3023-    MONTH();
3024+    MONTH.apply(this, []);
3025   }, ERRORS.NA_ERROR);
3026   catchAndAssertEquals(function() {
3027-    MONTH(213123, 123123);
3028+    MONTH.apply(this, [213123, 123123]);
3029   }, ERRORS.NA_ERROR);
3030   catchAndAssertEquals(function() {
3031     MONTH("str");
3032@@ -1232,13 +1232,13 @@ test("DAYS360", function(){
3033   assertEquals(DAYS360(33779, 33780), 1);
3034   assertEquals(DAYS360([1, "str"], [390, "str"]), 384);
3035   catchAndAssertEquals(function() {
3036-    DAYS360();
3037+    DAYS360.apply(this, []);
3038   }, ERRORS.NA_ERROR);
3039   catchAndAssertEquals(function() {
3040-    DAYS360(100);
3041+    DAYS360.apply(this, [100]);
3042   }, ERRORS.NA_ERROR);
3043   catchAndAssertEquals(function() {
3044-    DAYS360(100, 200, true, "str");
3045+    DAYS360.apply(this, [100, 200, true, "str"]);
3046   }, ERRORS.NA_ERROR);
3047   catchAndAssertEquals(function() {
3048     DAYS360("str", 100);
3049@@ -1268,13 +1268,13 @@ test("DAYS", function(){
3050   assertEquals(DAYS([0, "str"], [100, "str"]), -100);
3051   assertEquals(DAYS("1992, 6, 25", "1992, 6, 24"), 1);
3052   catchAndAssertEquals(function() {
3053-    DAYS();
3054+    DAYS.apply(this, []);
3055   }, ERRORS.NA_ERROR);
3056   catchAndAssertEquals(function() {
3057-    DAYS(100);
3058+    DAYS.apply(this, [100]);
3059   }, ERRORS.NA_ERROR);
3060   catchAndAssertEquals(function() {
3061-    DAYS(100, 200, 300);
3062+    DAYS.apply(this, [100, 200, 300]);
3063   }, ERRORS.NA_ERROR);
3064   catchAndAssertEquals(function() {
3065     DAYS([[], 100], 22);
3066@@ -1307,10 +1307,10 @@ test("DAY", function(){
3067     DAY("str");
3068   }, ERRORS.VALUE_ERROR);
3069   catchAndAssertEquals(function() {
3070-    DAY();
3071+    DAY.apply(this, []);
3072   }, ERRORS.NA_ERROR);
3073   catchAndAssertEquals(function() {
3074-    DAY(DATE(1992, 6, 24), 4);
3075+    DAY.apply(this, [DATE(1992, 6, 24), 4]);
3076   }, ERRORS.NA_ERROR);
3077   catchAndAssertEquals(function() {
3078     DAY(-1);
3079@@ -1333,10 +1333,10 @@ test("EDATE", function(){
3080     EDATE("str", 2);
3081   }, ERRORS.VALUE_ERROR);
3082   catchAndAssertEquals(function() {
3083-    EDATE(DATE(1992, 6, 24));
3084+    EDATE.apply(this, [DATE(1992, 6, 24)]);
3085   }, ERRORS.NA_ERROR);
3086   catchAndAssertEquals(function() {
3087-    EDATE(DATE(1992, 6, 24), 4, 4);
3088+    EDATE.apply(this, [DATE(1992, 6, 24), 4, 4]);
3089   }, ERRORS.NA_ERROR);
3090   catchAndAssertEquals(function() {
3091     EDATE(-1, 1);
3092@@ -1365,6 +1365,12 @@ test("EOMONTH", function(){
3093   assertEquals(EOMONTH(false, 1), DATE(1900, 1, 31));
3094   assertEquals(EOMONTH(1, 1), DATE(1900, 1, 31));
3095   assertEquals(EOMONTH(true, 1), DATE(1900, 1, 31));
3096+  catchAndAssertEquals(function() {
3097+    EOMONTH.apply(this, []);
3098+  }, ERRORS.NA_ERROR);
3099+  catchAndAssertEquals(function() {
3100+    EOMONTH.apply(this, [true, 1, 1]);
3101+  }, ERRORS.NA_ERROR);
3102   catchAndAssertEquals(function() {
3103     EOMONTH("str", 2);
3104   }, ERRORS.VALUE_ERROR);
3105@@ -1382,10 +1388,10 @@ test("DATE", function(){
3106     DATE(1900, 0, 5);
3107   }, ERRORS.NUM_ERROR);
3108   catchAndAssertEquals(function() {
3109-    DATE(1900, 0, 5, 22);
3110+    DATE.apply(this, [1900, 0, 5, 22]);
3111   }, ERRORS.NA_ERROR);
3112   catchAndAssertEquals(function() {
3113-    DATE(1900, 0);
3114+    DATE.apply(this, [1900, 0]);
3115   }, ERRORS.NA_ERROR);
3116   assertEquals(DATE(1992, 6, 24), 33779);
3117   assertEquals(DATE(2017, 2, 26), 42792);
3118@@ -1451,10 +1457,10 @@ test("DATEVALUE", function(){
3119   assertEquals(DATEVALUE("January-2017 10:10:10"), 42736);
3120   assertEquals(DATEVALUE("January-2017 10:10:10am"), 42736);
3121   catchAndAssertEquals(function() {
3122-    DATEVALUE("6/24/92", 10);
3123+    DATEVALUE.apply(this, ["6/24/92", 10]);
3124   }, ERRORS.NA_ERROR);
3125   catchAndAssertEquals(function() {
3126-    DATEVALUE();
3127+    DATEVALUE.apply(this, []);
3128   }, ERRORS.NA_ERROR);
3129   catchAndAssertEquals(function() {
3130     DATEVALUE(false);
3131diff --git a/tests/Formulas/DateFormulasTestTimeOverride.ts b/tests/Formulas/DateFormulasTestTimeOverride.ts
3132index b5c2ba9..0b27752 100644
3133--- a/tests/Formulas/DateFormulasTestTimeOverride.ts
3134+++ b/tests/Formulas/DateFormulasTestTimeOverride.ts
3135@@ -32,7 +32,7 @@ test("NOW", function(){
3136   lockDate(1944, 1, 2, 1, 11, 55);
3137   assertEquals(NOW(), 16104.29994212963);
3138   catchAndAssertEquals(function() {
3139-    NOW(12);
3140+    NOW.apply(this, [12]);
3141   }, ERRORS.NA_ERROR);
3142 });
3143 
3144@@ -47,6 +47,6 @@ test("TODAY", function(){
3145   lockDate(1944, 1, 2, 1, 11, 55);
3146   assertEquals(TODAY(), DATEVALUE("Feb 2 1944"));
3147   catchAndAssertEquals(function() {
3148-    TODAY(12);
3149+    TODAY.apply(this, [12]);
3150   }, ERRORS.NA_ERROR);
3151 });
3152diff --git a/tests/Formulas/EngineeringTest.ts b/tests/Formulas/EngineeringTest.ts
3153index 521513d..b425b07 100644
3154--- a/tests/Formulas/EngineeringTest.ts
3155+++ b/tests/Formulas/EngineeringTest.ts
3156@@ -26,10 +26,10 @@ test("BIN2DEC", function(){
3157     BIN2DEC("str");
3158   }, ERRORS.NUM_ERROR);
3159   catchAndAssertEquals(function() {
3160-    BIN2DEC();
3161+    BIN2DEC.apply(this, []);
3162   }, ERRORS.NA_ERROR);
3163   catchAndAssertEquals(function() {
3164-    BIN2DEC("10", "10");
3165+    BIN2DEC.apply(this, ["10", "10"]);
3166   }, ERRORS.NA_ERROR);
3167 });
3168 
3169@@ -53,10 +53,10 @@ test("BIN2HEX", function(){
3170     BIN2DEC("str");
3171   }, ERRORS.NUM_ERROR);
3172   catchAndAssertEquals(function() {
3173-    BIN2DEC();
3174+    BIN2DEC.apply(this, []);
3175   }, ERRORS.NA_ERROR);
3176   catchAndAssertEquals(function() {
3177-    BIN2DEC("10", 4, 4);
3178+    BIN2DEC.apply(this, ["10", 4, 4]);
3179   }, ERRORS.NA_ERROR);
3180 
3181 });
3182@@ -82,10 +82,10 @@ test("BIN2OCT", function(){
3183     BIN2OCT("str");
3184   }, ERRORS.NUM_ERROR);
3185   catchAndAssertEquals(function() {
3186-    BIN2OCT();
3187+    BIN2OCT.apply(this, []);
3188   }, ERRORS.NA_ERROR);
3189   catchAndAssertEquals(function() {
3190-    BIN2OCT("10", 4, 4);
3191+    BIN2OCT.apply(this, ["10", 4, 4]);
3192   }, ERRORS.NA_ERROR);
3193 });
3194 
3195@@ -114,10 +114,10 @@ test("DEC2BIN", function(){
3196     DEC2BIN(513, 10);
3197   }, ERRORS.NUM_ERROR);
3198   catchAndAssertEquals(function() {
3199-    DEC2BIN(100, 100, 10);
3200+    DEC2BIN.apply(this, [100, 100, 10]);
3201   }, ERRORS.NA_ERROR);
3202   catchAndAssertEquals(function() {
3203-    DEC2BIN();
3204+    DEC2BIN.apply(this, []);
3205   }, ERRORS.NA_ERROR);
3206   catchAndAssertEquals(function() {
3207     DEC2BIN("str");
3208@@ -152,10 +152,10 @@ test("DEC2HEX", function(){
3209     DEC2HEX(54975581, -10);
3210   }, ERRORS.NUM_ERROR);
3211   catchAndAssertEquals(function() {
3212-    DEC2HEX(100, 100, 10);
3213+    DEC2HEX.apply(this, [100, 100, 10]);
3214   }, ERRORS.NA_ERROR);
3215   catchAndAssertEquals(function() {
3216-    DEC2HEX();
3217+    DEC2HEX.apply(this, []);
3218   }, ERRORS.NA_ERROR);
3219   catchAndAssertEquals(function() {
3220     DEC2HEX("str");
3221@@ -190,10 +190,10 @@ test("DEC2OCT", function(){
3222     DEC2OCT(536870910, -10);
3223   }, ERRORS.NUM_ERROR);
3224   catchAndAssertEquals(function() {
3225-    DEC2OCT(100, 100, 10);
3226+    DEC2OCT.apply(this, [100, 100, 10]);
3227   }, ERRORS.NA_ERROR);
3228   catchAndAssertEquals(function() {
3229-    DEC2OCT();
3230+    DEC2OCT.apply(this, []);
3231   }, ERRORS.NA_ERROR);
3232   catchAndAssertEquals(function() {
3233     DEC2OCT("str");
3234@@ -219,9 +219,9 @@ test("DELTA", function(){
3235     DELTA("n", "n");
3236   }, ERRORS.VALUE_ERROR);
3237   catchAndAssertEquals(function() {
3238-    DELTA();
3239+    DELTA.apply(this, []);
3240   }, ERRORS.NA_ERROR);
3241   catchAndAssertEquals(function() {
3242-    DELTA(1, 2, 3);
3243+    DELTA.apply(this, [1, 2, 3]);
3244   }, ERRORS.NA_ERROR);
3245 });
3246diff --git a/tests/Formulas/FinancialTest.ts b/tests/Formulas/FinancialTest.ts
3247index 06ca457..c0cec49 100644
3248--- a/tests/Formulas/FinancialTest.ts
3249+++ b/tests/Formulas/FinancialTest.ts
3250@@ -48,10 +48,10 @@ test("ACCRINT", function(){
3251     ACCRINT(100, 2, 1, 0.1, 1000, 1, 4);
3252   }, ERRORS.NUM_ERROR);
3253   catchAndAssertEquals(function() {
3254-    ACCRINT(100, 2, 1, 0.1, 1000);
3255+    ACCRINT.apply(this, [100, 2, 1, 0.1, 1000]);
3256   }, ERRORS.NA_ERROR);
3257   catchAndAssertEquals(function() {
3258-    ACCRINT(1, 2, 1461, 0.1, 1000, 1, 1, 1);
3259+    ACCRINT.apply(this, [1, 2, 1461, 0.1, 1000, 1, 1, 1]);
3260   }, ERRORS.NA_ERROR);
3261 });
3262 
3263@@ -71,13 +71,13 @@ test("CUMPRINC", function(){
3264     CUMPRINC(0.12, 12, 100, 3, 1, false);
3265   }, ERRORS.NUM_ERROR);
3266   catchAndAssertEquals(function() {
3267-    CUMPRINC();
3268+    CUMPRINC.apply(this, []);
3269   }, ERRORS.NA_ERROR);
3270   catchAndAssertEquals(function() {
3271-    CUMPRINC(0.12, 12, 100, 1, 5, true, 55);
3272+    CUMPRINC.apply(this, [0.12, 12, 100, 1, 5, true, 55]);
3273   }, ERRORS.NA_ERROR);
3274   catchAndAssertEquals(function() {
3275-    CUMPRINC(0.12, 12, 100, 1, 5);
3276+    CUMPRINC.apply(this, [0.12, 12, 100, 1, 5]);
3277   }, ERRORS.NA_ERROR);
3278 });
3279 
3280@@ -100,13 +100,13 @@ test("CUMIPMT", function(){
3281     CUMIPMT(0.12, 12, 100, 3, 1, false);
3282   }, ERRORS.NUM_ERROR);
3283   catchAndAssertEquals(function() {
3284-    CUMIPMT();
3285+    CUMIPMT.apply(this, []);
3286   }, ERRORS.NA_ERROR);
3287   catchAndAssertEquals(function() {
3288-    CUMIPMT(0.12, 12, 100, 1, 5, true, 55);
3289+    CUMIPMT.apply(this, [0.12, 12, 100, 1, 5, true, 55]);
3290   }, ERRORS.NA_ERROR);
3291   catchAndAssertEquals(function() {
3292-    CUMIPMT(0.12, 12, 100, 1, 5);
3293+    CUMIPMT.apply(this, [0.12, 12, 100, 1, 5]);
3294   }, ERRORS.NA_ERROR);
3295 });
3296 
3297@@ -131,10 +131,10 @@ test("DDB", function(){
3298   assertEquals(DDB(100, 50, 10, 2, 2.25), 17.4375);
3299   assertEquals(DDB(100, [50], 10, 2, "2.25"), 17.4375);
3300   catchAndAssertEquals(function() {
3301-    DDB(100, 50, 10, 12, 2.25);
3302+    DDB.apply(this, [100, 50, 10, 12, 2.25]);
3303   }, ERRORS.NUM_ERROR);
3304   catchAndAssertEquals(function() {
3305-    DDB(100, -50, 10, 2, 12);
3306+    DDB.apply(this, [100, -50, 10, 2, 12]);
3307   }, ERRORS.NUM_ERROR);
3308 });
3309 
3310@@ -154,10 +154,10 @@ test("DOLLAR", function(){
3311   assertEquals(DOLLAR(31111.41592653589793, -4), 30000);
3312   assertEquals(DOLLAR(31111.41592653589793, -2), 31100);
3313   catchAndAssertEquals(function() {
3314-    DOLLAR();
3315+    DOLLAR.apply(this, []);
3316   }, ERRORS.NA_ERROR);
3317   catchAndAssertEquals(function() {
3318-    DOLLAR(3.1, 1, 1);
3319+    DOLLAR.apply(this, [3.1, 1, 1]);
3320   }, ERRORS.NA_ERROR);
3321 });
3322 
3323@@ -180,13 +180,13 @@ test("DOLLARDE", function(){
3324     DOLLARDE(100, 0.99);
3325   }, ERRORS.DIV_ZERO_ERROR);
3326   catchAndAssertEquals(function() {
3327-    DOLLARDE();
3328+    DOLLARDE.apply(this, []);
3329   }, ERRORS.NA_ERROR);
3330   catchAndAssertEquals(function() {
3331-    DOLLARDE(3.1);
3332+    DOLLARDE.apply(this, [3.1]);
3333   }, ERRORS.NA_ERROR);
3334   catchAndAssertEquals(function() {
3335-    DOLLARDE(3.1, 32, 22);
3336+    DOLLARDE.apply(this, [3.1, 32, 22]);
3337   }, ERRORS.NA_ERROR);
3338 });
3339 
3340@@ -209,13 +209,13 @@ test("DOLLARFR", function(){
3341     DOLLARFR(100, 0.99);
3342   }, ERRORS.DIV_ZERO_ERROR);
3343   catchAndAssertEquals(function() {
3344-    DOLLARFR();
3345+    DOLLARFR.apply(this, []);
3346   }, ERRORS.NA_ERROR);
3347   catchAndAssertEquals(function() {
3348-    DOLLARFR(3.1);
3349+    DOLLARFR.apply(this, [3.1]);
3350   }, ERRORS.NA_ERROR);
3351   catchAndAssertEquals(function() {
3352-    DOLLARFR(3.1, 32, 22);
3353+    DOLLARFR.apply(this, [3.1, 32, 22]);
3354   }, ERRORS.NA_ERROR);
3355 });
3356 
3357@@ -227,10 +227,10 @@ test("EFFECT", function(){
3358   assertEquals(EFFECT("100000", 12.999), 1.123182670038387e+47);
3359   assertEquals(EFFECT([100000], [12.999]), 1.123182670038387e+47);
3360   catchAndAssertEquals(function() {
3361-    EFFECT();
3362+    EFFECT.apply(this, []);
3363   }, ERRORS.NA_ERROR);
3364   catchAndAssertEquals(function() {
3365-    EFFECT(0.99);
3366+    EFFECT.apply(this, [0.99]);
3367   }, ERRORS.NA_ERROR);
3368   catchAndAssertEquals(function() {
3369     EFFECT(-0.99, 12);
3370diff --git a/tests/Formulas/LogicalTest.ts b/tests/Formulas/LogicalTest.ts
3371index 37e47c8..672266f 100644
3372--- a/tests/Formulas/LogicalTest.ts
3373+++ b/tests/Formulas/LogicalTest.ts
3374@@ -25,7 +25,7 @@ test("AND", function(){
3375     AND(1, "");
3376   }, ERRORS.VALUE_ERROR);
3377   catchAndAssertEquals(function() {
3378-    AND();
3379+    AND.apply(this, []);
3380   }, ERRORS.NA_ERROR);
3381   catchAndAssertEquals(function() {
3382     AND(1, "str");
3383@@ -49,21 +49,20 @@ test("EXACT", function(){
3384   assertEquals(EXACT([10], [10]), true);
3385   assertEquals(EXACT(["str"], [10, 22]), false);
3386   catchAndAssertEquals(function() {
3387-    EXACT([], []);
3388+    EXACT.apply(this, [[], []]);
3389   }, ERRORS.REF_ERROR);
3390   catchAndAssertEquals(function() {
3391-    EXACT([]);
3392+    EXACT.apply(this, [[]]);
3393   }, ERRORS.NA_ERROR);
3394   catchAndAssertEquals(function() {
3395-    EXACT("m");
3396+    EXACT.apply(this, ["m"]);
3397   }, ERRORS.NA_ERROR);
3398   catchAndAssertEquals(function() {
3399-    EXACT(10, 10, 10);
3400+    EXACT.apply(this, [10, 10, 10]);
3401   }, ERRORS.NA_ERROR);
3402   catchAndAssertEquals(function() {
3403-    EXACT(false);
3404+    EXACT.apply(this, [false]);
3405   }, ERRORS.NA_ERROR);
3406-
3407 });
3408 
3409 
3410@@ -115,10 +114,10 @@ test("NOT", function(){
3411     NOT("1.2");
3412   }, ERRORS.VALUE_ERROR);
3413   catchAndAssertEquals(function() {
3414-    NOT();
3415+    NOT.apply(this, []);
3416   }, ERRORS.NA_ERROR);
3417   catchAndAssertEquals(function() {
3418-    NOT(false, false);
3419+    NOT.apply(this, [false, false]);
3420   }, ERRORS.NA_ERROR);
3421 });
3422 
3423@@ -144,7 +143,7 @@ test("OR", function(){
3424     OR(false, "1.1");
3425   }, ERRORS.VALUE_ERROR);
3426   catchAndAssertEquals(function() {
3427-    OR();
3428+    OR.apply(this, []);
3429   }, ERRORS.NA_ERROR);
3430 });
3431 
3432diff --git a/tests/Formulas/MathTest.ts b/tests/Formulas/MathTest.ts
3433index bd10cdb..52a5b4a 100644
3434--- a/tests/Formulas/MathTest.ts
3435+++ b/tests/Formulas/MathTest.ts
3436@@ -66,10 +66,10 @@ test("ABS", function(){
3437   assertEquals(ABS(false), 0);
3438   assertEquals(ABS("-44"), 44);
3439   catchAndAssertEquals(function() {
3440-    ABS();
3441+    ABS.apply(this, []);
3442   }, ERRORS.NA_ERROR);
3443   catchAndAssertEquals(function() {
3444-    ABS("str");
3445+    ABS.apply(this, ["str"]);
3446   }, ERRORS.VALUE_ERROR);
3447 });
3448 
3449@@ -86,6 +86,9 @@ test("ACOS", function(){
3450   catchAndAssertEquals(function() {
3451     ACOS(2);
3452   }, ERRORS.NUM_ERROR);
3453+  catchAndAssertEquals(function() {
3454+    ACOS.apply(this, []);
3455+  }, ERRORS.NA_ERROR);
3456 });
3457 
3458 
3459@@ -102,6 +105,9 @@ test("ACOSH", function(){
3460   catchAndAssertEquals(function() {
3461     ACOSH(false);
3462   }, ERRORS.NUM_ERROR);
3463+  catchAndAssertEquals(function() {
3464+    ACOSH.apply(this, []);
3465+  }, ERRORS.NA_ERROR);
3466 });
3467 
3468 
3469@@ -118,6 +124,9 @@ test("ACOTH", function(){
3470   catchAndAssertEquals(function() {
3471     ACOTH(false);
3472   }, ERRORS.NUM_ERROR);
3473+  catchAndAssertEquals(function() {
3474+    ACOTH.apply(this, []);
3475+  }, ERRORS.NA_ERROR);
3476 });
3477 
3478 
3479@@ -132,6 +141,9 @@ test("ASIN", function(){
3480   catchAndAssertEquals(function() {
3481     ASIN("str");
3482   }, ERRORS.VALUE_ERROR);
3483+  catchAndAssertEquals(function() {
3484+    ASIN.apply(this, []);
3485+  }, ERRORS.NA_ERROR);
3486 });
3487 
3488 
3489@@ -144,6 +156,9 @@ test("ASINH", function(){
3490   catchAndAssertEquals(function() {
3491     ASINH("str");
3492   }, ERRORS.VALUE_ERROR);
3493+  catchAndAssertEquals(function() {
3494+    ASINH.apply(this, []);
3495+  }, ERRORS.NA_ERROR);
3496 });
3497 
3498 
3499@@ -154,8 +169,11 @@ test("ATAN", function(){
3500   assertEquals(ATAN(false), 0);
3501   assertEquals(ATAN(true), 0.7853981633974483);
3502   catchAndAssertEquals(function() {
3503-    ASINH("str");
3504+    ATAN("str");
3505   }, ERRORS.VALUE_ERROR);
3506+  catchAndAssertEquals(function() {
3507+    ATAN.apply(this, []);
3508+  }, ERRORS.NA_ERROR);
3509 });
3510 
3511 
3512@@ -173,6 +191,9 @@ test("ATAN2", function(){
3513   catchAndAssertEquals(function() {
3514     ATAN2("str", false);
3515   }, ERRORS.VALUE_ERROR);
3516+  catchAndAssertEquals(function() {
3517+    ATAN2.apply(this, []);
3518+  }, ERRORS.NA_ERROR);
3519 });
3520 
3521 
3522@@ -206,10 +227,10 @@ test("CEILING", function(){
3523     CEILING(10, 0);
3524   }, ERRORS.DIV_ZERO_ERROR);
3525   catchAndAssertEquals(function() {
3526-    CEILING(10, 1, 2);
3527+    CEILING.apply(this, [10, 1, 2]);
3528   }, ERRORS.NA_ERROR);
3529   catchAndAssertEquals(function() {
3530-    CEILING();
3531+    CEILING.apply(this, []);
3532   }, ERRORS.NA_ERROR);
3533 });
3534 
3535@@ -232,13 +253,13 @@ test("COMBIN", function(){
3536     COMBIN(0, 1);
3537   }, ERRORS.NUM_ERROR);
3538   catchAndAssertEquals(function() {
3539-    COMBIN();
3540+    COMBIN.apply(this, []);
3541   }, ERRORS.NA_ERROR);
3542   catchAndAssertEquals(function() {
3543-    COMBIN(4);
3544+    COMBIN.apply(this, [4]);
3545   }, ERRORS.NA_ERROR);
3546   catchAndAssertEquals(function() {
3547-    COMBIN(4, 2, 66);
3548+    COMBIN.apply(this, [4, 2, 66]);
3549   }, ERRORS.NA_ERROR);
3550 });
3551 
3552@@ -254,10 +275,10 @@ test("COS", function(){
3553     COS("str");
3554   }, ERRORS.VALUE_ERROR);
3555   catchAndAssertEquals(function() {
3556-    COS();
3557+    COS.apply(this, []);
3558   }, ERRORS.NA_ERROR);
3559   catchAndAssertEquals(function() {
3560-    COS(1, 1);
3561+    COS.apply(this, [1, 1]);
3562   }, ERRORS.NA_ERROR);
3563   assertEquals(COS([0, "str"]), 1);
3564 });
3565@@ -270,16 +291,16 @@ test("COSH", function(){
3566   assertEquals(COSH(0), 1);
3567   assertEquals(COSH(true), 1.5430806348152437);
3568   assertEquals(COSH(""), 1);
3569+  assertEquals(COSH([0, "str"]), 1);
3570   catchAndAssertEquals(function() {
3571     COSH("str");
3572   }, ERRORS.VALUE_ERROR);
3573   catchAndAssertEquals(function() {
3574-    COSH();
3575+    COSH.apply(this, []);
3576   }, ERRORS.NA_ERROR);
3577   catchAndAssertEquals(function() {
3578-    COSH(1, 1);
3579+    COSH.apply(this, [1, 1]);
3580   }, ERRORS.NA_ERROR);
3581-  assertEquals(COSH([0, "str"]), 1);
3582 });
3583 
3584 
3585@@ -301,10 +322,10 @@ test("COT", function(){
3586     COT("str");
3587   }, ERRORS.VALUE_ERROR);
3588   catchAndAssertEquals(function() {
3589-    COT();
3590+    COT.apply(this, []);
3591   }, ERRORS.NA_ERROR);
3592   catchAndAssertEquals(function() {
3593-    COT(1, 1);
3594+    COT.apply(this, [1, 1]);
3595   }, ERRORS.NA_ERROR);
3596 });
3597 
3598@@ -328,10 +349,10 @@ test("COTH", function(){
3599     COTH("str");
3600   }, ERRORS.VALUE_ERROR);
3601   catchAndAssertEquals(function() {
3602-    COTH();
3603+    COTH.apply(this, []);
3604   }, ERRORS.NA_ERROR);
3605   catchAndAssertEquals(function() {
3606-    COTH(1, 1);
3607+    COTH.apply(this, [1, 1]);
3608   }, ERRORS.NA_ERROR);
3609 });
3610 
3611@@ -373,13 +394,13 @@ test("COUNTIF", function(){
3612   assertEquals(COUNTIF([1, 5, 5, 5, 10, 5], "=$10"), 1);
3613   assertEquals(COUNTIF([1, 5, 5, 5, 10, 5], "=  $ 10"), 1);
3614   catchAndAssertEquals(function() {
3615-    COUNTIF([0, 1, 0, 1]);
3616+    COUNTIF.apply(this, [[0, 1, 0, 1]]);
3617   }, ERRORS.NA_ERROR);
3618   catchAndAssertEquals(function() {
3619-    COUNTIF();
3620+    COUNTIF.apply(this, []);
3621   }, ERRORS.NA_ERROR);
3622   catchAndAssertEquals(function() {
3623-    COUNTIF([], "=1", []);
3624+    COUNTIF.apply(this, [[], "=1", []]);
3625   }, ERRORS.NA_ERROR);
3626 });
3627 
3628@@ -438,7 +459,7 @@ test("COUNTUNIQUE", function(){
3629   assertEquals(COUNTUNIQUE(["", " ", [""], []]), 2);
3630   assertEquals(COUNTUNIQUE([[""], []]), 1);
3631   catchAndAssertEquals(function() {
3632-    COUNTUNIQUE();
3633+    COUNTUNIQUE.apply(this, []);
3634   }, ERRORS.NA_ERROR);
3635 });
3636 
3637@@ -454,10 +475,10 @@ test("DEGREES", function(){
3638     DEGREES("str");
3639   }, ERRORS.VALUE_ERROR);
3640   catchAndAssertEquals(function() {
3641-    DEGREES();
3642+    DEGREES.apply(this, []);
3643   }, ERRORS.NA_ERROR);
3644   catchAndAssertEquals(function() {
3645-    DEGREES(10, 10);
3646+    DEGREES.apply(this, [10, 10]);
3647   }, ERRORS.NA_ERROR);
3648 });
3649 
3650@@ -470,7 +491,7 @@ test("ERF", function(){
3651   assertEquals(ERF(true), 0.8427007929497149);
3652   assertEquals(ERF(false), 1.1102230246251565e-16);
3653   catchAndAssertEquals(function() {
3654-    ERF();
3655+    ERF.apply(this, []);
3656   }, ERRORS.NA_ERROR);
3657   catchAndAssertEquals(function() {
3658     ERF([]);
3659@@ -488,7 +509,7 @@ test("ERFC", function(){
3660   assertEquals(ERFC(-1), 1.842700792949715);
3661   assertEquals(ERFC(-10), 2);
3662   catchAndAssertEquals(function() {
3663-    ERFC();
3664+    ERFC.apply(this, []);
3665   }, ERRORS.NA_ERROR);
3666   catchAndAssertEquals(function() {
3667     ERFC([]);
3668@@ -506,10 +527,10 @@ test("EVEN", function(){
3669   assertEquals(EVEN([11, 22]), 12);
3670   assertEquals(EVEN([10, 22, "str"]), 10);
3671   catchAndAssertEquals(function() {
3672-    EVEN();
3673+    EVEN.apply(this, []);
3674   }, ERRORS.NA_ERROR);
3675   catchAndAssertEquals(function() {
3676-    EVEN(1, 2, 3);
3677+    EVEN.apply(this, [1, 2, 3]);
3678   }, ERRORS.NA_ERROR);
3679   catchAndAssertEquals(function() {
3680     EVEN("str");
3681@@ -532,10 +553,10 @@ test("FLOOR", function(){
3682     FLOOR(10, 0);
3683   }, ERRORS.DIV_ZERO_ERROR);
3684   catchAndAssertEquals(function() {
3685-    FLOOR(10, 1, 2);
3686+    FLOOR.apply(this, [10, 1, 2]);
3687   }, ERRORS.NA_ERROR);
3688   catchAndAssertEquals(function() {
3689-    FLOOR();
3690+    FLOOR.apply(this, []);
3691   }, ERRORS.NA_ERROR);
3692 });
3693 
3694@@ -566,10 +587,10 @@ test("INT", function(){
3695   assertEquals(INT(""), 0);
3696   assertEquals(INT([1.1, "str"]), 1);
3697   catchAndAssertEquals(function() {
3698-    INT(100, 10);
3699+    INT.apply(this, [100, 10]);
3700   }, ERRORS.NA_ERROR);
3701   catchAndAssertEquals(function() {
3702-    INT();
3703+    INT.apply(this, []);
3704   }, ERRORS.NA_ERROR);
3705   catchAndAssertEquals(function() {
3706     INT("str");
3707@@ -585,10 +606,10 @@ test("ISEVEN", function(){
3708   assertEquals(ISEVEN(true), false);
3709   assertEquals(ISEVEN([4]), true);
3710   catchAndAssertEquals(function() {
3711-    ISEVEN(100, 10);
3712+    ISEVEN.apply(this, [100, 10]);
3713   }, ERRORS.NA_ERROR);
3714   catchAndAssertEquals(function() {
3715-    ISEVEN();
3716+    ISEVEN.apply(this, []);
3717   }, ERRORS.NA_ERROR);
3718   catchAndAssertEquals(function() {
3719     ISEVEN("");
3720@@ -604,10 +625,10 @@ test("ISODD", function(){
3721   assertEquals(ISODD(true), true);
3722   assertEquals(ISODD([4]), false);
3723   catchAndAssertEquals(function() {
3724-    ISODD(100, 10);
3725+    ISODD.apply(this, [100, 10]);
3726   }, ERRORS.NA_ERROR);
3727   catchAndAssertEquals(function() {
3728-    ISODD();
3729+    ISODD.apply(this, []);
3730   }, ERRORS.NA_ERROR);
3731   catchAndAssertEquals(function() {
3732     ISODD("");
3733@@ -627,24 +648,21 @@ test("LN", function(){
3734     LN("str");
3735   }, ERRORS.VALUE_ERROR);
3736   catchAndAssertEquals(function() {
3737-    LN();
3738+    LN.apply(this, []);
3739   }, ERRORS.NA_ERROR);
3740   catchAndAssertEquals(function() {
3741-    LN(10, 10);
3742+    LN.apply(this, [10, 10]);
3743   }, ERRORS.NA_ERROR);
3744 });
3745 
3746 
3747 test("LOG", function(){
3748   assertEquals(LOG(256, 2), 8);
3749-  assertEquals(LOG(100), 2);
3750-  assertEquals(LOG(100), 2);
3751+  assertEquals(LOG(100, 10), 2);
3752   assertEquals(LOG(256, 10), 2.408239965311849);
3753-  assertEquals(LOG(256), 2.408239965311849);
3754-  assertEquals(LOG("100"), 2);
3755   assertEquals(LOG(1, 2), 0);
3756   catchAndAssertEquals(function() {
3757-    LOG("str");
3758+    LOG("str", 10);
3759   }, ERRORS.VALUE_ERROR);
3760   catchAndAssertEquals(function() {
3761     LOG(256, 0);
3762@@ -658,6 +676,9 @@ test("LOG", function(){
3763   catchAndAssertEquals(function() {
3764     LOG(256, true);
3765   }, ERRORS.DIV_ZERO_ERROR);
3766+  catchAndAssertEquals(function() {
3767+    LOG.apply(this, [10]);
3768+  }, ERRORS.NA_ERROR);
3769 });
3770 
3771 
3772@@ -676,27 +697,30 @@ test("LOG10", function(){
3773     LOG10("str");
3774   }, ERRORS.VALUE_ERROR);
3775   catchAndAssertEquals(function() {
3776-    LOG10();
3777+    LOG10.apply(this, []);
3778   }, ERRORS.NA_ERROR);
3779   catchAndAssertEquals(function() {
3780-    LOG10(10, 10);
3781+    LOG10.apply(this, [10, 10]);
3782   }, ERRORS.NA_ERROR);
3783 });
3784 
3785 
3786 test("MOD", function(){
3787   assertEquals(MOD(10, 3), 1);
3788+  assertEquals(MOD(10, "3"), 1);
3789+  assertEquals(MOD(10.1, 3), 1.0999999999999996);
3790+  assertEquals(MOD(10, 3.1), 0.6999999999999997);
3791   catchAndAssertEquals(function() {
3792-    MOD(10, 3, 10);
3793+    MOD.apply(this, [10, 3, 10]);
3794   }, ERRORS.NA_ERROR);
3795   catchAndAssertEquals(function() {
3796-    MOD([10, 3]);
3797+    MOD.apply(this, [[10, 3]]);
3798   }, ERRORS.NA_ERROR);
3799   catchAndAssertEquals(function() {
3800     MOD(0, 0);
3801   }, ERRORS.DIV_ZERO_ERROR);
3802   catchAndAssertEquals(function() {
3803-    MOD(10);
3804+    MOD.apply(this, [10]);
3805   }, ERRORS.NA_ERROR);
3806   catchAndAssertEquals(function() {
3807     MOD(10, false);
3808@@ -707,9 +731,6 @@ test("MOD", function(){
3809   catchAndAssertEquals(function() {
3810     MOD(10, "str");
3811   }, ERRORS.VALUE_ERROR);
3812-  assertEquals(MOD(10, "3"), 1);
3813-  assertEquals(MOD(10.1, 3), 1.0999999999999996);
3814-  assertEquals(MOD(10, 3.1), 0.6999999999999997);
3815 });
3816 
3817 
3818@@ -723,10 +744,10 @@ test("ODD", function(){
3819   assertEquals(ODD([10, 22]), 11);
3820   assertEquals(ODD([10, 22, "str"]), 11);
3821   catchAndAssertEquals(function() {
3822-    ODD();
3823+    ODD.apply(this, []);
3824   }, ERRORS.NA_ERROR);
3825   catchAndAssertEquals(function() {
3826-    ODD(1, 2, 3);
3827+    ODD.apply(this, [1, 2, 3]);
3828   }, ERRORS.NA_ERROR);
3829   catchAndAssertEquals(function() {
3830     ODD("str");
3831@@ -736,6 +757,9 @@ test("ODD", function(){
3832 
3833 test("PI", function(){
3834   assertEquals(PI(), 3.141592653589793);
3835+  catchAndAssertEquals(function() {
3836+    PI.apply(this, [1]);
3837+  }, ERRORS.NA_ERROR);
3838 });
3839 
3840 
3841@@ -749,13 +773,13 @@ test("POWER", function(){
3842     POWER(4, "str");
3843   }, ERRORS.VALUE_ERROR);
3844   catchAndAssertEquals(function() {
3845-    POWER();
3846+    POWER.apply(this, []);
3847   }, ERRORS.NA_ERROR);
3848   catchAndAssertEquals(function() {
3849-    POWER(4);
3850+    POWER.apply(this, [4]);
3851   }, ERRORS.NA_ERROR);
3852   catchAndAssertEquals(function() {
3853-    POWER(4, 10, 22);
3854+    POWER.apply(this, [4, 10, 22]);
3855   }, ERRORS.NA_ERROR);
3856 });
3857 
3858@@ -768,27 +792,25 @@ test("RADIANS", function(){
3859     RADIANS("str");
3860   }, ERRORS.VALUE_ERROR);
3861   catchAndAssertEquals(function() {
3862-    RADIANS();
3863+    RADIANS.apply(this, []);
3864   }, ERRORS.NA_ERROR);
3865   catchAndAssertEquals(function() {
3866-    RADIANS(4, 10);
3867+    RADIANS.apply(this, [4, 10]);
3868   }, ERRORS.NA_ERROR);
3869 });
3870 
3871 
3872-
3873 test("ROUND", function(){
3874   assertEquals(ROUND(99.44, 1), 99.4);
3875   assertEquals(ROUND(99.44, 0), 99);
3876   assertEquals(ROUND(99.4444444444444, 9), 99.444444444);
3877-  assertEquals(ROUND(99.44), 99);
3878-  assertEquals(ROUND("99.44"), 99);
3879+  assertEquals(ROUND("99.44", 0), 99);
3880   assertEquals(ROUND([99.44, 22.222], [1, 4]), 99.4);
3881   catchAndAssertEquals(function() {
3882-    ROUND();
3883+    ROUND.apply(this, []);
3884   }, ERRORS.NA_ERROR);
3885   catchAndAssertEquals(function() {
3886-    ROUND(99.44, 1, 44);
3887+    ROUND.apply(this, [99.44, 1, 44]);
3888   }, ERRORS.NA_ERROR);
3889   catchAndAssertEquals(function() {
3890     ROUND(99.999, "str");
3891@@ -804,10 +826,10 @@ test("ROUNDDOWN", function(){
3892   assertEquals(ROUNDDOWN("99.99"), 99);
3893   assertEquals(ROUNDDOWN([99.46666, 22.222], [1, 4]), 99.4);
3894   catchAndAssertEquals(function() {
3895-    ROUNDDOWN();
3896+    ROUNDDOWN.apply(this, []);
3897   }, ERRORS.NA_ERROR);
3898   catchAndAssertEquals(function() {
3899-    ROUNDDOWN(99.44, 1, 44);
3900+    ROUNDDOWN.apply(this, [99.44, 1, 44]);
3901   }, ERRORS.NA_ERROR);
3902   catchAndAssertEquals(function() {
3903     ROUNDDOWN(99.999, "str");
3904@@ -823,10 +845,10 @@ test("ROUNDUP", function(){
3905   assertEquals(ROUNDUP("99.99"), 100);
3906   assertEquals(ROUNDUP([99.46666, 22.222], [1, 4]), 99.5);
3907   catchAndAssertEquals(function() {
3908-    ROUNDUP();
3909+    ROUNDUP.apply(this, []);
3910   }, ERRORS.NA_ERROR);
3911   catchAndAssertEquals(function() {
3912-    ROUNDUP(99.44, 1, 44);
3913+    ROUNDUP.apply(this, [99.44, 1, 44]);
3914   }, ERRORS.NA_ERROR);
3915   catchAndAssertEquals(function() {
3916     ROUNDUP(99.999, "str");
3917@@ -849,6 +871,9 @@ test("SIN", function(){
3918   assertEquals(SIN([1]), 0.8414709848078965);
3919   assertEquals(SIN([[1]]), 0.8414709848078965);
3920   assertEquals(SIN([1, "str"]), 0.8414709848078965);
3921+  catchAndAssertEquals(function() {
3922+    SIN.apply(this, [1, 44]);
3923+  }, ERRORS.NA_ERROR);
3924 });
3925 
3926 
3927@@ -885,10 +910,10 @@ test("SQRT", function(){
3928     SQRT(-9);
3929   }, ERRORS.VALUE_ERROR);
3930   catchAndAssertEquals(function() {
3931-    SQRT();
3932+    SQRT.apply(this, []);
3933   }, ERRORS.NA_ERROR);
3934   catchAndAssertEquals(function() {
3935-    SQRT(4, 4);
3936+    SQRT.apply(this, [4, 4]);
3937   }, ERRORS.NA_ERROR);
3938 });
3939 
3940@@ -907,10 +932,10 @@ test("SQRTPI", function(){
3941     SQRTPI(-1);
3942   }, ERRORS.NUM_ERROR);
3943   catchAndAssertEquals(function() {
3944-    SQRTPI();
3945+    SQRTPI.apply(this, []);
3946   }, ERRORS.NA_ERROR);
3947   catchAndAssertEquals(function() {
3948-    SQRTPI(4, 4);
3949+    SQRTPI.apply(this, [4, 4]);
3950   }, ERRORS.NA_ERROR);
3951 });
3952 
3953@@ -972,13 +997,13 @@ test("SUMIF", function(){
3954   assertEquals(SUMIF(["mom", "pop", "dad", "etc", "mom"], "????", [1, 1, 1, 1, 1]), 0);
3955   assertEquals(SUMIF([0, 1, 0, 1], "=1", [1, 2, 4, 8]), 10);
3956   catchAndAssertEquals(function() {
3957-    SUMIF([0, 1, 0, 1]);
3958+    SUMIF.apply(this, [[0, 1, 0, 1]]);
3959   }, ERRORS.NA_ERROR);
3960   catchAndAssertEquals(function() {
3961-    SUMIF();
3962+    SUMIF.apply(this, []);
3963   }, ERRORS.NA_ERROR);
3964   catchAndAssertEquals(function() {
3965-    SUMIF([], "=1", [], true);
3966+    SUMIF.apply(this, [[], "=1", [], true]);
3967   }, ERRORS.NA_ERROR);
3968 });
3969 
3970@@ -1020,7 +1045,7 @@ test("SUMSQ", function(){
3971     SUMSQ([]);
3972   }, ERRORS.REF_ERROR);
3973   catchAndAssertEquals(function() {
3974-    SUMSQ();
3975+    SUMSQ.apply(this, []);
3976   }, ERRORS.NA_ERROR);
3977 });
3978 
3979@@ -1036,10 +1061,10 @@ test("SUMX2MY2", function(){
3980     SUMX2MY2([1,2,3],[4,5, []]);
3981   }, ERRORS.REF_ERROR);
3982   catchAndAssertEquals(function() {
3983-    SUMX2MY2([1,2,3],[4,5]);
3984+    SUMX2MY2.apply(this, [[1,2,3],[4,5]]);
3985   }, ERRORS.NA_ERROR);
3986   catchAndAssertEquals(function() {
3987-    SUMX2MY2();
3988+    SUMX2MY2.apply(this, []);
3989   }, ERRORS.NA_ERROR);
3990 });
3991 
3992@@ -1055,10 +1080,10 @@ test("SUMX2PY2", function(){
3993     SUMX2PY2([1,2,3],[4,5, []]);
3994   }, ERRORS.REF_ERROR);
3995   catchAndAssertEquals(function() {
3996-    SUMX2PY2([1,2,3],[4,5]);
3997+    SUMX2PY2.apply(this, [[1,2,3],[4,5]]);
3998   }, ERRORS.NA_ERROR);
3999   catchAndAssertEquals(function() {
4000-    SUMX2PY2();
4001+    SUMX2PY2.apply(this, []);
4002   }, ERRORS.NA_ERROR);
4003 });
4004 
4005@@ -1076,10 +1101,10 @@ test("TAN", function(){
4006     TAN("str");
4007   }, ERRORS.VALUE_ERROR);
4008   catchAndAssertEquals(function() {
4009-    TAN();
4010+    TAN.apply(this, []);
4011   }, ERRORS.NA_ERROR);
4012   catchAndAssertEquals(function() {
4013-    TAN(1, 1);
4014+    TAN.apply(this, [1, 1]);
4015   }, ERRORS.NA_ERROR);
4016   assertEquals(TAN([1, 44]), 1.5574077246549023);
4017   assertEquals(TAN([1, "str"]), 1.5574077246549023);
4018@@ -1099,10 +1124,10 @@ test("TANH", function(){
4019     TANH("str");
4020   }, ERRORS.VALUE_ERROR);
4021   catchAndAssertEquals(function() {
4022-    TANH();
4023+    TANH.apply(this, []);
4024   }, ERRORS.NA_ERROR);
4025   catchAndAssertEquals(function() {
4026-    TANH(1, 1);
4027+    TANH.apply(this, [1, 1]);
4028   }, ERRORS.NA_ERROR);
4029   assertEquals(TANH([1, 44]), 0.7615941559557649);
4030   assertEquals(TANH([1, "str"]), 0.7615941559557649);
4031@@ -1121,9 +1146,9 @@ test("TRUNC", function(){
4032   assertEquals(TRUNC(31111.41592653589793, -4), 30000);
4033   assertEquals(TRUNC(31111.41592653589793, -2), 31100);
4034   catchAndAssertEquals(function() {
4035-    TRUNC();
4036+    TRUNC.apply(this, []);
4037   }, ERRORS.NA_ERROR);
4038   catchAndAssertEquals(function() {
4039-    TRUNC(3.1, 1, 1);
4040+    TRUNC.apply(this, [3.1, 1, 1]);
4041   }, ERRORS.NA_ERROR);
4042 });
4043diff --git a/tests/Formulas/StatisticalTest.ts b/tests/Formulas/StatisticalTest.ts
4044index b9f2208..77df6ef 100644
4045--- a/tests/Formulas/StatisticalTest.ts
4046+++ b/tests/Formulas/StatisticalTest.ts
4047@@ -145,13 +145,13 @@ test("CORREL", function(){
4048     CORREL([9], [5]);
4049   }, ERRORS.DIV_ZERO_ERROR);
4050   catchAndAssertEquals(function() {
4051-    CORREL();
4052+    CORREL.apply(this, []);
4053   }, ERRORS.NA_ERROR);
4054   catchAndAssertEquals(function() {
4055-    CORREL([9, 5]);
4056+    CORREL.apply(this, [[9, 5]]);
4057   }, ERRORS.NA_ERROR);
4058   catchAndAssertEquals(function() {
4059-    CORREL([9, 5],[10]);
4060+    CORREL.apply(this, [[9, 5],[10]]);
4061   }, ERRORS.NA_ERROR);
4062 });
4063 
4064@@ -228,13 +228,13 @@ test("EXPONDIST", function(){
4065     EXPONDIST(4, 0.5, "1");
4066   }, ERRORS.VALUE_ERROR);
4067   catchAndAssertEquals(function() {
4068-    EXPONDIST();
4069+    EXPONDIST.apply(this, []);
4070   }, ERRORS.NA_ERROR);
4071   catchAndAssertEquals(function() {
4072-    EXPONDIST(4, 0.5);
4073+    EXPONDIST.apply(this, [4, 0.5]);
4074   }, ERRORS.NA_ERROR);
4075   catchAndAssertEquals(function() {
4076-    EXPONDIST(4, 0.5, true, 1);
4077+    EXPONDIST.apply(this, [4, 0.5, true, 1]);
4078   }, ERRORS.NA_ERROR);
4079 });
4080 
4081@@ -246,10 +246,10 @@ test("FINV", function(){
4082   assertEquals(FINV(["0.42"], [33, []], [5]), 1.303222112500911);
4083   assertEquals(FINV("0.42", 2, 3), 1.174597274485816);
4084   catchAndAssertEquals(function() {
4085-    FINV();
4086+    FINV.apply(this, []);
4087   }, ERRORS.NA_ERROR);
4088   catchAndAssertEquals(function() {
4089-    FINV(0.42, 2, 4, 4);
4090+    FINV.apply(this, [0.42, 2, 4, 4]);
4091   }, ERRORS.NA_ERROR);
4092   catchAndAssertEquals(function() {
4093     FINV(0.42, 2, []);
4094@@ -277,10 +277,10 @@ test("FISHER", function(){
4095     FISHER(-1);
4096   }, ERRORS.NUM_ERROR);
4097   catchAndAssertEquals(function() {
4098-    FISHER();
4099+    FISHER.apply(this, []);
4100   }, ERRORS.NA_ERROR);
4101   catchAndAssertEquals(function() {
4102-    FISHER(0.55, 0.1);
4103+    FISHER.apply(this, [0.55, 0.1]);
4104   }, ERRORS.NA_ERROR);
4105 });
4106 
4107@@ -298,10 +298,10 @@ test("FISHERINV", function(){
4108     FISHER("str");
4109   }, ERRORS.VALUE_ERROR);
4110   catchAndAssertEquals(function() {
4111-    FISHER();
4112+    FISHER.apply(this, []);
4113   }, ERRORS.NA_ERROR);
4114   catchAndAssertEquals(function() {
4115-    FISHER(0.55, 0.1);
4116+    FISHER.apply(this, [0.55, 0.1]);
4117   }, ERRORS.NA_ERROR);
4118 });
4119 
4120@@ -408,9 +408,9 @@ test("F.DIST", function(){
4121     FDIST$LEFTTAILED(-15.35, 7, 6, 1);
4122   }, ERRORS.NUM_ERROR);
4123   catchAndAssertEquals(function() {
4124-    FDIST$LEFTTAILED(15.35, 7, 6);
4125+    FDIST$LEFTTAILED.apply(this, [15.35, 7, 6]);
4126   }, ERRORS.NA_ERROR);
4127   catchAndAssertEquals(function() {
4128-    FDIST$LEFTTAILED();
4129+    FDIST$LEFTTAILED.apply(this, []);
4130   }, ERRORS.NA_ERROR);
4131 });
4132diff --git a/tests/Formulas/TextTest.ts b/tests/Formulas/TextTest.ts
4133index bc617da..7086557 100644
4134--- a/tests/Formulas/TextTest.ts
4135+++ b/tests/Formulas/TextTest.ts
4136@@ -26,7 +26,7 @@ test("SPLIT", function(){
4137     SPLIT([], "er");
4138   }, ERRORS.REF_ERROR);
4139   catchAndAssertEquals(function() {
4140-    SPLIT("er", "er", true, 10);
4141+    SPLIT.apply(this, ["er", "er", true, 10]);
4142   }, ERRORS.NA_ERROR);
4143 });
4144 
4145@@ -49,7 +49,7 @@ test("CHAR", function(){
4146     CHAR(0);
4147   }, ERRORS.NUM_ERROR);
4148   catchAndAssertEquals(function() {
4149-    CHAR();
4150+    CHAR.apply(this, []);
4151   }, ERRORS.NA_ERROR);
4152 });
4153 
4154@@ -61,17 +61,18 @@ test("CODE", function(){
4155   assertEquals(CODE('#'), 35);
4156   assertEquals(CODE(false), 70);
4157   assertEquals(CODE(true), 84);
4158+  assertEquals(CODE(['a']), 97);
4159+  assertEquals(CODE([['a'], 'p']), 97);
4160   catchAndAssertEquals(function() {
4161-    CODE();
4162+    CODE.apply(this, []);
4163   }, ERRORS.NA_ERROR);
4164   catchAndAssertEquals(function() {
4165-    CODE("a", "m");
4166+    CODE.apply(this, ["a", "m"]);
4167   }, ERRORS.NA_ERROR);
4168   catchAndAssertEquals(function() {
4169     CODE("");
4170   }, ERRORS.VALUE_ERROR);
4171-  assertEquals(CODE(['a']), 97);
4172-  assertEquals(CODE([['a'], 'p']), 97);
4173+
4174 });
4175 
4176 
4177@@ -84,7 +85,7 @@ test("CONCATENATE", function(){
4178   assertEquals(CONCATENATE([22, 14, "m", false]), "2214mFALSE");
4179   assertEquals(CONCATENATE([22, 14, ["m", false]]), "2214mFALSE");
4180   catchAndAssertEquals(function() {
4181-    CONCATENATE();
4182+    CONCATENATE.apply(this, []);
4183   }, ERRORS.NA_ERROR);
4184   catchAndAssertEquals(function() {
4185     CONCATENATE("10", 4, false, []);
4186@@ -110,6 +111,12 @@ test("CONVERT", function(){
4187   assertEquals(CONVERT(10, "ton", "stone"), 1428.5714285714287);
4188   assertEquals(CONVERT(10, "tspm", "bushel"), 0.0014188796696394089);
4189   assertEquals(CONVERT(10, "c", "Wh"), 0.011622222222222223);
4190+  catchAndAssertEquals(function() {
4191+    CONVERT.apply(this, []);
4192+  }, ERRORS.NA_ERROR);
4193+  catchAndAssertEquals(function() {
4194+    CONVERT.apply(this, [5.1, "mm", "m", 10]);
4195+  }, ERRORS.NA_ERROR);
4196 });
4197 
4198