prolet-008.md 18 KB

Диалектика динамики типов

Рассмотрим более подробно ещё одно диалектическое противоречие: "статическая типизация -- динамическая типизация". Надо получить ясный, структурированный переход между строгой статикой и высокой динамикой. А также предусмотреть контролируемый механизм перехода из одного состояния в другое.

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

  • Статика — стремление к порядку, предсказуемости, закону.
  • Динамика — стремление к адаптации, изменению, практике.

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

Постановка противоречия

Плюсы

  • статическая типизация: Безопасность, производительность, документация в коде
  • динамическая типизация: Гибкость, быстрая разработка, адаптивность

Минусы

  • статическая типизация: Жёсткость, сложность, высокий порог входа
  • динамическая типизация: возможны ошибки на этапе исполнения, трудно масштабировать, слабая документация

Философия

  • статическая типизация: идеализм порядка (мир должен быть упорядочен)
  • динамическая типизация: идеализм вечного изменения (мир — поток, форма не важна)

Ни одна сторона не может победить полностью.

Победа — в синтезе, в контролируемом переходе от одной формы к другой, в зависимости от объективных условий задачи.

Цель: диалектическая типизация

Не смешение статики и динамики, а их единство в движении, где:

  • Статика — норма,
  • Динамика — вынужденное отклонение,
  • Переход — не хаос, а сознательный, контролируемый, документируемый акт.

Основные принципы диалектической типизации

Статика по умолчанию

Вся переменная, функция, структура — строго типизированы.

Динамика — как отрицание нормы

Разрешена только в явно обозначенных зонах.

  • Переход — через форму, а не через волю
  • Не просто any, а структурированный механизм

Обратный переход — обязательный

Из динамики можно выйти только через проверку и приведение типа.

Контекст определяет

  • В ядре системы — только статика.
  • В интерфейсе с внешним миром — динамика разрешена.

Педагогический контроль

Новичок не может использовать динамику без одобрения.

Механизм перехода: "шлюз"

Введём новую конструкцию — шлюз, который ограничивает пространство и время действия динамики.

Динамический шлюз -- это форма диалектического преодоления несовершенства внешнего мира.

@шлюз_вход, @шлюз_выход — это не просто синтаксический сахар, это — граница между мирами, между упорядоченным миром prolet и хаосом внешних данных, между типизированным бытием и бестиповым небытием.

Шлюз не всегда требуется при обмене с внешним миром. Если приём данных из внешнего источника из экосистемы prolet -- тогда такой поток байтовых данных будет сопровождаться метками типа. В этой ситуации шлюз не нужен.

