Salvador Dali
Salvador Dali

Reputation: 222601

Why is "int + string" possible in statically-typed C# but not in dynamically-typed Python?

While studying C# I found it really strange, that dynamically typed Python will rise an error in the following code:

i = 5
print i + " "

whereas statically typed C# will normally proceed the similar code:

int i = 5;
Console.Write(i + " ");

I would expect other way around (in python I would be able to do this without any casting, but C# would require me to cast int to string or string to int).

Just to highlight, I am not asking what language is better, I am curious what was the reason behind implementing the language this way.

Upvotes: 10

Views: 730

Answers (6)

Eric Lippert
Eric Lippert

Reputation: 660159

You are right that something is odd here. What is odd is that + means string concatenation in either language! Whether + can concatenate an int onto a string or not is a small point compared with the oddity that is + meaning "concatenate" at all.

I do not know which language first allowed + to be used to mean string concatenation, but that misfeature has been repeated over and over again so often that now we typically don't even notice how truly strange it is. Let's list some of the properties of normal addition and see if strings measure up.

  • Addition is commutative, but string concatenation is not. x + y != y + x
  • Addition is associative, but string concatenation in C# is not. (x + y) + z need not equal x + (y + z) if, say, y and z are integers.
  • Addition is paired with an inverse operation, subtraction, with the property that if x + y is z then z - y is x. There is no such operation for strings.
  • Addition has a left and right identity, and so does string concatenation. (The empty string).

One out of four ain't good. String concatenation is very unlike addition, so why should they share an operator?

I don't say this often but C got it right. The string concatenation operator should be just that: concatenation. In C "X" "Y" means "XY". If you put two string literals beside each other, they concatenate into a third.

Upvotes: 23

kindall
kindall

Reputation: 184190

This isn't really a static/dynamic question but rather a matter of language design philosophy.

In Python, + is defined to be addition for numbers and concatenation for strings. This is perfectly reasonable behavior if you have even a little programming experience.

But when you have one of each, what happens? Does it try to convert the string to a number, or does it convert the number to a string? Either is, again, perfectly reasonable behavior to anyone who has done any programming at all, but since different languages have different rules about how this happens, you may make assumptions different from the ones someone else would make depending on which languages you have experience with already.

Python has as one of its guiding principles "explicit is better than implicit" (import this) and so it makes you explicitly state which behavior you want. How? By converting either the string or the number to the desired type, of course. Then they are both strings or both numbers and the behavior is obvious.

The resulting code is easier to read (even if you don't know much Python), because you don't have to guess what it's going to do.

Upvotes: 9

Derek W
Derek W

Reputation: 10026

For C#, there is a method called ToString() for Int32(int) and almost all types for that matter - pointer types being the exception in this case.

The String class in C# has overloaded the + operator which in this case just makes a call to String.Concat(Object, Object).

In my opinion, this is more of a result of the workings of the .NET Framework than anything else.

Upvotes: 3

John Spong
John Spong

Reputation: 1381

Understanding the python data model (http://docs.python.org/2/reference/datamodel.html#emulating-numeric-types) will help you out here.

When you execute a + b, this is translated to a.__add__(b) behind the scenes. This is how python supports operator overloading, given the lack of static typing.

C# allows for implicit casting to strings via the ToString() method; python does not have any notion of implicit casting. This works, because ToString() is a method defined on every object, and C# has static typing, so it's obvious to the caller when their object is going to be casted.

If you want to see this behavior in action, you can run the following (but don't do this in production):

class MyString(str):
    def __add__(self, other):
        """ automatically concatenate other values as strings """
        return super(MyString, self).__add__(str(other))

s = MyString("this is a string")
print s + 1

Of course, if you look at the conversion above, you'll have trouble with print 1 + s. I suggest being explicit about your type conversion, even when just converting to string, since the edge cases will drive you crazy.

Upvotes: 2

Konrad Rudolph
Konrad Rudolph

Reputation: 545638

This isn’t really the area of static vs. dynamic typing. Rather it’s strong vs. weak typing (at least according to some commonly used terminology which Wikipedia also happens to be using in its characterisation of programming languages). And both C# and Python are strongly typed (by that definition).

All these notions are unfortunately not black and white but rather a greyscale, and ill-defined to boot. However, the upshot is that there are nuances in how strongly a language performs type checks, and which checks it performs.

It just so happens that in your particular situation C# overloads operator + for strings and numbers (actually, arbitrary objects), where Python doesn’t. This arguably makes Python slightly stricter in this case.

Upvotes: 9

redtuna
redtuna

Reputation: 4600

Dynamic typing doesn't really come into play here, both languages understand that i is an int and " " is a string. The difference is that C# has a function + that takes (int,string) arguments, Python does not.

Upvotes: 1

Related Questions