🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Opinion: AngelScript 2.0 operators

Started by
24 comments, last by WitchLord 19 years, 7 months ago
I'll have to agree with that having the assignment operator do a reference assignment by default can be confusing. As I want the script language to be as easy to use as possible, I'll avoid that.

Still at times it is good to have a reference assignment. Maybe I'll go with:

a = &b // a references b

or perhaps simply use

obj &a = b; // Initialization of reference, further assignment affects b.

I also agree with that the fact that objects are stored by reference should be transparent.

I would also prefer not to add new operators to the language, as it is already quite full of them. I will have to add an operator for comparing references though, or maybe a built in function like C++'s sizeof().

Thanks for the feedback everyone. It's been really helpful. If you have some more suggestions or ideas, please let me know.

---------

I feel I need to explain some of my decisions as well.

I decided to remove pointers from AS2.0 because they complicated matters, and since the language didn't allow manipulation of the pointers anyway, they weren't all that useful.

I also decided to store all objects by reference in the script engine, because it allows me to identify the type at run-time, which makes it a lot easier to do exception handling and context serialization, etc. It should also be quite easy to do dynamic casting of objects with inheritance using this model.

AngelScript won't be exactly like C++, but I'll try to keep as close to it as possible.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Advertisement
I think that you should support both methods of refference assignment, but that's just my opinion.

As for comparing references, you should make that as transparant as possible. Some things that I feel are acceptable are:
a == &b&a == &ba is bisref(a, b) //or other name


Some things that I would preffer not to use:
a === ba.isref(b)a &== b //Could work, but only if you really don't have anything elsea =&= b //some variation of the abovea !&! b

I definitely agree with Gyrbo, on both accounts. I prefer the first type of reference assignments over the second, but having both shouldn't be too much trouble I would think.

Some thoughts,
a == &b looks like it would be an overloaded bool operator==(Object * obj), implemented in the class that a belongs to, not dealing with a's reference.
&a == &b is a lot more natural for C++ programmers, and I feel the best way to compare references since it reads 'reference a has the same numeric value as reference b' or close enough :P
I also like a is b, though with this it'd make sense to also provide 'a is <class>' that checks if a is a subtype of <class>.
isref(a,b) I would honestly put in the second list of don't do's :P But that's just me
Generally I like how Java implements things.. in this case, when you do "a = b;" it's reference assignment, and a real copy is done by other means, e.g. via a method (for new copies there's the clone-method). Comparison is through a method as well - "a.equals(b);"

When everything is done via references I think that's pretty clean way to solve the problem. It'll still require user to know and understand that they are working with references. But the other ways to do it, e.g. making "=" to a real copy operator, having "===" for reference comparison etc. sound to me like they really aren't easier to understand at all.

Since AS is heavily C++ influenced, and becoming a bit more Java influenced as well, my personal opinion is that I'd like it to implement things in Java way when possible, and if not, then do it like C++ does it. (that is, avoid adding custom operators with syntax like ":=", "===" etc)
--Jetro Lauha - tonic - http://jet.ro
I agree with jetro. Make it clean and clear to the user what they are doing. The different obscure operators that I have seen suggested in this thread are just going to cause issues through confusion, all because people want to type the least number of keys possible to get something done.

b = a; // Both reference same object instance
b.Copy(a); // b is a separate identical object instance to a

So I would strongly endorse alternative #1.
Steve 'Sly' Williams  Monkey Wrangler  Krome Studios
turbo game development with Borland compilers
OK. It seems that everyone agrees that no new operators should be added if at all possible. I agree with that.

What still remains is if an assignment should create a copy of the object, or simply a new reference to the object. There seems to be different opinions here.

Having the assignment do a reference assignment by default would be the same as if all your C++ objects were stored by pointers, so this is in fact very similar to how C++ does it as well. The difference is that the pointer is an implicit smart pointer, that will make sure that the object is freed once all references to it are released.

It may be a little less confusing to a script writer when reference assignments are done. But I think that is only if he didn't read the manual for the script language. On the other hand I believe almost all scripting languages that deal with objects are actually doing reference assignments, think &#106avascript, VBScript, Lua, etc. Why should AngelScript be different? Besides, a reference assignment is a lot faster than making a copy of the object.

