Почему оператор + для списка устарел в Scala?

Почему оператор + для списка устарел в Scala?

http://www.scala-lang.org/docu/files/api/scala/List.html#%2B%28B%29

Ответы

Ответ 1

Хороший вопрос, поэтому я просмотрел его в книге Odersky et al. В нем говорится следующее (надеюсь, это не нарушение авторских прав, чтобы процитировать это здесь: -)):


Почему бы не добавить в списки?

Класс List не предлагает операцию добавления, поскольку время, которое требуется для добавления в список, растет линейно с размером списка, тогда как добавление с :: занимает постоянное время. Ваши параметры, если вы хотите создать список, добавляя элементы, - это добавить их, а затем, когда вы закончите, вызовите reverse; или используйте ListBuffer, измененный список, который предлагает операцию добавления, и когда вы закончите вызов toList.


Насколько я понимаю FP, добавление к списку гораздо чаще, чем добавление, по крайней мере, на чистых функциональных языках. Я могу только предположить, что дизайнеры Scala добавили оператор + в качестве удобства для разработчиков Java, которые используются для добавления с помощью add(), а затем подумали об этом.

Ответ 2

В мае 2008 года он был устаревшим в версии 15071 с сообщением:

Измените все проблемные + методы и удалите те, которые никогда не появлялись в релизе.

Я ожидаю, что это должно было избежать двусмысленности со StringAdd #+. Сравните разницу между 2.7.6 и 2.8.0 Beta ниже:

Welcome to Scala version 2.7.6.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_15).
Type in expressions to have them evaluated.
Type :help for more information.

scala> List(1) + 2
warning: there were deprecation warnings; re-run with -deprecation for details
res0: List[Int] = List(1, 2)

scala> List(1) + "2"
warning: there were deprecation warnings; re-run with -deprecation for details
res1: List[Any] = List(1, 2)

В 2.8, метод был удален, и вы получаете:

Welcome to Scala version 2.8.0.Beta1-RC8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_15).
Type in expressions to have them evaluated.
Type :help for more information.

scala> List(1) + 2
<console>:5: error: type mismatch;
 found   : Int(2)
 required: String
       List(1) + 2
                 ^

scala> List(1) + "2"
res1: java.lang.String = List(1)2

UPDATE

В списке scala -user Мартин Одерский отмечает:

Чтобы узнать, что действительно плохо Список # +, подумайте, что вы ожидаете для получения:

Список (1, 2, 3) + "является правильным результат"

?

oxbow_lakes добавляет - мне потребовалось некоторое время, чтобы распаковать этот критический комментарий, но я думаю, что дело в том, что оно нарушит коммутативность типов, подразумеваемых оператором +. То есть тип a + b должен быть таким же, как тип b + a

UPDATE Прояснение Мартина Одерского:

Что вы ожидаете

Список (1, 2, 3) + "- правильный результат"

производить? Я бы ожидал строку: "Список (1, 2, 3) - правильный результат".

С 2,7 списком стилей + вы получаете вместо этого Список [Any], List (1, 2, 3, "является правильный результат" ).

Я классифицирую это как плохой сюрприз. В резюме, никогда не должно быть + метод для коллекций, ковариантных по типу элементов. наборы и карты не являются вариантами, поэтому они могут иметь + метод. Все это довольно деликатный и грязный. Мы будем лучше, если бы мы не пытались дублировать Java + для строки конкатенации. Но когда Scala получил Идея заключалась в том, чтобы по существу, все выражения Java синтаксис, включая String+. И это слишком поздно, чтобы изменить это сейчас.

Ответ 3

Он не был коммутативным и был особенно субоптимален в списках. Кроме того, поведение отличается от изменчивых и неизменных коллекций. На Scala 2.8 у вас есть следующее:

element +: sequence   // prepend
sequence :+ element   // append
sequenece ++ sequence // concatenate

Изменчивая/непреложная вещь не совсем решена. Несколько методов были устаревшими в качестве первого шага, но они не могут быть изменены или удалены без предварительного устаревания.

Ответ 4

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

Как правило, следует организовать конструкцию List, чтобы не добавлять. Scala Список - это неизменный одиночный связанный список, поэтому добавление к его концу - операция O (n).

ListA ::: ListB является право-ассоциативным и работает во времени, пропорциональном длине ListA 'a ::: b' - это операция /prepend/operation, которая выполняется в O(a.length) time