String concatenation like in PHP

Absolutely obvious idea, and I don't understand why other programming languages have not implemented that thousand years ago:

"string" . " concatenation" // "string concatenation"

This is the way to remove confustion between + sign for strings and + sign for numbers.

1 Like

So, what would happen if you tried to use a number with this "." operator? Would it throw a type error? Or try to coerce it into a string?

And what about other operators that fall into a similar boat? Like using obj[attr] for both property access and array entry lookup? Should those be separated out as well, to make it more obvious what you're trying to do. (I know that technically array entry lookup is property access, but on a high level, the two actions are done for different purposes, and a similar argument can easily be made to have a different array lookup operator).

(Also, as a minor note, we would need to pick some other operator, as . already means property access. You wouldn't be able to concatenate two string variables.)

const x = 'hello '
const y = 'world!'
console.log(x . y) // Today this would print undefined, we can't break this behavior.

I'm a little skeptical about how much value this would actually add. I usually don't feel like I get that confused about what the "+" is doing when reading other people's code, it's usually easy to tell from the context. but as I actually think about this more, I do recall an area in my code where I've wanted to concatenate a bunch of items together as a string, some of which were not strings. I had ended up writing it like this:

return '' + a + b + c + d + e

which feels a little icky. Though, I guess an alternative solution would have been to simply coerce the non-string values into strings first.

return String(a) + String(b) + c + String(d) + e
return '' + a + b + c + d + e

...

return String(a) + String(b) + c + String(d) + e

Though these two are also not necessarily equivalent ;)

const o = v => ({
  [Symbol.toPrimitive]([d]) {
    return d === 'd' ? `<${v}>` : `[${v}]`
  }
})
const a = o('a')
const b = o('b')
const c = ' "c" '
const d = o('d')
const e = ' "e" '

console.log('' + a + b + c + d + e) // <a><b> "c" <d> "e" 
console.log(String(a) + String(b) + c + String(d) + e) // [a][b] "c" [d] "e" 

If we cannot use β€œ.” (as does Perl or PHP), we can use β€œ~” (as does Raku) or whatever else. This is not a problem.

The real problem is the legacy β€œ+” operator, for which the legacy semantics will remain unchanged because of BC constraints, as no browser vendor would want to break the web. As a consequence, we are stuck with "1" + 1 == 11.

There's also that "template literals exist", which do all the right things, and just don't happen to involve a binary operator.

2 Likes

I would suggest another operator, like ##, for arbitrary concatenation of literals and variables. For concat of literals, we can omit the operator:

const x = 'hello' ' ' 'world';
const y = "hello " ## "world";
console.log(x === y) //true

We don't need a system for concatenating two literals. Just make it one literal.

But what if each literal is too long and needs to be split between lines?

It doesn’t.

Also you can use a template tag, or backslashes in a string literal.

True. I forgot about tagged template literals.

But I didn't know about the backslash thing. I thought it only worked in some langs, but not JS. It looks kind of ugly:

'\
example\
 text\
 string\
' == "example text string"

While a "cleaner" version looks like:

'example'
' text'
' string' == "example text string"

https://www.npmjs.com/package/deline

1 Like

I have to admit deline is a better alternative. Now I feel kind of stupid, lol