O AssemblyScript tem um novo competidor: a linguagem Grain, criada para WebAssembly, se autodenominou ruidosamente



Oscar Spencer é um dos fundadores da



linguagem Grain Grain, uma linguagem de programação de alto nível e fortemente tipada. É uma linguagem híbrida que combina alguns recursos de programação funcional (por exemplo, inferência de tipo, correspondência de padrões, fechamentos) e programação imperativa (por exemplo, variáveis ​​mutáveis).



Oscar Spencer, um dos criadores da linguagem, apresentou Grain no WebAssembly Summit 2021. Spencer falou sobre seus recursos mais interessantes e importantes, e também enfatizou que Grain foi criado e otimizado especificamente para WebAssembly. Ele só pode ser compilado em bytecode Wasm. Pelo menos é o que acontece hoje.



É assim que os desenvolvedores formularam a missão da linguagem Grain:



A Grain se esforça para obter o melhor das linguagens de programação funcionais e imperativas e levá-las a um público mais amplo. Muitas línguas têm grandes ideias, mas no final essas línguas não se espalharam. Isso ocorre porque eles são muito estranhos ou muito difíceis de aprender. E, conseqüentemente, suas tentativas de reunir uma grande comunidade ao seu redor falharam. O grão deve dar uma nova vida a essas ideias e apresentá-las de uma forma acessível, ao mesmo tempo que permanece fácil de usar.


O WebAssembly Summit é uma conferência anual dedicada a todos os aspectos do uso e interação com o Wasm. A cúpula discutida no artigo ocorreu em abril de 2021.



Tipos de dados



Além dos chamados tipos de dados centrais WebAssembly (por exemplo, tipos básicos i32 ou Int32), Grain tem tipos de dados compostos. Por exemplo: 



  • Opção é um tipo especial de enumeração que define a presença de opções (opções) como Alguns ou ausência como Nenhum; 
  • Resultado - tudo é padrão: Err, se algo deu errado, e Ok, se tudo deu certo; 
  • Stack é uma pilha imutável. 


Grain também implementa tuplas, registros, matrizes, listas, intervalos, caracteres, strings, conjuntos, mapas, filas e muito mais.



É assim que o programa Grain mais simples se parece:



import List from «list»

import Option from «option»

import { data } from «./data»

let allPairs = List.product(data, data);

let (a, b) = Option.expect (

	«Expected to find values»,

	List.find(((a ,b)) => a + b == 2020, allPairs)

);

print((«Values», a, b));

print((«Answer», a * b));

      
      





O exemplo é tirado do timecode do relatório de vídeo de Spencer.



Construtores Genéricos



Grain permite, por exemplo, criar enums usando construtores genéricos.



enum  Veggie {  Squash,  Cabbage,  Broccoli  }  

enum  Fruit {  Apples,  Oranges,  Bananas  }  

enum  Inventory<produce>  {  Crate(produce),  Truckload(produce)  }  

let veggieInventory  =  [Crate(Broccoli),  Truckload(Cabbage)]  

let fruitInventory  =  [Crate(Apples),  Truckload(Oranges)]

      
      





No exemplo de código acima, o parâmetro dos construtores Crate e Truckload é uma variável de produto.



Correspondência de padrões



enum  Topping {  Cheese,  Pepperoni,  Peppers,  Pineapple  }  

enum  Menu {  Pizza(Topping),  Calzone(Topping)  }  

let item  =  Calzone(Peppers)  

match  (item)  {  

 Calzone(topping)  =>  {  

 if  (checkSpecials(topping))  {  

 print(«These are half off this week.»)  

 }  else  {  

 print(«No current specials.»)  

 }  

 },  

 _  =>  print(«No current specials.»)  

}

      
      





A seção de documentação Ligações em Padrões de Correspondência diz que podemos ligar um padrão de correspondência (padrão) a, por exemplo, um nome de enumeração. Em seguida, substituindo seu nome no caso correspondente no corpo da expressão de correspondência, podemos verificar automaticamente os valores desta enumeração.



No exemplo de código acima, o valor da variável topping está vinculado à enumeração Topping, que inicializa o elemento na enumeração Menu com um de seus valores.



A correspondência de padrões também funciona para registros, tuplas e listas. Vejamos um exemplo de lista:



