flang компилятор доказывает, что программа не зациклится 0.6.2 GitHub

Узел нельзя написать обычной программой на flang, и мешает этому одна строка проверки типов, а не «нет доступа к миру»

Довод «узел на flang не пишется — у программы есть аргументы и результат, доступа к миру нет по построению» звучит убедительно и оказался НЕ ТЕМ доводом. Доступ к миру у программы как раз есть: седьмое действие поручить даёт процессу выдать поручение и получить отклик обычным сообщением, а в словаре поручений уже лежат и сокеты, и часы.

Настоящее препятствие другое, и оно называется точно:

FLANG_PROCESS — действие «отправить»: адресат обязан быть именем объявленного
процесса, записанным прямо здесь — вычисленное имя проверить нечем

(flang/src/types.mjs, addresseeOf; проверено прогоном на программе, где кому берётся из поля состояния.)

Узел обязан делать ровно это: письмо приезжает с провода, в нём написано имя процесса-адресата, и узел кладёт письмо в его ящик. Имя приходит СТРОКОЙ ИЗВНЕ, значит адресат вычисляемый, значит такая программа не собирается. То же и у поручить. У породить наоборот: вид литерален, а имя порождаемого вычисляется, — но поговорить с порождённым потом всё равно нечем.

Отсюда вывод, который стоит держать: узел — это не программа на языке, это часть рантайма цели, и стоит он там же, где планировщик. Спорить с этим незачем: правило про литерального адресата держит проверяемость доставки, и менять его ради узла значило бы менять язык ради одной программы.

Что при этом ПЕРЕНОСИМО

Решения узла о связи — рукопожатие, сроки, молчание, разрыв — переносимы целиком и напечатаны во все восемь целей (a-decision-about-the-world-is-portable-even-when-the-world-is-not). Непереносим сам мир и таблица процессов.

Чего словарю поручений не хватает, если узел всё-таки писать программой

Замерено прогонами 20 августа, ветка vypusk/sokety-i-chasy:

  1. Хозяина нет у семи целей из восьми. поручение печатает только цель C (flang/test/conc-io.test.mjs печатает это списком: «печатают поручение: c; отказывают: csharp, elixir, go, java, js, python, rust»). Остальные семь отказывают FLANG_IO_UNSUPPORTED — честно, но работать от этого не начинают.
  1. У единственного хозяина все четыре сетевых поручения отвечают отказом. Прогон напечатанной в C службы с "host": 1 на «Открыть соединение», «Принять соединение», «Прочитать из соединения» и «Ответить в соединение» даёт FLANG_IO_NET — «у хозяина на C нет способа ждать сеть: планировщик процессов не ждёт». Барьер настоящий: планировщик синхронен, а accept и recv ждут.
  1. Ждать нечем, но отвечать «пока ничего» — есть чем. В словаре откликов уже стоит вариант «Пока ничего», и его не производит ни один хозяин. Он и есть недостающий ответ неблокирующего чтения: спросил — не готово — займись другим. Это не новое слово в языке, а неиспользованное старое.
  1. Принятое соединение умирает от ответа. «Ответить в соединение» на принятом сокете закрывает его (правило «закрывает тот, кто завёл», flang/src/host/node.mjs). Узлу нужна двусторонняя связь, живущая долго: оба конца шлют признак жизни в один сокет. Обойти можно только двумя соединениями на пару узлов, по одному на направление.
  1. Отклик не сцеплен с поручением. У отклика нет ни номера, ни метки, по которой видно, на какое поручение он пришёл. Значит у процесса может быть ровно одно поручение в полёте, и узел с пятью связями обязан опрашивать их по очереди. Сцепка в языке всё же есть, но косвенная: поручить называет АДРЕСАТА отклика, и разные ящики — это и есть разные метки.

Пункт 1 стоит хозяина на цель. Пункты 2–4 — правки в рантайме цели, законные: рантайм цели не вторая реализация. Пункт 5 — решение, а не работа.

Чем ограничено. Всё перечисленное — про «узел программой». Для узла в рантайме ничего из этого не нужно вовсе, и именно поэтому узел живёт там.

Связано: a-decision-about-the-world-is-portable-even-when-the-world-is-not, cikl-porucheniy-prinadlezhit-hozyainu-a-ne-yazyku, distribution-splits-into-world-and-wire