Computed read-only property vs function in Swift

It seems to me that it's mostly a matter of style: I strongly prefer using properties for just that: properties; meaning simple values that you can get and/or set. I use functions (or methods) when actual work is being done. Maybe something has to be computed or read from disk or from a database: In this case I use a function, even when only a simple value is returned. That way I can easily see whether a call is cheap (properties) or possibly expensive (functions).

We will probably get more clarity when Apple publishes some Swift coding conventions.


Well, you can apply Kotlin 's advices https://kotlinlang.org/docs/reference/coding-conventions.html#functions-vs-properties.

In some cases functions with no arguments might be interchangeable with read-only properties. Although the semantics are similar, there are some stylistic conventions on when to prefer one to another.

Prefer a property over a function when the underlying algorithm:

  • does not throw
  • complexity is cheap to calculate (or caсhed on the first run)
  • returns the same result over invocations

While a question of computed properties vs methods in general is hard and subjective, currently there is one important argument in the Swift's case for preferring methods over properties. You can use methods in Swift as pure functions which is not true for properties (as of Swift 2.0 beta). This makes methods much more powerful and useful since they can participate in functional composition.

func fflat<A, R>(f: (A) -> () -> (R)) -> (A) -> (R) {
    return { f($0)() }
}

func fnot<A>(f: (A) -> Bool) -> (A) -> (Bool) {
    return { !f($0) }
}

extension String {
    func isEmptyAsFunc() -> Bool {
        return isEmpty
    }
}

let strings = ["Hello", "", "world"]

strings.filter(fnot(fflat(String.isEmptyAsFunc)))

Since the runtime is the same, this question applies to Objective-C as well. I'd say, with properties you get

  • a possibility of adding a setter in a subclass, making the property readwrite
  • an ability to use KVO/didSet for change notifications
  • more generally, you can pass property to methods that expect key paths, e.g. fetch request sorting

As for something specific to Swift, the only example I have is that you can use @lazy for a property.


There is a difference: If you use a property you can then eventually override it and make it read/write in a subclass.