Как черты Скалы на самом деле не черты? - PullRequest
8 голосов
/ 09 марта 2011

Кто-то недавно сказал мне, что черты Scala не являются «настоящими» чертами, и что они действительно были просто миксинами. К сожалению, у меня не было возможности спросить его, почему. У кого-нибудь есть идея, что он имел в виду?

Edit: В качестве определения «черт» я ссылаюсь на диссертацию Натальи Шерли и концептуальный документ , посвященный введению черт. Одна ключевая особенность, которая, по-видимому, отсутствует в большинстве реализаций смешанного и / или множественного наследования, - это возможность переименовывать методы при их импорте, чтобы избежать коллизий / неоднозначности. Может ли Scala это сделать?

Ответы [ 3 ]

9 голосов
/ 09 марта 2011

Я думаю, что это, вероятно, связано с тем, что в Scala, а не с тем, что было предложено в оригинальной бумаге .

Я когда-то тоже думал об этом вопросе, за исключением различий в реализации, я пришел к выводу, что черты в Scala действительно оставляют желать лучшего. То, как Scala позволяет создавать, но не исключать методы, странно. Чтобы избежать конфликтов, он заимствовал то, что называется порядок разрешения метода (или линеаризация на языке Scala) на других языках. Существует проблема, хорошо известная для языков, которые поддерживают множественное наследование, и я смело классифицирую Scala как члена этой группы. Проблема в том, что это слишком сложно и требует много времени для понимания.

Порядок разрешения методов в Scala - странный зверь, у него есть собственный алгоритм отправки методов. Это не C3 Дилана, который используется в Python, с некоторыми заметными проблемами , но имеет все проблемы, связанные с ним. Хуже того, я могу посмотреть MRO объекта Python, вызвав его метод .mro(). В Scala нет эквивалента.

Я могу вам сказать, что мне не очень нравится запускать алгоритм Scala MRO в моей голове каждый раз, когда мне нужно посмотреть, где будет разрешен метод.

2 голосов
/ 26 апреля 2012

Одним из ключевых различий между миксинами и чертами является то, что в миксинах есть поля, а у черт - нет. Перефразируя из оригинальной статьи, черта:

  • предоставляет методы, которые реализуют поведение
  • требует методов, которые параметризуют предоставленное поведение
  • не указывать и не получать доступ к полям
  • симметрично составлены
  • может быть вложенным, эквивалентно уплощенным чертам

На первый взгляд, третья точка выглядит так, как будто она нарушена в реализации Scala. Однако признаки могут иметь доступ только к открытым полям, которые защищены неявными получателями и установщиками. Далее в статье описывается, что это приемлемо для реализации признаков.

Вы отмечаете, что ключевой особенностью признаков является то, что методы можно переименовывать при их импорте. Это невозможно, учитывая ограничения JVM. Последовательное обсуждение этого можно найти здесь: http://scala -programming-language.1934581.n4.nabble.com / Trait-method-aliasing-td2322026.html , особенно сообщения Дэвида Поллака.

Наконец, мой ответ на ваш общий вопрос "своего рода". Чтобы уточнить, хотя черты Scala не являются строго чертами, как определено в статье, они также не являются строго миксинами. В любом случае, лучше всего использовать их так, как если бы они были чертами характера и придерживаться их принципов дизайна.

  • Держите их маленькими, с целью их повторного использования.
  • Указать поведение, а не состояние.
1 голос
/ 09 марта 2011

Нет, Scala не может переименовать при импорте.

Интересно, как бы это сработало. Если метод m черты T переименован в m2 в объекте o, как будет p.m разрешаться, если p является параметром типа T, и o был передан через это?

...