Статически решить, является ли класс Scala неизменным - PullRequest
9 голосов
/ 21 июня 2011

Я только что посетил Scala-лекцию в летней школе.Лектор получил следующий вопрос:

- «Есть ли у компилятора способ определить, является ли класс неизменным?»

Лектор ответил:

- "Нет, нет. Было бы очень хорошо, если бы это было возможно. "

Я был удивлен. Разве это не просто проверить, содержит ли класс какие-либо переменные-члены?

Ответы [ 6 ]

7 голосов
/ 22 июня 2011

Что такое неизменяемое?

Проверка того, содержит ли объект только поля val, представляет собой избыточное приближение неизменности - объект может очень хорошо содержать var с, но никогда не назначать в них другие значения.Или сегменты программы, присваивающие значения var s, могут быть недоступны.

Согласно терминологии Крис Окасаки , существуют неизменяемые структуры данных и функциональные структуры данных.

Неизменяемая структура данных (или класс) - это структура данных, которая, будучи построенной в памяти, никогда не изменяет свои компоненты и значения - примером этого является кортеж Scala.

Однако, если вы определяете неизменность объекта как неизменность самого себя и всех объектов, достижимых посредством ссылок из объекта, тогда кортеж может не быть неизменным - это зависит от того, с чем вы позднее создадите его экземпляр.Иногда недостаточно информации о программе, доступной во время компиляции, чтобы решить, является ли данная структура данных неизменной в том смысле, что она содержит только val s.А информация отсутствует из-за полиморфизма, будь то параметрический, подтип или ad-hoc (классы типов).

Это первая проблема с решением неизменности - отсутствие статической информации.

Функциональная структура данных - это структура данных, в которой вы можете выполнять операции, выходные данные которых зависят исключительно от входных данных для данного состояния.Примером такой структуры данных является дерево поиска, которое кэширует последний найденный элемент, сохраняя его в изменяемом поле.Несмотря на то, что каждый поиск записывает последний искомый элемент в изменяемое поле, так что, если элемент снова ищется, поиск не должен повторяться, выходные данные операции поиска для такой структуры данных всегда остаются неизменными, есличто никто не вставляет новые предметы в него.Другим примером функциональной структуры данных являются деревья сплайнов .

В общей модели императивного программирования, чтобы проверить, является ли операция чистой, то есть - зависят ли выходные данные исключительно от входных данных, неразрешима .Опять же, можно использовать такой метод, как абстрактная интерпретация, чтобы дать консервативный ответ, но это не точный ответ на вопрос о чистоте.

Это вторая проблема с решением, если что-то имеет var sнеизменный или функциональный (наблюдаемый неизменный) - неразрешимость.

5 голосов
/ 21 июня 2011

Думаю, проблема в том, что вам нужно убедиться, что на всех ваших val нет ни одного члена var.И это вы не можете.Рассмотрим

class Base
case class Immutable extends Base { val immutable: Int = 0 }
case class Mutable extends Base { var mutable: Int = _ }

case class Immutable_?(b: Base)

Даже если Immutable_?(Immutable) действительно является неизменным, Immutable_?(Mutable) - нет.

2 голосов
/ 21 июня 2011

В дополнение к тому, что сказали другие, взгляните на системы эффектов и обсуждение поддержки одной из них в Scala .

2 голосов
/ 21 июня 2011

Если вы сохраняете изменяемый объект в val, сам объект все еще является изменяемым.Поэтому вам нужно проверить, является ли каждый класс, который вы используете в val, неизменным.

case class Mut(var mut:Int)

val m = Mut(1)
println(m.toString)
m.mut = 3
println(m.toString)
1 голос
/ 21 июня 2011

Это не так просто, поскольку у вас могут быть значения, связанные с другими изменяемыми классами, или, что еще труднее, обнаружить, вызывающие методы в других классах или объекты, которые могут изменяться.

Кроме того, у вас вполне может быть неизменный класс, который на самом деле имеет переменные (для большей эффективности, например ...).

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

0 голосов
/ 21 июня 2011

Вы можете иметь класс, который может быть создан для объекта, и этот объект может быть изменяемым или неизменным.

Пример: класс может содержать List[_], который во время выполнения может быть List[Int] или List[StringBuffer]. Таким образом, два разных объекта класса могут быть либо изменяемыми, либо неизменяемыми.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...