0

I have this ADT for representing expressions:

 trait Expression {
    def value: Int
  }

  case class Number(value: Int) extends Expression
  case class Add(a: Expression, b: Expression) extends Expression {
    override def value: Int = a.value + b.value
  }

I could add more case class for other operations like "-", "*", etc. Then I could represent "2 + 7 + 9" like this:

val addingThreeNumbers = Add(Number(2), Add(Number(7), Number(9)))

If I want to get the result of addingThreeNumbers I could implement:

  def evaluate(e: Expression): Int = {
    e match {
      case Number(value) => value
      case Add(a, b)     => evaluate(a) + evaluate(b)
    }
  }

This implementation works.

But, how can I implement it using tail recursion?

1 Answer 1

3

If a recursive function makes two calls to itself then it can't be made tail recursive. You have to change the logic of function so that it only calls itself once, as the last action in a code branch.

For problems like this it typically means using a stack that contains the current state of the computation. Each recursive call updates the stack based on incoming values or the values on the stack itself. It then calls itself with the remaining incoming values and the new stack (or returns when complete).

In this particular case you essentially want to convert your infix notation into postfix notation (reverse polish notation) which can easily be computed using a recursive function.

This can be done in a single pass, but might be simpler done in two passes. One pass converts the incoming infix expressions into a postfix stack, and the second function just evaluates the stack by repeatedly combining elements at the top until only a single value remains.

In this case I wouldn't bother; the clarity of directly processing the infix notation outweighs any performance gain from using tail recursion.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.