2017-11-21 6 views
0

Also mein Problem ist folgendes:Verständnis seltsam logischen Operatoren in smalltalk

Wenn char = 0

boolean = char ~= 0 & char ~= 256 

true ergibt, und wenn ich invertieren die Anweisungen wie folgt:

boolean = char ~= 256 & char ~= 0 

Ich werde falsch.

Was ist los ?. Ich erwarte in beiden Fällen falsch.

+0

'char = 0 boolean = char ~ = 0 & char ~ = 256' ist kein gültiger Smalltalk-Ausdruck (ich meine, es ist gültig, aber Ganzzahlen implementieren nicht' # boolean' AFAIK). Kannst du deiner Frage auch einen exakten Ausdruck geben, damit sie leichter zu verstehen ist? – Uko

+2

Berücksichtigen Sie die Tatsache, dass Sie _messages_ und nicht _operators_ verwenden? I.e. 'boolean = char ~ = 256 & char ~ = 0' ist äquivalent zu' (((boolean = char) ~ = 256) & char) ~ = 0'. – Uko

+0

Wie kann ich diese Auswertung richtig machen? – patzi

Antwort

4

Wie @Uko sagte, müssen Sie den Vorrang von Nachrichten verstehen: Alle binären Nachrichten (+ = < & ~ = etc ..) werden von links nach rechts ausgewertet.

So bewerten Sie:

(((boolean = char) ~= 256) & char) ~= 0 

Ich glaube, Sie waren nach:

boolean := (char ~= 256) & (char ~= 0). 

Also, was mit Ihrem Ausdruck geschieht?

  • boolean wird vermutlich unitialized (also nil)
  • char ist 0.
  • boolean = char falsch ist.
  • false ~= 256 ist wahr.
  • true & char ist char (siehe unten warum)
  • char ~= 0 falsch ist (da char = 0)

Wenn Sie invertieren 0 und 256, wobei nur die letzte Stufe Änderungen und awnswer wahr.

Der interessante Teil ist die Umsetzung der Nachricht & in Klasse True: es wohl nicht behaupten, dass der Parameter ein Boolean ist und wie folgt aussieht:

& aBoolean 
    ^aBoolean 

Wenn Sie etwas übergeben, die kein Boolean ist, (Wie 0 in Ihrem Fall), wird es dieses Ding, was auch immer es überraschend sein kann zurückgeben ...

Wenn Sie eine IDE verwenden (Squeak/Pharo/Visualworks/Dolphin ... aber nicht Gnu Smalltalk) Ich schlage vor, Sie verwenden das Menü Debug It und evaluiere den Ausdruck Schritt für Schritt im Debugger.

Beachten Sie, dass char im Smalltalk-Kontext wahrscheinlich kein guter Name ist: es könnte irreführend sein. In der Tat, wenn es 0 enthält, ist es eher ein Integer, kein Charakter.

+0

Ich habe es. Vielen Dank. Der Vorrang im Smalltalk ist knifflig, und ich habe lange gebraucht, um herauszufinden, dass das Einzige, was ich falsch gemacht habe, seit ich mich an die imperative Programmierung gewöhnt habe. – patzi

+0

Precdence-Regeln sind in allen Sprachen schwierig. Smalltalk-Regeln sind einfach und das System ist einfach zu erweitern, am überraschendsten ist vielleicht der arithmetische Ausdruck a + b * c, weil wir sehr früh in der Schule den arithmetischen Vorrang lernen und es dann schwer ist, zu verlernen ... –

3

Es gibt etwas, was wir in einigen Antworten wiederholen, die meiner Meinung nach weitere Klärung verdienen. Wir sagen Bewertung läuft von links nach rechts. Richtig, aber die eigentliche Semantik der Nachrichten lautet:

Zuerst werten Sie den Empfänger aus, dann die Argumente in Reihenfolge; endlich die Nachricht senden.

Da die Smalltalk VM basierte stapeln, so bedeutet dies, dass Regel:

  1. Der Empfänger zuerst ausgewertet wird und das Ergebnis wird auf dem Stapel abgelegt.
  2. Die Argumente werden in der Reihenfolge ausgewertet und ihre Ergebnisse auf den Stapel geschoben. wird
  3. Die Meldung

Punkt 3 bedeutet, dass das Verfahren, das die Sende ruft den Empfänger und die Argumente in dem Stapel in der Reihenfolge oben definiert hat gesendet.

Zum Beispiel in

a := 1. 
b := 2. 
b := a - (a := b) 

Variable b wird (1 - (a := 2)) = -1 und a-2 bewerten. Warum? Weil zu der Zeit, zu der die Zuweisung a := b ausgewertet wird, wurde der Empfänger a der Subtraktion bereits mit dem Wert, den er zu dieser Zeit hatte, d. H. 1 gedrückt.

Beachten Sie auch, dass diese Semantik beibehalten werden muss, auch wenn die VM Register anstelle des Stapels verwendet. Der Grund ist, dass Bewertungen die Semantik und damit die Reihenfolge bewahren müssen. Diese Tatsache wirkt sich auf die Optimierungen aus, die der systemeigene Code möglicherweise implementiert.

Es ist interessant zu beobachten, dass diese Semantik zusammen mit der Priorität unary> binary> Schlüsselwort Polymorphismus in einer einfachen Art und Weise unterstützt. Eine Sprache, die beispielsweise * als + mehr Vorrang gibt, geht davon aus, dass * eine Multiplikation und + ein Zusatz ist. In Smalltalk ist es jedoch Sache des Programmierers, die Bedeutung dieser (und anderer) Selektoren zu bestimmen, ohne dass die Syntax der eigentlichen Semantik im Wege steht.

Mein Punkt hier ist, dass "von links nach rechts" von der Tatsache kommt, dass wir Smalltalk auf Englisch schreiben, die von "links nach rechts" gelesen wird. Wenn wir Smalltalk mit einer Sprache implementieren, die von "rechts nach links" gelesen wird, würde diese Regel widerlegt werden. Die tatsächliche Definition, die wird unverändert bleiben, ist die eine in den Punkten 1, 2 und 3 oben ausgedrückt, die aus dem Stapel Metapher kommt.

Verwandte Themen