Git hub repository Examples and specification. Expression evaluator allows you to evaluate specified expressions, for example: 12*3 is 36 [1,2,3].reverse() is an array of [3,2,1] 'Kate'.reverse() is "etaK" Expressions may depend on input variables: 10*x + 4 depends on the value of x. 'My name is {userName}. Age is {2022-birthYear}' depends on the userName and birthYear values. A script can contain several such expressions: In general, you can use Nfun wherever you have previously stored, passed, or configured constants. In the example below, we formally set the rules for calculating bonuses Here are some usage examples: Backend: Incoming request filters; Embedded: configuring signal processing; Loyalty system: bonus program settings; Robotics: kinematic model. Trajectory Descriptions; Low-code solutions. Nfun continues the idea of the Ncalc library, but for a rich type system Primitive types - byte, u16, u32, u64, i16, i32, i64, real, bool, ip, char, text, any Arrays, structures, Lambda expressions and Linq. Arithmetic, binary, discrete operators, array operators Conditional if expression. String interpolation. Named expressions and user-defined functions. Strict type system with type inference. Built-in functions. semantics customization Install the nuget package NFun PM> Install-Package NFun Let's start with the classics! Let 's calculate the constants Let's calculate the output data And now let's switch to hardcore mode. This mode provides access to all variables, and to low-level execution control. Calculating multiple values based on input variable Customization Nfun provides customization of syntax and semantics for your needs   Prohibition or permission of if-expressions   Decimal or Double arithmetic   Integer overflow behavior  Prohibition or permission of custom functions  Default type for integer constants Add functions and constants  Nfun supports single-line expressions: Multiline named expressions: And custom functions: Depending on the task, you can enable and disable these features. if-expression User functions and generic arithmetic Arrays Structures Strings Anonymous-functions  Nfun is strictly typed - this was the main challenge, and a key feature for integration into C#, as well as error protection. However, the syntax of strongly typed languages is always more complicated. To solve this problem, I relied on the postulate: Anything that looks like a proper script (within the framework of syntax/semantics) should run Or, more formalized: If the code looks like a weakly typed script, but it runs without errors, then it can be unambiguously output types for it.  Or to show that such code cannot be executed without errors. This required the development of a complex type inference system, from which the entire semantics of the language is based. The result of this is the widespread use of Generic-types. In the example below, functions, calculations, and even constants are generalized types (from the list int32, uint32, int64, uint64, real). However, the user should not think about it: Thus, it was possible to collect all the advantages of strict typing: If the expression types do not converge, you get an error at the interpretation stage. If the types do not converge with the expected C# types, you get an error at the interpretation stage. Perfomance At the same time, the syntax remained as simple as possible for an usual user! Since Nfun is "almost a programming language" under the hood, its architecture is fairly standard. I will not describe it in detail here, there are already many cool articles about it. Code interpretation can be divided into several stages: Tokenization (lexer). A self-written lexer parses the input string into tokens, taking into account the possibility of string interpolation. Parsing. Parsing tokens into the AST tree. A self-written parser is used. The syntax specification relies on the language specification (and a lot of tests). The formal grammar is not described. Type inference. A custom, graph-based type inference algorithm, with support for implicit conversions between types. Type inference nuances: Integer constants are "generalized constants" The node type may depend on both the previous and subsequent code Restrictions on generic variables can be set both from above (inheritance, the type to which this can be reduced) and from below (descendant, the type that can be reduced to this) Assembly of expressions (construction of runtime) A self-written tree of calculated expressions is assembled from the results of solving types and the Ast tree. Conversion of CLR values to Nfun. Execution of expressions. Conversion of results to CLR values. I deliberately did not use the Csharp-expression-tree, since one of the most important criteria was the "one-time-shot" speed. That is, the launch, from the moment the script line is received until the execution results are received. The project is ready for use in production. It has been used for a year as part of a scada system, covered with 6000+ tests, a specification has been written for it, and .. there are even a few stars on the github (yes, it's a call to action!). Almost a success! When I started Nfun, I dreamed of creating a simple, reliable and intuitive open source tool. I wanted to implement syntactic ideas and experiment with type inference systems, try something new for myself... As a result, Nfun cost a huge amount of effort, time and investment. This is the first time I have faced such a task. Now I want people to use this tool! And they wrote tickets and requests for github. Well, or comments under this post ;)