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

David Waite david at alkaline-solutions.com
Wed Jan 27 14:24:15 CST 2016

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. 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.

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.

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.


> 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

More information about the swift-evolution mailing list