Sign in to follow this  

[java] Java No Operator Overloading Why?

This topic is 4748 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Just wondering why Java didn't implement operator overloading as have just converted a quaterion camera from c++ to java and the maths equations in java is just painful. Was there a good reason for leaving out op overloading?

Share this post


Link to post
Share on other sites
It was a matter of taste. The creators of Java decided that operator overloading can cause a lot more problems than the ones it can fix. And since Java is a language that is supposed to make shooting yourself in the foot as hard as possible, they kept it out.

shmoove

Share this post


Link to post
Share on other sites
Ican understand that op overload can create problems but, i think they really lost a valuable tool for equations. Of course it can be abused, i just think that its way to useful to just drop, have they ever considered introducing it i wonder, maybe i could send sun an email ;)

Share this post


Link to post
Share on other sites
Well, it's just syntactic sugar. You can do exactly the same without it, but the code will look different. Hell, you could even write a small preprocessor that can replace "overloaded operator syntax" to regular Java syntax right before compilation if it's that important.

And I'm sure you can send Sun a letter, but you'll probably have some more luck (though not much I wager) by becoming a JCP member and starting a JSR.

shmoove

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Preacher
Ican understand that op overload can create problems but, i think they really lost a valuable tool for equations.


Nope.

Only if your OOP skill is poor do you need op-overloading.

OR: if you are doing some niche stuff (e.g. financial services work). In that case, however, you SHOULDN'T BE USING JAVA - if what you *really* want is a mathematical language, you should be using a mathematical language, and preferably a pure functional one, and only using java for the non-mathematical bits.

Such niches are very small, so small that Sun decided rather than spite the many to make the few happy they would make the many happy and spite the few. They do have projects underway trying to make statistical analysis people happier with java, and there is lots of ongoing discussion about what changes Sun could introduce to make life easier for people who need more control over the FP operations, for instance. But 3D engines are not included, since they don't need any of this.

For 3D engines, there's no way you need op-overloading. Mainly because op-overloading produces inferior engines: there are too many things you need to do in an engine, and yet only about 6 operations that have stnandard meaning; these are way too insufficient.

For instance, in a 3d engine you need:
- add vector A to B, returning result C, without modifying anything
- ditto, but store result in A
- ditto, but store result in A and normalize it
- any combination of 1 above with 2 or 3 simultaneously

Seeing as each of these creates different numbers of temporary objects, and is used in different algorithms, you really need all of them (sooner or later), but there are only TWO standardized operators for addition: + and +=

And this is a simple case.

Most of the vector algebra you need to do benefits greatly from having the verbosity of words. Please c.f. the discussions in the 1980's and 1990's about whether we should use "long variable names". Most of the arguments in favour of long var names apply to non op-overloading (in addition to the other arugments against op-overloading).

The only time you need op overloading is when you need a mathematical language or you have a crap IDE. Go and get a better IDE with autocomplete. Even VIM can do heuristic autocomplete (i.e. it analyses your code and second-guesses what you probably want to complete, putting that to the first item in the list, so often you don't need to select an item manually).

(PS: I've written 5 software renderers, everything from C scanliners to a 3kb java engine with dynamic lighting. I speak from experience: over the years it's become more and more obvious that op overloading is unnecessary and undesirable in 3D engines)

redmilamber

Share this post


Link to post
Share on other sites
All good, i must admit i've haven't much experience making game engines its just as i siad my first try at making a quaterion camera was not helped by the fact that having to use methods to add, dot product etc.. vectors confused the matter further. I'm sure i'll get used to it in time and i didn't think of some of the ideas presented. So no to operator overloading then ;)

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Quote:
Original post by Preacher
Ican understand that op overload can create problems but, i think they really lost a valuable tool for equations.


Nope.

Only if your OOP skill is poor do you need op-overloading.

That's not necessarily true. Operator-overloading, while it can cause problems while it's being implemented, can also make code a lot easier to read when they are used. Honestly, which is easier to read?

This:
BigInteger num = a + b - c * d / e;

Or this:
BigInteger num = a.add(b.subtract(c.multiply(d).divide(e)));

True, you can get by without operator-overloading. Even the best OOP programmer would probably agree that the first example above is much easier to read and write, though. Since part of Java's purpose was to be simple and get rid of unnecissary complications, I have to agree with their decision to keep operator-overloading out of the language. However, to an experienced programmer operator-overloading can, when used properly, clarify code and make its meaning clearer. (I guess that's probably one reason why there's more than one programming language. [lol])

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by TheBluMage
Quote:
Original post by Anonymous Poster
Quote:
Original post by Preacher
Ican understand that op overload can create problems but, i think they really lost a valuable tool for equations.


Nope.

Only if your OOP skill is poor do you need op-overloading.

That's not necessarily true.


I did give one other possibility...

Quote:

Operator-overloading, while it can cause problems while it's being implemented, can also make code a lot easier to read when they are used. Honestly, which is easier to read?

This:
BigInteger num = a + b - c * d / e;

Or this:
BigInteger num = a.add(b.subtract(c.multiply(d).divide(e)));


Ha! You fell into the trap ;) :P. The second one is better, because it has explicit binding. The first one would need to be written:

