Yet another example of the horrible mess unprincipled automatic type conversion causes.
What prevents language designers from avoiding all these lurking bugs with a generic type-conversion operator? E.g. here's how it might look in a Python-like language:
>>> x = 1
>>> y = "2"
>>> print(x + cast(y))
3
>>> print(cast(x) + y)
"12"
>>> print(cast(x) + cast(y))
Exception: ambiguous type
you can already do exactly that in Python with a bit of evil magic:
$ cat evil.py
class cast(object):
def __init__(self, x):
if isinstance(x, cast):
self.x = x.x
else:
self.x = x
def __add__(self, other):
return other.__class__(self.x) + other
def __radd__(self, other):
return other + other.__class__(self.x)
$ python3 -i evil.py
>>> a = 1
>>> b = "2"
>>> a + b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> cast(a) + b
'12'
>>> a + cast(b)
3
>>> cast(a) + cast(b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "evil.py", line 9, in __add__
return other.__class__(self.x) + other
File "evil.py", line 9, in __add__
... repeated many times ...
File "evil.py", line 9, in __add__
return other.__class__(self.x) + other
RuntimeError: maximum recursion depth exceeded
Here's an example interaction. There's a difference, though, since + is only for {Num instance,Fin} addition while ++ is {String,List,Vect} concatenation.
Automatic type casting remains popular because it reduces the syntactic and cognitive overhead. I'm suggesting that a better solution would be to retain explicit casting, but minimise the overheads.
So, to take things a step further, lets use, say, the $ operator for casting. Then we have:
The proper way to do this is using something like TryParse() and ToString() and to handle the case of failing to parse the string as a number and maybe even specifying the locale for both operations. If you are absolutely sure that parsing can not fail you can use Parse() and omit the error handling.
What prevents language designers from avoiding all these lurking bugs with a generic type-conversion operator? E.g. here's how it might look in a Python-like language: