Support Patrick's opinion. It seems for me that 'map'(+'flatMap') and 'reduce' could be leaved as-is as *true* terms of art. Nothing else should be added to these exception group.

Also please consider this code:
let foo = elements .map {..} .reduce() {...} .filter {} .sorted {}
why is so: "filter" but "sorted"

Note, that if *non-mutating* versions of methods were chosen to have "normal" names in Swift(as was before 3.0) - we'll have no questions regarding "map"/"reduce"/"filter"/"sort"/etc IMO the reason we have this questions now is *other* modern languages has non-mutating methods with "normal" names.

So, as soon as Swift decided to move its own way, IMO it should take only these 2(3) methods as "term of art" and change all other method names to conform to Swift's own naming rules.

On 17.06.2016 14:30, Patrick Smith via swift-evolution wrote:
On 17 Jun 2016, at 8:21 AM, Brent Royal-Gordon via swift-evolution 
<[email protected]> wrote:

map       => mapped
flatMap   => flatMapped
filter    => filtered
reduce    => reduced

You posted before I finished responding to this on the other thread, so I guess 
I'll do it here.

You're right that renaming these operations wouldn't be terrible. But I think 
they're easily distinguishable from things like `dropFirst`, and 
distinguishable in a way that tilts rather strongly towards leaving these as-is.

`map`, `filter`, and `reduce` are *the* higher-order functions. Almost anything 
with any kind of block/lambda/closure feature supports them (I'm giving the 
side-eye to Foundation here), and all three names are backed by *very* strong 
conventions:

