[swift-evolution] [Draft] Apply -ed/-ing rule to core functional methods (e.g. filter => filtered)

Brent Royal-Gordon brent at architechies.com
Fri Jun 17 21:13:40 CDT 2016


> – What sin(x) should do is unambiguous, unlike array.filter { ... }.

A decent argument label, like `including` or even `to`, would fix the name `filter`. And as I said, if we feel `filter` is unsalvageable, the alternate Smalltalk-lineage `select` is clearer.

> – There's very significant brevity issues here, e.g. hyperbolicArcTangent() vs atanh().

Sure, but `mappingAndFlattening(to:)` would have brevity issues as well. (You didn't think the API Guidelines merely meant "add -ed or -ing to everything", did you?)

> – The relevant metric of the strength of a term of art would be for how many users it already is a very much ingrained term (i.e. not how long it has been around). For sin() this is the case for pretty much anyone who has done high-school math. Conversely, map/filter/reduce will only be significantly ingrained for experienced users of languages that are functionally-centered enough to regularly use these, which is a much smaller percentage (though not insignificant).

I think "languages that are functionally-centered enough to regularly use these" makes this set of languages sound rather smaller than it really is. The languages with C in their names—C, C++, Objective-C, and C#—are almost the only ones in modern use which *don't* include higher-order functions. Few people would regard Perl, Javascript, Java, Python, or Ruby as "functional" languages, but all of them support `map`. If you look at RedMonk's list of 21 popular languages <http://fossbytes.com/21-top-programming-languages-on-github-and-stack-overflowjanuary-2016/>:

* 1 (CSS) has no real concept of lists or list operations.
* 2 (shell and C) do not have closures.
* 1 (Go) could support `map`, but K&R still think it's 1973.
* 1 (Objective-C) could support `map`, but...well, if the Foundation guys want to tell us why they don't, they know where to find us.
* 16 have a version of `map`:
	* 1 (Matlab) has vectorization features which act like an implicit `map`.
	* 2 (C# and Visual Basic) have a `select` operation from LINQ
	* 3 (C++, R, and Groovy) have other names for `map`
	* 10 (Javascript, Java, PHP, Python, Ruby, Perl, Scala, Go, Haskell, Swift, and Clojure) call it `map`.

Of 16 languages with `map`, Scala, Haskell, Clojure, and maybe R and Matlab would typically be considered functional, and all of those are in the bottom half of the list. The other 11 languages with a version of `map` are all mainstream multi-paradigm languages of the sort people coming to Swift might be familiar with.

In short: Higher-order functions are not a specialized feature that only the functional eggheads use. Outside of a few small pockets—one of which is native Apple apps—they are a pervasive feature of modern programming environments. They are the rule, not the exception.

>> Let me turn your question around: What concrete benefits do we gain from modifying terms which are extremely widely recognized? It is not consistent, but is there any reason to believe that causes actual confusion? If not, then why fix what isn't broken?
>  
> The benefits of renaming:
> – It makes learning easier as it establishes a consistent way to read Swift methods right from the start.
> – It would help users in intuitively learning consistent naming for their own methods, even if they haven't read the API guidelines.

These are basically two ways of stating the same point, which again, is not considered strong enough to overcome strong terms-of-art in other areas.

> – It allows defining e.g. an in-place filter variant.

Several people have mentioned this could be done, but has anyone actually *asked* for it? And if it did exist, wouldn't it be better to offer this functionality as a `remove(where:)` function, matching existing methods like `first(where:)` and `index(where:)`?

(Actually, if we're going to rename `filter`, `where` might not be a terrible name. It's valid after a dot, but not without one.)

Even if we *do* want to offer it for `filter`, the others are not good candidates for mutating variants. Mutating `map` could only be offered on certain sub-protocols of `Collection`, could not be guaranteed to be in-place (and probably wouldn't be for most collection types), and would have a severely restricted set of use cases compared to its nonmutating equivalent. Mutating `flatMap` would suffer even more from these limitations, making it desperately tricky to implement. And `reduce` simply couldn't be offered at all.

> I agree with your points on the problems with dropFirst/dropLast btw.

Incidentally, I just noticed that `removeFirst(_:)`/`removeLast(_:)` ought to get this treatment too.

I'll see if I can write up at least a sketch of what I'd like to do to these methods in the next few days, but I'm busy today preparing for the local (Orange County, CA) Apple community's post-WWDC event. Need to come up with something to talk about. :^)

-- 
Brent Royal-Gordon
Architechies



More information about the swift-evolution mailing list