Btw, there is also .first(where:) which accepts a predicate.
@interface Foo : NSObject
{
NSString * name;
NSInteger count;
}
- (NSString)name;
- (void)setName:(NSString *)newName;
- (NSInteger)count;
@end
(This is still legal, of course, but bad practice now that there's `@property` synthesis as well as ivars being declarable in either an extension or the `@implementation` block.)Shuffled may accept arguments. First does not
The runtime cost of first is nearly zero, whereas shuffled is doing significant work (constant versus linear time)
It sort of doesn’t matter because autocomplete won’t let you do the wrong thing.
Although I do believe Swift has "virtual properties" that are really a method under the hood.
The fact that you need to use function call syntax for things like this in other languages seems like it is unnecessarily exposing implementation details to the API because of limitations of the language.
For instance, let's imagine in some C++-like language I had two list implementations: one static and one dynamic:
class StaticList {
...
int count; // set at initialization time
}
class DynamicList {
...
int count() {
... // compute the count dynamically
return count;
}
}
Here `count` is conceptually the same between these two implementations, but if I want to get that value, I have to access it differently: int c1 = staticList.count;
int c2 = dynamicList.count();
But that difference is essentially an implementation detail which means nothing to the client. The Swift way just lets me express my interface however I decide is most fitting.In languages like C, C++ and Rust, properties are things that are definitely in memory, and functions/methods are things that may not be. If you have an interface like `count` that may be dynamic, it should be uniformly expressed as a method/function (that may have a trivial "return count;" implementation).
On the other, Swift has to put a non-trivial amount of infrastructure into making sure all the things with property syntax can behave as if they are backed by memory, so that an address/pointer can be generated for them (in the general case, a temporary pointer, that becomes invalid quickly).
Having "first" as a property feels like exposing implementation details to me. Sure, a array/vector is a contiguous slice of memory filled with items of a certain size. But the vector/array is is basically a pointer to the start of the memory + a size, so "first" is not a inherent part of the data structure, rather a computed/derived property.
When I see a property I think member of a struct, which is not the case here.
(ps: this is all really just hair splitting, it's a minor difference that you would get used to pretty quickly either way)