Given the significant number of languages other than Python that have some version of a feature that allows implicit conversion of unlike operands to concatenate something like a "number" and a string into a string, the question may not be silly as to how or why Python chose as it chose.
As I see it, python did put in quite a bit of customizability and flexibility including the ability to create your own object types that alter the behavior of an operator like plus. I have seen plenty of code that takes advantage and makes the user of the code assume that different types can interact seamlessly. But it is like many other things. Languages that support a wide variety of integer types such as signed and unsigned versions of integers in 8 bits, sixteen bits, 32 bits and even 64 bits or perhaps higher, will often look like they allow you to mix them in various combinations for not just addition. But underneath it all can be lots of hidden complexity. I have seen languages that make lots of functions with the same names but different signatures and then dispatch a call like add(int8, unsignedint32) to the right function that best matches their signature. The functions internally can do many things but often convert their arguments to a common format, perform the operations, then perhaps convert back to whatever result output was expected. In the case being discussed we might have to create something that looks like do_plus(int, int) and then do_plus(int, char) and so on. The other alternatives can include tables of "generality" and "convertibility" with rules that govern how to perform a calculation by changing or upgrading or downgrading things to make a match that can then be handled. The issue here is a sort of operator overloading. In Python, "+" does not mean plus at all. It means whatever the programmer wanted it to mean. An infix line of code that includes "obj1 + obj2" is supposed to investigate how to do it. I am not sure if some built-in objects may be different, but it does a sequence of operations till it finds what it needs and does it. I believe it looks a bit like this. The LHS object, obj1, is examined to see if it has defined a __add__() method. If found, it is called and either produces a result or signals it cannot handle obj2 for some reason. If that method is not found, or fails, then it looks to see if the RHS, obj2, has a __radd__() method defined. That can be given obj1 and return an answer or signal failure. If obj1 is 5 and obj2 is "pm" then we are using the built-in predefined classes that currently have no interest in concatenating or adding unlike types like this. If you could add or change these dunder methods (and note you may also need to deal with __iadd__() to handle the case where x=5 and you write "x += "pm" albeit that could weirdly change the type of x without a linter having a clue. I suggest the latter argument may be a good enough reason that Python did not implement this. There are many good reasons. Does anyone like a language that lets you type 2 + "three" and quietly makes that be 5? Sure, it can be made to work on a subset of number in say English, but will it work in other languages. It can be hard enough now to write code in UNICODE (I have seen some) that tries to determine if a code point represents a number in some language or representation and treats it as a numeral. I have seen the numeric bullets such as a dark circle containing a white nine be treated as if the user had put in a nine, for example. As was mentioned, some languages have different operators for addition versus concatenation and in that context, it may be intuitive that using the wrong object type is an implicit call to conversion. Python uses "+" for both purposes depending on context and potentially for many more purposes the programmer can devise. Consider the asterisk operator as a companion concept. It gladly accepts a string and a number in either order and does something somewhat intuitive with them by treating multiplication as a sort of repeated addition: >>> 5 * "6" '66666' >>> "5" * 6 '555555' >>> 3 * "Hello? " 'Hello? Hello? Hello? But it will not handle float. >>> "Hello" * 2.5 TypeError: can't multiply sequence by non-int of type 'float' If you want to either truncate a float to an into or round it or take a ceiling, though, it will not guess for you and you must do something explicit like this: >>> "Hello" * round(2.5) 'HelloHello' >>> "Hello" * round(2.6) 'HelloHelloHello' >>> "Hello" * int(2.6) 'HelloHello' There is a parallel argument here in arguing it should accept a float and truncate it. But since you can easily cast a float to an int, in any of many ways, why have the program choose when it quite likely reflects an error in the code. And, no, I do not suggest 2.5 be interpreted as putting in an approximate percentage so that .8 * "Hello" should result in "Hell" ... -----Original Message----- From: Python-list <python-list-bounces+avi.e.gross=gmail....@python.org> On Behalf Of Cameron Simpson Sent: Wednesday, April 12, 2023 11:43 PM To: python-list@python.org Subject: Re: Weak Type Ability for Python On 13Apr2023 03:36, MRAB <pyt...@mrabarnett.plus.com> wrote: >I thought that in Java you can, in fact, concatenate a string and an >int, so I did a quick search online and it appears that you can. I stand corrected. I could have sworn it didn't, but it has been a long time. - Cameron Simpson <c...@cskk.id.au> -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list