
Recentemente, um grande número de novas linguagens de programação apareceu no mercado: Go, Swift, Rust, Dart, Julia, Kotlin, Hack, Bosque - e essa é apenas uma daquelas que são ouvidas.
É difícil superestimar o valor do que essas linguagens trazem para o mundo da programação, mas, como o Y Combinator
observou no ano passado, ao falar sobre ferramentas de desenvolvimento:
As estruturas estão melhorando, as linguagens são um pouco mais inteligentes, mas basicamente fazemos o mesmo.
Este artigo irá falar sobre uma linguagem construída sobre uma abordagem que é fundamentalmente diferente das abordagens usadas em todos os idiomas existentes, incluindo os listados acima. Em geral, essa linguagem pode ser considerada uma linguagem de uso geral, embora algumas de suas capacidades e a implementação atual da plataforma construída sobre ela, no entanto, provavelmente limitem sua aplicação a uma área um pouco mais estreita - o desenvolvimento de sistemas de informação.
Farei uma reserva imediatamente, não se trata de uma ideia, um protótipo ou até MVP, mas de uma linguagem completa pronta para produção com toda a linguagem de infraestrutura necessária - do ambiente de desenvolvimento (com um depurador) ao suporte automático de várias versões da linguagem (com correções automáticas de erros de mesclagem entre elas , nota de lançamento etc.). Além disso, usando essa linguagem, várias dezenas de projetos de complexidade do nível de ERP já foram implementados, com centenas de usuários simultâneos, bancos de dados em terabytes, “prazos de ontem”, orçamentos limitados e desenvolvedores sem experiência em TI. E tudo isso ao mesmo tempo. Bem, é claro, deve-se notar que agora não é o ano de 2000, e todos esses projetos foram implementados em cima dos sistemas existentes (o que não estava lá), o que significa que, a princípio, era necessário fazer "como estava" gradualmente, sem interromper os negócios e, em seguida, gradualmente, faça como deveria ser. Em geral, é assim que se vendem os primeiros carros elétricos, não a descolados ricos da Califórnia, mas a serviços de táxi de baixo custo em algum lugar de Omsk.
Uma plataforma criada neste idioma é liberada sob a licença LGPL v3. Honestamente, eu não queria escrever direito na introdução, pois isso está longe de ser a vantagem mais importante, mas, conversando com pessoas que trabalham em um de seus principais mercados em potencial - plataformas de ERP, notei uma característica: todas essas pessoas, sem exceção, dizem que mesmo se você fizer o mesmo que já está no mercado, mas de graça, já será muito legal. Então deixe aqui.
Pouco de teoria
Vamos começar com a teoria para destacar a diferença nas abordagens fundamentais usadas nesta e em outras linguagens modernas.
Um pequeno aviso, outras considerações, até certo ponto, são uma tentativa de atrair uma coruja para o mundo, mas com uma teoria fundamental na programação, em princípio, digamos sem rodeios, na verdade não, então você precisa usar o que é.
Uma das primeiras e principais tarefas resolvidas pela programação é o problema de calcular os valores das funções. Do ponto de vista da teoria computacional, existem duas abordagens fundamentalmente diferentes para resolver esse problema.
A primeira dessas abordagens consiste em várias máquinas (a mais famosa delas é uma máquina de Turing) - um modelo que consiste no estado atual (memória) e uma máquina (processador), que a cada passo altera esse estado atual de uma maneira ou de outra. Essa abordagem também é chamada de arquitetura de Von Neumann, e é ele quem sustenta todos os computadores modernos e 99% das linguagens existentes.
A segunda abordagem baseia-se no uso de operadores, sendo usada pelas chamadas
funções parcialmente recursivas (a seguir denominadas ChRF). Além disso, a principal diferença entre essa abordagem não está no uso de operadores como tais (operadores, por exemplo, também estão na programação estrutural usando a primeira abordagem), mas na possibilidade de iterar sobre todos os valores da função (consulte o operador de minimizar o argumento) e na ausência de estado em processo de cálculo.
Como a máquina de Turing, funções parcialmente recursivas são Turing completas, ou seja, elas podem ser usadas para especificar qualquer cálculo possível. Aqui, esclarecemos imediatamente que tanto a máquina de Turing quanto a CRF são apenas bases mínimas e, em seguida, focaremos nelas como abordagens, ou seja, em um modelo com memória de processador e em um modelo com operadores sem o uso de variáveis e a possibilidade de iterar sobre todos os valores funções respectivamente.
A CRF como abordagem tem três vantagens principais:
- É muito melhor otimizado. Isso se aplica diretamente à otimização do processo de cálculo do valor e à possibilidade de paralelismo desse cálculo. Na primeira abordagem, o efeito posterior, pelo contrário, introduz uma complexidade muito grande nesses processos.
- É muito melhor incrementado, ou seja, para uma função construída, pode ser muito mais eficiente determinar como seus valores serão alterados quando os valores das funções que essa função construída usa mudar. A rigor, essa vantagem é um caso especial da primeira, mas é justamente isso que oferece um grande número de possibilidades, que basicamente não podem estar na primeira abordagem, portanto, é destacada como um item separado.
- É muito mais fácil entender. Isto é, grosso modo, a descrição da função de calcular a soma de um indicador no contexto de dois outros indicadores é muito mais fácil de entender do que se o mesmo for descrito em termos da primeira abordagem. No entanto, em problemas algoritmicamente complexos, a situação é diametralmente oposta, mas vale a pena notar que problemas algoritmicamente complexos na grande maioria das áreas são bons se 5%. Em geral, para resumir um pouco, a CRF é matemática e as máquinas de Turing são ciência da computação. Consequentemente, a matemática é estudada quase no jardim de infância, e a ciência da computação é opcional e do ensino médio. Comparação mais ou menos, é claro, mas ainda fornece algum tipo de métrica nesse assunto.
Máquinas de Turing têm pelo menos duas vantagens:
- Melhor aplicabilidade já mencionada em problemas algoritmicamente complexos
- Todos os computadores modernos são construídos sobre essa abordagem.
Além disso, nesta comparação, estamos falando apenas de tarefas de computação de dados; em problemas de alteração de dados sem máquinas de Turing, você ainda não pode fazer.
Depois de ler este local, qualquer leitor atento fará uma pergunta razoável: "Se a abordagem da CRF é tão boa, por que não é usada em nenhuma linguagem moderna comum?" Portanto, de fato, não é assim, é usado, além disso, na linguagem usada na grande maioria dos sistemas de informação existentes. Como você pode imaginar, essa linguagem é SQL. Aqui, é claro, o mesmo leitor atento objetará razoavelmente que o SQL é a linguagem da álgebra relacional (ou seja, trabalhar com tabelas, não funções), e estará correto. Formalmente. De fato, podemos lembrar que as tabelas no DBMS geralmente estão na terceira forma normal, ou seja, possuem colunas-chave, o que significa que qualquer coluna restante dessa tabela pode ser considerada como uma função de suas colunas-chave. Não é óbvio, francamente. E por que o SQL não cresceu de uma linguagem de álgebra relacional para uma linguagem de programação completa (isto é, trabalhar com funções) é uma grande questão. Na minha opinião, existem muitas razões para isso, a mais importante das quais é "uma pessoa russa (de fato, qualquer pessoa) não pode trabalhar com o estômago vazio, mas não quer trabalhar com um estômago bem alimentado", no sentido de que, como mostra a prática, o trabalho necessário para isso é verdadeiramente titânico e apresenta muitos riscos para as pequenas empresas, e para as grandes empresas, em primeiro lugar, está tudo bem e, em segundo lugar, é impossível forçar esse trabalho com dinheiro - a qualidade é importante aqui, não a quantidade. Na verdade, a ilustração mais vívida do que acontece quando as pessoas tentam
resolver um problema por
quantidade e não por qualidade é o Oracle, que até conseguiu implementar até mesmo a aplicação mais básica da incrementalidade - representações materializadas atualizadas para que esse mecanismo tenha várias
restrições de várias páginas (justiça) por isso, a Microsoft ainda é
pior ). No entanto, esta é uma história separada, talvez haja um artigo separado sobre isso.
Ao mesmo tempo, não é que o SQL esteja ruim. Não. Em seu nível de abstração, ele executa suas funções perfeitamente, e a implementação atual da plataforma a utiliza um pouco menos do que totalmente (em qualquer caso, muito mais do que todas as outras plataformas). Outra coisa é que, imediatamente após o seu nascimento, o SQL parou no desenvolvimento e não se tornou o que poderia se tornar, a linguagem que será discutida agora.
Mas teoria suficiente, é hora de ir diretamente para o idioma.
Então, nos
encontramos :
Especificamente, este artigo será a primeira parte de três (já que ainda há muito material, mesmo para dois artigos), e falará apenas sobre o modelo lógico - ou seja, apenas sobre o que está diretamente relacionado à funcionalidade do sistema e não está relacionado a processos. desenvolvimento e implementação (otimização de desempenho). Além disso, falaremos apenas sobre uma das duas partes do modelo lógico - a lógica da área de assunto. Essa lógica determina quais informações o sistema armazena e o que você pode fazer com essas informações (ao desenvolver aplicativos de negócios, também é chamado de lógica de negócios).
Graficamente, todos os conceitos de lógica de domínio no lsFusion podem ser representados pela seguinte figura:
As setas nesta figura indicam as direções de uso dos conceitos um do outro, portanto, os conceitos formam um tipo de pilha e, portanto, é na ordem dessa pilha que vou falar sobre eles.
Sumário- As propriedades
- Propriedade primária (DATA)
- Composição (JOIN), Constante, Aritmética (+, -, /, *), Lógica (AND, OR), String (+, CONCAT), Comparação (>, <, =), Escolha (CASE, IF), Pertencente à classe (IS)
- Agrupamento (GROUP)
- Particionando / Organizando (PARTITION ... ORDER)
- Recursão (RECURSION)
- Acções
- Loop (FOR), Loop Recursivo (WHILE)
- Chamada (EXEC), Sequência ({...}), Ramificação (CASE, IF), Interrupção (BREAK), Saída (RETURN)
- Alteração de propriedade (CHANGE)
- Adicionando Objetos (NOVO)
- Excluindo objetos (DELETE)
- Alterar sessões
- Criando sessões (NEWSESSION, NESTEDSESSION)
- Aplicar alterações (APLICAR), Cancelar alterações (CANCELAR)
- Operadores de mudança (ANTERIOR, MUDADO, DEFINIDO, GOTA)
- Eventos
- Limitações
- Aulas
- Agregações
As propriedades
Uma propriedade é uma abstração que pega um ou mais objetos como parâmetros e retorna algum objeto como resultado. A propriedade não tem efeito posterior e, de fato, é uma função pura; no entanto, ao contrário da última, ela pode não apenas calcular valores, mas também armazená-los. Na verdade, o nome “propriedade” é emprestado de outras linguagens de programação modernas, onde é usado para aproximadamente os mesmos fins, mas é pregado ao encapsulamento e, portanto, é suportado apenas para funções com um parâmetro. Bem, o fato de que essa própria palavra "propriedade" é mais curta que "função pura", além de não ter associações desnecessárias, foi a favor do uso desse termo em particular.
As propriedades são definidas recursivamente usando um conjunto predefinido de operadores. Existem muitos operadores, portanto, consideramos apenas os principais (esses operadores cobrem 95% de qualquer projeto estático médio).
Propriedade primária (DATA)
A propriedade primária é uma propriedade cujo valor é armazenado no banco de dados e pode ser alterado como resultado da ação correspondente (um pouco mais tarde). Por padrão, o valor de cada uma dessas propriedades para qualquer conjunto de parâmetros é igual a um valor NULL especial.
, ( ), .
. :
class X {
Y y;
Map<Y, Z> f;
Map<Y, Map<M, Z>> m;
List<Y> n;
LinkedHashSet<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 ), .
UPD:
.