package function.builtin.math import function.ArgumentValidator import function.FunctionNames import function.LispFunction import sexpression.Cons import sexpression.LispNumber import sexpression.LispNumber.Companion.ONE @FunctionNames("*") class Multiply(name: String) : LispFunction() { private val argumentValidator = ArgumentValidator(name).apply { setEveryArgumentExpectedType(LispNumber::class.java) } private val mathFunction: MathFunction = MathFunction({ it }, this::multiply) override fun call(argumentList: Cons): LispNumber { argumentValidator.validate(argumentList) return mathFunction.callTailRecursive(Cons(ONE, argumentList)) } private fun multiply(number1: LispNumber, number2: LispNumber) = LispNumber(number1.value * number2.value) }