Pourquoi la dernière partie d’un nom de méthode Objective-C doit-elle prendre un argument (lorsqu’il y a plus d’une partie)?

En Objective-C, vous ne pouvez pas déclarer de noms de méthodes où le dernier composant ne prend pas d’argument. Par exemple, ce qui suit est illégal.

-(void)take:(id)theMoney andRun; -(void)take:(id)yourMedicine andDontComplain; 

Pourquoi Objective-C a-t-il été conçu de cette façon? Était-ce juste un artefact de Smalltalk dont personne n’avait besoin de se débarrasser?

Cette limitation a du sens dans Smalltalk, puisque Smalltalk ne dispose pas de délimiteurs autour de l’invocation des messages, de sorte que le composant final serait interprété comme un message unaire au dernier argument. Par exemple, BillyAndBobby take:'$100' andRun sera analysé comme le fait BillyAndBobby take:('$100' andRun) . Cela n’a pas d’importance en Objective-C où les crochets sont nécessaires.

La prise en charge de composants de sélecteur sans paramètre ne nous permettrait pas de gagner beaucoup de points, car la méthode nomme un programmeur (par exemple, runWith: plutôt que take:andRun ) n’affecte pas la sémantique fonctionnelle d’un programme, ni la expressivité de la langue. En effet, un programme avec des composants sans parameters est équivalent à un sans alpha. Je ne suis donc pas intéressé par les réponses indiquant qu’un tel dispositif n’est pas nécessaire (à moins que ce ne soit les raisons invoquées par les concepteurs d’Objective-C, est-ce que quelqu’un connaît Brad Cox ou Tom Love? Sont-ils ici?) comment écrire des noms de méthode pour que la fonctionnalité ne soit pas nécessaire. Le principal avantage est la lisibilité et l’écriture (ce qui est comme la lisibilité, seulement … vous savez), car cela signifierait que vous pourriez écrire des noms de méthodes qui ressemblent encore plus à des phrases en langage naturel. Les applications de -(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication (que Matt Gallagher souligne avec “Cocoa With Love” est un peu déroutante lorsque vous supprimez le paramètre formel) pourrait être nommée -(BOOL)application:(NSApplication*)theApplication shouldTerminateAfterLastWindowClosed , plaçant ainsi le paramètre immédiatement à côté du nom approprié.

Le runtime Objective-C d’Apple (par exemple) est parfaitement capable de gérer ce type de sélecteur, alors pourquoi pas le compilateur? Pourquoi ne pas les supporter également dans les noms de méthodes?

 #import  #import  @interface Potrzebie : NSObject -(void)take:(id)thing; @end @implementation Potrzebie +(void)initialize { SEL take_andRun = NSSelectorFromSsortingng(@"take:andRun"); IMP take_ = class_getMethodImplementation(self, @selector(take:)); if (take_) { if (NO == class_addMethod(self, take_andRun, take_, "@@:@")) { NSLog(@"Couldn't add selector '%@' to class %s.", NSSsortingngFromSelector(take_andRun), class_getName(self)); } } else { NSLog(@"Couldn't find method 'take:'."); } } -(void)take:(id)thing { NSLog(@"-take: (actually %@) %@",NSSsortingngFromSelector(_cmd), thing); } @end int main() { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; Potrzebie *axolotl=[[Potrzebie alloc] init]; [axolotl take:@"paradichloroaminobenzaldehyde"]; [axolotl performSelector:NSSelectorFromSsortingng(@"take:andRun") withObject:@"$100"]; [axolotl release]; [pool release]; return 0; } 

    Voici Brad Cox. Ma réponse originale a mal compris la question. J’ai supposé que reallyFast était une extension codée en dur pour déclencher une messagerie plus rapide, pas une sorte de sucre syntaxique. La vraie réponse est que Smalltalk ne l’a pas supporté, peut-être parce que son parsingur ne pouvait pas gérer l’ambiguïté (supposée). Bien que les crochets d’OC puissent éliminer toute ambiguïté, je n’ai simplement pas pensé à me départir de la structure de mots-clés de Smalltalk.

    21 ans de programmation Objective-C et cette question ne m’a jamais traversé l’esprit. Étant donné la conception du langage, le compilateur est correct et les fonctions d’exécution sont incorrectes ().

    La notion d’arguments entrelacés avec des noms de méthode a toujours signifié que, s’il y a au moins un argument, le dernier argument est toujours la dernière partie de la syntaxe d’invocation de la méthode.

    Sans trop y penser, je parie que certains bugaboos syntaxiques ne permettent pas d’appliquer le modèle actuel. Au minimum, cela rendrait le compilateur plus difficile à écrire car toute syntaxe comportant des éléments optionnels entrelacés avec des expressions est toujours plus difficile à parsingr. Il pourrait même y avoir un cas d’arête qui l’empêche complètement. Certes, Obj-C ++ le rendrait plus difficile, mais cela ne s’intégrait pas au langage avant que la syntaxe de base ne soit déjà définie.

    En ce qui concerne la raison pour laquelle Objective-C a été conçu de cette manière, je suppose que la réponse est que les concepteurs originaux du langage n’ont tout simplement pas envisagé de permettre à la syntaxe entrelacée de dépasser ce dernier argument.

    C’est une meilleure conjecture. Je vais demander à l’un d’entre eux et mettre à jour ma réponse lorsque j’en découvrirai plus.


    J’ai demandé à Brad Cox à ce sujet et il a été très généreux en répondant en détail (Merci, Brad !!):

    À ce moment-là, je me concentrais sur la duplication de Smalltalk autant que possible dans C et de le faire aussi efficacement que possible. Tous les cycles de rechange sont passés rapidement à la messagerie ordinaire. Il n’y avait aucune idée d’une option de messagerie spécialisée (“reallyFast?” [ Bbum: j’ai demandé à utiliser “doSomething: withSomething: reallyFast” comme exemple ]) puisque les messages ordinaires étaient déjà aussi rapides qu’ils pourraient l’être. Cela impliquait de régler à la main la sortie de l’assembleur du proto-messager C, ce qui était un cauchemar de portabilité que certains, sinon tous, ont été ultérieurement éliminés. Je me souviens que le messager piraté à la main était très rapide; sur le coût de deux appels de fonction; un pour entrer dans la logique de messagerie et le rest pour faire des recherches de méthode une fois là-bas.
    Les améliorations de typage statique ont été ajoutées par la suite au typage dynamic pur de Smalltalk par Steve Naroff et d’autres. Je n’avais qu’une implication limitée dans cela.

    Allez lire la réponse de Brad!

    Juste pour votre information, le runtime ne se soucie pas vraiment des sélecteurs, n’importe quelle chaîne C est valide, vous pourriez aussi bien créer un sélecteur comme celui-ci: “== + === + —__– ¨ ¨ ^ :::::: “sans argument, le runtime l’acceptera, le compilateur ne peut tout simplement pas ou sinon il est impossible d’parsingr. Il n’y a absolument aucune vérification de la santé mentale quand il s’agit de sélecteurs.

    Je suppose qu’ils ne sont pas pris en charge dans Objective-C car ils n’étaient pas non plus disponibles dans Smalltalk. Mais cela a une raison différente de celle que vous croyez: ils ne sont pas nécessaires. Ce qu’il faut, c’est un support pour les méthodes avec les arguments 0, 1, 2, 3, … Pour chaque nombre d’arguments, il existe déjà une syntaxe de travail pour les appeler. L’ajout de toute autre syntaxe ne ferait que créer une confusion inutile.

    Si vous vouliez des sélecteurs sans paramètre multi-mots, pourquoi s’arrêter avec un seul mot supplémentaire? On pourrait alors demander que

      [axolotl perform selector: Y with object: Y] 

    devient également pris en charge (c.-à-d. qu’un sélecteur est une séquence de mots, certains avec deux-points et un paramètre, et d’autres non). Même si cela aurait été possible, je suppose que personne n’a jugé cela utile.