Как проверить, если функция не имеет побочных эффектов (чисто) во время выполнения? - PullRequest
0 голосов
/ 13 марта 2020

Допустим, мы загрузили функцию F, которая принимает / выводит набор args и возвращает result. Как проверить во время выполнения, если это F не действует ни на что, кроме args членов и функций? Значение no Console.Writeline, Singletons (или другой материал, не представленный в args). Возможно ли это с библиотекой CodeContracts или другим решением?

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

Почему я не понимаю, как [Pure] может помочь - этот код компилируется:

class Test {
    public struct Message {
        public string Data;
    }

    public struct Package {
        public int Size;
    }

    [Pure]
    public static List<Package> Decomposse(Message m) {
        Console.WriteLine("rrrr"); // This sould not happen
        var mtu = 1400;
        Package p = new Package{Size = mtu};
        return Enumerable.Repeat(p, m.Data.Length / mtu).ToList();
    }
}

И я хочу устранить (или, по крайней мере, обнаружить, что эта функция вызывает такие вещи, как Console.WriteLine("rrrr"))

1 Ответ

1 голос
/ 13 марта 2020

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

А как насчет безопасных вызовов API, которые просто извлекают данные, такие как DateTime.Now ()? Собираетесь ли вы создать список вызовов API, которые изменяют состояние и обновляют его для всех нас в течение долгого времени, для всех приложений в вашей организации или на Земле? Собираетесь ли вы документировать, что обрабатывает встроенный компилятор? Тогда, сводя этот подход к абсурду, можем ли мы признать, что это неосуществимо?

Моя архитектура моделирует машины, которые должны изменять только точки данных «Продукт», но даже я признаю, что это невыполнимое правило. У меня есть и другие правила, чтобы попытаться навязать детерминизм. Однако в какой-то момент эти модули должны выполнять вызовы API, чтобы выполнять значимую работу, уже организованную в API сегодня. В противном случае мы переписали бы их все.

    class Machine1Product
    {
        public Cvar<int> Y { get; set; }
    }
    class Machine1 : Producer<Machine1Product>, IMachine
    {
        public Cvar<int> X { get; set; }
        public void M()
        {
            // work which changes only product data points (Y)
        }
    }

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

...