Действительно ли все дело в передаче сообщений в smalltalk

#smalltalk

#smalltalk

Вопрос:

Я новичок в smalltalk, и я впечатлен тем фактом, что в языке всего 6 ключевых слов (self, super, true, false, nil amp; thisContext), и насколько это чисто, поскольку при передаче сообщений используется почти все, например, цикл с использованием whileTrue, if / else с использованием ifTrue и т.д… которые сильно отличаются от того, к чему я привык на других языках.

Тем не менее, есть случаи, когда я просто не могу понять, как передача сообщений действительно вписывается, к ним относятся:

  • оператор присваивания :=
  • каскадный оператор ;
  • оператор period .
  • способ создания набора #( ... )

Это не передача сообщений, верно?

Комментарии:

1. 1 но как они обычно используются? Для меня «передача сообщений» — это то, как объекты взаимодействуют друг с другом. Если вы говорите о деталях внутри объектов, для меня это не имеет отношения, и вопрос спорный: en.wikipedia.org/wiki/Message_passing Обратите внимание, что даже на совершенно «не чистом языке OO», таком как Java, вы можете улучшить «передачу сообщений», чем то, что будет делать средний Java-разработчик (например, везде используются методы получения и установки, не понимая, что методы получения и установки являются противоположностью OO).

2. Да, некоторые из них действительно не передают сообщения. Но потом я подумал, := выглядит как один, например. x := 1 2 может просто означать, что отправить двоеточие равно message to x , так что оно принимает значение 1 2 , но тогда правило приоритета не подходит.

3. @SyntaxT3rr0r «получатели и установщики являются противоположностью OO», не так ли? Простые средства доступа к экземпляру, определенные в собственном классе объекта, являются основой OO. Они являются краеугольным камнем инкапсуляции, которая позволяет создавать слабо связанные объекты. Многие Java-программисты, должно быть, включают сложные и тесно связанные модели поведения в базовые методы доступа getter и setter, если getter и setters рассматриваются как антитеза OO в Java-коде. Или я что-то упускаю?

Ответ №1:

Как вы обнаружили, все еще существует некоторый актуальный синтаксис Smalltalk. Построение блоков, литеральные строки / символы / комментарии, объявление локальной переменной ( |...| ) и возврат ( ^ ) — это несколько вещей, которые вы не упомянули, которые также являются синтаксисом.

Некоторые расширения (например, #(...) , которые обычно создают Array , а не набор), безусловно, могут быть выражены иным образом, например, #(1 2 3) эквивалентно Array with: 1 with: 2 with: 3 ; они просто предназначены для облегчения чтения и записи кода.

Комментарии:

1. Обратите внимание, что возврат ^ и присвоение := также можно выразить с помощью message sends: thisContext return: anObject и anObject instVarNamed: 'foo' put: anObject (например, переменные, временные и глобальные значения работают аналогично).

2. Мы почти можем сказать, что ^ и := являются синтаксическим сахаром 😉

Ответ №2:

Одна вещь, которая может помочь прояснить: self , super , true false nil thisContext amp;,, это примитивы данных, а не ключевые слова.

Это единственные 6 примитивов данных. Эти 6 также известны как псевдопеременные. Абсолютно все остальное является экземпляром класса Object или его подклассов.

В Smalltalk очень мало предопределенных ключевых слов. Они могут быть написаны в очень сжатой форме.

Известным примером является синтаксис Smalltalk на открытке (ссылка)

  exampleWithNumber: x

    | y |
    true amp; false not amp; (nil isNil) ifFalse: [self halt].
    y := self size   super size.
    #($a #a "a" 1 1.0)
        do: [ :each |
            Transcript show: (each class name);
                       show: ' '].
    ^x < y
  

Вот комментарий к этому методу, который больше, чем сам метод:

«Метод, который иллюстрирует каждую часть синтаксиса метода Smalltalk, за исключением примитивов. Он содержит унарные, двоичные сообщения и сообщения с клавиатуры, объявляет аргументы и временные значения, обращается к глобальной переменной (но не к переменной экземпляра), использует литералы (массив, символ, symbol, string, integer, float), использует псевдопеременные true, false, nil, self и super, а также имеет последовательность, присваивание, возврат и каскад. У него есть блоки как с нулевым аргументом, так и с одним аргументом. «