2015-01-06 2 views
10

Я изучаю описание инструмента Scala WartRemover и был спутан на один из сторон. Описание сказало это:Возвращает ли обратная ссылочная прозрачность?

return перерывы ссылочной прозрачности. Рефакторинг для безопасного завершения вычислений.

// Won't compile: return is disabled 
def foo(n:Int): Int = return n + 1 
def foo(ns: List[Int]): Any = ns.map(n => return n + 1) 

Это не имеет никакого смысла для меня, и оба примера выглядят референциально прозрачными. Есть ли какой-то способ, в котором ключевое слово return делает его более вероятным для функции, нарушающей ссылочную прозрачность? Я просто полностью не понимаю их точку зрения?

+0

Я думаю, что предупреждение 'return' предназначено для предотвращения использования, такого как' def f (x: Int): Int = ((w: Nothing) => 3) (return x) '(это функция тождества, а не константа' 3'). Хотя я могу согласиться с запретом 'return' (есть ли какие-либо причины для его использования в чистом коде?), Я бы не сказал, что« раннее возвращение »нарушает ссылочную прозрачность, поскольку вы можете добиться того же эффекта, используя продолжение -passing transform. – chi

+1

@chi, call/cc или подобные конструкции, которые позволяют вам получить дескриптор первого класса в вашем _implicit_ продолжении, также не являются ссылочными. Передача функции продолжения _explicitly_ - совершенно другая история. То, что глобальное преобразование создает ссылочно прозрачную программу, не означает, что оригинал является ссылочно прозрачным (иначе изменяемое состояние будет также RT). –

+0

@ Андреас Россберг. Я, вероятно, путал RT «возвращения» с чистотой 'foo'. – chi

ответ

3

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

За исключением того, что утверждения «return» вообще не оцениваются. Они приводят к тому, что текущий вызов метода включения оценивается. Нет никакого способа, который бы соответствовал концепции ссылочной прозрачности. Аналогичная проблема имеет и оператор «throw».

Для примеров, первый

def foo(n:Int): Int = return n + 1 

является доброкачественным, но многословным и не идиоматичен. Второй

def foo(ns: List[Int]): Any = ns.map(n => return n + 1) 

гораздо более проблематичный. Если он прошел пустой список, он возвращает пустой список. Если передано непустой список, он возвращает значение главы списка плюс 1.

+3

Почему вторая проблема? '= if (ns.isEmpty)() else ns.head + 1' имеет такое же поведение без' return'? –

+0

Поскольку наивное чтение (в котором возврат становится оценкой функции, а не методом) является ns.map (_ + 1), почти наверняка предназначен программисту. Гораздо более вероятно, что «возврат» - это блуждающий Java-ism, чем тот, который вы описываете, - это то, что хотел сказать программист. –

+1

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

Смежные вопросы