Umka: nova linguagem de script estaticamente tipada


A primeira versão da linguagem de script incorporável estaticamente tipada Umka que desenvolvi acaba de ser lançada . Ele visa combinar a flexibilidade de linguagens de script familiares com a proteção contra erros de tipo no estágio de compilação no bytecode. A idéia principal da linguagem - explícita é melhor do que implícita - é emprestada do "Zen of Python", no entanto, ela deve adquirir um significado um pouco diferente e mais óbvio aqui.

Não importa quão privadas e subjetivas sejam as impressões que me levaram a empreender o desenvolvimento da linguagem, espero que o plano não tenha sido ingênuo. Sob o corte, vou falar brevemente sobre as capacidades da linguagem e os motivos para sua criação.

Motivos


A primeira virtude da digitação dinâmica é geralmente chamada de encurtamento do ciclo de desenvolvimento / depuração e economia de tempo do programador. Correndo o risco de causar descontentamento público, devo admitir que minha própria experiência não confirma isso de forma alguma. Toda vez que após uma pequena correção do meu script de treinamento de rede neural em Python, tenho que esperar o Python, NumPy, PyTorch carregar, ler uma grande matriz de dados de arquivos, transferi-la para a GPU, iniciar o processamento - e só então descobrir que o PyTorch esperava um tensor de tamanho (1, 1 , m, n, 3) em vez de (1, m, n, 3).

Eu admito prontamente que muitas pessoas preferem idiomas tipificados dinamicamente por razões pessoais. É até possível que a tendência ou hostilidade à digitação dinâmica seja um fenômeno da mesma ordem que a atitude em relação às azeitonas e ao suco de tomate. As tentativas de um estudo objetivo dessa questão aparentemente levam a resultados inconclusivos .

Ao mesmo tempo, a popularidade do TypeScript, a introdução de anotações de tipo no Python, discussões acaloradas sobre o Reddit e o Habré nos fazem pensar que a identificação real de linguagens de script com linguagens dinamicamente tipadas não é um dogma, mas uma coincidência e uma linguagem de script estaticamente tem todo o direito de existir.

Então havia uma linguagem com o nome de um gato com o nome de um urso.

Língua


A sintaxe do idioma como um todo foi inspirada no Go. Exemplos de construções de sintaxe podem ser encontrados na página do projeto . Ao declarar variáveis, uma notação abreviada com inferência de tipo pode ser usada. Digno de nota é o desvio das regras Go feitas na sintaxe dos ponteiros. Os criadores de Go reclamou que, literalmente, seguindo o exemplo C acabou por ser uma sintaxe desnecessariamente complicado aqui e que seria mais razoável para introduzir um postfix dereferencing operador como Pascal p^vez *p. Foi exatamente o que Umka fez.

TradutorO Umka é compilado no bytecode, que é então executado pela máquina virtual da pilha. Todas as verificações de tipo são feitas no estágio de compilação. Os dados na pilha não carregam mais nenhuma informação de tipo. O tradutor vem na forma de uma biblioteca dinâmica com sua própria API e um pequeno "wrapper" - um arquivo executável. O código fonte é escrito em C99 e portado para diferentes plataformas. As compilações para o processador x86-64 (Windows e Linux) agora são lançadas .

Gerenciamento de memóriaaté agora feito com base em balcões de referência. Se o idioma causar algum interesse e forem feitas tentativas para usá-lo, fará sentido organizar um coletor de lixo mais avançado. O idioma suporta os tipos de dados compostos clássicos (matrizes e estruturas) colocados na pilha e matrizes dinâmicas colocadas no heap. Qualquer matriz ou estrutura clássica também pode ser colocada no heap com uma chamada explícita new().

O polimorfismo é fornecido pelas interfaces no estilo Go. Não há conceitos de classe, objeto e herança.

MultitarefaÉ baseado no conceito de "fibras" - fluxos simplificados que são executados na mesma máquina virtual e causam claramente um ao outro. Em essência, isso é sinônimo de corotinas. Como a lógica do uso dessas corotinas se desvia um pouco da tradição Go e se aproxima de Lua e Wren, faz sentido fornecer uma amostra de código:

fn childFunc(parent: std.Fiber, buf: ^int) {
    for i := 0; i < 5; i++ {
        std.println("Child : i=" + std.itoa(i) + " buf=" + std.itoa(buf^))
        buf^ = i * 3
        fibercall(parent)
    }
}

fn parentFunc() {
    a := 0
    child := fiberspawn(childFunc, &a)    
    for i := 0; i < 10; i++ {
        std.println("Parent: i=" + std.itoa(i) + " buf=" + std.itoa(a))
        a = i * 7
        if fiberalive(child) {
            fibercall(child)
        }
    }    
    fiberfree(child)
}

Exemplos


Como exemplo básico demonstrando os recursos da linguagem, recomendo examinar um programa de renderização para cenas tridimensionais com base no traçado de raios reversos. É muito usado organicamente recursão, interfaces, matrizes dinâmicas; um pouco mais artificial - multitarefa.

Um exemplo de incorporação do tradutor Umka em um projeto C é o código-fonte do wrapper executável do próprio tradutor. Há também um exemplo de extensão de idioma Umka com funções externas em C.

imagem

All Articles