Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All zero-argument methods that return a value should be computed properties instead #7

Closed
sstigler opened this issue Mar 4, 2018 · 7 comments
Labels

Comments

@sstigler
Copy link

sstigler commented Mar 4, 2018

What would you think about changing the method signatures such that as a general rule, all zero-argument methods that return a value were replaced with computed properties? For example, func now() -> Instant would be replaced by var now: Instant. I think this would make code that called those methods significantly more concise and easier to read.

@sstigler sstigler changed the title All zero-argument method that return a value should be computed properties instead All zero-argument methods that return a value should be computed properties instead Mar 4, 2018
@davedelong
Copy link
Owner

I could be convinced of this this for things like .yearMonth vs .yearMonth(), since the value technically won't change between invocations. However, Clock.now() (and related methods) IMO should remain as functions because each time you call them, you can technically get different values (especially with .now(), which returns a new value every time you call it).

@davedelong davedelong added the api label Mar 4, 2018
@sstigler
Copy link
Author

sstigler commented Mar 4, 2018

Ah, interesting. I haven’t heard that argument before, that computed properties are reserved for things that don’t change every time you call them. Is that officially documented somewhere?

@davedelong
Copy link
Owner

davedelong commented Mar 4, 2018

I'm not sure if that's documented explicitly, but my understanding is that this is a motivation for differentiating between "properties" and "methods". If I were to guess, this is a holdover from the days of C, where "properties" were really members of structs (like ivars in Objective-C), and so looking them up is an O(1) operation and implies that each lookup is doing the same thing. By contrast, a method is executing code, and thus can do different things each time depending on the state of the world.

I would also say that, philosophically, now is not a property of a Clock, in that a Clock doesn't "have" a "now". However, you can generate a "now" by executing a method.

@davedelong
Copy link
Owner

The only real hesitation I would have about making this change is that, since the rest of Chronology's implementation is still undecided, I'm not sure I'd ever need variations on a .hourMinute value (as an example). For instance, let's say I decide to add a way to get a value's HourMinute in a different timezone... To do that, I'd probably make a func hourMinute(in timeZone: TimeZone? = nil) → HourMinute method. Having this method would be at odds with also having a .hourMinute property.

@klaaspieter
Copy link

I agree that .yearMonth and .hourMinute could be computed properties. I also agree that .now probably shouldn't, although it would make code nicer to read.

There's nothing stopping you from adding a hourMinute(in:) method when there is an hourMinute property right? Unless I'm mistaken Swift will do the right thing as long as you don't also want a hourMinute() method.

@Saklad5
Copy link

Saklad5 commented Mar 1, 2020

Ah, interesting. I haven’t heard that argument before, that computed properties are reserved for things that don’t change every time you call them. Is that officially documented somewhere?

The Swift API Design Guidelines encourage developers to document when computed properties involve significant computation.

Personally, I think it comes down to the usage mindset you want. If you are “doing” something, it should be a method. If you are “using” or “reading” something, it should be a computed property.

.now is a complicated case, with arguments for both approaches. Foundation itself seems to use the computed property approach.

@davedelong
Copy link
Owner

I've made a decision on this:

If a value has a method such that repeated invocations would produce the same value every time, then it will be a property. If repeated invocations will produce potentially different values, then it will be a method.

For example:

  • clock.today() is a method, because repeated invocations may produce different values.
  • today.nextDay is a property, because repeated invocations will always produce the same value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants