Show HN: Underscore.js for Objective-C
underscorem.org
underscorem.org
That said, I use underscore.js in nearly all of my browser and node.js code, so I'll certainly consider this when the iPhone train comes back around.
The more Objective-C way to do this, without the dot syntax and the need for wrapping, is to add categories (sets of extra methods) to the NSArray and NSDictionary classes.
The square brackets don't impair chaining in any way - you can still [[[myDict allKeys] filter:filterMethod] invoke: invokeMethod]
[[array filter:^BOOL (id obj) {
return [obj passesTest];
}]
map:^id (id obj) {
return [obj transformedObject]
}];
Edit: Also, it's good practice to prefix your categories methods so they don't clash with other category's, so you'd have something like us_map:, us_filter:, reducing readability even further.That's not what he's doing, he's exposing blocks as properties because he couldn't wrap his head around indentation which is the wrong motivation. Maybe read the source before condescending next time.
Just declare a normal function, which can correctly throw a compiler warning if you try to pass anything that does not conform to NSFastEnumeration to it.
[[array filter:@selector(passesTest)] map:@selector(transformedObject)];
That's not perfect, but better.
NSArray* map(id<NSFastEnumeration> enumerable, id(^)(id object) block);
?Obviously, you'd still want to have a prefix of some sort for namespacing.
But I agree, supporting any class that implements NSFastEnumeration would be nice to have.
The latter giving you the ability to enumerate in reverse order or spread the enumeration across multiple cores using Grand Central Dispatch.
[1] https://developer.apple.com/library/mac/documentation/Cocoa/...: [2] https://developer.apple.com/library/mac/documentation/Cocoa/...:
It's always been a curiosity that a company like Apple, who prides themselves on making great user interfaces can't even get it together to make a programming language that's nice to look at. They seem to care about everyone BUT their own kind these days...
[UIMelon melonWithNumberOfSeeds:10
andPriceInDollars:10];
which is a lot more self explanatory than new Melon(10, 10)
That being said, for a lot of common and well known fuctions (including map, filter,
reduce), Objective-C tends to be overly verbose. I think everybody is looking forward
to the new literals, that will allow you to replace [NSDictionary dictionaryWithObjectsAndKeys:foo, @"foo",
bar, @"bar",
nil];
with the much more concise @{@"foo": foo, @"bar": bar}
Underscore.m tries to achieve something similar. I hope that people will be able
see past the - granted, inconventional - syntax to focus on the actual operations
done on the data structures.
For example: // - (NSDictionary *)transformedDictionary;
NSMutableDictionary *result = [NSMutableDictionary dictionary];
[myDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj) {
[result setValue:[obj transformedObject]
forKey:key];
}];
return result;
vs. return _dict(myDict).map(^id (id key, id obj) {
return [obj transformedObject];
})
.unwrap;Yes, and other people have the uninformed idiotic opition that significant whitespace sucks, or that lots of parenthesis a la Lisp suck.
Alternative syntaxes do not "suck", nor are superficial features like whitespace, brackets and parenthesis the real essence of a syntax (actually those are not even syntactical, they are lexical, and are handled by the lexer, not the parser).
Objective-C is an established language with great features for what it has to do (be dynamic and bridge low level and high level while keeping performance on par with C/C++ when needed). And it has a HUGE API library for both Mobile and Desktop.
Not to mention that it has a noble history of being the language on which both the first web browser and the first modern first person shooter were written in.