num = a + (b - (c * d / e) )

in order to be as informative as the second.

Quote:

True, you can get by without operator-overloading. Even the best OOP programmer would probably agree that the first example above is much easier to read and write, though. Since part of Java's purpose was to be simple and get rid of unnecissary complications, I have to agree with their decision to keep operator-overloading out of the language. However, to an experienced programmer operator-overloading can, when used properly, clarify code and make its meaning clearer.


But...you're still talking "theoretically", and ignoring things like the simple fact that:

*

Has 5 standard meanings, just in basic programming, just off the top of my head. (multiply, cross-product, any-char, any-char-except-dot, FSM-0-or-more). I'm sure if I sat around all day I could think of 3 or 4 more common meanings.

Even:

+

has plenty of meanings in vector algebra (and even more in general computer science)

e.g. How many of these mean the same thing?

=
==
:=
:==
<=
=<
<

Answer: all of them, if you're writing parsers. Because the "standardization" on the first operator used in grammars is so weak that all the above are used frequently :(. They also mean 6 different things, if you're writing parsers. Confused? You will be...

It's a nice idea to think that the use of simple operators is "easier to read", but it's an idea that any professional programmer ought to soon realise is a pipedream: After more than 2000 years of history, Mathematicians *still* haven't managed to standardize on symbols, and they have a lot more to play with than programmers do. IMHO it is naive to think that a symbol means the same thing to different readers, and it's blatantly not true.

redmilamber

Share this post


Link to post
Share on other sites
BigInteger num = a.add(b.subtract(c.multiply(d).divide(e)));
(setf num (add a (subtract b (multiply c (divide d e)))))

BTW: "add" is just as ambigous as "+"

[Edited by - Trap on December 16, 2004 7:49:32 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
chuckle. Nice try.

Add is in fact less ambiguous than "+", seeing as the latter has standard meanings as diverse as (space), but your point is fair.

However:

1. add can be embellished to addAndStore, addEquals, addNoCopy, addNormalized, etc etc, whilst still clearly being a derivative of the basic add function, whereas embellishment of + to each of those is somewhere between hard and impossible

2. you would choose a better name than add. You don't get much option, comparitively, of "better operators", but your names can be as descriptive as necessary, and it doesn't even require more typing and it doesn't take up more space (if htose things are a concern to you).

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Quote:

BigInteger num = a + b - c * d / e;


Ha! You fell into the trap ;) :P. The second one is better, because it has explicit binding. The first one would need to be written:

num = a + (b - (c * d / e) )

in order to be as informative as the second.


No, not at all. It's called "order of operations."

And I dispute your claim that good OOP shouldn't use operator overloading. Really what all that comes down to is what your definition of "good" OOP is.

Share this post


Link to post
Share on other sites
Quote:
Original post by Strife
Quote:
Original post by Anonymous Poster
Quote:

BigInteger num = a + b - c * d / e;


Ha! You fell into the trap ;) :P. The second one is better, because it has explicit binding. The first one would need to be written:

num = a + (b - (c * d / e) )

