Ответ 1
Формально говорящий возврат определяется как всегда возвращающийся из ближайшего охватывающего именованного метода
Возвращаемое выражение return e должно происходить внутри тела некоторого включая именованный метод или функцию. Самая внутренняя оболочка, названная метод или функция в исходной программе, f, должен иметь явно объявленный тип результата, и тип e должен соответствовать ему. Возврат выражение оценивает выражение e и возвращает его значение как результат f. Оценка любых выражений или выражений после возвращаемого выражения опускается.
Таким образом, у него нет другой семантики в лямбда. Морщина заключается в том, что, в отличие от обычного метода, закрытие, созданное из лямбда, может избежать вызова метода размещения, и вы можете получить исключение, если есть возврат в таком закрытии.
Если выражение return само по себе является частью анонимной функции, оно возможно, что экземпляр окружения f уже вернулся перед выполнением выражения return. В этом случае брошенный scala.runtime.NonLocalReturnException не будет поймано и будет распространять стек вызовов.
Теперь, что касается "почему". Еще одна причина - эстетика: lambdas - это выражения, и это хорошо, когда выражение и все его подвыражения имеют одинаковое значение независимо от структуры гнездования. Нил Гафтер рассказывает об этом http://gafter.blogspot.com/2006/08/tennents-correspondence-principle-and.html
Основная причина, по которой она существует, заключается в том, что она позволяет легко моделировать формы потока управления, обычно используемые в императивном программировании, но все же позволяет абстрагироваться от функций более высокого порядка. В качестве примера игрушки конструкция Java foreach ( "для x: xs {yada;}" ) позволяет возвращать внутри цикла. Scala не имеет языкового уровня foreach. Вместо этого он помещает foreach в библиотеку (не считая "для выражения" без урожая, поскольку они просто desugar для foreach). Наличие нелокального возврата означает, что вы можете использовать Java foreach и переводить непосредственно в Scala foreach.
Кстати, Ruby, Smalltalk и Common Lisp (с моей головы) также имеют похожие "нелокальные" возвращения.