package function.builtin.math; import java.util.function.*; import sexpression.*; class MathFunction { Function singleValueOperation; BiFunction multipleValueOperation; public MathFunction(Function singleValueOperation, BiFunction multipleValueOperation) { this.singleValueOperation = singleValueOperation; this.multipleValueOperation = multipleValueOperation; } public SExpression callTailRecursive(Cons argumentList) { Cons remainingArguments = (Cons) argumentList.getCdr(); SExpression firstArgument = argumentList.getCar(); LispNumber number1 = (LispNumber) firstArgument; if (remainingArguments.nullp()) return singleValueOperation.apply(number1); SExpression secondArgument = remainingArguments.getCar(); LispNumber number2 = (LispNumber) secondArgument; LispNumber operationResult = multipleValueOperation.apply(number1, number2); SExpression remainingNumbers = remainingArguments.getCdr(); if (remainingNumbers.nullp()) return operationResult; return callTailRecursive(new Cons(operationResult, remainingNumbers)); } }