Подтвердить что ты не робот

Насколько чистым и ленивым может быть Scala?

Это всего лишь один из вопросов "Я задавался вопросом...".

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

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

4b9b3361

Ответ 1

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

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 только один раз, независимо от семантики вызова по имени, Если язык допускает побочные эффекты, то такая оптимизация не всегда применима.

Ответ 2

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

Чистота

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

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

Лень

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

Ответ 3

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

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

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

Но, что наиболее проблематично, параметры функции строги, а также параметры закрытия.

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