Начни с объяснения того, почему при умножении int на float получается именно float. Компилятор экстрасенс? Почему он неявно приводит тип int к float? Какие ещё есть «особые случаи»? В том же строго типизированном Common Lisp * умножает number и проблем с неявным приведением типов нет.
#!/usr/bin/env python3
class myint(object):
def __init__(self, num):
self.num = num
def __mul__(self, b):
if isinstance(b, myfloat):
return self.num+'*'+b.num
assert 0
class myfloat(object):
def __init__(self, num):
self.num = num
i = myint('123')
f = myfloat('qwe')
print(i*f)
И это даже с диспетчеризацией только по первому аргументу. Нафига эта «сильная» типизация такой ценой? Ни typeclass'ов, ни ООП нормального. Лучше бы неявно приводили
Т.е. В каждом классе я должен реализовать __mul__ для всех вариантов
Нет, только у float который обрабатывает два типа в __mul__(...).
И это даже с диспетчеризацией только по первому аргументу. Нафига эта «сильная» типизация такой ценой? Ни typeclass'ов, ни ООП нормального. Лучше бы неявно приводили
Какую-то хрень несёшь не понимая смысла слов которыми её составляешь.
Ну и вернемся к выводу типов. Допустим, у нас есть самописные классы для int, float и double. При умножении int на float, получаем float, float на double получаем double. Как мне сделать автоматическое выведение типов для их произведения? Как выведение типов будет работать со встроенными классами?
Допустим, у нас есть самописные классы для int, float и double. При умножении int на float, получаем float, float на double получаем double. Как мне сделать автоматическое выведение типов для их произведения?
А это принципиально отличается от любых других классов?
Не нужно ни к чему возвращаться, мог бы сам уже давно придумать ответы на все свои вопросы.
1. В полностью динамическом ЯП вроде питона тип определяется по факту возвращаемого объекта, никакого вывода нет. Тот же __mul__() может вернуть что угодно и заранее не ясно что.
2. Хрень из топика ситуацию никак не меняет, она использует необязательные хинты которые ни к чему не обязывают даже если они указаны. Так по крайней мере в текущей реализации и навряд ли такое поведение будут ломать.
When a binary arithmetic operator has operands of different numeric types, the operand with the “narrower” type is widened to that of the other, where plain integer is narrower than long integer is narrower than floating point is narrower than complex. Comparisons between numbers of mixed type use the same rule. [2] The constructors int(), long(), float(), and complex() can be used to produce numbers of a specific type
The * (multiplication) operator yields the product of its arguments. The arguments must either both be numbers, or one argument must be an integer (plain or long) and the other must be a sequence. In the former case, the numbers are converted to a common type and then multiplied together. In the latter case, sequence repetition is performed; a negative repetition factor yields an empty sequence.
Алгоритм вывода типа тривиально выведет тип функции plus. Кого ты называешь «он», «заранее» по сравнению с чем - ХЗ.
1. В полностью динамическом ЯП вроде питона тип определяется по факту возвращаемого объекта, никакого вывода нет. Тот же __mul__() может вернуть что угодно и заранее не ясно что.
Алгоритм вывода типа тривиально выведет тип функции plus. Кого ты называешь «он», «заранее» по сравнению с чем - ХЗ.
1. В полностью динамическом ЯП вроде питона тип определяется по факту возвращаемого объекта, никакого вывода нет. Тот же __mul__() может вернуть что угодно и заранее не ясно что.
Я же просил конкретно указать, где ты увидел противоречие. В приведенных высказываниях его нет. Алгоритм вывода в самом деле выведет тип plus; но в Python не используется никакой алгоритм вывода.
Топик о _разработке предложения_ по добавлению некоторой формы статической типизации в Python (эта форма будет включать в себя некоторый вывод типов); в чем я и mashina не сходимся, так это в полезности такого добавления.