Warum fügt add: das in Smalltalk-Sammlungen hinzugefügte Objekt zurück?

8

Hintergrund

Etwas, das jeden Smalltalk-Neuling abfängt, ist, dass add: nicht "self" zurückgibt, sondern das hinzuzufügende Objekt.

Zum Beispiel mit diesem Code:

%Vor%

myCollection enthält den String "Paul" und nicht die Kollektion selbst.

Dies liegt daran, dass add: das hinzuzufügende Objekt zurückgibt und der gesamte kaskadierte Ausdruck die letzte gesendete Nachricht auswertet.

Stattdessen sollte es am Ende mit yourself geschrieben werden:

%Vor%

Fragen

  • Warum ist das so?
  • Was war das auf diese Weise?
  • Was sind die Vorteile von add: , die sich so verhalten?
Sebastian N. 27.12.2012, 00:24
quelle

5 Antworten

12

Ich habe viel darüber nachgedacht. Ich habe noch nie von den ursprünglichen Designern von Smalltalk gehört, die diese Entscheidung verteidigen, also wissen wir nicht genau, warum sie es getan haben. Ich habe entschieden, dass der Grund dafür in Kaskaden liegt. Wenn add: den Empfänger zurückgegeben, dann (Dinge hinzufügen: thing1) add: thing2 wäre das gleiche wie die Dinge hinzufügen: thing1; füge hinzu: sache2. Wenn add: das Argument zurückgegeben wird, sind diese beiden Ausdrücke unterschiedlich und der Programmierer kann sie verwenden, wenn es angemessen ist.

Aber ich denke, es ist ein Fehler. Ich lehre Smalltalk seit über 25 Jahren und jedes Mal, wenn ich es lehre, haben die Leute Probleme damit. Ich warne sie immer, aber sie fügen immer noch Fehler hinzu. Also halte ich das für eine schlechte Designentscheidung.

Bei dieser Designentscheidung geht es um die Bibliothek, nicht um den Compiler. Sie können dies ändern, indem Sie in die Sammlungsklassen wechseln und sie ändern. Natürlich ist es unmöglich vorherzusagen, wie viele Smalltalk-Programme kaputtgehen würden. Sammlungen sind so grundlegend, dass diese Veränderung genauso schwierig wäre wie eine echte Veränderung der Sprache.

    
Ralph Johnson 27.12.2012, 07:52
quelle
6

In anderen Sprachen können Sie schreiben:

%Vor%

Dies wird irgendwie in Smalltalk beibehalten, wenn at:put: das Put-Objekt zurückgibt:

%Vor%

Dasselbe Interesse besteht für add: / remove: , die diese Art der Verkettung erlauben:

%Vor%     
aka.nice 27.12.2012 01:22
quelle
3

Es ist immer am besten, solche Methoden-Sends zu kaskadieren und sich niemals auf ihre Rückgabewerte zu verlassen. Das gleiche gilt für die Setter-Methoden, manchmal können sie sich selbst zurückgeben, manchmal geben sie den Parameter zurück. Es ist am sichersten anzunehmen, dass der Rückgabewert dieser Methoden nahezu zufällig ist und niemals verwendet wird.

    
Karsten 27.12.2012 08:12
quelle
2

Ich kann es nicht verteidigen, und ich kann auch Ralphs Erfahrung nicht widerlegen.

Ein Wunsch nach Symmetrie könnte ein Faktor gewesen sein. Da #remove: das Objekt zurückgibt, das entfernt wurde, ist es sinnvoll, #add: das hinzugefügte Objekt zurückzugeben.

Einfache Beispiele beeinflussen uns auch, denke ich. Wenn wir das Objekt bereits in einer Variablen hinzufügen oder es ein einfaches Literal ist, erscheint der Wert der Rückgabe sinnlos. Aber wenn wir (fraglichen) Code haben, der so aussieht:

%Vor%

Wenn someProfile eine lineare Liste ist, nehme ich an, dass Sie den soeben hinzugefügten Wert abrufen können: 'ed via last. Aber es könnte nur eine Tasche oder ein Set sein. In diesem Fall kann es praktisch sein:

%Vor%

Manche würden das besser finden als:

%Vor%

Obwohl das Beste wäre:

%Vor%     
Travis Griggs 27.12.2012 20:27
quelle
0

Die beste Erklärung, die ich mir ausgedacht habe, ist, sie einer Aufgabe gleichzustellen. Angenommen, Sie haben einen solchen Code:

%Vor%

Die Zuweisung in eine Variable ergibt das zugewiesene Objekt. Ich sollte in der Lage sein, die Variable durch eine Sammlung zu ersetzen und gleiches Verhalten zu erhalten:

%Vor%

Nun, nachdem ich das gesagt habe, würde ich jeden Entwickler, der diesen Code geschrieben hat, bestrafen, weil er nicht lesbar ist. Ich würde es lieber in zwei Zeilen aufteilen:

%Vor%

Das ist die beste Begründung, die ich geben kann. Es ist getan, um die Zuordnung in Sammlungen mit der Zuweisung in Variablen zu konsistent zu machen, aber wenn Sie diese Funktion nutzen, haben Sie Code, der schwer zu lesen ist.

    
David Buck 05.01.2013 01:33
quelle