The issue here is a consequence of the automatic conversion of strings to numbers and vice versa according to the context, combined with the fact that the + operator acts as addition or concatenation, again depending on the context. There are at least two scenarios where this can cause you problems.
One is that most operators and functions expect a certain type of argument, and if that doesn't match the type supplied, it inserts a STR() or VAL() operation to convert the argument. So for example, LEN(987) results in 3 because it gets converted by the compiler into LEN(STR(987)), i.e. LEN("987"). Usually that's intuitive. The one place where it isn't is with the STR() function. Since it expects a numeric argument, if you pass it a string, it inserts a VAL() operation. So for example, STR("ABC") becomes STR(VAL("ABC")) which is zero, not "ABC". See
this thread for another discussion of the problem in which we entertained the possibility of changing the behavior to be more intuitive (even if less consistent), but I think ended up deciding not to out of fear of breaking backward compatibility.
Your solution of
STR(num1 + num2) works because of a variation of the same non-intuitive concept, i.e. it expects numeric arguments to it sets the expression mode to numeric, thus overriding the string mode set initially by the string result variable.
The other one is accidental concatenation. The expression
string = (num1+num2) starts out with a string variable, which sets the expression mode to string. That in turn causes the subsequent operands num1 and num2 to be converted to string, which then causes the + to work as concatenation. To avoid that, you either have to change the result of the expression to be a numeric variable, or insert explicit conversion functions, or use the
Explicit Plus Operators, or the
NUMEXPR$() function.