[swift-evolution] [Review] SE-0023 API Design Guidelines (when to use properties)

Dave Abrahams dabrahams at apple.com
Wed Jan 27 17:45:37 CST 2016


on Wed Jan 27 2016, David Waite <david-AT-alkaline-solutions.com> wrote:

> IMHO, there are safety-level consistency aspects below the design/consistency aspects. 
>
> From a safety perspective, people expect property and subscript
> getters to behave like pure functions (at least externally) - calling
> does not change the state. 

Yes, I'm sorry that I wasn't explicit about this; the guidelines group
takes this for granted as a requirement for being a property.  Thanks
for pointing it out.

> Whether I get a collection’s count once at the start of my loop or for
> each iteration of my loop, both will give me safe behavior.

I'm not sure whether you're conflating two ideas here.  When we say
"safe" in Swift, we don't mean "doesn't have side-effects;" we mean
either type safety (not accessing initialized memory as a type it
doesn't have) or memory safety (not accessing uninitialized memory).
Could you clarify what you mean?

> People expect property setters to be idempotent - if they mutate an
> object, calling a setter again will result in the same object
> representation (at least externally) and not further mutation.

Again, the group takes this for granted as a requirement for being a
property. Thanks for pointing it out.

> Once you have the safety aspect underway, usability and consistency
> determine what stays as properties or gets promoted to methods.
>
> Example: from a safety perspective, “reverse” and many other methods
> could be getter property on CollectionType. However, they could not be
> properties on the super type SequenceType, because SequenceType is
> allowed to consume the underlying data. To have “reverse’ be
> consistent across both SequenceType and its subtype CollectionType, it
> needs to be a method.
>
> underestimateCount() looks like it could be a property for safety, but
> some other design/consistency aspects made it a method.

This is useful, thanks!

> -DW
>
>> On Jan 27, 2016, at 12:23 PM, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>> I'm glad you mentioned this, Jacob.  We had extensive internal
>> discussions about properties, and made substantial progress, but we do
>> not yet have wording suitable for the guidelines.  Let me tell you where
>> things stand.
>> 
>> ,----[ Side Note, since you mentioned efficiency ]
>> | I originally wanted to uphold the principle that, “if it isn't O(1), you
>> | don't make it a property.”  The implication is that on collections,
>> | “count” would be a method.  That would include Array, for which counting
>> | the elements *is* O(1).  Some people argued that:
>> | 
>> | 1. The idea of writing “a.count()” instead of “a.count” to count the
>> |    elements of an Array was absurd.
>> | 2. Programmers don't draw conclusions about efficiency based on whether
>> |    something is a property.
>> | 3. The fact that Array would have an O(1) non-property that *could* have
>> |    been a property (if it weren't for CollectionType conformance)
>> |    undermines any communicative power that you might get from using this
>> |    distinction to choose properties.
>> | 
>> | I did not win that argument :-)
>> `----
>> 
>> So we surveyed the entire standard library, trying to arrive at some
>> consensus about what ought to be a property and what ought not to be
>> one.  Fortunately I happen to already have a write-up of those results:
>> https://gist.github.com/dabrahams/b6b79f19c2bf9b2a0083
>> 
>> The parts I'm not currently satisfied with are:
>> 
>> 1. I don't know how to nail down what was meant by “intrinsic” in:
>> 
>>     Things that are “intrinsic” to the receiver are properties
>> 
>> 2. (possibly-related): The following don't seem (to me) to be a clear
>>   fit for any of the criteria.  I think we made the right decision in
>>   most cases, but I don't know how to describe why:
>> 
>>   * description, debugDescription, customReflectable.customMirror
>>   * first
>>   * unsafePointer.pointee
>>   * string.utf8.nulTerminatedUTF8
>>   * collection.min()
>>   * sequence.iterator()
>> 
>> 3. I don't understand the rationale we currently have for
>>   sequence.iterator() not being a property, even though I think that's
>>   the right choice.
>> 
>> I *do* think there's enough here to eventually turn it into wording for
>> the guidelines, but it's going to take a little more work.  If the
>> community can help us clarify the points above, I'm sure it could be a
>> big help!
>> 
>> Cheers,
>> 
>> -- 
>> -Dave
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution

-- 
-Dave


More information about the swift-evolution mailing list