(// Внутри — следует использовать байтовый поток, атрибут на выходе -- @возможно)
((ВебЗапросить "/data"
    @шлюз_вход
    @требует_ревью) -> данные)
(// тип: фиксированный срез байтов)

(// Обратный переход — только через проверку)
 (если (ПроверитьФорму данные как Структ.Пользователь)
    тогда (ОбработатьПользователя данные)
    иначе (ПечатьОшибка "неверный формат"))

Особенности шлюза:

  • всегда принимает поток байт.
  • прекращает работу, если атрибут @шлюз_вход не указан, а формат байтового потока не имеет меток типов полей.
  • Запрещён в критических модулях (ядро, безопасность).
  • Только после ревью (для уровней < 3).

Это — не либерализм, а учёт требований объективной реальности, как военный коммунизм → нэп → социализм.

Суть @шлюз_вход: граница между мирами

🌍 Два мира:

МИР PROLET                   ВНЕШНИЙ МИР
Типы — первичны              Типы — отсутствуют или скрыты
Данные — структурированы     Данные — байтовый поток
Порядок — внутренний         Хаос — норма
конст, фикс, мут — везде     Никаких категорий

@шлюз_вход — это не функция, это — онтологическая граница, где байт становится сущим, а хаос — формой порядка.

Динамический тип, как переходное состояние

Динамический тип — не тип-ловушка, а тип-процесс.

Он не может участвовать в вычислениях напрямую. Чтобы использовать — нужно привести к статическому типу.

(// по умолчанию статичность на выходе @фикс, параметр контакта с внешним миром -- @шлюз_вход)
((ПолучитьИзApi) -> x)

(// Ошибка: (x + 1) — запрещено)
(ЕслиТип x как Целое
    тогда (ОбработатьЧисло (ТипКонверт Целое в x))
    иначе (ПечатьОшибка "ожидалось число"))

Это — материалистическое требование: чтобы работать с реальностью, нужно понять её структуру.

Если данные пришли от другого prolet-процесса, и сериализованы с метаданными (структуры в духе prolet), то @шлюз_вход не нужен — это внутренний поток выраженный иными средствами для внешнего хаотического мира, как товарообмен в социалистическом хозяйстве между различными предприятиями в одной цепочке производства и в одной стране, но разных городах.

Но если данные — извне:

  • JSON без схемы,
  • бинарный протокол,
  • CSV,
  • XML с xsi:type="string" —

тогда нужен @шлюз_вход, потому что форма несёт в себе противоречие: байты есть, а типов — нет.

Система приведения типов: "путь к статике"

Проверка типа:

  • (ЕслиТип х как Пользователь) Булево, безопасно
  • Безопасное извлечение типа

    (ЕслиТип х как Пользователь)
    тогда (Обработать (ТипКонверт х в Пользователь))
    иначе (ПечатьОшибка "ожидался пользователь"))
    

Приведение с проверкой ((ТипКонверт х в Пользователь) -> @фикс х) Падает, если не подходит

Функциональный стиль

Схемная валидация для сложных форматов:

(ЕслиПробаИз дата к Схема.Пользователь
    тогда ((ПривестиИз дата к Схема.Пользователь) -> х)
    иначе (ПечатьОшибка "ожидалось число"))

Переход из динамики в статику — не автоматический, а требующий сознательного усилия, как переход от чувственного восприятия к рациональному пониманию.

Контекстно-зависимая типизация: где разрешена динамика?

  • ввод: файлы (Внешний мир не контролируется)
  • ввод: внешние API (не из экосистемы)
  • ввод: конфигурация (не из экосистемы)

Это — не абсолютизация, а диалектический релятивизм: истина — в конкретной практике.

Развитие типов: от динамики к статике через практику

Когда динамический интерфейс стабилизируется, его можно возвысить до статического закона:

(// Сначала — динамически, "ЗапросАпи" определён как @шлюх_вход, и данные как @фикс)
((ЗапросАпи @шлюз_вход) -> данные)
(ЕслиПробаИз данные как Схема.ФорматV1
        тогда ...
        иначе ...)

(// Через месяц практики — выносим в структур)
(структ ФорматV1
  поле1 Накладная.Название
  поле2 Список.Целое)

(// Использование через приведение, результат определён как @фикс)
(ЕслиТип х как ФорматV1
    тогда ((ЧитатьИз "data/sample.json") -> конфигТекст)
)

Это — отрицание отрицания: динамика отрицает статику, но на основе практического действия — порождает заново безопасную статику.

Почему именно @шлюз_вход, а не просто функция?

Потому что:

  • Это — не вычисление,
  • Это — переход количества в качество,
  • Это — восстановление формы из хаоса.

Как у диалектики: Из хаоса — порядок, из количества — качество.

Почему @шлюз_вход — однонаправленный?

Потому что:

  • Вход — из байт → в типизированное сущее — требует труда, проверки, интерпретации.
  • Выход — из prolet → в байты — может быть автоматическим, если используется самоописывающий формат (например, prolet-bin с метками типов).

Но если выход — в неструктурированный формат (например, raw TCP), то нужен обратный шлюз — @шлюз_выход:

(фн Отправить (@x Пользователь)
    @шлюз_выход
    @цель legacy_система
   (СериализоватьБезТипов x))

Это — единство и борьба: вход и выход — разные по природе, потому что мир несимметричен.

Что делает @шлюз_вход на уровне ВМ?

При встрече @шлюз_вход:

  • Активируется режим проверки:
  • Все значения извне — являются списком байтов.
  • Нельзя использовать напрямую.

Требуется явное приведение:

  • (тип х как Пользователь) → с проверкой.
  • Или — (ПробаИз ... как Схема.ХХХ).

Фиксируется событие:

  • В лог: (@шлюз_выход @логОткл) (по умолчанию активно).
  • В граф жизненного цикла — новая ветвь анализа.

Психологические и педагогические механизмы

Для новичка:

  • Динамика отключена.
  • При попытке использовать — подсказка: "Динамические типы доступны после прохождения модуля 'Работа с внешними данными'".

Для мастера:

  • Можно использовать динамический шлюз,
  • но только с обоснованием, и с автоматическим логированием всех операций (включено по умолчанию).

Для системы:

  • Все динамические участки автоматически документируются.
  • Нет идеалистических типов данных (всегда присутствует байтовый поток).
  • При стабилизации — предлагает: "Этот шлюз использован 100 раз. Создать статический тип?" (возможна автоматическая генерация обратимого конвертера)

Пример: полный цикл перехода

(// Внешний API — неизвестная структура)
((ВебЗапросить "https://api.partner/data"
                @шлюз_вход @возможно) -> фикс данные)

(// Проверка и переход к статике)
(ЕслиПробаИз данные как Схема.АнализДанных)
    тогда (
        ((ПривестиИз данные к Схема.АнализДанных) -> отчёт @фикс)
        (ОтправитьОтчёт отчёт))
    иначе (ПечататьОшибку "некорректные данные"))

(// Определение типа на основе практики)
(структ АнализДанных
  показатель ПроцентПлана
  дата       АбсолютнаяМетка
  регион     РегионПеречисление
  док        "Анализ данных по регионам с привязкой по времени")

От хаоса внешнего мира → к порядку внутренней системы через безопасные однонаправленные шлюзы.

Заключение: типизация как диалектический процесс

Предлагаемое решение не устраняет противоречие, а развивает отношения внутренних форм в конкретной ситуации:

  • Статика — не догма, а результат победы над хаосом.
  • Динамика — не свобода, а временное отступление перед объективной необходимостью, но без отрыва от реальности.
  • Переход — не скачок, а контролируемый, документируемый, педагогически организованный процесс.
  • Язык — не набор правил, а механизм познания реальности через типы.

Это — не просто типовая система, это — диалектика познания:

от незнания → к гипотезе (динамика) → к истине (статика).