Здравствуйте, Кодт, Вы писали:
К>Но тут фигня в том, что авторы накопипастили кучу сигнатур, вместо того, чтобы позволить пользователю выражать всё через одну.
К>Вот у чисел есть единственное x *y, а не x *y *z *t
У Boolean есть еще один незамеченный тобой селектор, а именно &. Он ведет себя так же как *.
aBool1 & aBool2 & aBool3 ...
К>Возможно, это была битва против правой ассоциативности, т.к.
К>a and: b or: c and: d разбивается на (a and: (b or: (c and: d)))
К>И, соответственно, без мега-сигнатур с одними and было бы
К>(a and: (b and: (c and: d (and: (e and: f)))))
Нет. Оно разбивается не так. В выражении (a and: b or: c and: d) объекту a посылается сообщение (and: or: and: ). Т.е. все эти имена с двоеточиями считаются частью одного и того же сообщения.
К>а с мега-сигнатурами — вот тут нужно уточнить, жадный ли компилятор
К>(a and: b and: c and: d and: (e and: f))
К>или ленивый
К>(a and: (b and: c and: d and: e and: f))
К>Вроде бы жадный...
Компилятор жадный. Основная операция для логического И является "&". Там вычисляются все выражения.
А вот для ленивости добавили and: и пр. Значения вычисляются при необходимости.
Именно поэтому в & передается параметр Boolean, а в and: передается Block.
К>Куда легко добавить? В стандартную библиотеку?!
К>Ну я понимаю, что смолток-среда является песочницей, и у себя в песочнице можно творить всё, что хочешь.
К>Например, пропатчить стандартные классы.
Да, добавляешь в образ свой модуль и получаешь нужные именно тебе методы в стандартных классах.
К>Можно даже на боярский язык перевести, ибо:, вотще:, еслиЧо:, еслиНичо: — но непоймут-с!
Согласен, не поймут. Но and: and: and: and: and: and: поймут.
Б>>Можно оставить только ifTrue: (аналог if) и ifTrue:ifFalse: (аналог if else).
Б>>ifFalse и ifFalse:ifTrue — сахар.
К>Конечно, можно. Я, вообще, удивился, почему они сделали всё на откуп в субклассы. Может, ради производительности?
Скорее, ради чистоты языка. Нет ключевых слов boolean, true, false. Есть лишь классы (Boolean, True, False) и объекты (true, false).
К>У смолтока проблемы не с переменным, а с множеством аргументов. Из-за того, что пользователь может захотеть послать сообщение, начиная с произвольного ярлыка, приходится рожать кучу сигнатур. Ну там setWidth:height: и setHeight:width: и т.п. То есть, выбрав вот такой синтаксис, обрекли себя на многословие (и вошли в диссонанс с самоназванием).
Да, я имел виду множество аргументов. Ну нет именованных параметров в smalltalk, ну и что — это обходится, не усложняя язык.
К>Хотя есть языки, поддерживающие именованные параметры. Даже лисп.
И куча языков их не поддерживающих. Тот же haskell.
К>А с учётом того, что все методы виртуальные, придётся договариваться — что подлежит переопределению в субклассе, а что является шаблонным методом (в случае с Boolean — and:and:and: — шаблон, and: переопределяется).
Кому договариваться? Создатели библиотеки и сами все знают. А если мы сами чего-нибудь не переопределим то получим ошибку #errSubclassResponsibility ('My subclass should have overridden one of my messages.'). Ошибка генерируется в методе subclassResponsibility. Т.е. если мы переопределим метод and: то будет вызван метод субкласса. Если нет, то будет вызван subclassResponsibility, который уведомит об ошибке.
К>Я бы в С++ офигел вводить методы setWidthHeight(w,h) и setHeightWidth(h,w)
Я не понимаю...
// C++
a.setWidthHeight(w,h);
"smalltalk"
a.setWidth: height.
// C++
a.setWidth(w);
a.setHeight(h);
"smalltalk"
a setWidth: w.
a setHeight: h.
"smalltalk - посылка нескольких сообщений одному объекту"
a setWidth: w;
setHeight: h.
А вообще, методы типа ifFalse: ifTrue: — это удобно, поэтому и добавили.
// C++
if(!wrongMessage)
...
else
...
"smalltalk"
wrongMessage ifFalse: [...]
ifTrue: [...]
То же и с whileTrue и whileFalse.