
Recently, a huge number of new programming languages have appeared on the market: Go, Swift, Rust, Dart, Julia, Kotlin, Hack, Bosque - and this is only among those that are heard.
The value of what these languages bring to the world of programming is hard to overestimate, but, as Y Combinator rightly
pointed out last year, speaking of development tools:
The frameworks are getting better, the languages are a little smarter, but basically we do the same.
This article will talk about a language built on an approach that is fundamentally different from the approaches used in all existing languages, including the ones listed above. By and large, this language can be considered a general-purpose language, although some of its capabilities and the current implementation of the platform built on it, nevertheless, probably limit its use to a slightly narrower area - the development of information systems.
Immediately, I’ll make a reservation, it’s not about the idea, prototype, or even MVP, but about a fully-fledged production-ready language with all the necessary infrastructure infrastructure - from the development environment (with debugger) to automatic support of several versions of the language (with automatic merge bugfixes between them , release-note, etc.). In addition, several dozens of ERP-level projects have already been implemented using this language, with hundreds of simultaneous users, terabyte databases, “need-yesterday” deadlines, limited budgets and developers with no IT experience. And all this at the same time. And, of course, it should be noted that now is not the year 2000, and all these projects were implemented on top of existing systems (which wasn’t there), which means that you first had to gradually, without stopping the business, do it “as it was”, and then also gradually, to do "as it should be." In general, this is how to sell the first electric cars not to rich hipsters in California, but to low-cost taxi services somewhere in Omsk.
A platform built in this language is released under the LGPL v3 license. Honestly, I didn’t want to write it directly in the introduction, as this is not the most important advantage of it, but after talking with people working on one of its main potential markets - ERP platforms, I noticed one feature: all these people, without exception, say that even if you do the same thing that is already on the market, but for free, it will be very cool. So leave it here.
')
A bit of theory
Let's start with the theory to identify the difference in the fundamental approaches used in this and other modern languages.
A small disclaimer, further reasoning to some extent is an attempt to pull an owl on the globe, but in principle we don’t really use the fundamental theory in programming, so we have to use what we have.
One of the first and most important problems solved by programming is the task of calculating the values of functions. From the point of view of the theory of computation, there are two fundamentally different approaches to solving this problem.
The first such approach is the various machines (the most famous of which is the Turing machine) - a model that consists of the current state (memory) and the machine (processor), which at each step in one way or another changes this current state. This approach is also called the Von Neumann architecture, and it is the basis of all modern computers and 99 percent of existing languages.
The second approach is based on the use of operators, it is used by so-called
partially recursive functions (hereinafter referred to as the RFF). In this case, the most important difference between this approach is not in the use of operators as such (operators, for example, exist in structured programming using the first approach), but in the possibility of iteration over all function values (see the argument minimization operator) and in the absence of a state in calculation process.
Like the Turing machine, partially recursive functions are Turing-complete, that is, they can be used to specify any possible calculation. Here we will immediately clarify that both the Turing machine and the FFR are only minimal bases, and then we will speak about them as approaches, that is, a model with a memory-processor and a model with operators without using variables and the ability to iterate over all values functions accordingly.
The CRF as an approach has three main advantages:
- It is much better optimized. This applies both directly to the optimization of the value calculation process itself, and to the possibility of parallelism of such a calculation. In the first approach, the aftereffect, on the contrary, introduces a very great complexity in these processes.
- It is much more incremented, that is, for a function constructed, it is much more efficient to determine how its values will change as the values of the functions that this function uses changes. Strictly speaking, this advantage is a special case of the first, but it provides a huge number of possibilities, which in principle can not be in the first approach, and therefore highlighted a separate item.
- It is much easier to understand. That is, roughly speaking, the description of the function of calculating the sum of one indicator in the context of the other two indicators is much easier to understand than to describe the same in terms of the first approach. However, in algorithmically complex tasks, the situation is diametrically opposite, but here it is worth noting that algorithmically complex problems in an absolute majority of areas are good if 5%. In general, to summarize a bit, the FFL is mathematics, and the Turing machines are informatics. Accordingly, mathematics is studied almost in kindergarten, and computer science is also optional from high school. So-so comparison, of course, but still gives some kind of metric in this question.
Turing machines have at least two advantages:
- Already mentioned best applicability in algorithmically complex problems.
- All modern computers are built on this approach.
Plus, in this comparison we are talking only about the tasks of calculating data, in the problems of changing data without Turing machines it is still necessary.
Having read to this point, any attentive reader will ask a reasonable question: “If the PRF approach is so good, why is it not used in any common modern language?”. So, in fact, it is not, it is used, and in the language that is used in the vast majority of existing information systems. As you can guess, this language is SQL. Here, of course, the same attentive reader will reasonably argue that SQL is the language of relational algebra (that is, working with tables, not functions), and it will be right. Formally. In fact, we can recall that the tables in the DBMS are usually in the third normal form, that is, they have key columns, which means that any remaining column of this table can be viewed as a function of its key columns. Not obvious, frankly. And why SQL never evolved from the language of relational algebra into a full-fledged programming language (that is, working with functions) is a big question. In my opinion, there are many reasons for this, the most important of which is “Russian (in fact, anyone) cannot work on an empty stomach, but does not want to be fed,” in the sense that, as practice shows, the work necessary for this truly titanic, and carries too great risks for small companies, and for large companies, firstly, everything is good, and secondly, this work cannot be forced with money — here it is quality that matters more than quantity. Actually, the most vivid illustration of what happens when a problem is tried to
be solved by quantity, not quality , is Oracle, which even the most basic use of incrementality — updatable materialized views — managed to be implemented in such a way that this mechanism has a number of
restrictions the size of several pages ( for the sake of Microsoft is still
worse ). However, this is a separate story, perhaps, there will be a separate article about it.
At the same time, it’s not that SQL is bad. Not. At its level of abstraction, it performs its functions perfectly, and the current implementation of the platform uses it a little less than completely (in any case, much more than all other platforms). Another thing is that right after its birth, SQL actually stopped its development and did not become what it could be, namely, the language that will be discussed now.
But enough of the theory, it's time to go directly to the language.
So, we
meet :
Specifically, this article will be the first part of the three (as there is still too much material even for two articles), and it will only talk about the logical model - that is, only what is directly related to the functionality of the system and is not related to the processes development and execution (performance optimization). Moreover, we will discuss only one of the two parts of the logical model - the domain logic. This logic determines what information the system stores and what can be done with this information (it is also often called business logic in developing business applications).
Graphically, all concepts of domain logic in lsFusion can be represented by the following image:
The arrows in this picture indicate the directions of using each other's concepts, thus, concepts form a kind of stack, and, accordingly, it is in the order of this stack that I will talk about them.
Properties
A property is an abstraction that takes as input one or more objects as parameters and returns some object as a result. The property has no aftereffect, and, in fact, is a pure function, however, unlike the latter, it can not only calculate values, but also store them. Actually, the name “property” itself is borrowed from other modern programming languages, where it is used for approximately the same purposes, but nails are encapsulated and, accordingly, are supported only for functions with one parameter. Well, in favor of the use of this particular term, the fact that this very word “property” is shorter than “pure function” has played, plus it has no unnecessary associations.
Properties are set recursively using a predefined set of operators. There are quite a few of these operators, so we will consider only the main ones (these operators cover 95% of any average project).
Primary Property (DATA)
The primary property is a property whose value is stored in the database and may change as a result of the execution of the corresponding action (about it a little later). By default, the value of each such property for any set of parameters is equal to the special value NULL.
When using the operator of the primary property, it is necessary to specify which classes the created property accepts as input (about the classes themselves also a little later), and which value class this property can return.
In fact, this operator summarizes the fields and collections in modern languages. So:
class X {
Y y;
Map<Y, Z> f;
Map<Y, Map<M, Z>> m;
List<Y> l;
static Set<Y> s;
}
:
(JOIN), , (+,-,/,*), (AND, OR), (+, CONCAT), (>,<,=), (CASE, IF), (IS)
- , . , , , :
- , . , ( NULL). , lsFusion – , , , – TRUE ( FALSE NULL), 3-state’.
- NULL: (+), (-), CONCAT . :
- : NULL 0, – , 0 NULL ( 5 (+) NULL = 5, 5 (-) 5 = NULL, 5 + NULL = NULL 5 — 5 = 0).
- : NULL ( CONCAT ‘ ‘, ‘John’,’Smith’ = ‘John Smith’, CONCAT ‘ ‘, ‘John’, NULL = ‘John’, ‘John’ + ‘ ‘ + NULL = NULL).
- (IF) ( ) : f(a) IF g(a), f(a) g(a) NULL, NULL – .
(GROUP)
– . (, ) .
:
- :
, ( i sk). , , - : - SQL-:
( , , )
, ( ), – ( ). , , , ( , , SQL – ). , ( BY), - :
, , , , , .
:
/ (PARTITION … ORDER)
( , ) , . , ( , ). / .
, , , , , , .
SQL ( , ) (OVER PARTITION BY… ORDER BY).
(RECURSION)
– , . , , .
. , ( ):
- (result) ( ) :
- result(0, o1, o2, ..., oN) = initial(o1, ..., oN), initial –
- result(i+1, o1, o2, ..., oN) = step(o1, ..., oN, $o1, $o2, ..., $oN) IF result(i, $o1, $o2, ..., $oN), step – .
- , ( o1, o2, …, oN). , .
, , , , :
, / , , , .
, , , , , lsFusion – .
SQL CTE, , , . , Postgres GROUP BY , , , , , , . , , WHILE’ .
. , , .
– , , , , ( , , ). , , “”, , -, , , -, , “”.
, – lsFusion. , – . , – ( , , , ). , – . .
, . / , , , , , . 3 97, lsFusion – 60 40.
, , . , -, ( , ), .
, :
(FOR), (WHILE)
, lsFusion , , NULL ( ).
, :
, , (IF).
(WHILE) , :
(EXEC), ({…}), (CASE, IF), (BREAK), (RETURN)
- . , , .
(CHANGE)
. , , , , NULL. :
, :
, , , ( , , , , selected discount – ), . , , .
(NEW)
( , , , , ). , , .
:
, , — NEW (FOR), ( ):
, FOR :
– , , , .
(DELETE)
– :
, «» .
, , .
, , . , , . .
, . , — / .
, , . , ( ), .
, , . , :
: (APPLY) (CANCEL). , , , . , , , . – , , , , . — .
(NEWSESSION, NESTEDSESSION)
(, , http- ..). , , . , , , «», «» ( , ). NEWSESSION, ( ). :
, , , . , :
, , ( ). NESTED, , , , . , ( , NESTED). :
. :
- , , , < —
- , , : < —
- , : < — .
, (, ), , . , , - , , , , , :
(APPLY), (CANCEL)
– , . , . , :
- . , , , NESTED ( ).
- , . , - , , , . , (update conflict), , , . , :
PS: Authentication, , , ( ) ( ). , , lsFusion , (, ).
– , , , , ( ).
(PREV, CHANGED, SET, DROPPED)
: (PREV), (CHANGED), NULL NULL (SET) .. ( ), , , :
. , , , , .
“ ?”, “ ?”. , , .
, , . , . .
:
, , :
, , , .
:
:
- , « ». , , , ( , , 5-10 , ).
- , ( ), , , , .
:
:
( , ), .
, , , , ‘Something changed’ (!) ( , ). , , - , (CHANGED, SET, DROPPED ..). , - , -, -. – :
, – , . , :
, , / , , .
SQL ( ) . , , , ( ) , .
, :
, , . , , NULL:
, – , NULL (SET) , – NULL . – , , , / , .
, – ( ), , , ( ), , .
. , , , – . , :
, f NULL , A. :
, , – . ( , , «»), , , , : - , .
, lsFusion . , lsFusion . , . lsFusion , , - :
lsFusion , :
, – .
lsFusion – . , , :
/ , :
( ):
, , ( ), . ABSTRACT :
, .
, , :
, , ( ). , , .
, , . () : , , . , , , , , . NULL , , :
( ) – , . , , , :
, .
enum’, , .
( lsFusion, ) :
.
() , NULL . , , , , , .
:
, , ( ):
, (, ), ( ) , . ,
ERP 1100 . , , , . , ( 50 ), , 1100 300 .
, , , , . , , – , – , , , « - », , , .
, lsFusion . , , , , , , , , , ( , , ). , lsFusion ( ACID), , SQL-, . , DSL lsFusion , , – – . , SQL , , lsFusion . , , – , github ( , ), (IDE, , VCS, ), slack telegram- , (linux maven, - ), , , , , lsFusion , SQL, ABAP 1 – .
, , lsFusion, , ( ), : ERP-, SQL- , ORM-, RAD-, . , , .
, :
- SQL- – - – , , .
- ERP- – - – , , ..
- ORM- – - (, ), .
- RAD – - , , , IT-.
- – , RAD, , - , , Excel (, , , – ).
, lsFusion ERP, RAD SQL , lsFusion ( ). , SQL, , , , , , Fortran C ( , ). ORM- , – . , , - .
SME ( , ), ( ). , 1 , .
, , , , , ( 12 ), .