For some reason, I am totally obsessed with this so it's one of the things I love about python! The basic idea behind it is quite simple. You calculate like in math with numbers but with String or text instead. Many programming languages allow you to do concatenation using the "+"-sign. Python also implements multiplication allowing "s" times four to equal "ssss".
Defining String
A string is a data type in programming languages to store text data. The way it does that is by storing characters in an array or list. "ABC" contains the characters "A" at position zero, "B" at position one and "C" at position two (in programming counting it often started at zero).
Addition
Just like in all the programming languages addition will work like that. It's quite simple. When you add 3 to 5 you get 8. In our example though if we add an "a" to a "b" it's gonna be "ba". The difference between our addition and the addition of (ℕ, +) is that ours is not commutative. Commutative means that a + b = b + a. In the case of (ℕ, +): 3 + 5 = 5 + 3. In the case of the way, most programming languages do the addition of Strings the second one is added to the first one. It is a concatenation after all.
- 3 + 5 = 8 "a" + "b" = "ab"
- 5 + 3 = 8 "b" + "a" = "ba"
It does not work in our case. You could argue that "ab" equals "ba", but.. it just feels wrong.
Continuing With (ℕ, +) Properties!
Let's move on to the next aspect. The (ℕ, +) group has a neutral element. The neutral element is zero. The neutral element basically does not change any element of the group if the group operation is used upon it. This means that a + 0 = a. We actually have that too when working with Strings. There's something called the empty String "". It's basically a String with no characters in it, a length of zero pretty much. If we add or concatenate this to anything it will result in the same you started off with:
- 5 + 0 = 5 "a" + "" = "a"
- 0 + 5 = 5 "" + "a" = "a"
Funnily enough, the neutral element is also commutative, haha.
String Subtraction
Another property of the (ℕ, +) group is that there is an inverse element. If you apply the group operation to an element and it's the inverse element you get the neutral element. Additionally, the inverse element undoes the element. The inverse of three is minus three since 3 + -3 = 0. The inverse is often written with a negative exponent, a^-1. As such we have a definition like a + a^-1 = 0. This doesn't work for our strings though. The only way to get an empty string is to remove elements. We need the opposite of adding one character. We basically want to undo "" + "a" = "a" and that's removing the character. For this, we're gonna use the same way it's written with normal calculations. Thus we say "a" + -"a" = "". Interestingly we just declared subtraction
The definition of String subtraction will now be:
"The removal of a character, the opposite of the concatenation."
But what if we have multiple elements like in "Hello"? Well, concatenation adds to the end. Thus subtraction should work just like that. If the character is not at the end, we just take the last occurrence of it. Simple, isn't it?
- "Hello" - "o" = "Hell"
- "Hello" - "ll" = "Heo"
Another thing we can define here is the subtraction of an a∈ℕ. Let's not go too complicated and just define it as subtracting a character from the end. So "Hello" - 3 = "Hel".
String Multiplication
In python, if you multiply an a∈ℕ with a String it takes the String multiple times. That makes sense. If we look at the definition of multiplication you might have learned that taking three apples four times you get twelve apples. Taking the three-four times is not different from 3 + 3 + 3 + 3 = 12. Which is the same as 3 * 4 = 12 thus 3 + 3 + 3 + 3 = 3 * 4 = 12.
If we concatenate "a" + "a" + "a" + "a" we get "aaaa". This is the reason why python defined String multiplication so that 4 * "a" = "aaaa".
But what about multiplying "a" * "b"?
The distributive property of (ℕ, *) allows a(b + c) = ab + ac. If we calculate "a" * ("b" + "c") we can calculate the addition to get "a" * "bc". If we assume that the result follows the example from the (ℕ, *) we can potentially define "a" * ("b" + "c") = "ab" + "ac" = "abac". This means that
"a" * "bc" = "abac". This is similar to how matrix multiplication works.
The only weird thing we get from this definition is that "a" * "a" = "a" + "a" = "aa". It sounds not too bad. But there's one more thing I want to define and let's see whether or not it causes issues.
String Division
While this sounds like we're going to partition our Strings it's gonna be more like it works in normal math. There are multiple ways to calculate division. But we go with the opposite of multiplication.
One of them is to see it as the opposite of the multiplication. We're saying that if 3 * 5 = 15 we can also reverse or inverse this with 15 / 5 = 3. This means that if "a" * "a" = "aa" then "aa" / "a" = "a". At the same time our other example of "abac" / "a" = "bc". As you can see basically what happens is that division removes all occurrences of the divisor. This clashes with the multiplication of "a" * "a" = "aa". Since the opposite of it is "aa" / "a" = "a" but we would want it to be "aa" / "a" = "". Additionally if we assume "aa" / "a" = "" this means that "" * "a" = "aa", however, logically multiplying something with the empty String per our multiplication should result in no change.
"" * "a" = "a". This also matches the "a" / "a" = "".
I guess there's a reason why people use "w/o" as "without".
Hooray
We defined the plus, minus, multiplication, and division on Strings or Text. It can't get any nerdier than that. The only issue is that "a" * "a" is not defined as the result does not make any sense in our definition. Though there might be even more issues in there. Nonetheless, it is fun just to think about such weird things, think it through and see how much hold up. Also, you can troll your friends or other people by calculating "1" + "1" = "11". :P
- 1 + 1 = 2
- "1" + "1" = "11"
- 0b1 + 0b1 = 0b10