Open neojski opened 9 years ago
Hi. Yes, the vectors are mutable on purpose. The idea behind it is that,.. let's say you have a space ship that moves. So the ship has a position vector and a and a velocity vector. To move the ship you add the velocity vector to the position vector:
var ship = {
position: new Victor(100, 200),
velocity: new Victor(1, 0),
move: function () {
this.position.add(this.velocity);
}
};
setInterval(function () {
ship.move();
draw();
}, 1000 / 16);
instead of doing:
// let's assume Victor is immutable
var ship = {
...
move: function () {
this.position = this.position.add(this.velocity);
}
};
...
Do you think this is a bad idea?
You can use the .clone()
method if you want to create a new vector based on another.
var ship = {
...
move: function () {
// add only half the velocity without modifying the velocity
this.position.add(this.velocity.clone().divide(new Victor(2, 2)));
}
};
...
What are your thoughts?
Sure, I'm not saying mutability is inherently bad. My scenario where I prefer things to be immutable is more math style:
var a = Vector(23, 12);
var b = Vector(25, 13);
var c = a.normalize().add(b.normalize());
to calculate angle bisector. With mutable stuff I need
var a = Vector(23, 12);
var b = Vector(25, 13);
var c = a.clone().normalize().add(b.clone().normalize());
With more calculations it's clone
everywhere. Most likely we cannot do anything about that except for introducing API for both mutable and immutable operations. In that case, I think, I prefer them to be separate libraries.
I would also prefer if the methods such as add
or divide
would not modify the vector. I think they should be immutable by default as every library with vector that I have ever used behaves like that.
I made a Immutable vector library https://github.com/yukulele/Vector.js
i agree to have an immutable version. this just makes things much more simpler to reason about.
this is extremely useful when you want to simulate something. immutability allows to travel back to the time.
+1 for immutability feature. Will be awesome now that functional Javascript is becoming more and more popular. see Redux and co. there are also a lot of games using functional programming now .. and i think games are definitly one of your library's core audiences :smile:
Shouldn't this be closed? Victor has been mutable for years, so changing it would break functionality for existing users. Besides, @neojski, @yukulele, and @graue have filled the need for immutable vectors.
Gah, just been bitten by this. I was really surprised that operation are mutable. Should clearly mention this on the website
They are mutable, because of the ability to chain.
It would be nice to state that the library is not immutable on the README
or the docs; up-front.
If you check out the docs e.g. the add
method, it states that the vector is added in-place:
.add(vector)
[chainable]Adds another vector to itself.
I will side with the author and say that this:
this.position.add(this.velocity);
Is easier to read than:
this.position = this.position.clone().add(this.velocity); // or
this.position = Victor.fromObject(this.position).add(this.velocity);
The ability to chain has nothing to do with mutability, it's just a matter of whether the methods return this
(or a new object in the case of an immutable version). If the methods returned nothing, then they would have to mutate this
, or do a weird C-like thing like this:
let a = new Victor(1, 2);
let b = new Victor(3, 4);
let ret = new Victor(0, 0);
a.add(b, ret);
// ret has been modified by the add method
Though I think in C, the ret value is generally uninitialized, which we can't do in JavaScript due to the lack of pointers, but objects are shared by reference, so ret
could be initialized as {value: null}
and then a method can set value
to whatever it wants.
Totally agree with your opinion examples. Would be nice if JavaScript supported operator overloading, then you could do this.position += this.velocity
.
It was very annoying for me that methods like
add
ordivide
modified the vector. My temporary solution is my immutable-vector2d library. Do you have any ideas as how to merge my project into this one?