

Objective-C literals for NSDictionary, NSArray, and NSNumber - julien_p
http://cocoaheads.tumblr.com/post/17757846453/objective-c-literals-for-nsdictionary-nsarray-and

======
Derbasti
Well, I guess that was long overdue. Anyway, another nice step to bring
Objective-C forward.

It seems to develop into a nice combination of low-level, high-performance C
and a pretty straightforward, dynamic, object system. In short, I vastly
prefer its object system to C++, because it reasonably trades some performance
for greater dynamisms and an easier syntax.

It'll be interesting how Objective-C will develop.

~~~
___Calv_Dee___
I completely agree, it's great to see that the language continues to move
forward and advance in it's OO design. It's especially nice that these forward
steps do not hinder or reduce Obj-C's low-level functionality, leaving
available the performance gains from it's use.

~~~
aaronblohowiak
Exactly, gcd could have been objc but it is just a c extension!!

------
jawngee
This is for Apple LLVM 4.0 which ships with XCode 4.4.

Also included:

    
    
       - Automatic @synthesize
       - NSArray/NSDictionary subscripting, eg id object=MyArray[12];

~~~
Someone
For those wondering: Xcode 4.3 is what currently ships, 4.4 Developer Preview
ships with the Mountain Lion per-release, so it only is available to those in
Apple's Developer Program.

~~~
pooriaazimi
> _...so it only is available to those in Apple's Developer Program._

correction: Apple's _Mac_ developer program. I'm an iOS developer and I don't
see Xcode 4.4 in my dashboard.

~~~
rbrown46
This is the second time (to my knowledge, may have been going on for a while)
that an Xcode beta has been made available to only one of the two (Mac and
iOS) developer programs. The Xcode 4.3 beta was only available to iOS
developers -- despite containing bug fixes and improvements useful to
developers on both platforms. Now the Xcode 4.4 beta is only available to Mac
developers.

I really don't see the logic in withholding from paying members of either
platform.

~~~
marcins
You can't use the beta Xcode / SDKs to build apps for the relevant App Store
anyway, so while it contains neat new features it's technically only useful
for developers developing that particular pre-release OS (whether iOS 5.1 or
OS X 10.8).

Interestingly now Xcode 4.3 is out of beta the iOS 5.1 SDK is still only
available with Xcode 4.3 DP3 (although realistically there's not much public
new stuff in iOS 5.1 since presumably it's all under wraps for the iPad 3).

------
terhechte
This is fantastic. Previously I was employing a macro library that offered
$dict(k, v, k, v) and $arr(1, 2, 3) and $bool. But the @[] feels much better,
and it increases code portability if a class is not dependent upon a separate
macro library. It will really remove the verbosity of objc which is oftentimes
one of the major criticisms.

------
boucher
We've been talking about similar changes to Objective-J for quite some time
(we already have JavaScript literals that map more cleanly than C ones). The
one thing we've discussed that I don't think made it here is a set literal. It
would be nice to have sets treated in a more first class way, considering how
often arrays are used when sets would be more appropriate.

~~~
zoul
Indeed. Even [NSDictionary allKeys] returns an array instead of a set.

------
cageface
The excessively verbose collection syntax is my #1 pain point with Obj-C.
Looking forward to kicking the tires on this one.

~~~
glhaynes
It's never before fully struck me how cleanly the "Objective-C is too verbose"
complaint really breaks down to two separate issues: one of them being that
method names are long (which is arguably a plus) and the other being mostly
comprised of the stuff that's apparently mostly taken care of with this
release. Actually, I suppose there used to be a third, too:
(auto)release/retain statements all over the place.

As somebody who loves the long method names but of course wants less syntactic
cruft, I'm really happy with their recent progress.

~~~
yuhao
ARC in XCode 4.2 takes care of the release/retain business!

~~~
pjmlp
Kind of. It does not apply to all Cocoa libraries and you need to follow
certain conventions, otherwise the compiler will fail to add the
release/retain calls.

------
chrisdevereux
@-prefixed literals for collections are definitely welcome (I won't miss those
nested 'dictionaryWith...' calls for sure).

Anyone know how the []-access will work? Is this going to be a special case
for NSArray/NSDictionary synthesized in by the compiler, or is there going to
be runtime support for a []-operator message a la Ruby, or maybe something
related to key-value coding?

I hope this is done coherently, anyway. I worry that too many special cases to
overcome problems like verbose collection access could snowball.

~~~
jbrennan
There are methods you can implement in your own classes to provide setting and
getting for both the array and dictionary style syntax.

If you're a Mac developer, check the forums. Else, wait for the info to be
non-NDA.

------
demallien
ugh. As much as I love the changes that Apple have been making to Objective-C,
as someone with a rather large - first-time project undrway, the pace of
change is just killing me. In the last three years we have seen blocks (and
Grand Central Dispatch) and garbag collection, Automatic Reference Counting,
and now this.

These are all good changes (well, except for garbage collection, but hey, they
kicked that out with ARC anyway), but it really is hard to stay up-to-date.
Yeah, I know, woe is me, my tools supplier is constantly supplying better free
tools, but it is daunting having to review each of this evolutions, and
determine if it is worth the effort to integrate it into my project.

~~~
flyosity
Maybe I'm misunderstanding, but how much effort are you talking about here?
Skipping @synthesize on properties or using literal syntax where/when it makes
sense wouldn't cause much additional cognitive load and you don't have to
convert old code to use the new sugar.

~~~
demallien
It's not as simple as that when you're planning for the long term. Firstly you
need to examine the changes and make sure that they aren't going to create any
compatability problems, of the type "if you activate this option, then you can
no longer link to libraries that don't use this option". Garbage collection in
particular had a lot of those sorts of problems.

But even if you can convince yourself that it _is_ just syntactic sugar, you
have to have a long hard think about whether or not you are going to adopt the
style. Adopting means going back and changing the code you have already
written. Not adopting the style is not tenable in the long term - the new
syntax is clearly superior to the old syntax, so there will be a lot of
pressure to code the new way. This is particularly true when playing in
Apple's backyard, as they have a habit of taking a nice new technology that is
optional in one release, and then building on that optional feature for a next
release.

For me, in this one particular case, I'll probably go with the new syntax,
going back through modules that are already written and redoing them with the
new syntax each time I have to touch one for a bug fix/feature.

I'm just getting frustrated because my project started about 18 months ago - I
work on it nights and weekends, and I have to keep stopping work on the
project and spending time adapting to new tools. The last 18 months or so have
been particularly tumultuous. XCode 4 was a _big_ change compared to its
predecessors. I started using the garbage collector just to have it more or
less replaced by ARC.

None of this is insurmountable, but as a one person, part-time shop with a
fairly ambitious project, this is really starting to become painful for me,
which is the point I was trying to get across, and I suspect that I'm not the
only one to be feeling the pain. Perhaps I would feel better about deciding
not to follow Apple on this one if I could be sure that that decision wouldn't
mean me finding myself with a big code base on my hands that is unable to take
advantage of the new hotness in the _next_ version of Objective-C because I
decided to skip _this_ version's changes...

~~~
pooriaazimi
I understand what you mean; but in this case, I think it's fairly easy to
adopt new syntax in all of you code base. Just search for _NSArray
arrayWithObjects:_ , _NSDictionary dictionaryWithObjects:_ and _NSNumber
numberWithChar:_ and replace them with new syntax. It wouldn't be this easy if
it was a major change (like ARC).

------
glhaynes
Nice! As somebody who's not a member of the Mac Developer Program but whose
Twitter feed has been _full_ of people gushing about how nice the new
additions to Objective-C are, I'm glad to see what all the hubbub is about.

------
openbear
I'm glad to see these additions, but the syntax for an NSArray literal bugs
me.

When I want an array literal in C, I'd write ...

    
    
      int foo[] = { 1, 2, 3, 4, 5};
    

... but in Objective-C, for an NSArray literal I'd write ...

    
    
      NSArray *bar = @[o1, o2, o3];
    

Why did they choose '[' over '{'? Oddly enough, NSDictionary uses '{'.

I feel like the syntax for an NSString literal is more natural (as a C
developer).

    
    
      NSString *baz = @"look, an NSString literal";
      char szBaz[] = "look, a C string literal";

~~~
bebop
I think they chose the [] for arrays and {} for dictionaries as that is the
style that seems to be most popular right now. Python for instance uses this.

~~~
openbear
When adding features to something, I tend to be a big fan of "when in
Rome"[1]. If these were extensions to Python (or Ruby or JavaScript) then I
would totally be for using '[' with arrays. As a C guy though, I would rather
have seen them use '{' for NSArray and '[' for NSDictionary. Regardless, I'm
glad to see this stuff added.

[1]
[http://en.wiktionary.org/wiki/when_in_Rome,_do_as_the_Romans...](http://en.wiktionary.org/wiki/when_in_Rome,_do_as_the_Romans_do)

~~~
xsmasher
It's already custom in objc to use {} for dicts and [] for arrays when
printing them out, unless I'm misremembering. It also matches the use of those
characters in JSON, so it seems natural to me.

------
droithomme
Well this is good news. I have nothing to complain about here, it was even
done with the obviously correct syntax following the principle of least
surprise. Yay!

------
natesm
On one hand, it's nice, and it'll make coding in Obj-C nicer.

On the other hand, it strengthens the coupling between Objective-C the
language the Cocoa the framework, and I'm not sure how I feel about that.

I do like it better than the property dot syntax though. (is a simple
assignment to a struct member? is it an objc_msgSend of unknown complexity?)

~~~
glhaynes
Apple's weird in the way they couple things in different ways than the rest of
the industry and against the conventional wisdom. Since essentially nobody has
an investment in Objective-C-without-Cocoa or Cocoa-without-Objective-C, I
don't see any problem with them evolving them together whichever way seems
best to them.

Also, there's long precedent with @"…" syntax for embedding NSString literals
and most of the changes are really just preprocessor/static analysis-driven
syntactic sugar — sometimes _extreme_ sugar, yes, but optional, highly-
predictable, purely-syntactic-cleanup nonetheless. So if they ever decide "the
future of Cocoa is Ruby!" or something like that, I'd think most of the sugar
could be, to mix metaphors, transplanted.

On that note, though: I don't see Apple moving primarily away from Objective-C
any sooner than I see .Net moving primarily away from C#. It's "the language"
until something huge changes the landscape, in large part because they've been
able to so substantially evolve it, just like Microsoft, who also controls the
primary framework used with their language, has been able to do with C#.

------
jemeshsu
Nice. I wish for ability for function to return multiple values. Is it
possible at all?

~~~
pornel
You can use C99 struct literals:

    
    
        return (struct x){a,b};
    

Small structs may be passed in registers.
<http://stackoverflow.com/a/3355560/27009>

~~~
drpancake
IIRC passing Obj-C object pointers in C structs is disallowed or discouraged
by ARC.

~~~
DrJokepu
You have to explicitly bridge them in or out of ARC and indicate the ownership
rules. Sometimes, for example when you're interfacing straight C code, you
have no other option.

------
frou_dh
Does this come courtesy of a new version of the Objective-C language?

The definition of ObjC confuses me a bit. It's said to be a superset of C -
but which C? C89? C99? GNU-C-Something?

~~~
thought_alarm
Obj-C is essentially a preprocessor on top of a C compiler. Whether that C
compiler is C89, C99, or C++11 is up to you.

Obj-C also includes the Foundation classes that were originally introduced
with the OpenStep SDK in 1994 (NSObject, NSString, NSNumber, NSArray,
NSRunLoop, NSAutoreleasePool, etc.).

~~~
frou_dh
Is it possible to see this straight C translation? Using Clang for example.
I'm sort of aware of the "objc_msgSend" business, but would like to see more.

Talking of OpenStep, after seeing some of those NeXT videos on HN the other
day, I found a torrent of OpenStep 4.2 incl the dev tools. It's a VMware image
and boots and runs just fine. Pretty nifty. Then I noticed OpenStep 5.0
redirects to Mac OS X on Wikipedia!

~~~
Zev
Quick example of calling a method that doesn't take any arguments and returns
an object:

    
    
      id foo = [self bar];
    

is the same as:

    
    
      id foo = self.bar;
    

which is also the same as:

    
    
      id foo = [self performSelector:@selector(bar)];
    

or:

    
    
      IMP barImp = [self methodForSelector:@selector(bar)];
      id foo = barImp(self, @selector(bar); [1]
    

and finally:

    
    
      id foo = ((id)(id, SEL)objc_msgSend)(self, @selector(bar)); [2, 3, 4]
    

1\. Because we're calling the IMP, or implementation, directly, we don't need
a cast (like we do below, with objc_msgSend).

2\. Casting the function is optional, but, helps to prevent things like endian
differences and your return value getting mangled when using the same code on
PPC and Intel. Not too big of a deal anymore.

3\. There are actually two other varieties of objc_msgSend, depending on your
return type — specifically, floating point calls should use objc_msgSend_fpret
and calls that return a struct should use objc_msgSend_stret.

4\. I hope I got this cast right, I didn't try to compile it.

~~~
natesm
Those first two and following aren't equivalent, are they? Wouldn't they
compile, respectively, to:

    
    
        objc_msgSend(self, @selector(bar));
    

And:

    
    
        objc_msgSend(self, @selector(performSelector:), @selector(bar));
    
    ?

~~~
Zev
The first two are the same, with a different syntax, yes.

They would both become:

    
    
      objc_msgSend(self, @selector(bar));
    

However, your examples are basically explicitly passing a message (1 and 2),
vs dynamically building a message to pass (3).

For the second to work, the objc_msgCall function would really be:

    
    
      objc_msgSend(self, @selector(performSelector:), @selector(bar));
    

(The first example is saying to self to call the selector (method) named
'bar'. The second example is telling self to call the method
'performSelector:' with an argument of 'bar'.)

The runtime may or may not be smart enough to optimize this out. It has never
been a bottleneck for me to bother looking into it, and I haven't come across
anything to indicate one way or the other.

