dbachrach/OCUDL

Alternative Syntax Suggestion

hypercrypt opened this issue · 3 comments

I wanted to suggest a tweak on the syntax, something like:

$(NSURLRequest)[@"http://apple.com"];
$(NSURL)[@"http://apple.com"];
$(UIColor)[0xff0000];

This can be implemented with the following macro:

#define $(cls) (cls *)((id)[cls class])

To make a class support the syntax, nothing needs to be registered, the only thing that needs to be implemented is one of the following:

+ (id)objectAtIndexedSubscript:(NSUInteger)idx;
+ (id)objectForKeyedSubscript:(id)key;

More details are here

What do you think?

This is very interesting. Here are a couple thoughts:

  • Love that the result is typed. This is my biggest issue with OCUDL right now. C++'s literals are typed and that's what makes them so powerful. You can do:
Meters myMeters = 5m + 10km; // ok
Meters myMeters2 = 5m + 20sec; // compiler error
  • I didn't realize that the subscripting APIs worked as class methods. That's actually really cool.
  • The verbosity is definitely a downside:
$(NSURL)[@"http://apple.com"];
// vs
[NSURL urlWithString:@"http://apple.com"];

I think for classes that already offer class constructors, this syntax isn't much quicker. Now for new functionality like your UIColor example, it's still useful.

As an aside, one thing I'm playing with is regex supported literals like:

PhoneNumber* num = $(555-666-7777);

Your proposal is very explicit about what class gets created, and that's ideal so we get type checking, but less ideal for concise literals. I wonder if there's a way to get the type checking without having to explicitly list the class.

I agree that it is verbose. I have been thinking about getting it down.

The class methods work because classes are just instances of their meta class, so the runtime doesn't care about it being a class.

Just realized you can do:

#define _(x) ("9AD499E3-61B8-43AC-83A1-4B322E67C9B3" #x)

And then you can create a literal like:

id x = @_(555b);

This goes back to the boxed c strings, but it looks very much like all the other objc literals. The only limitation is that the compiler expects an NSString*, so you still have to cast to id.

Still cool :)