Как скрытое сообщение SmallTalk реализовано за кулисами? - PullRequest
2 голосов
/ 28 января 2009

Я пытаюсь научить себя Smalltalk. В учебнике приведен пример цикла while:

|i| 
i:=5. 
[i >0] whileTrue:[ 
 Transcript show: ((i*2) asString) ; cr. 
 i:=i-1. 
].

Насколько я понимаю, whileTrue - это сообщение, отправленное BlockClosure, сообщающее принимающему BlockClosure запустить BlockClosure, заданную в качестве аргумента, до тех пор, пока получатель верен.

Как сообщение whileTrue, на которое отвечает BlockClosure, реализовано без конструкции цикла while в Smalltalk? Или это реализовано на любом языке, на котором написано время выполнения?

Ответы [ 3 ]

6 голосов
/ 29 января 2009

В моем образе VisualWorks это сделано с помощью рекурсии:

<b>whileTrue: aBlock</b>

   ^self value
      ifTrue:
      [aBlock value.
      [self value] whileTrue: [aBlock value]]

Однако, есть также примечание о том, что компилятор встроит вызов # whileTrue:, если и получатель, и аргумент являются литеральными блоками. Так что в большинстве случаев вы также можете рассмотреть # whileTrue: одно из «волшебных» сообщений, которое выглядит как сообщение, отправленное синтаксически, но действительно оптимизировано под разные байт-коды.

0 голосов
/ 22 августа 2010

Как уже упоминалось: компилятор обманывает и вставляет во все известные мне реализации. Таким образом, нет необходимости в том, чтобы метод присутствовал в обычных ситуациях, и он обычно не вызывается. Однако этот метод может быть полезен при выполнении или интерпретации динамически генерируемых структур кода без фактического использования компилятора.

Между прочим, поскольку стандарт языка Smalltalk (который на самом деле не существует) не заставляет реализации устранять хвостовые вызовы (в отличие, например, от Scheme), рекурсивная реализация в VW не очень полезна выполнение или интерпретация (если код-компилятор не стандартизирован).

Альтернативой без рекурсии может быть:

whileTrue:aBlock
    self value ifFalse:[^ nil].
    aBlock value.
    thisContext restart
0 голосов
/ 28 января 2009

Согласно этому форуму whileTrue не является настоящим сообщением.

...