# left-hand and right-hand operators

3 replies
Russ P.
Joined: 2009-01-31, I recently wrote a Matrix class in Scala. Scala allows it to be done very nicely. However, I noticed one significant problem. The standard math operators, (+, -, *, /) apparently can only be defined as methods of the left operand type. Thus, I can write

val mat1 = new Matrix(2,2)
...
val mat2 = mat1 * 2

and it works fine. But if I try to write,

val mat3 = 3 * mat1

I have a problem. To make it work, I had to define an implicit conversion from Int and Double to Matrix, then determine that the resulting Matrix is 1 x 1 (i.e., a scalar) then multiply the Matrix by the scalar. That is probably inefficient.

It seems that there should be a way to define the operator so that it works if it finds a method for the right operand. That can be done in Python. Can that feature be added to Scala without causing problems?

Russ P.

--
http://RussP.us
James Iry
Joined: 2008-08-19, Re: left-hand and right-hand operators
Why wouldn't you have an implicit conversion to a class with a * operation that's efficient for scalar by matrix multiplication?
class Scalar(x : Double) {   def *(y : Matrix) = y * value }implicit def double2Scalar(x : Double) = new Scalar(x)

On Thu, Jun 17, 2010 at 12:49 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com> wrote:

I have a problem. To make it work, I had to define an implicit conversion from Int and Double to Matrix, then determine that the resulting Matrix is 1 x 1 (i.e., a scalar) then multiply the Matrix by the scalar. That is probably inefficient.

Alex Cruise
Joined: 2008-12-17, Re: left-hand and right-hand operators

On 10-06-17 12:49 PM, Russ Paielli wrote:
> I recently wrote a Matrix class in Scala. Scala allows it to be done
> very nicely. However, I noticed one significant problem. The standard
> math operators, (+, -, *, /) apparently can only be defined as methods
> of the left operand type.
James' suggestion is a good one, but another answer is that such methods
aren't right-associative because their names don't end with a colon.
The :: (pronounced "cons") method on s.c.i.List is right-associative,
not because it's intrinsic or anything (it's not) but because methods
whose names end with ":" are right-associative by definition in Scala.
That's how 1 :: 2 :: 3 :: Nil gets turned into Nil.::(3.::(2.::(1)))
without anything really fancy going on.

> Thus, I can write
>
> val mat1 = new Matrix(2,2)
> ...
> val mat2 = mat1 * 2
>
> and it works fine. But if I try to write,
>
> val mat3 = 3 * mat1
>
> I have a problem. To make it work, I had to define an implicit
> conversion from Int and Double to Matrix, then determine that the
> resulting Matrix is 1 x 1 (i.e., a scalar) then multiply the Matrix by
> the scalar. That is probably inefficient.

If you don't mind the operator being "*:" instead, you should be able to
make it work--without an implicit conversion--like this:

class Matrix2 {
def *:(i: Int) = ...
}
val mat3 = 3 *: mat1 // rewritten by the compiler to mat1.*:(3)

-0xe1a

Jason Zaugg
Joined: 2009-05-18, Re: left-hand and right-hand operators

You might also like to take a look at Scalala: