[swift-evolution] [Review] SE-0023 API Design Guidelines (when to use properties)
Dave Abrahams
dabrahams at apple.com
Wed Jan 27 17:50:32 CST 2016
on Wed Jan 27 2016, Howard Lovatt <howard.lovatt-AT-gmail.com> wrote:
> I would say that if it doesn't have arguments and doesn't mutate then it
> should be a property, since it will read better and is flexible (you can
> switch between a stored and calculated property without affecting the
> external interface easily).
We had at least one member of the guidelines group initially felt *very*
strongly that we should use (basically) that criterion. But then, in
our survey of the standard library, we found that applying it left us
with many properties that he wasn't comfortable with, such as
`sequence.iterator` (today's `sequence.generate()`).
> On Thursday, 28 January 2016, David Waite via swift-evolution <
> swift-evolution at swift.org> 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. 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.
>>
>> -DW
>>
>> > On Jan 27, 2016, at 12:23 PM, Dave Abrahams via swift-evolution <
>> swift-evolution at swift.org <javascript:;>> 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 <javascript:;>
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <javascript:;>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
--
-Dave
More information about the swift-evolution
mailing list