Я работаю в лаборатории вычислительной биологии, где у нас есть несколько человек, работающих над несколькими проектами, в основном в R (что меня волнует этот пост). Раньше люди просто разрабатывали свой код для каждого проекта, что может включать или не включать шаблонный код, скопированный с предыдущих проектов. Одной вещью, которую я подталкивал на протяжении многих лет, было то, чтобы принести некоторую централизованную структуру этому беспорядку, и люди идентифицируют общие шаблоны, чтобы мы могли превратить эти повторяющиеся/общие блоки кода в пакеты по всем многим причинам, которые можно было бы подумать, что хорошая вещь. Итак, теперь наши люди используют сочетание централизованных пакетов/подпрограмм в своих сценариях, специфичных для проекта.
Там здесь есть. У нас есть мандат от полномочий, которые будут заключаться в том, что каждый script для каждого проекта должен быть на 100% воспроизводимым с течением времени, насколько это возможно (и это включает в себя 100% всего кода, к которому у нас есть прямой доступ, включая наши пакеты), То есть, если я вызываю функцию foo в панели пакетов с параметром A, чтобы получить результат X сегодня, через 4 года я должен получить тот же результат. (ошибочный вывод из-за ошибок исключается здесь)
Тема воспроизводимости возникала сейчас и в R в разных кругах, но, как правило, она, как представляется, обсуждалась с точки зрения воспроизводимости процесса (например, виньетки). Это не то же самое - я могу запустить виньетку сегодня, а затем запустить тот же код через 6 месяцев с помощью обновленных пакетов и получить совершенно разные результаты.
Решение, которое было согласовано (что я не являюсь поклонником), заключается в том, что если функция или пакет необходимо изменить в непереходном совместимом изменении, оно просто получает новое имя. Таким образом, если нам нужно радикально изменить функцию foo(), ее можно было бы назвать foo2(), и если для этого требуется радикальное изменение, она называется foo3(). Это гарантирует, что любой script, который называется foo(), всегда будет получать исходный результат, позволяя вещам продвигаться вперед в репозитории пакетов. Это работает, но мне это очень не нравится - кажется, это эстетически чрезвычайно захламлено, и я волнуюсь, что это приведет к массовому запутанности с течением времени, имеющему пакеты bar, bar2, bar3, bar4... функции foo1, foo2, foo3 и т.д.
Проблема в том, что я не придумал альтернативное решение, которое действительно лучше. Одна из возможностей - отметить номера версий пакетов, R и т.д. И убедиться, что они загружены, но у них много проблем - не в последнюю очередь из-за того, что он полагается на правильную дисциплину управления версиями и подвержен ошибкам. Кроме того, эта альтернатива уже была отвергнута;) Идеально, что у нас было бы, есть какое-то понятие развития и выпуска, поскольку большинство из этих изменений, как правило, происходят раньше, а затем выравниваются с изменениями, происходящими гораздо реже. OTOH, что на самом деле означает devel, - это "пока еще не пакет" (что мы делаем), но может быть трудно точно определить, в какой момент это право, чтобы транспортировать материал. Неизменно в тот момент, когда вы считаете себя в безопасности, когда осознаете, что нет.
Таким образом, имея в виду все это, мне любопытно, если кто-то еще там справился с подобными ситуациями и как они могли бы решить что-то.
edit: просто для того, чтобы быть ясным, без обратной совместимости, я говорю не только об API и т.д., но и о выходах для заданного набора входов.