I think when mathematicians call an operation denoted by juxtaposition a "product", that's usually because it's denoted by juxtaposition for some independent reason and they're drawing the syntactic analogy with the numerical product, and there isn't any deeper connection with multiplication than that. Independent reasons for using juxtaposition might include:
1. juxtaposition is shorter than any alternative and hence a natural choice for the most common / only operation on the set in question
2. the operation is roughly analogous to function composition, and when you apply two composed functions it looks like f(g(x)) with f and g juxtaposed (if the functions are among those that have the longest history of being written as prefix operators, e.g. sin, cos, log, you don't even need the paren between the f and the g)
3. juxtaposition is a natural way to express an operation which is just "putting stuff together", such as string concatenation
So while it makes sense to denote string concatenation by juxtaposition in mathematics, I think it's a bit of a leap to go from there to say that A * B is the right notation for a programming language. (Actually using juxtaposition would be fine, but a general-purpose programming language is likely to want to reserve juxtaposition for something else.)
Also if you run with the idea that string concatenation = putting two strings together, well, addition is sort of like putting two numbers together. Rephrasing that in mathematical language: natural numbers can be encoded as elements of the free monoid on one generator, in which case the monoid operation turns out to be addition. I think that might be why the A + B notation is preferred over A * B when we have to choose one or the other.
I think multiplication for string concatenation makes more sense than just "its juxtaposition so we call it multiplication". If you look at type theory, then a tuple of type (A, B) is called the product type of A and B. This is because there are #A times #B elements in the new type. A Sum type, in type theory is a tagged union. It is an element of Either A or B. (Like a C union with an extra tag saying which type it contains). This is a sum because it contains #A plus #B elements.
Concatenation of strings is much closer to the tuple approach. And the argument about the number of elements in the type still holds if you keep the string-length fixed.
1. juxtaposition is shorter than any alternative and hence a natural choice for the most common / only operation on the set in question
2. the operation is roughly analogous to function composition, and when you apply two composed functions it looks like f(g(x)) with f and g juxtaposed (if the functions are among those that have the longest history of being written as prefix operators, e.g. sin, cos, log, you don't even need the paren between the f and the g)
3. juxtaposition is a natural way to express an operation which is just "putting stuff together", such as string concatenation
So while it makes sense to denote string concatenation by juxtaposition in mathematics, I think it's a bit of a leap to go from there to say that A * B is the right notation for a programming language. (Actually using juxtaposition would be fine, but a general-purpose programming language is likely to want to reserve juxtaposition for something else.)
Also if you run with the idea that string concatenation = putting two strings together, well, addition is sort of like putting two numbers together. Rephrasing that in mathematical language: natural numbers can be encoded as elements of the free monoid on one generator, in which case the monoid operation turns out to be addition. I think that might be why the A + B notation is preferred over A * B when we have to choose one or the other.