Насколько чистым и ленивым может быть Scala? - PullRequest
22 голосов
/ 26 сентября 2011

Это всего лишь один из вопросов «мне было интересно ...».

Scala имеет неизменные структуры данных и (необязательно) ленивые значения и т. Д.

Насколько близко может быть Scala-программабыть к тому, кто полностью чист (в смысле функционального программирования) и полностью ленив (или, как указывает Инго, может ли он быть достаточно нестрогим)?Какие значения неизбежно изменяемы и какие оценки неизбежно являются жадными?

Ответы [ 3 ]

15 голосов
/ 26 сентября 2011

Относительно ленивости - в настоящее время передача параметра в метод является строгой по умолчанию:

def square(a: Int) = a * a

, но вы используете параметры вызова по имени:

def square(a: =>Int) = a * a

но это не лениво в том смысле, что оно вычисляет значение только один раз при необходимости:

scala> square({println("calculating");5})
calculating
calculating
res0: Int = 25

Была проделана некоторая работа по добавлению метода lazy параметров, но он еще не был интегрирован (нижеприведенное объявление должно печатать "calculating" сверху только один раз):

def square(lazy a: Int) = a * a

Это одна часть, которая отсутствует, хотя вы можете смоделировать ее с локальнымlazy val:

def square(ap: =>Int) = {
  lazy val a = ap
  a * a
}

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

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

Например, в языке с чистыми выражениями a * a в приведенном выше определении вызова по имени (a: =>Int) можно оптимизировать для оценки a только один раз, независимо от вызова по именисемантика.Если язык допускает побочные эффекты, то такая оптимизация не всегда применима.

14 голосов
/ 26 сентября 2011

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

Чистота

Принимая во внимание, что Haskell отслеживает примеси с помощью системы типов, Scala решила не идти по этому пути, и такие вещи трудно решить, если вы не ставили перед собой цель.начало (а также, когда совместимость с совершенно нечистым языком, таким как Java , является главной целью языка).

Тем не менее, некоторые считают, возможно и стоит приложить усилия для документирования эффектов в системе типов Scala.Но я думаю, что к чистоте в Scala лучше всего относиться как к самодисциплине, и вы должны постоянно скептически относиться к предполагаемой чистоте стороннего кода.

Laziness

Haskell ленивпо умолчанию, но его можно сделать более строгим, добавив некоторые аннотации в ваш код ... Scala - наоборот: строго по умолчанию, но с ключевыми словами и параметрами по имени lazy вы можете сделать его настолько ленивым, насколько захотите.

3 голосов
/ 26 сентября 2011

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

Что касается нестрогости, вот сделка ... Во-первых, если вы решите пойти совсем не строговы оставите все классы Scala.Даже Скалаз не является строгим по большей части.Если вы готовы построить все самостоятельно, вы можете сделать свои методы нестрогими, а ваши значения - ленивыми.

Далее, мне интересно, могут ли неявные параметры быть нестрогими или нет, или каковы будут последствияделая их нестрогими.Я не вижу проблемы, но могу ошибаться.

Но, самое проблемное из всех, параметры функции являются строгими, как и параметры замыканий.

Итак, теоретически это так.можно пойти совсем не строго, это будет невероятно неудобно.

...