(C++11 is actually an interesting thing to analyze regarding this tradeoff, by the way: the new "common initializer" syntax is designed to provide as much of the benefits as possible of a simplified built-in data type syntax without taking on the semantic burden of having it; however, it also does not provide syntax that ends up being entirely devoid of the type of the container.)
You can't redefine haskell's syntax unless you're using Template Haskell (which is a language extension, not part of Haskell itself). It also has nothing to do with monads. Likewise with most MLs, or with Erlang. All of them have a literal list syntax.
And if containers have no reason to be special, why would strings be special? They're just sequences of unicode codepoints after all.
Continuing your argument into absurdity, why have literal syntax for most datatype at all really? You could just shove a bag of bytes into a constructor when you want integers or floats as well. Now you've got one literal syntax (which isn't even for a datatype): bunch of bytes.
As for strings, it is very seldom that you find interesting alternative implementations: the only one I can think of is a rope. Interestingly, C++11 now allows you to override string literals, so you can actually do this.
Sure but it's not syntax redefinition.
> Interestingly, C++11 now allows you to override string literals, so you can actually do this.
You still have a literal string notation. Literal notations don't have to impede multiple implemetations, and the truth is there is generally a primary representation used for the vast majority of cases (even if that representation is a cluster class and flexible under the interface).
In Cocoa, the primary sequence and maps are NSArray and NSDictionary, what would be the issue with making those literal? And one of your objections is
> When this suddenly matters, you are in the situation where what you want to be able to do is to make a very small modification to areas of your code where you need to select a different algorithm, in order to get the different result; you don't want to be forced to rewrite half your code to use a different syntax just because it was slow
But that makes no sense: as long as all equivalent containers implement the same interface (which they do, or you can't swap them anyway) that creating an object be done with a literal or with a constructor and a bunch of messages has no influence on the rest of the code, the only thing you need to change is the initialization code in both cases.
Hell, a smart enough editor can even swap between the literal and the "constructor" versions of a given collection (IntelliJ can do that for Python dicts, for instance). Not to mention in many cases the non-literal can just take the literal as a parameter, if the collection with a literal syntax has been well chosen, that way you get your cake eat it.
http://gcc.gnu.org/onlinedocs/gcc/Constant-string-objects.ht...
I will also, though, point out that I write almost as much (if not more) Python as I do Objective-C++ these days: I therefore can be said to certainly not consider Python to be for "stupid people", without including myself in that set. ;P