# Vector operations: vec1.dot(vec2) vs vec1 * vec2 vs dot(vec1, vec2) [closed]

What's your preferred way to implement/use vector operations?

• vec1.dot(vec2)
• allows to reuse vec1 but is hard to read for longer equations
• dot(vec1, vec2)
• A friend of mine prefers this as "dot" isn't a property of vector
• vec1 * vec2
• probably looks best, but not possible in all languages (e.g. Java)
-

## closed as too broad by gnat, MichaelT, GlenH7, Bart van Ingen Schenau, jwentingAug 25 '14 at 13:29

There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs.If this question can be reworded to fit the rules in the help center, please edit the question.

What does `NumPy` library do? – Job Apr 13 '11 at 16:39

## 7 Answers

Overloaded operators can be good, but only if the redefined operators behave similarly to the originals. Since there's two common products for vectors (dot and cross), this can cause problems. (I'd consider `operator*()` for dot and `operator%` for cross, but I've never seen that in practice.)

The dot product relates to both vectors equally, so I wouldn't want to use the first version. It looks too much like vec2 applied to vec1 somehow.

Therefore, I'd rather use `dot(vec1, vec2)`. It looks as symmetric as it is, and it doesn't make the vector class interface any bigger. The more stuff you pack into a class (cough`std:string`cough), the more complicated it is, and the more chance of something going wrong somewhere.

-
+1 for not overloading to do totally crazy things (though that can be fun). – TZHX Apr 13 '11 at 14:17

While this isn't a basis for a good subjective question, I would steer clear of the third example

``````vec1 * vec2
``````

since multiplication is different from a dot function. This could easily cause confusion from the (subjective intuitive) possibility of overloading the '*' character.

-
It's called a "dot product", so both of them produce "products". That isn't a big problem. The big problem is that there are different products on vectors. 3-D vectors have cross products. Vectors can also have tensor products, but I've never seen that in practice, so it probably isn't important. – David Thornley Apr 13 '11 at 13:55
And it being "the dot product" is exactly why `*` is a good name for the operator - it mimics the actual proper character used in the mathematical notation. (And so `x` would be a good operator to use for the cross product (if your language allows it).) – Frank Shearar Apr 13 '11 at 16:18

Assuming C++, I would go with your second option.

The last option is my least favourite, but it adds confusion: what does `*` mean? Dot product or cross product? Particularly if you make `vec * scalar` scalar multiplication (which I would also avoid, personally) then it becomes even more confusing.

So it's just between the first and second options then. If you read Herb Sutter's article, Monoliths "Unstrung", he goes into great detail about why non-member non-friend functions make a better interface than member functions do, so I won't repeat everything he says, except to say that I agree with much of it.

-

it depends on the language, for example in haskell you could do soemthing like

``````v1 `dot` v2
``````

While in Javascript I would probably do something like

``````v1.dot(v2);
``````

or maybe

``````Vector.dot(v1, v2);
``````

In lisp/scheme it would be

``````(dot v1 v2)
``````
-

In the first example, it looks like you are applying an operation to a vector, but since a vector cannot be converted to a scalar the operation returns a value and does not modify the original object. So maybe `dot` should be a static method in the `Vector` class. This gives something similar to the second example:

``````Vector.dotProduct(v1, v2);
``````
-

All are valid, it's a matter of taste and the options given by the implementation language.

In a non-functional language, I would probably use the first option. Yes, "dot" isn't strictly a property of the vector, but it can only be applied to vector. In a heavily classed application, having a bunch of global functions lying around can make things tricky, and unless your developers are all well aware of the different functions - they may implement something themself. Having it as a method on the vector object makes it less likely that this will happen.

The second option is the sort of thing I would do if I was working with a functional language. I don't really know how to explain why, but it just looks like it would fit better. Though you could overload the multiply operator, the weak typing in most functional languages would make this awkward I think.

Just my \$0.02

-
So what symbol would you use for cross-product? – FrustratedWithFormsDesigner Apr 13 '11 at 13:42
I'd still use *, but have it return a vector rather than a double. Overloading is a wonderful thing. – TZHX Apr 13 '11 at 13:47
@TZHX: But... cross-* and dot-* both take two vectors as arguments... how would it know which should return the scalar and which should return the vector? Maybe it's been too long since I did overloaded operators... – FrustratedWithFormsDesigner Apr 13 '11 at 13:49
well, the return type of the function and the variable it's being assigned to... – TZHX Apr 13 '11 at 13:51
@TZHX: In C++, you can't overload on return type. Trying to have `operator*()` as both cross and dot products will produce an error. – David Thornley Apr 13 '11 at 13:53

Neither. There already is a perfectly good notation for the dot product of two vectors:

``````vec1⋅vec2
``````

Why do you want to invent a new one?

Here is a simple example in Haskell:

``````a ⋅ b = foldl1 (+) \$ zipWith (*) a b

infixl 7 ⋅

main = putStrLn \$ show \$ [1, 3, -5] ⋅ [4, -2, -1]
-- 3
``````

This declares `⋅` to be a left-associative infix operator at precedence level 7, which is the same associativity, fixity and precedence as Haskell’s other multiplication operators. (Although, generally speaking, the dot product is usually non-associative, so you might want to make it `infix 7` instead, to avoid confusion.)

Here is another example in Scala:

``````sealed case class Vector[T](ns: T*)(implicit n: Numeric[T]) {
def ⋅(o: Vector[T]) =
ns zip o.ns map {case (a, b) => n.times(a, b) } reduceLeft (n.plus _)
}

println(Vector(1, 3, -5)⋅Vector(4, -2, -1))
// 3
``````

Unfortunately, Scala doesn’t support user-defined precedence or associativity.

And even in a very restrictive language like Ruby, which unfortunately doesn’t support user-defined operators at all, you can still get a pretty reasonable result by just using a plain old method instead of an operator:

``````#encoding: UTF-8

class Vector
def initialize(*ns)
@ns = ns
end

def ⋅ o
ns.zip(o.ns).map{|a, b| a*b }.reduce(:+)
end

protected

attr_reader :ns
end

def Vector(*ns)
Vector.new(*ns)
end

puts Vector(1, 3, -5).⋅ Vector(4, -2, -1)
# 3
``````

Or in Clojure:

``````(defn ⋅ [a b] (reduce + (map * a b)))

(println (⋅ [1 3 -5] [4 -2 -1]))
``````

[Note: the example is obviously very simplistic, since it uses a simple list of numbers for the vector representation. Obviously, in a real vector implementation, you would use a proper Vector type.]

-