Один из аргументов, которые я слышал от функциональных языков, заключается в том, что кодирование с одним присваиванием слишком сложно или, по крайней мере, значительно сложнее, чем "нормальное" программирование.
Но просматривая мой код, я понял, что у меня действительно не много (каких-либо?) шаблонов использования, которые нельзя написать так же хорошо, используя единую форму назначения, если вы пишете на достаточно современном языке.
Итак, каковы варианты использования переменных, которые варьируются в пределах одного вызова их области? Принимая во внимание, что индексы цикла, параметры и другие значения границ области, которые различаются между вызовами, не являются множественными присвоениями в этом случае (если по какой-то причине вам не нужно их менять в теле) и предполагая, что вы пишете что-то достаточно далеко от уровня языка ассемблера, где вы можете писать такие вещи, как
values.sum
или (в случае, если сумма не указана)
function collection.sum --> inject(zero, function (v,t) --> t+v )
и
x = if a > b then a else b
или
n = case s
/^\d*$/ : s.to_int
'' : 0
'*' : a.length
'?' : a.length.random
else fail "I don't know how many you want"
когда вам нужно, и у вас есть список, отображение/сбор и т.д. Доступно.
Вы обнаружите, что вам все еще нужны/нужны переменные переменные в такой среде, и если да, то зачем?
Чтобы уточнить, я не прошу прочесть возражения против формы SSA, а скорее конкретные примеры, где эти возражения будут применяться. Я ищу фрагменты кода, которые являются ясными и краткими с изменяемыми переменными и не могут быть записаны без них.
Мои любимые примеры до сих пор (и лучшее возражение, которое я ожидаю от них):
-
Пол Джонсон алгоритм Фишера-Йейта, который довольно силен, когда вы включаете ограничения большого вывода. Но тогда, как указывает catulahoops, проблема с большим О не связана с вопросом SSA, а скорее с изменчивыми типами данных, и с учетом этого алгоритм может быть достаточно четко записан в SSA:
shuffle(Lst) -> array:to_list(shuffle(array:from_list(Lst), erlang:length(Lst) - 1)). shuffle(Array, 0) -> Array; shuffle(Array, N) -> K = random:uniform(N) - 1, Ek = array:get(K, Array), En = array:get(N, Array), shuffle(array:set(K, En, array:set(N, Ek, Array)), N-1).
-
jpalecek Пример области многоугольника:
def area(figure : List[Point]) : Float = { if(figure.empty) return 0 val last = figure(0) var first= figure(0) val ret = 0 for (pt <- figure) { ret+=crossprod(last - first, pt - first) last = pt } ret }
который все еще может быть написан как:
def area(figure : List[Point]) : Float = { if figure.length < 3 0 else var a = figure(0) var b = figure(1) var c = figure(2) if figure.length == 3 magnitude(crossproduct(b-a,c-a)) else foldLeft((0,a,b))(figure.rest)) { ((t,a,b),c) => (t+area([a,b,c]),a,c) }
Или, поскольку некоторые люди возражают против плотности этой формулировки, ее можно переделать:
def area([]) = 0.0 # An empty figure has no area def area([_]) = 0.0 # ...nor does a point def area([_,_]) = 0.0 # ...or a line segment def area([a,b,c]) = # The area of a triangle can be found directly magnitude(crossproduct(b-a,c-a)) def area(figure) = # For larger figures, reduce to triangles and sum as_triangles(figure).collect(area).sum def as_triangles([]) = [] # No triangles without at least three points def as_triangles([_]) = [] def as_triangles([_,_]) = [] def as_triangles([a,b,c | rest) = [[a,b,c] | as_triangles([a,c | rest])]
-
Принцесса указывает на трудность реализации O (1) очередей с неизменяемыми структурами, является интересной (и вполне может служить основой для убедительного примера), но, как было заявлено принципиально о изменчивости структуры данных, а не непосредственно о проблеме множественного присвоения.
-
Я заинтригован решением Сито Эратосфена, но не убежден. Правильный большой-O, вытащить столько простых чисел, сколько вы хотели бы, чтобы генератор, указанный в цитируемой им статье, выглядит нелегко для правильной реализации с SSA или без нее.
Хорошо, спасибо всем за попытку. Поскольку большинство ответов оказалось либо 1) основано на изменчивых структурах данных, но не на одиночном присвоении, и 2) в той мере, в какой они были о единичной форме назначения, легко противостоящей специалистам в данной области техники, я собираюсь удалите строку из моего разговора и/или реструктуризации (возможно, иметь ее в резервной копии в качестве темы обсуждения в маловероятном случае, когда у меня заканчиваются слова, прежде чем у меня закончится время).
Еще раз спасибо.