Regardless of the decision taken on the question of assignments. AngelScript will continue to support overloading of operators like +, -, etc, as I believe it make the code much easier to read. I believe the comparison operators should also be overloadable operators, comparing the value of the objects and not the reference.

I'm currently leaning towards doing reference assignments. A ref comparison would then be made with the 'is' operator (it's a new operator, I know, but at least it is not obscure [wink]).

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Quote: Original post by WitchLord
Having the assignment do a reference assignment by default would be the same as if all your C++ objects were stored by pointers, so this is in fact very similar to how C++ does it as well. The difference is that the pointer is an implicit smart pointer, that will make sure that the object is freed once all references to it are released.


That statement is very true, but I thought that the use of references was ment to be a "behind the scenes" change i.e. the script writer should more or less be unaware of the change.

The only argument that I have is when exactly in C++ do you actually do this:

int a = 10;int & b = a;b = 20; //Now a == 20RandomClass myClass;int & c = myClass.subclass.member;


The last case is about the only time I would personally use a reference; not just for performance, but for ease and readability. However, most the time I do assignments it's because I want to chnage the value. E.g:

//start is an int passed into the functionfor (int current = start; current < end; ++current)	//access some arrayif (start == current) //we didn't move through the array, perhaps some condition was met and it terminated early	//Do stuffint offset = current - start; //Now wtf happens?


Now what happens in the above code? Using references, everytime current is advanced, it will advance start!? So the final if statement will always be true! Also, what happens in the last line, will offset be a regular int, or will it be a reference to a random bit of memory?

Admitadly, this is a silly example, but you get the idea.

BTW, I see you like my 'is' operator idea [embarrass] But by no new operators, do you mean that literally i.e. you wont be doing:

int a = new int;
I've already voice my opinion, but I like doing so, so I'm doing it again :p.

I have to agree with desertcube here. Most of the time when you do assignment, you actually need the new variable to contain a copy. I personally highly dislike something like Class newvar = oldvar.Copy(), especially when you have to do it a lot. Class newvar = *oldvar; is still acceptable IMHO, but since you probably use it most often, it should be the default. (See desertcube's example)
Furthermore, it would be unlogical IMO to have all operators except the assignment work on the value. Even new += old would change the value, whereas new = new + old wouldn't.
The only instance when assignment would default to reference assignment would be if the new variable is explicitly declared as reference.

About new operators: I don't really mind them as long as they're logical and unambiguous. Textual operators are usually clearer than symbolic ones.
Reference variables to primitive types won't be allowed, as it would allow a function to store a pointer to some memory that could later be freed, making the reference variable point to illegal memory.

I've already implemented AS 2.0 to do assignment by reference because it was easier, but this doesn't mean it is set in stone. I will leave it like this for WIP 1, because I want to get everything back up and running soon. Afterwards I'll take the decision if I will convert it to do assignment by copy.

I see no problem with having all operators except assignment work with the value. An addition takes two objects, computes their sum, and returns a new object with the result. a += b will just be a shorter way of writing a = a + b; It will not be a separate operator as it is in C++.

The 'new' operator will work like it does in C++. It will allocate an object and return it already initialized. Object a = new Object();



AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Quote: Original post by WitchLord
The 'new' operator will work like it does in C++. It will allocate an object and return it already initialized. Object a = new Object();


Fair enoiugh about the reference thingy, but I'm still confused about the need for the 'new' operator. To declare a primative, such as an int, I just do this:
int myInt;

But, if I want to create a custom object, I have to do this:
SomeClass myClass = new SomeClass();

I'm not sure why I need to do this though! What is the purpose of the 'new' operator? Surley it would be nicer to do this:
SomeClass myClass(); //Create an objectSomeCladd myClass; //Same as the above, the default constructor is called

The point I'm trying to make is I'm not sure angelscript needs the operator 'new', as everything you create will infact be a smart pointer, why complicate things. Perhaps I'm missing something, but I don't like the way in C# you have to use new unless it's a primative or struct (in C# there is a difference between classes and structs), but if it is a struct, you can still use new if you want. Since C# has garbage collection (AS kinda does, as the scri[pt takes care of all the memory), I've never really understood the need to declare somethings with new, but otherthings don't need it.

I hope that makes sense, my question is basically why do we need operator 'new'?

Thanks for your time.

This topic is closed to new replies.

Advertisement