in order to be as informative as the second.


No, not at all. It's called "order of operations."

And I dispute your claim that good OOP shouldn't use operator overloading. Really what all that comes down to is what your definition of "good" OOP is.
Don't bother, good little OOP coders cringe at using operators on primitive types anyway.

Share this post


Link to post
Share on other sites
Operator overloading can certainly be abused, but you're looking at some extremely basic examples. For the record, Direct3DX 9 has a C++ implementation that uses operator overloading.

Anyways operator overloading goes far beyond writing "+" instead of "add()". It starts to get cool when combined with templates (for example, any list storing objects with a < operator can be sorted using "sort", or unique/associative using "set" or "map").

If you want an advanced example of operator overloading in the context of template metaprogramming, check out LibSH at http://www.libsh.org.

However since Java does not have templates, then yes: you lose a lot of the advantages of operator overloading.

Share this post


Link to post
Share on other sites
Quote:
for example, any list storing objects with a < operator can be sorted using "sort"


correct me if i'm wrong, but isnt that just the equivalent of implementing the Comparable interface in java? your example of overloading is still debatably useful syntactic sugar...and what youre really talking about is templates anyway.

personally i think operator overloading can be nice, but its unnecessary and can often obfuscate more than what it is replacing...especially, as the AP pointed out, when symbols can mean completely different things to different people.

i like being more explicit, but thats just my style. just set up a preprocessor if it's not yours.

Share this post


Link to post
Share on other sites
Quote:
Original post by justo
Quote:
for example, any list storing objects with a < operator can be sorted using "sort"


correct me if i'm wrong, but isnt that just the equivalent of implementing the Comparable interface in java? your example of overloading is still debatably useful syntactic sugar...and what youre really talking about is templates anyway.

personally i think operator overloading can be nice, but its unnecessary and can often obfuscate more than what it is replacing...especially, as the AP pointed out, when symbols can mean completely different things to different people.

i like being more explicit, but thats just my style. just set up a preprocessor if it's not yours.

because by defining an operator instead of implementing an interface, you can write containers that can hold both primitive types and class types. If you implement an interface, then you will have to box those primitive data types. ugly code ensues.

Share this post


Link to post
Share on other sites
Quote:
Original post by justo
correct me if i'm wrong, but isnt that just the equivalent of implementing the Comparable interface in java? your example of overloading is still debatably useful syntactic sugar...and what youre really talking about is templates anyway.

Agreed, it is mainly the templates that give operator overloading power, although they can also do some very cool things when combined with recursion :) As capn_midnight noted as well, it allows more flexible containers without needing to "wrap" any existing objects in this interface.

Quote:
Original post by justo
personally i think operator overloading can be nice, but its unnecessary and can often obfuscate more than what it is replacing...especially, as the AP pointed out, when symbols can mean completely different things to different people.

Agreed. Like most programming language features, it can be misused. However, that isn't a point for its global disutility.

There are also other things that you can do with operator overloading that are somewhat cool. For example, you can make a data type interchangable with a primative. I've seen people who code "float" classes that compile down to using the primative type directly, but give them the flexability to change between float and double, rounding modes, implementations of "_ftol", etc. It can be pretty powerful actually, and allow another level of abstraction.

Of course it isn't necessary to accomplish anything, but neither is OOP. Both are just tools that in some cases can make the management of larger programs easier, and reduce bugs. Of course both when misused can do the opposite!

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Ha! You fell into the trap ;) :P. The second one is better, because it has explicit binding. The first one would need to be written:

num = a + (b - (c * d / e) )

in order to be as informative as the second.

As was mentioned by Strife, the order of operations comes into play and naturally implies what will be done first. Yes, operator overloading is just syntactic sugar, but when you get down to it, so is every other part of any high-level language. It's all just sugar that wraps the underlying processor commands. Even assembly could be concidered syntactic sugar, as it uses words (ADD, SUB, MUL, DIV, MOV, etc.) to hide the 1's and 0's that are actually getting fed to the processor. Our lives would be a lot harder without syntactic sugar.

Quote:
Original post by Anonymous Poster
*

