Pull to refresh

Comments 11

Действительно, в более новых версиях убрали. Жалко, мне такой синтаксис кажется красивым обобщением над объявлением функций.

Extensions одна из любимых фич c#, особенно круто работает с интерфейсами, не знаю как без этого вообще жить. Вот бы ещё в джаву добавили.

Я забил на изучение 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, но при этом не было нагромождения деталей — это искусство, думаю тут ещё много прогресса можно ждать.

> В scala варианте implicit меня оттолкнуло то, что поведение кода меняется в зависимости от import в заголовке файла

имплиситы по-разному могут резолвиться, не обязательно импортом в заголовке или импортом вообще.
Стоит добавить, что во второй скале на каждый вызов расширения создается объект неявного класса
x -> y
//эквивалентно
new ArrowAssoc(x).->(y)

В третьей версии создается функция верхнего уровня
x ~> y
//эквивалентно
~>(x, y)
Sign up to leave a comment.

Articles