[swift-evolution] Stdlib closure argument labels and parameter names
Charlie Monroe
charlie at charliemonroe.net
Mon Jun 27 00:10:24 CDT 2016
> I like `predicate`. I endorse `predicate`. Does this mean the rule of "must
> read like a sentence" can be overturned for things like "comparison" and
> "order"? If so, woo!
I've suggested that a few emails back as well, but I've asked myself if it's not a bit confusing when you have (NS)Predicate - if it doesn't seem like something taking the Predicate object argument instead of a block.
>
>>
>>> I get the `is` desire but it's being tossed away in a lot of other
>>> places in this diff. and `suchThat` feels out of place.
>>
>> I think I'm pretty strongly sold on “soEach” as a label for closures in
>> all the filtering components.
>
> To quote greatness:, "I personally find `soEach` repulsive".
> (cite: http://article.gmane.org/gmane.comp.lang.swift.evolution/16998/match=repulsive <http://article.gmane.org/gmane.comp.lang.swift.evolution/16998/match=repulsive>)
>
>>
>>> - || u16.contains({ $0 > 127 || _isspace_clocale($0) }) {
>>> + || u16.contains(elementWhere: { $0 > 127 || _isspace_clocale($0) }) {
>>>
>>> I assume the challenge here is differentiating contains(element) from contains(closure).
>>> This feels predicate-y, which is why I put it near the predicates. But I think something
>>> like `containsElement(where:)` works better.
>>
>> I understand your motivation for suggesting it. The downside is that it
>> severs the strong basename relationship between algorithms that do
>> effectively the same things, one using a default comparison and the
>> other using an explicitly-specified one. I'm truly not sure where we
>> ought to land on this one.
>
> May I recommend `predicate:` then since it looks like that's actually a possibility?
>
>>
>>> - let result = try base._withUnsafeMutableBufferPointerIfSupported(body)
>>> + let result = try base._withUnsafeMutableBufferPointerIfSupported(invoke: body)
>>>
>>> I hate "ifSupported"
>>
>> Me too.
>>
>>> but that's another discussion
>>
>> Quite. It's also an internal API so it's not an evolution issue. The
>> point of having that change as part of the diff (as with all the other
>> use sites), is to observe how the changes affect real usage.
>
> Woody Allen: "The heart wants what it wants"
> Me: "The spleen vents what it vents"
>
>>
>>> (withSupportedUnsafeMutableBufferPointer,
>>> withAvailableUnsafeMutableBufferPointer, it's all lipstick)
>>>
>>> This is procedural, so `do` or `perform` rather than `invoke`
>>>
>>> - for test in removeFirstTests.filter({ $0.numberToRemove == 1 }) {
>>> + for test in removeFirstTests.filter(
>>> + suchThat: { $0.numberToRemove == 1 }
>>>
>>> The difference between `filter` and `forEach` is that `forEach` is explicitly
>>> procedural while `filter` is functional. I do not like functional chainable
>>> calls being modified to use explicit external labels in this way.
>>>
>>> I'd prefer no label here.
>>
>> Can you provide rationale for treating functional methods differently,
>> or is it just personal taste?
>
> Functional programming flow. I follow Kevin Ballard's rule of parens around
> functional elements and naked braces for trailing closures that do not return
> values. This ensures the compiler is never confused at places like:
>
> for x in foo when y.f{...} {
> ...
> }
>
> and instantly identifies to the reader when there's a non-returning scope, as
> in forEach or GCD dispatch.
>
> However, if you use chaining and if the language insists on external label
> preambles, which would not be seen when using the call with a trailing closure,
> it becomes far less readable and encourages people to use trailing closures to
> avoid the label, i.e. an attractive nuisance. Simple selectors encourage better fp:
>
> let x = myStream.f1({...}).f2({...})
>
>>
>>> public func split(
>>> maxSplits: Int = Int.max,
>>> omittingEmptySubsequences: Bool = true,
>>> - isSeparator: @noescape (Base.Iterator.Element) throws -> Bool
>>> + separatedWhere isSeparator: @noescape (Base.Iterator.Element) throws -> Bool
>>>
>>> I'm torn on this one. It's not the worst ever but something more like where/at/when
>>> makes more sense to me than
>>> "separatedWhere/separatedAt/separatedWhen".
>>
>> The biggest reason to keep “separate” in the name is the connection with
>> the semantics of the other `split` method, that takes a single element
>> that is tested for equality. I think this is very similar to the
>> `contains(elementWhere` vs `containsElement(where` discussion. If you
>> leave “separate” out of the name it fails to imply that those elements
>> for which the predicate returns true are not present in the result.
>
> `predicate` ftw.
>
>>
>>>
>>> + count: __manager._headerPointer.pointee.count)
>>>
>>> For the sake of Zippy the Pinhead, surely there has to be something better than `pointee`.
>>> Like...`reference`?
>>
>> It's not a reference; it's a value. But that, my friend, is an
>> *entirely* different discussion. Let's try to stick to the scope of the
>> proposal: names and labels for parameters of function type, OK?
>
> It was humor. It was at the end. I assumed the joke would lighten the
> previous complaints and bookend the positive support at the start of
> my message.
>
>>
>> --
>> -Dave
>
> -- E
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160627/acf05890/attachment.html>
More information about the swift-evolution
mailing list