Has 5 standard meanings, just in basic programming, just off the top of my head. (multiply, cross-product, any-char, any-char-except-dot, FSM-0-or-more). I'm sure if I sat around all day I could think of 3 or 4 more common meanings.

The word 'multiply' has six standard meanings, just looking in my dictionary:

multiply1
1. To increase the quantity, amount, or degree of.
2. Math. To determine the product of by multiplication.
3. To become more in number, amount, or degree; increase.
4. Math. To determine the product by multiplication.
5. To grow in number by procreation; propagate.

multiply2
So as to be multiple; in many ways.

I won't go into the word 'add', as I would have to sit here most of the day typing.

Quote:
Original post by Anonymous Poster
Answer: all of them, if you're writing parsers. Because the "standardization" on the first operator used in grammars is so weak that all the above are used frequently :(. They also mean 6 different things, if you're writing parsers. Confused? You will be...

Speaking for myself, the symbols didn't confuse me anywhere near as much as the arguments against them. (No offense.)

Quote:
Original post by Anonymous Poster
It's a nice idea to think that the use of simple operators is "easier to read", but it's an idea that any professional programmer ought to soon realise is a pipedream: After more than 2000 years of history, Mathematicians *still* haven't managed to standardize on symbols, and they have a lot more to play with than programmers do. IMHO it is naive to think that a symbol means the same thing to different readers, and it's blatantly not true.

Unlike mathematical symbols, programming languages can easily be standardized, though that decision hasn't been made yet for Java. If you think about it, the mathematical symbols we use are much more universal than the words used to represent their meaning. Pick out at random a programmer who doesn't speak English and ask him or her to interpret the following:

num = a + b - c * d / e

Then ask him/her to interpret this:

num = a.add(b.subtract(c.multiply(d).divide(e)))

Which one do you think s/he will understand quicker? In my opinion, it's naive to think that an English word will mean the same thing to different readers.

I have nothing against the decision to avoid operator-overloading in Java - it makes sense for this language. The technique itself, though, can be a very powerful tool and shouldn't be dismissed as something reserved for people with "poor OOP skill".

Share this post


Link to post
Share on other sites
Yes operator overloading, yet again.
Operators are for example:
new
)
>
:
=
,

and imagine overloading this ";"

Of course Java does have operator overloading. Did you ever seen this? System.out.println(" line "+variable) ;
It's operator overloading described in the Java language specification. Java, however doesn't alow to define your own extremely "clever" ways how to ... It's one of big advantages, if you have hunger for operator overloading use an advanced IDE and do your worst. (Just the output files would be readable by any standard compiler, and by some programmers.)

So if you'd like to overload add for vectors, then it might be interesting how your code would look if you'd use some unstandard add in the mix.
And how would look operator for dot and cross product?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by TheBluMage
The word 'multiply' has six standard meanings, just looking in my dictionary:


c.f. below for my comment re: suitability of such words. I would never use them as method names (c.f. my original points: the advantage of not op-overloading is your ability to use rich method names. Using overly generic words like "multiply" is throwing away that advantage).

As noted previously, you can embellish the word until it's precise enough. Embellishing operators is much much harder, because our vocabulary to describe an operation through operators is very very poor (compared to our vocabulary to describe something in our native language).

Quote:

Speaking for myself, the symbols didn't confuse me anywhere near as much as the arguments against them. (No offense.)


Ah...the confusion comes when you see 3 of them used at once in the same equation. Which means which? Or ... when you see 3 separate equations that use 3 separate operators to mean the same thing. Or do they? Do they mean different things? How do you know? There isn't a standard... (Well, there is, but this is the point: it's a standard honoured more by it's avoidance than it's adherence)

Quote:

Unlike mathematical symbols, programming languages can easily be standardized, though that decision hasn't been made yet for Java.


! The moment you do that, you have removed operator overloading.

Java standardization of operator meaning == exact opposite of adding operator overloading into the syntax of the language.

You can't have it both ways...

Quote:

Pick out at random a programmer who doesn't speak English


