<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">On Jun 20, 2016, at 3:25 PM, Dave Abrahams via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><div><blockquote type="cite" class=""><br class="Apple-interchange-newline"><div class=""><div class=""><br class="">Hi All,<br class=""><br class="">A couple of weeks ago we started to notice that we had some poorly-named<br class="">closure parameters and argument labels in the standard library, so we<br class="">did a complete audit of the standard library's APIs and came up with a<br class="">preliminary proposal for changes, which we applied in a branch and you<br class="">can review in <a href="https://github.com/apple/swift/pull/2981" class="">https://github.com/apple/swift/pull/2981</a>. Let's please<br class="">carry on further discussion here rather than in the pull request, though.<br class=""></div></div></blockquote><br class=""></div><div><div class=""><div class=""><b class="">- /// - `isEquivalent(a, a)` is always `true`. (Reflexivity)</b></div><div class=""><b class=""> - /// - `isEquivalent(a, b)` implies `isEquivalent(b, a)`. (Symmetry)</b></div><div class=""><b class=""> - /// - If `isEquivalent(a, b)` and `isEquivalent(b, c)` are both `true`, then</b></div><div class=""><b class=""> - /// `isEquivalent(a, c)` is also `true`. (Transitivity)</b></div><div class=""><b class=""> + /// - `areEquivalent(a, a)` is always `true`. (Reflexivity)</b></div><div class=""><b class=""> + /// - `areEquivalent(a, b)` implies `areEquivalent(b, a)`. (Symmetry)</b></div><div class=""><b class=""> + /// - If `areEquivalent(a, b)` and `areEquivalent(b, c)` are both `true`, then</b></div><div class=""><b class=""> + /// `areEquivalent(a, c)` is also `true`. (Transitivity)</b></div></div><div class=""><br class=""></div><div class="">I like this change!</div><div class=""><br class=""></div><div class=""><b class="">- func forEach<S: SequenceType>(_ body: (S.Iterator.Element) -> ())</b></div></div><div class=""><div class=""><b class="">+ func forEach<S: SequenceType>(invoke body: (S.Iterator.Element) -> ())</b></div></div><div class=""><br class=""></div><div class="">Adding an external label makes sense here. This is a procedural call and</div><div class="">using it within the parens should have a "code ripple".</div><div class=""><br class=""></div><div class="">That said, would prefer `do` or `perform` over `invoke` or `invoking` as in</div><div class="">`runRaceTest`, `_forAllPermutationsImpl`, `expectFailure`, etc. This also applies</div><div class="">where there's a `body` label instead of an empty external label.</div><div class=""><br class=""></div><div class=""><b class="">-public func withInvalidOrderings(_ body: ((Int, Int) -> Bool) -> Void) {</b></div><div class=""><div class=""><b class="">+public func withInvalidOrderings(invoke body: ((Int, Int) -> Bool) -> Void) {</b></div><div class=""><b class=""><br class=""></b></div><div class="">For any with/external label pair, I'd prefer `with-do` or `with-perform` </div><div class="">over `with-invoke`.</div></div><div class=""><b class=""><br class=""></b></div><div class=""><b class="">- return IteratorSequence(it).reduce(initial, combine: f)</b></div><div class=""><div class=""><b class="">+ return IteratorSequence(it).reduce(initial, accumulatingBy: f)</b></div></div><div class=""><br class=""></div><div class="">For `reduce`, I'd prefer `applying:` or `byApplying:`</div><div class=""><br class=""></div><div class="">Similarly in `starts(with:comparingBy:)`, I'd prefer byComparing`,</div><div class="">min/max, byOrdering</div><div class=""><br class=""></div><div class=""><div class=""><b class="">- ).encode(encoding, output: output)</b></div><div class=""><b class="">+ ).encode(encoding, sendingOutputTo: processCodeUnit)</b></div></div><div class=""><br class=""></div><div class="">How about `exportingTo`?</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class=""><b class="">- tempwords.sort(isOrderedBefore: <)</b></div><div class=""><b class="">+ tempwords.sort(orderingBy: <)</b></div></div><div class=""><br class=""></div><div class="">With `sort` and `sorted`, I'd prefer `by:`</div><div class=""><br class=""></div><div class=""><div class=""><b class="">- if !expected.elementsEqual(actual, isEquivalent: sameValue) {</b></div><div class=""><b class="">+ if !expected.elementsEqual(actual, comparingBy: sameValue) {</b></div></div><div class=""><br class=""></div><div class="">I'm torn on this one. I don't like but I don't have a good solution.</div><div class=""><br class=""></div><div class=""><div class=""><div class=""><b class="">- /// for which `predicate(x) == true`.</b></div><div class=""><b class="">+ /// for which `isIncluded(x) == true`.</b></div></div><div class=""><div class=""><div class=""><b class="">- _base: base.makeIterator(), whereElementsSatisfy: _include)</b></div><div class=""><b class="">+ _base: base.makeIterator(), suchThat: _include)</b></div></div></div><div class=""><b class=""><br class=""></b></div><div class="">How about simply `include` for both? I get the `is` desire but it's being tossed away</div><div class="">in a lot of other places in this diff. and `suchThat` feels out of place.</div></div><div class=""><br class=""></div><div class=""><div class=""><div class=""><b class="">- || u16.contains({ $0 > 127 || _isspace_clocale($0) }) {</b></div><div class=""><b class="">+ || u16.contains(elementWhere: { $0 > 127 || _isspace_clocale($0) }) {</b></div></div><div class=""><br class=""></div><div class="">I assume the challenge here is differentiating contains(element) from contains(closure).</div><div class="">This feels predicate-y, which is why I put it near the predicates. But I think something</div></div><div class="">like `containsElement(where:)` works better.</div><div class=""><br class=""></div><div class=""><b class=""> - let result = try base._withUnsafeMutableBufferPointerIfSupported(body)</b></div><div class=""><div class=""><div class=""><b class="">+ let result = try base._withUnsafeMutableBufferPointerIfSupported(invoke: body)</b></div></div><div class=""><br class=""></div><div class="">I hate "ifSupported" but that's another discussion (withSupportedUnsafeMutableBufferPointer,</div><div class="">withAvailableUnsafeMutableBufferPointer, it's all lipstick)</div><div class=""><br class=""></div><div class="">This is procedural, so `do` or `perform` rather than `invoke`</div></div><div class=""><br class=""></div><div class=""><div class=""><b class="">- for test in removeFirstTests.filter({ $0.numberToRemove == 1 }) {</b></div><div class=""><b class="">+ for test in removeFirstTests.filter(</b></div><div class=""><b class="">+ suchThat: { $0.numberToRemove == 1 }</b></div></div><div class=""><br class=""></div><div class="">The difference between `filter` and `forEach` is that `forEach` is explicitly </div><div class="">procedural while `filter` is functional. I do not like functional chainable</div><div class="">calls being modified to use explicit external labels in this way. </div><div class=""><br class=""></div><div class="">I'd prefer no label here.</div><div class=""><br class=""></div><div class=""><div class=""><i class="">public func split(</i></div><div class=""><i class=""> maxSplits: Int = Int.max,</i></div><div class=""><i class=""> omittingEmptySubsequences: Bool = true,</i></div><div class=""><b class="">- isSeparator: @noescape (Base.Iterator.Element) throws -> Bool</b></div><div class=""><b class="">+ separatedWhere isSeparator: @noescape (Base.Iterator.Element) throws -> Bool</b></div></div><div class=""><br class=""></div><div class="">I'm torn on this one. It's not the worst ever but something more like where/at/when</div><div class="">makes more sense to me than "separatedWhere/separatedAt/separatedWhen".</div><div class=""><br class=""></div><div class=""><div class=""><div class=""><b class="">+ count: __manager._headerPointer.pointee.count)</b></div></div></div><div class=""><br class=""></div><div class="">For the sake of Zippy the Pinhead, surely there has to be something better than `pointee`.</div><div class="">Like...`reference`?</div><div class=""><br class=""></div><div class=""><div class=""><br class=""></div></div></body></html>