* `map` is by far the strongest. It is universally supported among languages with 
higher-order collection operations, and is almost always called `map`. In Wikipedia's 
list of 32 languages with a `map` 
<https://en.wikipedia.org/wiki/Map_(higher-order_function)#Language_comparison>,
 we find (grouping together similar names like `map` and `maplist`, and 
double-counting languages with several aliases):

        Map: 19
        Collect: 3
        Apply: 3
        Special syntax: 2
        Select: 1 (C#, which uses it in the SQL-inspired LINQ)
        Transform: 1 (C++, which uses a bizarre signature involving an out 
parameter)
        ForEach: 1 (XPath)

* `filter` is supported nearly as widely as `map`, and the name `filter` is used 
nearly as consistently as `map`. Wikipedia lists 27 languages supporting a 
`filter`-style function, and `filter` is by far the most common choice, arguably 
favored even more consistently than `map` 
<https://en.wikipedia.org/wiki/Filter_(higher-order_function)>:

        Filter: 17
        Select: 4
        Special syntax: 3
        FilteredArrayUsingPredicate: 1 (Foundation, doesn't actually take a 
closure)
        Where: 1 (C#, in LINQ)
        CopyIf: 1 (C++, bizarre signature)
        FindAll: 1
        Grep: 1
        RemoveIfNot: 1

* `reduce` is extremely popular among functional languages because it's a primitive 
list-handling operation, although it's a little less common among mainstream 
languages than the other two. It *does* actually have an alternate name, `fold`, 
which is nearly as common as `reduce`. However, languages using `fold` are usually 
those which support both leftward- and rightward-reducing versions of the operation, 
whereas languages using `reduce` usually don't. Swift falls into the second camp. 
From Wikipedia's 39-language list 
<https://en.wikipedia.org/wiki/Fold_(higher-order_function)>:

        Reduce: 20      (with both left and right: 4)
        Fold: 18        (with both left and right: 12)
        Inject: 3
        Special syntax: 3
        Aggregate: 1 (C#, in LINQ)
        Accumulate: 1 (C++, bizarre signature)
        Partition: 1
        ToIterator: 1

(Note that, although I *would* have counted the -ed or -ing forms of these 
names with the originals, I don't believe I saw any.)

Great research. Thanks for doing this.


Another illustration of the strength of these names: Google named a distributed 
computing project MapReduce, and everyone basically understood what it meant.

If `map`, `filter`, and `reduce` are not covered by the term-of-art rule, we 
might as well rename it to the sin()-and-Int rule, because I don't know what 
else it would cover. There is remarkable consistency in the naming of these 
operations across dozens of languages.

(Incidentally, I think if we *do* decide to rename the main higher-order list 
APIs, they would be better named as `mapping(to:)`, `flatMapping(to:)`, 
`filtering(by:)`, and `reducing(from:with:)`. Unlike `sorted`, the parameters 
are mandatory and deeply necessary to understand what the call does, so they 
deserve grammatical labels. Grammatical labels usually imply -ing form, not -ed 
form. If we want to address Dave's complaint about the ambiguity of `filter`, 
we might rename that to `selecting(where:)`, which is crystal clear about 
whether it keeps the true elements or the false ones.)

It would seem strange in one way to get rid of such strong terms of art (and 
also since they are nice and short, they are easy to glance at), but it also 
seems very inconsistent to keep them. These are methods that will be used by 
new programmers to Swift, so is it better to keep the existing terms or to 
modify them?

Say my type has a method filtered(with: Author), is it then strange that I am 
changing tense within the method’s implementation?

filtered(with author: Author) -> [Item] {
  return items.filter{ $0.author == author }
}

Would it not make more sense to write?

filtered(with author: Author) -> [Item] {
  return items.filtered(where: { $0.author == author })
}


dropFirst => droppingFirst
dropLast  => droppingLast

Here, however, I think you're being under-ambitious.

* Even with a nonmutating suffix, `dropping` carries such a strong connotation 
of deletion that I think it's a poor choice. I would prefer `skipping`, which 
is much more clearly an operation that doesn't change anything (and finds 
precedent in other languages—`skip*` functions are a common alternative name 
for `drop*` functions.)

+1 to skipping


* The `First` and `Last` suffixes are inappropriate for the versions of this 
function which take an argument. These are inverse operations to `prefix(_:)` 
and `suffix(_:)`, and should be named accordingly.

* `prefix(upTo:)`, `prefix(through:)`, and `suffix(from:)` are sort of strange, 
because they're tied deeply into indices and aren't closely related to the 
other prefix/suffix methods. I would at least seriously consider renaming these 
to `upTo(_:)`, `through(_:)`, and `from(_:)`—or perhaps even reimagine these 
entirely as subscripts `[upTo:]`, `[through:]`, and `[from:]`.

I really like the subscript idea. Named subscripts are not used nearly enough 
as they could. This gives these similar index-related operations a common home, 
and I believe would work well with autocomplete after typing a `[`.

I could even imagine a `[filtering:]` / `[where:]` / `[passing:]` instead of 
`filtered()`, but can imagine it might be unpopular.


This is the area where the term-of-art argument is weaker, the API is more 
inconsistent and difficult to understand, and the methods are more rarely seen 
and so more important to be understandable without remembering them. All of 
these factors combine to make the gains from rationalizing them greater.

`map`, `flatMap`, `filter`, and `reduce` are in some ways the "sexy" targets: We use them 
all over the place, and changing them would "fix" more lines of code. But these calls are 
so common, and so heavily precedented, that few users will be confused by them—they've probably 
seen them before Swift, and even if they haven't, they'll see them enough to keep their meanings 
fresh in their minds. It is the dimmer, less loved corners of the standard library which we ought 
to focus on, because they stand to benefit much more from following the conventions than the things 
we use constantly.

`filter` is the big one to me, as it is a common verb that people are likely to 
use in their own `filtered-` methods. `reduce` is also a common verb, so it 
does make sense to change to `reducing`, however I don’t imagine many people 
will be writing their own `reducing-` methods, and similarly `mapping-`, so 
these possibly fall more into the terms of art category for me; `filtered` is 
the most important one. Besides, the word 'map' always suggests to me that a 
new array/sequence will be returned, and never replace each item by mutation.

`filtered`: +1
`reducing`: +0.7
`mapping`: + 0.2


--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to