Репозиторий. Примеры и спецификация. Expression evaluator позволяет вычислять указанные выражения, например: 12*3 это 36 [1,2,3].reverse() это массив [3,2,1] 'Kate'.reverse() это "etaK" Выражения могут зависеть от входных переменных: 10*x + 4 зависит от значения x.  'My name is {userName}. Age is {2022-birthYear}' зависит от значений userName и birthYear. Скрипт может содержать несколько таких выражений: В общем случае, вы можете использовать Nfun везде, где раньше вы хранили, передавали или настраивали константы. В примере ниже, мы формульно задаем правила начисления бонусов Вот несколько примеров использования: Backend: фильтры входящих запросов; Embeded: настройка обработки сигналов; Система лояльности: настройки бонусной программы; Робототехника: кинематическая модель. Описания траекторий; Low-code решения. Nfun продолжает идею библиотеки Ncalc, но для богатой системы типов Примитивные типы - byte, u16, u32, u64, i16, i32, i64, real, bool, ip, char, text, any Массивы, структуры, лямбда выражения и Linq. Арифметические, бинарные, дискретные операторы, операторы по работе с массивами Условный оператор if. Интерполяция строк. Именованные выражения и пользовательские функции. Строгая типизация с выведением типов. Встроенные функции. Кастомизация семантики. Установите nuget пакет NFun  PM> Install-Package NFun Начнем с классики! Посчитаем константы Посчитаем выходные данные  А теперь перейдем в режим хардкора. Этот режим предоставляет доступ ко всем переменным, и к контролю исполнения на низком уровне Nfun предоставляет кастомизацию синтаксиса и семантики под ваши нужды - Запрет или разрешение if-выражений - Decimal или Double арифметика - Integer overflow поведения - Запрет или разрешение пользовательских функций - Тип по умолчанию для целочисленных констант  Nfun поддерживает однострочные выражения: Многострочные именованные выражения: И пользовательские функции: В зависимости от задачи, вы можете включать и отключать эти возможности.  Nfun строго типизирован - это было основным вызовом, и ключевой особенность для гармоничной интеграции в C#, а так же защиты от ошибок. Однако, синтаксис языков со строгой типизацией всегда сложнее.  Что бы решить эту проблему я опирался на постулат:  Все, что выглядит как правильный скрипт (в рамках синтаксиса/семантики) - должно запуститься Или, более формализовано: Если код выглядит как слабо-типизированный скрипт, но при этом запускается без ошибок, значит для него можно однозначно вывести типы.    Либо показать, что такой код не может быть выполнен без ошибок. Это потребовало разработки сложной системы выведения типов, от которой и отталкивается вся семантика языка. Результатом этого является повсеместное использование Generic-ов.  В примере ниже - функции, вычисления, и даже константы - являются обобщенными типами (из списка int32, uint32, int64, uint64, real). Однако, пользователь не должен задумываться об этом: Таким образом, удалось собрать все преимущества строгой типизации: Если типы выражения не сходятся - вы получаете ошибку на этапе интерпретации. Если типы не сходятся с ожидаемыми C# типами - вы получаете ошибку на этапе интерпретации. Производительность. При этом, синтаксис остался максимально простым для неподготовленного пользователя! Так как Nfun под капотом это - "почти язык программирования", то его архитектура достаточно стандартна. Не буду описывать ее здесь подробно, об этом уже есть много классных статей. Интерпритацию кода можно разделить на несколько этапов: 1. Токенизация (лексер).  Самописный лексер разбирает входную строку на токены, учитывается возможность интерполяции строк. 2. Парсинг. Разбор токенов в дерево AST. Используется самописный парсер.  Спецификация синтаксиса опирается на спецификацию языка (и очень много тестов). Формальная грамматика не описана. 3. Выведение типов. Кастомный, графовый алгоритм выведения типов, с поддержкой неявных преобразований между типами.  Нюансы: Целочисленные константы являются "обобщенными константами" Тип узла может зависеть, как от предыдущего, так и от последующего кода Ограничения на дженерик-переменные могут быть заданы, как сверху (наследование, тип к которому можно привести данный), так и снизу ( потомок, тип, которой может быть приведен к данному) 4. Сборка выражений (построение рантайма) Из  результатов решения типов и Ast-дерева собирается самописное дерево вычисляемых выражений. Конвертация CLR-значений в Nfun. Исполнение выражений. Конвертация результатов в CLR значения. Я сознательно не использовал Csharp-expression-tree, так как, одним из важнейших критериев была скорость "one-time-shot". То есть запуска, от момента получения строки со скриптом и до момента получения результатов выполнения. Проект готов к использованию в продакшене. Используется в течении года в составе scada-системы, покрыт 6000+ тестами, к нему написана спецификация, и..  даже есть несколько звездочек на гитхабе (да-да, это call to action!). Почти успех! Когда я начинал Nfun, я мечтал создать простой, надежный и интуитивный опенсорс-инструмент. Я хотел реализовать синтаксические идеи и поэкспериментировать с системами выведения типов, попробовать для себя что-то новое... По итогу, Nfun стоил огромного количества сил, времени и инвестигаций. Я впервые столкнулся с подобной задачей. Теперь мне хочется, чтобы люди пользовались этим инструментом! И писали тикеты, да реквесты на гитхаб. Ну, или комментарии под этот пост ;)