That is a great point. Unfortunately, the way the world works, you have to speak english to be a programmer, or else suffer massive restrictions on your employability. If API's tended to be i18N'd then you would be going somewher; however, at the same time, different nationalities are considerably more likely to disagree on symbol meaning than same nationalities: this is the fault of the mathematicians, because over the centuries symbols have been divided along teacher/student groupings AND national boundaries. e.g. there are common symbols which German mathematicians "tend" to use where English ones "tend" to use a noticeably different one.

Quote:

In my opinion, it's naive to think that an English word will mean the same thing to different readers.


Point taken. But...as I said earlier (I think it got lost in the discussion going on here) the word "add" or "multiply" is a bad method name anyway (ask any good OOP practitioner) - you'd typically use 3 words for the method name (c.f. my earlier examples of appropriate names in a 3D engine).

By that point, the English words are going to mean the same things to different readers, because of the increased amount of context, but ... some may need a dictionary to work out what they mean. As noted above, this is sad, but the way the world works.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Raghar
Of course Java does have operator overloading. Did you ever seen this? System.out.println(" line "+variable) ;


That's an overloaded operator, not operator overloading ;D. The former is typically used to mean "an operator with multiple meanings" and the latter to mean "the ability to programmatically add extra meanings to an operator".

WHY did they do this? IIRC + is the only (non-numeric) example of operator overloading in java.

...IIRC, it basicaly went something like this:

1. We need a string-concatenation operator

2. It's typed very veyr very frequently, so we can't use a keyword to do it (c.f. "instanceof" which is an infix operator which is a keyword - it's used rarely, so using a word was deemed "OK")

3. Only numerical operators have multi-symbol operators (+=, -=, etc). It would be nice to retain this "operators are all only one symbol, unless they're numerical" as far as possible.

4. + is already semi-standard as a string-concatenation operator in other languages.

IMHO, they would have been better off using a 2-char symbol (perhaps ::, which is the ML concatenator symbol). I don't thikn they had any idea how this one small decision would repeatedly open the way for the more naive fans of op-overloading to start arguments with "java already has op-overloading, so why not make it programmatic?". (not accusing Raghar of doing this, but I've seen so many others say it so many times)

Share this post


Link to post
Share on other sites
Let's be clear here though: I think most people are in agreement that operator overloading should not be in Java. Java is intended to be a simpler language and should remain that way: many question the introduction of generics and other more advanced features into Java, as it begins to erode the very reason that Java is good in the first place.

That said, operator overloading DOES have its place, beyond simple syntactic differences (see my previous posts). Can you accomplish the same things without it? Certainly. But similarly you can accomplish the same things as Java can in assembler (a VM assembler if you want to split hairs).

Can operator overloading get confusing? Absolutely. Can long method names on simple objects (like n-tuples or matrices) get confusing? Of course. However in certain situations both of these conventions can make things EASIER to read, provide MORE power and generally help the programmer.

I will agree that operator overloading can be somewhat dangerous in the hands of a novice who will be temped to just start providing automatic casts, and operator overloads for every situation. However if you truely understand the tool and what you are doing, it is indeed useful.

I would suspect that there would be a greater proportion of C++ coders that understand what is going on at the base level than Java coders. This isn't meant as an insult at all (personally I use both languages for different things), but rather an exact expression of the target market of both products. With that in mind, it's probably best to keep some of the more advanced and less-frequently-used programming language features OUT of Java. That is, indeed, the point.

[Edited by - AndyTX on December 17, 2004 12:46:06 AM]

Share this post


