Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A few questions about object oriented decomposition

I am learning scala from Coursera. I cannot understand the following slide on the limitations of object-oriented decomposition enter image description here

Can you please simplify this for me? What is being said here? If this is not the proper way to ask this question kindly guide me on how to make it better. But, this is all there is. I do not understand this slide. Looking for someone to help me make sense of it

like image 283
Nitin Siwach Avatar asked Apr 11 '26 08:04

Nitin Siwach


1 Answers

I guess they mean that this rule can be easily implemented in FP with pattern matching using nested patterns

sealed trait Expression
case class Lit(value: Int) extends Expression
case class Add(expr1: Expression, expr2: Expression) extends Expression
case class Mult(expr1: Expression, expr2: Expression) extends Expression

def simplify(expr: Expression): Expression = expr match {
  case Add(Mult(a, b), Mult(a1, c)) if a == a1 => Mult(a, Add(b, c))
  case _ => expr
}

But how to implement it easily in OOP style?

sealed trait Expression {
  def simplify: Expression
}
case class Lit(value: Int) extends Expression {
  override def simplify: Expression = ???
}
case class Add(expr1: Expression, expr2: Expression) extends Expression {
  override def simplify: Expression = ???
}
case class Mult(expr1: Expression, expr2: Expression) extends Expression {
  override def simplify: Expression = ???
}

Well, actually it can be implemented using visitor pattern (double/multiple dispatch, emulating multi-methods)

sealed trait Expression {
  def simplify: Expression
  def simplifyAdd(that: Expression): Expression
  def simplifyAddLit(lit: Lit): Expression
  def simplifyAddAdd(add: Add): Expression
  def simplifyAddMult(mult: Mult): Expression
}

case class Lit(value: Int) extends Expression {
  override def simplify: Expression = this
  override def simplifyAdd(that: Expression): Expression = that.simplifyAddLit(this)
  override def simplifyAddLit(lit: Lit): Expression    = Add(lit, this)
  override def simplifyAddAdd(add: Add): Expression    = Add(add, this)
  override def simplifyAddMult(mult: Mult): Expression = Add(mult, this)
}

case class Add(expr1: Expression, expr2: Expression) extends Expression {
  override def simplify: Expression = expr1.simplifyAdd(expr2)
  override def simplifyAdd(that: Expression): Expression = that.simplifyAddAdd(this)
  override def simplifyAddLit(lit: Lit): Expression    = Add(lit, this)
  override def simplifyAddAdd(add: Add): Expression    = Add(add, this)
  override def simplifyAddMult(mult: Mult): Expression = Add(mult, this)
}

case class Mult(expr1: Expression, expr2: Expression) extends Expression {
  override def simplify: Expression = this
  override def simplifyAdd(that: Expression): Expression = that.simplifyAddMult(this)
  override def simplifyAddLit(lit: Lit): Expression    = Add(lit, this)
  override def simplifyAddAdd(add: Add): Expression    = Add(add, this)
  override def simplifyAddMult(mult: Mult): Expression =
    if (mult.expr1 == expr1) Mult(expr1, Add(mult.expr2, expr2)) 
    else Add(mult, this)
}

or

sealed trait Expression {
  def simplify: Expression
  def simplifyAdd(that: Expression): Expression
  def simplifyAddMult(mult: Mult): Expression
}

case class Lit(value: Int) extends Expression {
  override def simplify: Expression = this
  override def simplifyAdd(that: Expression): Expression = Add(this, that)
  override def simplifyAddMult(mult: Mult): Expression   = Add(mult, this)
}

case class Add(expr1: Expression, expr2: Expression) extends Expression {
  override def simplify: Expression = expr1.simplifyAdd(expr2)
  override def simplifyAdd(that: Expression): Expression = Add(this, that)
  override def simplifyAddMult(mult: Mult): Expression   = Add(mult, this)
}

case class Mult(expr1: Expression, expr2: Expression) extends Expression {
  override def simplify: Expression = this
  override def simplifyAdd(that: Expression): Expression = that.simplifyAddMult(this)
  override def simplifyAddMult(mult: Mult): Expression   =
    if (mult.expr1 == expr1) Mult(expr1, Add(mult.expr2, expr2)) 
    else Add(mult, this)
}

What if we want to make simplify recursive?

like image 197
Dmytro Mitin Avatar answered Apr 14 '26 01:04

Dmytro Mitin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!