Nov. 30th, 2012

akuklev: (Свечка и валокардин)
[livejournal.com profile] orleans: У ФП есть обьективные преимущества в плане исполнения на многопроцессорных системах и организации юнит тестов. Все то что можно загнать в трубу функции без сильного усложнения кода - нужно загонять.

[livejournal.com profile] akuklev: Да хрень это всё на самом деле насчёт многопроцессорных систем и организации юнит-тестов. Если взять императивный код и куда-то его загнать, он от этого лучше не станет ваще, ни в плане юнит-тестов, ни в каком-либо ещё плане.

Наши дедушки писали спецификации программ, а потом их реализации (в машинных кодах). Мы дожили до времён, когда можно писать одну только спецификацию и её запускать. Уже когда написали “спецификацию”, запустили и убедились, что она корректна — вот после этого можно уже посмотреть: если что-то работает слишком медленно, не параллелится или памяти много жрёт, можно отдельные места низкоуровнево оптимизировать. И не надо думать, что низкоуровневая оптимизация это обязательно на ассемблере/Си и прочих close to machine языках. Когда вещь, которая естественным образом выражается через цикл, насильно запихивают в рамки ФП чтобы она лучше параллелилась — это низкоуровневая оптимизация.

Спецификация это такое описание процедуры или модуля, из которого очевидно, что именно они делают (такое описание не единственно, и выбор варианта дело вкуса). Ну вот например одна из спецификаций процедуры sort:
“Процедура sort берёт набор элементов и возвращает список, состоящий из минимального элемента этого набора, потом минимального элемента оставшегося набора и так далее.”
 sort(items: Сollection) = min(items) cons sort(items without min(items))
 sort(Collection.Empty) = List.Empty


Чем хорошо такое определение? Тем что оно функционально? — хрена с два; то, что оно функциональное это мелкая частность и стечение обстоятельств. По-настоящему оно хорошо тем, что соответствует понятному непрограммисту описанию на естественном языке и при этом максимально просто, вероятность допустить в таком определении ошибку минимальна. А если ещё делать перекрёстное ревью кода и написать пару юнит-тестов, то вообще исчезающе мала.

А вот если, скажем, процедуру sort определять через алгоритм, который хитрый и ещё надо доказывать, что он вообще работает, возникает вопрос что значит "доказывать что Х работает верно". Это значит, что нужно доказать что Х работает эквивалентно своей спецификации. А где эта спецификация? Её так или иначе надо написать, и доказательство так или иначе провести, потому что иначе вероятность ошибки колоссальна: я знаю как ошибки в нетривиальной алгоритмике выявлялись спустя годы использования софта в продакшине, то есть никакое закидывание юнит-тестами бы их не вскрыло. Вот потому я и адепт того, чтобы писать программы их конструктивными спецификациями, а оптимизации использовать максимально редко.

ФП я люблю ровно постольку поскольку функциональный стиль часто идеален для написания конструктивных спецификаций функций. Однако для написания конструктивных спецификаций модулей и сущностей доменной модели приложения, которое я делаю, функциональщины обычно нехватает. Поэтому в ещё большей степени я адепт мультипарадигменных языков, где можно за день накатать DSL отвечающий доменной модели и дальше писать код в таком вот спецификационном стиле, избегая частностей.

Сейчас таких языка, кстати, два: Perl и Scala. Оба люто прекрасны, однако имеют и общий недостаток: в руках неопытного программиста они как боевая граната в руках у двухлетнего карапуза. Перл лучше для rapid prototyping (потомучто без статической типизации), Скала для всего осталього (потомучто со статической типизацией).

December 2016

S M T W T F S
    123
456789 10
11121314151617
18192021222324
25262728293031

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 9th, 2025 02:18 pm
Powered by Dreamwidth Studios