Link to post
Share on other sites
Operator overloading breaks the philosophy of oop, so java avoided it, since it trys to stick ot a strict OO philosohpy. (that way, for example, you can't have things outside of classes, either)

C++ only has it because it's multiparadigmed and allows you to create more natural constructs.

Operator overloading confuses the OO concept of sending a message to an object.

object.message(parameters).

One form for calling a function. Very simple.

object + parameters

would be another form. For what reason?

I have a toy language of my own that's got some nifty features w.r.t. operators, since it's not object oriented (unless you VERY loosely interpret that word). For example, "if(currentNum in? seenNumbers)" is a valid statement.

Share this post


Link to post
Share on other sites
If Sun were really worried about breaking the OOP philosophy of Java, then they wouldn't have introduced the overloaded + operator for string concatenation. It's tatamount to hypocrisy.

And if Sun were worried about elliminating possible ways the programmer could mess things up, and increase readability, then they would get rid of annonymous inner classes (egad, my eyes, it's like fire)

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Quote:
Original post by Preacher
Ican understand that op overload can create problems but, i think they really lost a valuable tool for equations.

Nope.

Only if your OOP skill is poor do you need op-overloading.

Can you justify that claim? In what manner is operationg overloading incompatible with object-orientation?

I understand object-orientation to be comprised of polymorphism, encapsulation and inheritance.

The key point is here polymorphism. Polymorphism is a Good Thing because it allows you to use the same code to perform sematically equivalent operations upon objects of different type using the same code.

e.g. in C++

template<typename T> T average (int size, T *array) {
T r = 0;
for (int i = 0; i < size; ++i)
r += array[i];
return r / size;
}


This works on any type of object that defines (1) a conversion from 0, (2) a += operator, and (3) a / operator.

Requiring += is a bit nasty. But I can use polymorphism again to define += for any type that supports addition and assignment:

template<typename T1, typename T2>
T1 & operator += (T1 & a, const T2 & b) {
return a = a + b;
}

Quote:

OR: if you are doing some niche stuff (e.g. financial services work). In that case, however, you SHOULDN'T BE USING JAVA - if what you *really* want is a mathematical language, you should be using a mathematical language, and preferably a pure functional one, and only using java for the non-mathematical bits.

Then it's lucky that Java makes it so easy to use functions exported from programs written in a mathematical language (whatever that is).

Oh, hang on... It doesn't.
Quote:

For 3D engines, there's no way you need op-overloading. Mainly because op-overloading produces inferior engines: there are too many things you need to do in an engine, and yet only about 6 operations that have stnandard meaning; these are way too insufficient.

For instance, in a 3d engine you need:
- add vector A to B, returning result C, without modifying anything
- ditto, but store result in A
- ditto, but store result in A and normalize it
- any combination of 1 above with 2 or 3 simultaneously

Seeing as each of these creates different numbers of temporary objects, and is used in different algorithms, you really need all of them (sooner or later), but there are only TWO standardized operators for addition: + and +=

How is this a problem?

c = a + b;
a = a + b;
a = normalize(a + b);

Simple. And I didn't even need to use +=.

What's that you say? It's inefficient because of those temporary objects? So you think that you're better at optimising away temporary objects than the compiler, do you?

Premature optimisation is the root of all evil.
Quote:

And this is a simple case.

Most of the vector algebra you need to do benefits greatly from having the verbosity of words. Please c.f. the discussions in the 1980's and 1990's about whether we should use "long variable names". Most of the arguments in favour of long var names apply to non op-overloading (in addition to the other arugments against op-overloading).

Yes, you're quite right. That's why Java doesn't use short names like "+" and "int" for commonly used concepts.

Addition is not a bizarre concept. You don't need to think outside the box to figure out what "a + b" is intended to do when a and b are vectors.
Quote:

The only time you need op overloading is when you need a mathematical language or you have a crap IDE. Go and get a better IDE with autocomplete. Even VIM can do heuristic autocomplete (i.e. it analyses your code and second-guesses what you probably want to complete, putting that to the first item in the list, so often you don't need to select an item manually).

Quite so. That's the only time.

Consider these three lines of code.

a = a * t + b * 1 - t;

a = a.mul(t).add(b.mul(t.rsub(1)));

a = a.multiplyAddToMultiplyBySubtractFrom(t, b, 1, t);

Clearly, the first is opaque and impossible to understand. The second makes things almost crystal clear. But the third, with its long name, leaves us with absolutely no doubt as to what the code is going to do.
Quote:

(PS: I've written 5 software renderers, everything from C scanliners to a 3kb java engine with dynamic lighting. I speak from experience: over the years it's become more and more obvious that op overloading is unnecessary and undesirable in 3D engines)

Ah, argument from authority, is it?

Share this post


Link to post
Share on other sites

This topic is 4748 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this