История изменений
Исправление monk, (текущая версия) :
Если круг не может быть подтипом эллипса, то и ограниченные числа не могут быть подтипом всех чисел
Если круг/эллипс не могут изменяться методами, то круг является подтипом эллипса.
То есть должно быть
class ellipse()
{
ellipse scale(double p, double q); // возвращает масштабированный эллипс
}
А проблема (и у CLOS) в том числе, что объекты начинают использовать как хранилище состояний. И в этом смысле эллипс является потомком круга, так как он может изобразить все состояния круга.
К слову для GLS проблемы нет.
(defmethod (scale! (r <ellipse>) (p double?) (q double?))
(set-axis1 r (* p (axis1 r)))
(set-axis2 r (* q (axis2 r))))
Будет прекрасно работать и с объектом, который удовлетворяет типу (and? <ellipse> equal-axis?). Просто после выполнения данного метода объект перестанет быть кругом (что с точки зрения классо-ориентированных языков нонсенс: метод не может изменить тип объекта).
Исходная версия monk, :
Если круг не может быть подтипом эллипса, то и ограниченные числа не могут быть подтипом всех чисел
Если круг/эллипс не могут изменяться методами, то круг является подтипом эллипса.
То есть должно быть
class ellipse()
{
ellipse scale(double p, double q); // возвращает масштабированный эллипс
}
А проблема (и у CLOS) в том числе, что объекты начинают использовать как хранилище состояний. И в этом смысле эллипс является потомком круга, так как он может изобразить все состояния круга.
К слову для GLS проблемы нет.
(defmethod (scale! (r <ellipse>) (p double?) (q double?))
(set-axis1 r (* p (axis1 r)))
(set-axis2 r (* q (axis1 r))))
Будет прекрасно работать и с объектом, который удовлетворяет типу (and? <ellipse> equal-axis?). Просто после выполнения данного метода объект перестанет быть кругом (что с точки зрения классо-ориентированных языков нонсенс: метод не может изменить тип объекта).