Naming Boolean methods and properties

The API Design Guidelines said:

  • Uses of Boolean methods and properties should read as assertions about the receiver when the use is nonmutating, e.g. x.isEmpty, line1.intersects(line2).

Consider the code snippet below:

enum Features {
    static var isFeature1Available ... // A
    static var feature1IsAvailable ... // B
}

The name of B is more like an assertion than A, but I’ve never seen names like this neither in the stdlib nor in Apple’s frameworks. Which one is better? And why?

1 Like

I would prefer to say that isFeature1Available is a yes-no question rather than an assertion.

2 Likes

I think the key part is "read as assertions about the receiver". In your case there isn't a meaningful receiver because they are just static variables.

2 Likes

What if we’re getting the value dynamically? For example:

enum Features {
    static var isFeature1Available: Bool { // A
        if #available(iOS 26.0, *) { true } else { false }
    }
    static var feature1IsAvailable ... // B
}

And we use this variable like Array.isEmpty

// We may use it like this
if (Features...) ...
// or like this
myFunc(Features...)

In this scenario, which name is preferred?

It's more about the way you are designing these flags. Apple usually have a isAvailable property on the feature itself, not having all of them defined on an enum. For example, to detect whether the speech transcription is available, you use the static var isAvailable on SpeechTransciber:

import Speech

...

if (SpeechTranscriber.isAvailable) { ... }

...

I personally find this more ergonomic.

2 Likes

Neither is good. If you really have something enum-like, use cases:

enum Feature {
  case `1`, `2`

  var isAvailable: Bool {
    switch self {
    case .`1`: true
    case .`2`: false
    }
  }
}
Feature.`2`.isAvailable

Otherwise, just extend Bool.

extension Bool {
  static var namedFeatureIsAvailable: Self { true }

  enum FeatureIsAvailable {
    static var `1` : Bool { true }
    static var `2` : Bool { false }
  }
}
if .namedFeatureIsAvailable { }
if .FeatureIsAvailable.`1` { }

is goes as a prefix (e.g. isFeature1Available), this is a long standing tradition from Obj-C days.

1 Like

Agreeing with everyone so far (including the original poster!) I do think the design guidelines could say something about static variables, though I'm having trouble formulating a generally-applicable rule. (It's not just "phrase it like a question" because we don't write doesSyncToCloud, we just write syncsToCloud.)

In this particular overly abstract example, I can think of another alternative that stays more in line with the guidelines: Features.hasFeature1 (depending on what you mean by "available", of course). But overall I do think even with an amendment to the guidelines we can go back to our guiding fundamental:

Clarity at the point of use is your most important goal.

I, personally, would say that consistently putting the verb ("is") at the front makes things easier for me, personally, to understand, because it follows the same pattern as other APIs (for which it is better motivated). I don't mean that the other form is confusing; merely that it requires less brain processing power, i.e. the process of "understanding" is "easier".

Is that "clarity"? Maybe not quite, but it feels related.

5 Likes

Thanks for all of your replies! All the options are valuable. I finally decided to refactor my code to something like Feature1.isAvailable.

2 Likes

I chose the name A, referring to

UIView's isUserInteractionEnabled

UIPrintInteractionController's isPrintingAvailable

UIApplication's isProtectedDataAvailable

2 Likes