I don't really see how `name =~ "somepat"` is any more readable or writable than something like `name.matches("somepat")`, which can be trivially added as an extension of String, and needs no special syntactic support. Something like this:
extension String {
func matches(pattern: String) -> Bool {
return Regex.new(pattern).test(self)
}
} > They should put big intrusive warnings on operator
> overloads to discourage their use, like…
"Warning, you are using the addition operator to concatenate two Strings. Don't do this!", said no compiler, ever. Only C does the "right thing" with char*s or chars when using '+' ;-)In Swift, operator overloading requires no special syntactic support. Since it's a supported language feature, don't be surprised to see people use it.
Over the last decade I've heard this repeated (and been stuck in languages which don't support operator overloading), and by chance, the very first project I chose to try to implement in Swift and I found a valid use for operator overloading (manipulating coordinates in a simple 3D renderer).
foo = foo.add(bar)
baz = baz.div(car)
vs. foo = foo + bar
baz = baz / car
or even better: foo += bar
baz /= car
Unrelated to operator overloading, but taking some Objective-C 1.0 -> Swift resulted in 50% fewer lines of code (and I'm guessing ⅓ the total characters).edit: bug ;)
Several reasons:
It's not obvious what an operator does, whereas names are descriptive. Some operators are "obvious", because they're firmly ingrained into our culture - (+) for addition is an example, it's almost universally understood to mean that. On the other hand, where in tilde, ~, is it obvious that you meant to test if a string matches a regular pattern? It's only obvious to descendants of PERL, for the reason that Larry Wall decided arbitrarily to use it for such. If every programmer invented his own operators instead of using the common languages we share, we would get nowhere.
Indeed, operator overloads are really useful when you use them the right way, as per your own example, but the flaw in allowing people to overload operators arbitrarily is that they abuse them to mean something unexpected - we all expect + to mean addition, but when it's used to concatenate two strings, it's easy to get confused as to why the hell somebody thought that was a good idea.
A big hurdle is even figuring out what an operator means if you've never encountered it. Unless you have good IDE support to navigate to its definition, or a specialized search engine for searching your language, then a typical search is going to turn up naught. On the other hand, most search engines understand [a-ZA-Z]+.
We could argue that using "+" for string concatenation "is obvious", at least to other programmers - but only because they've encountered such usage before. We can't reasonably expect to learn, recall, and fluently read arbitrary operators for any conceivable operation you can think of. Well, unless you're a fan of Control.Lens.Operators (http://hackage.haskell.org/package/lens-4.1.2/docs/Control-L...), then nobody else is going to read your code.
There's times where it really does make stuff much more readable. It's about finding and taking advantage of those times.
Like many language arguments, I think it distills down to those that believe that when looking at any piece of code, it should be immediately apparent what's going on or where to look to find that out even without much knowledge about the codebase even at the expense of more code and having to scroll around to see it all, and those that believe that reducing the overall size of the code to be seen to it's more concise if better, even at the expense of requiring a bit more foreknowledge of the codebase.
The extreme examples of this are probably Java at one end, and APL on the other. Less extreme examples are probably Python and Perl.
I don't think it's right to say either is better than the other. They both have obvious benefits and costs. Unfortunately, I think those cost/benefit ratios are often changed because of outside forces, such as business demands that change how much time or how often a codebase is worked on and by who, so the initial impression of the programmers accessing this code is greatly swayed by the circumstances that they first see it in.
I am in the camp that wants the power to define operators on new types, but I am not that sure about new operators.
For example, if Swift's implementation matches its documentation, one could make /"\\d{3,6}"/ a way to specify a regex:
- define a prefix operator /
- define a suffix operator /
- define prefix /(string s) to return some builder object that remembers that string
- define suffix /(builder b) to take the string that the builder remembered and produce a regex from it.
With appropriate precedence, that makes
/"\\d{3,6}"/
parse as - Take the string "\\d{3,6}"
- Send it to the prefix operator /
- Send what comes out to suffix operator /
Unfortunately, that's all done at run time (or at least, users cannot enforce that the compiler does it at compile time), and of course, it would work with any string, for example: /"\\d{3,6}" + myStringFunction("test")/
(Again, with good choice for operator precedence)Ugly or genius? That is all in the eye of the beholder.
I am sure that techniques like this can earn you high marks in obfuscated Swift competitions, however (tip for beginners: one can define prefix operators // and /* that allow one to hide code in what look like comments)