let list  =  [123

match  (list)  {  

 []  =>  print(«List contains no elements»),  

 [_]  =>  print(«List contains one element»),  

 [_,  _]  =>  print(«List contains two elements»),  

 [_,  _,  _]  =>  print(«List contains three elements»),  

 _  =>  print(«List containes more than 3 elements»)  

}

      
      





Você pode ler mais sobre este recurso de idioma aqui.



Resumidamente sobre outras possibilidades de grãos



No processo de trabalho no Grain, os desenvolvedores deram grande atenção à implementação completa e moderna das funções. Por exemplo, uma função pode ser usada como um valor. Assim como o JavaScript, o Grain implementa closures.



Grain também sabe como imprimir valores sem convertê-los em uma string. Além disso, Grain pode acessar a WebAssembly System Interface (WASI). A interface do sistema WebAssembly deve permitir que o código Wasm seja executado em todos os dispositivos e sistemas operacionais. O WASI inclui APIs para E / S assíncrona, geração de número aleatório, obtenção da hora atual e muito mais.



Os programas de grãos podem ser divididos em módulos. Os módulos podem ser exportados ou importados de outros módulos Grain. Módulos de grãos também podem conectar funções externas. Mas apenas com a condição de que o próprio desenvolvedor se certifique de que as funções externas correspondentes sejam criadas.



Agora há uma conclusão ativa da interface de função estrangeira (FFI - Interface de função estrangeira ), bem como a vinculação estática, funcionando no modo de 64 bits, a biblioteca DOM padrão e macros.



Para quem quer mergulhar mais fundo



Link estático



Até o lançamento de abril de 2021, todos os programas Grain eram montados por um mecanismo js especial que desempenhava o papel de um vinculador dinâmico. No entanto, com essa abordagem, os programas só podem ser executados em Node.js e navegadores. O Grain agora pode usar tempos de execução independentes para WebAssembly - Wasmer, Wasmtime e Wasm3.



Em 2018, os desenvolvedores do Grain perceberam claramente que a vinculação estática era vital para o desenvolvimento futuro do projeto. Mas eles esperavam poder usar as ferramentas do ecossistema para fazer isso. Infelizmente, nenhuma ferramenta adequada foi encontrada, e Oscar decidiu incorporar a fase de link estático diretamente no compilador Grain. Para implementar links estáticos usando o kit de ferramentas Binaryen, demorou cerca de 600 linhas de código para escrever. 



No entanto, depois disso, tive que enfrentar uma tarefa mais complexa e volumosa - reescrever o código JavaScript do tempo de execução e o código AssemblyScript da biblioteca padrão em puro Grain.



Grain vs AssemblyScript



AssemblyScript , que compila um subconjunto de TypeScript para Wasm, também é descrito como uma linguagem especialmente criada para WebAssembly. Ele também possui uma biblioteca padrão com tipos compostos (por exemplo, para matrizes ou datas). Como o Grain, o AssemblyScript é compilado para WebAssembly usando Binaryen. O AssemblyScript, sendo uma linguagem de alto nível, visa fornecer aos desenvolvedores mais recursos de "baixo nível" ao resolver tarefas que exigem desempenho (em comparação com TS e JS). 



AssemblyScript, entretanto, requer anotações adicionaistipos. Comparado ao TypeScript, a inferência de tipo em AssemblyScript é limitada porque o tipo de cada expressão deve ser conhecido com antecedência. Isso significa que as declarações de variáveis ​​e parâmetros devem ser do tipo anotado ou inicializador.



Grain é uma linguagem fortemente tipada (fornecida por OCaml typechecker) que requer poucas ou nenhuma anotação. Isso foi conseguido devido ao fato de que os desenvolvedores implementaram um mecanismo de inferência de tipo. 



Onde procurar?



Grain (junto com a CLI, compilador, tempo de execução e biblioteca padrão) vem em um único binário. Esta versão está disponível para MacOS x64 , Linux x64 e Windows x64 . Em outras plataformas, você pode usar a versão JS do compilador Grain.



Documentação de grãos.



Vídeo com o relatório:










Os servidores em nuvem da Macleod são rápidos e seguros.



Cadastre-se pelo link acima ou clicando no banner e ganhe 10% de desconto no primeiro mês de aluguel de um servidor de qualquer configuração!






All Articles