Comments 11
кстати, если метод один, можно слово extension не использовать.
def[T, T2] (a: T) ~> (b: T2) = (a, b)
В M3
это не компилируется.
Я забил на изучение Scala и «похоронил» язык когда узнал про implicit, который позиционируется как некие type class. Мне было очевидно, что это плохая идея, странно, что создатели языка этого не видели. Думаю каждый, кто с C++ работал это тоже понимает, implicit поведение это всегда зло.
implicit, который позиционируется как некие type class
Следующая статья как раз будет про тайпклассы в Scala 3. Stay tuned!
implicit поведение это всегда зло
Тут надо понимать, что имплиситами вообще и тайпклассами в частности пользуются не от хорошей жизни. Как правило это уровень библиотек, которые должны быть максимально гибкими, и альтернатива там — запутанные иерархии наследования, рефлексия и куча оберток. Что из этого большее зло — вопрос как минимум дискуссионный.
Тут надо понимать, что имплиситами вообще и тайпклассами в частности пользуются не от хорошей жизни. Как правило это уровень библиотек, которые должны быть максимально гибкими, и альтернатива там — запутанные иерархии наследования, рефлексия и куча оберток. Что из этого большее зло — вопрос как минимум дискуссионный.
Это ложная дихотомия, выбор не между запутанной иерархией и implicit.
Хм… было бы интересно узнать, какие еще есть опции. Вот хочу я сделать библиотеку для сериализации JSON. Естественно, пользователи этой библиотеки могут захотеть сериализовать любой класс, который у них есть. Какие у меня есть варианты кроме наследования/рефлексии/оберток с одной стороны и тайпклассов с другой?
Добавлю мультиметоды к списку. Но я говорил про «запутанная иерархия» против «implicit» — иерархия не обязана быть запутанной, implicit реализация тоже может быть запутанной.
Сравнивать type class с классическим ООП подходом удобно на expression problem. Там видно, что type class (по одному параметру) строго лучше, но проблему все ещё не решает. А мультиметоды решают. Но все это верно пока мы производительность не берём во внимание. Там окажется, скорее всего, что single dispatch (классическое ООП) зарулит всех.
В scala варианте implicit меня оттолкнуло то, что поведение кода меняется в зависимости от import в заголовке файла. Это сродни тому, как C++ код меняется, при подключении разных заголовочных файлов (в одном из которых может быть #define TRUE FALSE :). Это плохая практика, глядя на код нужно помнить чего наимпортировали сверху, лишняя нагрузка на мозги. Сделать так, чтобы все было explicit, но при этом не было нагромождения деталей — это искусство, думаю тут ещё много прогресса можно ждать.
x -> y
//эквивалентно
new ArrowAssoc(x).->(y)
В третьей версии создается функция верхнего уровня
x ~> y
//эквивалентно
~>(x, y)
Scala 3: избавление от implicit. Extension-методы и неявные преобразования