I am currently working on a JVM-based programming language that supports operator overloading and custom operators. I wanted to stick to Java and use the +
operator for String concatenation, and this is implemented and works flawlessly in my language. However, the operator is also used in various other places, for example to add elements to a collection:
public interface Collection[E]
{
// ...
public Collection[E] +(E element)
// ...
}
List[String] strings = List()
List[String] strings2 = strings + "a"
As you can see, there is an ambiguity here: strings + "a"
can either mean 'call the +
method of Collection
to add an element to the strings
' or 'convert strings
to a String and append the String "a" to that String`. For the second meaning, the above code would generate a compile-time type error, which is currently what happens if you were to type this code in my language.
How would I go about solving this ambiguity, and how do other languages with operator overloading and +
for String concatenation (e.g. Scala, Xtend, ...) handle this problem?
If you're worried about that (which you should be), then define it.
Python has a concept of a reverse-operator in addition to the normal forward-operators. There is a defined method by which these work.
C++ takes the approach of "there's no such thing as a reverse-operator, but things can be casted." By Python's rules, your example would be:
Python would do this:
C++ would do this:
Now, if that weren't so, it'd do this next:
This, if necessary, goes through the list of all possible operator+ functions and sees if the arguments can undergo a constructor-based or operator-based cast to fit them to the function or a template instantiation of the function. THIS is when it would attempt to cast List[String] to String, but it would probably find that there's no user-defined conversion between a List[String] and a String.
The moral of the story: define it.