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

Как программы clojure/lisp моделируются как диаграмма?

Я пробовал вставлять диаграммы clojure в то, что доступно в UML, используя класс-блоки как пространства имен на уровне файлов и ссылки зависимостей, чтобы показать отношения, но это неудобно и имеет тенденцию препятствовать функциональным шаблонам. Я также пробовал разрабатывать специальные решения, но я не могу найти решение, которое работает так же хорошо, как UML с, скажем, Java (простые ориентированные графики, похоже, работают смутно, но это результаты не детализированы достаточно). Кроме того, я не нахожу ничего в Интернете об этом.

Просто, чтобы быть ясным, я не пытаюсь сделать что-то необычное, как генерация кода; Я просто говорю о диаграммах с пером и бумагой в основном для моей собственной выгоды. Я предполагаю, что я не первый человек, который когда-либо считал это для языка lisp.

Какие решения были предложены? Существуют ли общепринятые стандарты? Что вы порекомендуете? Какие инструменты вы используете?

4b9b3361

Ответ 1

Это зависит от того, что вы хотите описать в своей программе.

Зависимости

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

Вы также можете использовать диаграммы классов для моделирования зависимостей между участниками

Поток данных

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

Или, в случае актеров, изображать каждого актера как сущность и каждое сообщение как метод.

В любом случае, не полезно попробовать и описать алгоритм вашей программы в UML. По моему опыту, они лучше описаны в комментариях в исходном файле.

Ответ 2

Я думаю, что это меньше о языке и больше о вашей концептуальной модели. Если вы используете подход "потоковой обработки", то сетевая диаграмма потока данных может быть правильной, как в некоторых диаграммах схемы в SICP, Если вы используете более объектно-ориентированный подход (который хорошо поддерживается в Lisp), то диаграммы активности UML могут иметь больше смысла.

Ответ 3

Ну, UML глубоко укоренен в OO-дизайне (с С++!), поэтому будет очень сложно сопоставить функциональный подход с UML. Я не знаю Clojure, но вы можете представить вещи, которые похожи на классы Java и интерфейсы (протоколы?), Для всех остальных это будет очень сложно. FP больше похожа на серию преобразований от входа к выходу, для этого нет четкой UML-диаграммы (возможно, диаграммы активности?). Наиболее распространенные диаграммы для статической структуры и взаимодействия между объектами, но они не очень полезны для парадигмы FP. В зависимости от вашей цели могут быть применимы диаграммы компонентов и развертывания.

Ответ 4

Моя личная мысль заключается в моделировании потока данных, а не структуры кода, потому что из того, что я видел в больших (не очень больших) Clojure, проектирует компоновку кода имеет тенденцию быть очень скучным, с огромной кучей composeable utilities и одного класса, который объединяет их вместе с транзакциями map, redure и STM.

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

Ответ 5

Я не думаю, что что-то вроде UML было бы хорошо подходит для Clojure - UML скорее сфокусирован на объектно-ориентированной парадигме, которая обычно обескуражена в Clojure.

Когда я выполняю функциональное программирование, я склонен думать гораздо больше о данных и функциях:

  • Какие структуры данных мне нужны? В Clojure это обычно сводится к определению структуры карты для каждого важного объекта, с которым я имею дело. простой список полей часто бывает достаточно в простых случаях. В более сложных случаях со многими разными объектами вы, вероятно, захотите нарисовать дерево, показывающее структуру ваших данных (где каждый node в дереве представляет карту или тип записи)
  • Как эти структуры данных проходят через различные функции преобразования, чтобы получить правильный результат? В идеале это чистые функции, которые берут неизменное значение в качестве входных данных и вызывают неизменную ценность как выход. Обычно я рисую их как конвейер/блок-схему.

Если вы достаточно хорошо продумали это, то преобразование в код Clojure довольно просто.

  • Определите одну или несколько функций-конструкторов для ваших структур данных и напишите пару тестов, чтобы доказать, что они работают.
  • Запишите функции преобразования снизу вверх (т.е. сначала выполните самые основные операции, которые будут работать и протестированы, а затем составьте их вместе, чтобы определить более крупные функции). Напишите тесты для каждой функции.
  • Если вам нужны служебные функции для GUI или IO и т.д., напишите их по требованию, когда они необходимы.
  • Приклейте все вместе, проверив в REPL, чтобы убедиться, что все работает.

Обратите внимание, что исходные файлы, как правило, также должны быть структурированы в последовательности, указанной выше, с более элементарными функциями в верхней части и более высоким уровнем, составленным в нижней части. Вам не нужны никакие круговые зависимости (что плохой дизайн запах в Clojure). Тесты имеют решающее значение - IMHO гораздо важнее на динамическом языке, таком как Clojure, чем на статически типизированном языке ООП.

Общая логика моего кода - это, как правило, последние несколько строк моего основного файла исходного кода.

Ответ 6

Я тоже борюсь с этим. Я считаю, что блок-схемы отлично работают для базовых функций и данных. Это легко показать данные и поток данных таким образом. Условные и рекурсии просты. Схемы последовательности UML/совместной работы могут очень хорошо отображать некоторые из той же информации.

Однако, как только вы начнете использовать HOF, это совсем не сработает.

Нормальные диаграммы UML для пакетов работают нормально для пространств имен, но это не так.