www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - proposal for better syntax for extern objective-C and compatibility

reply Timothee Cour <thelastmammoth gmail.com> writes:
See [1][2] for related thread introducing extern(objective C)

A)
The syntax proposed in [2] transforms:
-(void) insertItemWithObjectValue: (NSString *) path atGreen:(NSInteger)
anInt;
[obj insertItemWithObjectValue:val atGreen:idx ];

into:
void insertItem(NSString* object, NSInteger anInt)
[insertItemWithObjectValue:atGreen:];
obj.insertItem(val, idx);

B)
I don't see how it handles this case:
[obj insertItemWithObjectValue:val atGreen:idx ];
[obj insertItemWithObjectValue:val atRed:idx ];

obj.insertItem(val, idx); //atGreen or atRed ?

C)
The fact that one needs to come up with a new name insertItem is not good
(as done in [2] ). And if we reuse the name:
'void insertItemWithObjectValue(NSString* object, NSInteger anInt)
[insertItemWithObjectValue: atGreen:];'
Then it's not DRY.

D)
the variable list is separated from the argument name list; this makes it
less readable with more arguments.

E)
the only benefit of objective C's syntax (making it clear at call site what
is the argument description) is lost.

----
F)
*I'd like to propose instead the following syntax:*
void insertItemWithObjectValue(NSString* object, NSInteger atGreen:);
void insertItemWithObjectValue(NSString* object, NSInteger atRed:);
obj. insertItemWithObjectValue(object, atGreen: idx);
obj. insertItemWithObjectValue(object, atRed: idx);

Advantages:
* unambiguous (cf B)
* no need to come up with new name or repeat it (cf C)
* no need to separate variables from their submethod name (cf D)
* more D-like, yet reminiscent of objective C argument description at call
site (without those fugly objective C brackets)

G)
Finally, this would be compatible with *named argument parameter
syntax*that I and others have been pushing for, if they are ever
introduced in D.
There were many proposals but I'd like to propose this:

void fun1(int a, int b, int c:, int d:);
obj.fun1(1, 2, c:3, d:4);

void fun2(int a, int b, int c:3, int d:4);
obj.fun2(1, 2); =3D> fun2(1,2,c:3,d:4)
obj.fun2(1, 2,d:0); =3D> fun2(1,2,c:3,d:0)
obj.fun2(1, 2,d:0, c:6); =3D> fun2(1,2,c:6,d:4)

'd:' indicates that d argument is mandatory at call site and name d is part
of the API.
'd:4' indicates that d argument is optional at call site and name d is part
of the API;
optional named arguments must appear after all other arguments, and can be
reordered / omitted.

----
[1]
for
https://www.google.com/url?sa=3Dt&rct=3Dj&q=3D&esrc=3Ds&source=3Dweb&cd=3D1=
&cad=3Drja&ved=3D0CC8QFjAA&url=3Dhttp%3A%2F%2Fforum.dlang.org%2Fthread%2Fkq=
7li9%242j9v%241%40digitalmars.com&ei=3DOMbLUae3LLD0iwLl04CACw&usg=3DAFQjCNH=
ScB2VEdtBBSnkFKum21Gz3sIUDw&sig2=3D1ToqlVmg6nDWMMpxPg5Lcg&bvm=3Dbv.48572450=
,d.cGE

[2]
http://michelf.ca/projects/d-objc/syntax/#protocols
Jun 26 2013
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-06-27 07:35, Timothee Cour wrote:
 See [1][2] for related thread introducing extern(objective C)

 A)
 The syntax proposed in [2] transforms:
 -(void) insertItemWithObjectValue: (NSString *) path atGreen:(NSInteger)
 anInt;
 [obj insertItemWithObjectValue:val atGreen:idx ];

 into:
 void insertItem(NSString* object, NSInteger anInt)
 [insertItemWithObjectValue:atGreen:];
 obj.insertItem(val, idx);

 B)
 I don't see how it handles this case:
 [obj insertItemWithObjectValue:val atGreen:idx ];
 [obj insertItemWithObjectValue:val atRed:idx ];

 obj.insertItem(val, idx); //atGreen or atRed ?
In my binding generator (DStep) I just use the whole selector name and replaces colons with underscores. This doesn't happen that often.
 F)
 *I'd like to propose instead the following syntax:*
 void insertItemWithObjectValue(NSString* object, NSInteger atGreen:);
 void insertItemWithObjectValue(NSString* object, NSInteger atRed:);
I think this looks a bit weird.
 obj. insertItemWithObjectValue(object, atGreen: idx);
 obj. insertItemWithObjectValue(object, atRed: idx);
Actually, I wouldn't mind this. -- /Jacob Carlborg
Jun 27 2013
prev sibling next sibling parent "Paulo Pinto" <pjmlp progtools.org> writes:
On Thursday, 27 June 2013 at 05:35:28 UTC, Timothee Cour wrote:
 See [1][2] for related thread introducing extern(objective C)

 A)
 The syntax proposed in [2] transforms:
 -(void) insertItemWithObjectValue: (NSString *) path 
 atGreen:(NSInteger)
 anInt;
 [obj insertItemWithObjectValue:val atGreen:idx ];

 into:
 void insertItem(NSString* object, NSInteger anInt)
 [insertItemWithObjectValue:atGreen:];
 obj.insertItem(val, idx);

 B)
 I don't see how it handles this case:
 [obj insertItemWithObjectValue:val atGreen:idx ];
 [obj insertItemWithObjectValue:val atRed:idx ];

 obj.insertItem(val, idx); //atGreen or atRed ?

 C)
 The fact that one needs to come up with a new name insertItem 
 is not good
 (as done in [2] ). And if we reuse the name:
 'void insertItemWithObjectValue(NSString* object, NSInteger 
 anInt)
 [insertItemWithObjectValue: atGreen:];'
 Then it's not DRY.

 D)
 the variable list is separated from the argument name list; 
 this makes it
 less readable with more arguments.

 E)
 the only benefit of objective C's syntax (making it clear at 
 call site what
 is the argument description) is lost.

 ----
 F)
 *I'd like to propose instead the following syntax:*
 void insertItemWithObjectValue(NSString* object, NSInteger 
 atGreen:);
 void insertItemWithObjectValue(NSString* object, NSInteger 
 atRed:);
 obj. insertItemWithObjectValue(object, atGreen: idx);
 obj. insertItemWithObjectValue(object, atRed: idx);

 Advantages:
 * unambiguous (cf B)
 * no need to come up with new name or repeat it (cf C)
 * no need to separate variables from their submethod name (cf D)
 * more D-like, yet reminiscent of objective C argument 
 description at call
 site (without those fugly objective C brackets)

 G)
 Finally, this would be compatible with *named argument parameter
 syntax*that I and others have been pushing for, if they are ever
 introduced in D.
 There were many proposals but I'd like to propose this:

 void fun1(int a, int b, int c:, int d:);
 obj.fun1(1, 2, c:3, d:4);

 void fun2(int a, int b, int c:3, int d:4);
 obj.fun2(1, 2); => fun2(1,2,c:3,d:4)
 obj.fun2(1, 2,d:0); => fun2(1,2,c:3,d:0)
 obj.fun2(1, 2,d:0, c:6); => fun2(1,2,c:6,d:4)

 'd:' indicates that d argument is mandatory at call site and 
 name d is part
 of the API.
 'd:4' indicates that d argument is optional at call site and 
 name d is part
 of the API;
 optional named arguments must appear after all other arguments, 
 and can be
 reordered / omitted.

 ----
 [1]
 for
 https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CC8QFjAA&url=http%3A%2F%2Fforum.dlang.org%2Fthread%2Fkq7li9%242j9v%241%40digitalmars.com&ei=OMbLUae3LLD0iwLl04CACw&usg=AFQjCNHScB2VEdtBBSnkFKum21Gz3sIUDw&sig2=1ToqlVmg6nDWMMpxPg5Lcg&bvm=bv.48572450,d.cGE

 [2]
 http://michelf.ca/projects/d-objc/syntax/#protocols
http://docs.xamarin.com/guides/ios/advanced_topics/binding_objective-c_libraries -- Paulo
Jun 27 2013
prev sibling parent Michel Fortin <michel.fortin michelf.ca> writes:
On 2013-06-27 05:35:11 +0000, Timothee Cour <thelastmammoth gmail.com> said:

 See [1][2] for related thread introducing extern(objective C)
 
 A)
 The syntax proposed in [2] transforms:
 -(void) insertItemWithObjectValue: (NSString *) path atGreen:(NSInteger)
 anInt;
 [obj insertItemWithObjectValue:val atGreen:idx ];
 
 into:
 void insertItem(NSString* object, NSInteger anInt)
 [insertItemWithObjectValue:atGreen:];
 obj.insertItem(val, idx);
 
 B)
 I don't see how it handles this case:
 [obj insertItemWithObjectValue:val atGreen:idx ];
 [obj insertItemWithObjectValue:val atRed:idx ];
 
 obj.insertItem(val, idx); //atGreen or atRed ?
If green and red are the same type then you can't use overloading and must come with two different function names. Here that'd be insertItemAtGreen and insertItemAtRed. I agree we lose some expressiveness by shortening the names, but I think keeping the same function call syntax as the rest of D is worthwhile. If you require a special syntax for those calls then it doesn't integrate well with other parts of D: you can't make an alias to those functions nor pass them as alias parameters to templates (not without a custom syntax for this too), and generic code designed with D in mind will probably not work.
 C)
 The fact that one needs to come up with a new name insertItem is not good
 (as done in [2] ). And if we reuse the name:
 'void insertItemWithObjectValue(NSString* object, NSInteger anInt)
 [insertItemWithObjectValue: atGreen:];'
 Then it's not DRY.
It doesn't matter much. The current design only require specifying the selector if you are generating bindings, and this should be automated anyway. Overrides inherit the selector, and original methods get a generated selector (which you can get and pass around with a simple syntax). So unless you're writing bindings you shouldn't have to care about selectors at all. This is a perfectly good way to define an Objective-C object: class MyObject : NSObject { private NSString _name; this(NSString name) { _name = name.copy; } property int name() const { return _name.retain.autorelease; } property void name(int newName) { _name = newName.copy; } override NSString description() { return name; } } The only thing telling you this is an Objective-C object is that it derives from NSObject. You're still programming in D, not in a special dialect of D meant to interact with Objective-C. That's the spirit.
 D)
 the variable list is separated from the argument name list; this makes it
 less readable with more arguments.
 
 E)
 the only benefit of objective C's syntax (making it clear at call site what
 is the argument description) is lost.
Well, the alternative is to use a custom syntax that doesn't play well with other D features. It's akin to how C++ and Objective-C can both be used in the same file. It could be done, but that's an entirely different project. -- Michel Fortin michel.fortin michelf.ca http://michelf.ca/
Jun 27 2013