![React 19 Change irrita alguns desenvolvedores; Saltos de uso de banco de dados vetorial](https://optimuscloud.com.br/wp-content/uploads/2024/06/1719069724_React-19-Change-irrita-alguns-desenvolvedores-Saltos-de-uso-de-150x150.png)
React 19 Change irrita alguns desenvolvedores; Saltos de uso de banco de dados vetorial
22 de junho de 2024![AI-in-a-Box com Podman AI Lab](https://optimuscloud.com.br/wp-content/uploads/2024/06/1719082805_AI-in-a-Box-com-Podman-AI-Lab-150x150.jpg)
AI-in-a-Box com Podman AI Lab
22 de junho de 2024Quando meu colega leu minha postagem sobre Virgil, ele imediatamente sugeriu que eu desse uma olhada no Gleam. É legal e novo – a versão 1 foi lançada em março deste ano – e se destaca solidamente no lado funcional da vida da programação.
Gleam é uma linguagem de programação funcional com segurança de tipo para construir sistemas simultâneos escaláveis. Ele é compilado em Erlang e JavaScript, portanto tem interoperabilidade direta com outras linguagens “BEAM”, como Erlang e Elixir. (BEAM é a máquina virtual que executa o código do usuário no Erlang Runtime System. Acredito que seja a abreviação de Máquina abstrata Erlang de Bogdan. Não pergunte.)
Erlang foi uma das primeiras línguas da indústria de telecomunicações, focando muito na simultaneidade e na tolerância a falhas. Sua maneira de fazer as coisas ainda é respeitada e é responsável pela popularidade do Elixir. Nesta postagem, não presumo que você esteja familiarizado com eles; e, na verdade, o Gleam é particularmente amigável, por isso também não faz muitas suposições.
Vamos começar com Olá Mundo:
import gleam/io pub fn main() { io.println("hello world!") }
Isso é muito semelhante à mesma coisa no Zig.
Há um tour de linguagem muito agradável que faz uso da compilação do Gleam para JavaScript para fornecer verificação dinâmica. Você também pode usá-lo como playground.
Instalar o Gleam também significa instalar o Erlang. Para o meu Mac, usei apenas o Homebrew:
> brew install gleam
O Homebrew instala o Erlang automaticamente.
O Gleam vem com um gerador de template (ou projeto), muito parecido com o Rails. Então, para fazer um novo Olá projeto, acabei de digitar:
Em vez de economizar tempo no momento, a linha única do estilo “olá mundo” já está lá como código padrão em olá.gleam:
Se eu executar o projeto inteiro:
Observe que os dois pacotes foram compilados apenas na primeira execução.
Gerenciamento de Pacotes
Existem dois .toml arquivos (aparentemente A linguagem de marcação do próprio Tom. Não pergunte), que atua como configuração.
Como deveriam ser simples, podemos dar uma olhada rápida. No brilho.toml:
(dependencies) gleam_stdlib = ">= 0.34.0 and < 2.0.0"
Observe que eles têm um restrição de versão — mencionando a versão máxima para reduzir incompatibilidades.
A versão real baixada e usada é mencionada no manifesto.toml.
Podemos aprender um pouco do Gleam e trabalhar com o gerenciador de pacotes se seguirmos um exemplo simples. Adicionaremos alguns pacotes e escreveremos algum código para imprimir variáveis de ambiente. vou usar o mesmo Olá modelo de projeto, mas com o novo código inserido.
Primeiro, adicionaremos os novos pacotes para permitir a leitura do ambiente (enviado) e a leitura de argumentos de linha de comando (argumento) — que você espera que seja integrado, mas pode refletir diferenças do sistema.
Então, vamos substituir o código em olá.gleam com o código para imprimir variáveis de ambiente sob demanda:
import argv import envoy import gleam/io import gleam/result pub fn main() { case argv.load().arguments { ("get", name) -> get(name) _ -> io.println("Usage: get <name>") } } fn get(name: String) -> Nil { let value = envoy.get(name) |> result.unwrap("") io.println(format_pair(name, value)) } fn format_pair(name: String, value: String) -> String { name <> "=" <> value }
Adicionado ao público main
ponto de entrada, temos duas funções. Eles usam exatamente o mesmo formato que vimos em Virgílio. Acontece que as anotações de tipo são opcionais, mas consideradas uma boa prática. Agora, ficamos um pouco funcionais. O argumento load faz o que você espera e obtém uma lista de exatamente duas strings – com a primeira string igual a “get”. Isto é usado em um case
declaração.
Como um aparte rápido, o Gleam case
é um pouco mais flexível do que na maioria das linguagens não funcionais. Aqui vemos o conteúdo de uma lista sendo comparado:
let result = case x { () -> "Empty list" (1) -> "List of just 1" (4, ..) -> "List starting with 4" (_, _) -> "List of 2 elements" _ -> "Some other list" }
Portanto, os padrões podem ser comparados em declarações de caso. Isso sublinhou _
representa um default, e os possíveis casos são exaustivamente verificados.
Voltando ao nosso código de leitura de variáveis de ambiente, se o padrão não é uma lista de duas strings, então o texto auxiliar é cuspido. Caso contrário, ele chama o pegar função.
Vemos a função pipe, que apenas ajuda a tornar chamadas funcionais longas um pouco mais legíveis da esquerda para a direita.
let value = envoy.get(name) |> result.unwrap("")
Isto é o mesmo que:
let value = result.unwrap(envoy.get(name),"")
Como o Gleam não lança exceções, ele usa o tipo Result integrado e desembrulhar busca o valor do caminho bom.
A estranheza final é:
name <> "=" <> value
…que é apenas concatenação de strings.
E aqui eu executo, com os argumentos necessários pela segunda vez:
Gleam não temnull
, sem conversões implícitas e sem exceções. Então, se compilar, você está bem. Além disso, não há sobrecarga de operadores numéricos, portanto o código para adicionar números inteiros é diferente daquele para adicionar números flutuantes:
io.debug(1 + 1) //ints io.debug(1.0 +. 1.5) //floats
A igualdade funciona para qualquer tipo. O conceito geral de imutabilidade é melhor experimentado usando uma linguagem funcional por um tempo, então não vou encobri-lo. Isso ajuda a eliminar todo um subconjunto de bugs.
Tipos de dados algébricos
Finalmente, vimos Tipos de dados algébricos (ADTs) usados no Virgil, então estou ansioso para ver como o equivalente funciona no Gleam. Na verdade, já vimos o uso do case
declaração.
Obtemos tipos personalizados, sobre os quais combinamos padrões. Então, fazemos parte do caminho até lá:
pub type Season { Spring Summer Autumn Winter } fn weather(season: Season) -> String { case season { Spring -> "Mild" Summer -> "Hot" Autumn -> "Windy" Winter -> "Cold" } }
Os tipos podem conter dados em registros, e é assim que nos aproximamos do meu exemplo de Virgílio:
import gleam/io pub type Travel { Walk(hours: Int) Cycle(hours: Int) Drive(hours: Int, speed: Int) } pub fn main() { let walking = Walk(1) let cycling = Cycle(1) let bus_trip = Drive(2, 50) let trip = (walking, cycling, bus_trip) io.debug(trip) } // (Walk(hours: 1), Cycle(hours: 1), Drive(hours: 2, speed: 50))
Não creio que possa associar um método dentro de um tipo, mas posso acessar os valores dos registros para obter um resultado semelhante ao que obtivemos em Virgil. Vou deixar isso como exercício para um usuário mais fluente!
Para alguém como eu, que não trabalha muito com código funcional, o Gleam é muito acessível e não me confronta imediatamente com terminologia como “currying” e outros choques funcionais. Mas deve ser uma boa maneira de fazer com que você aprecie as vantagens imutáveis da programação, caso você ainda não seja um defensor.
O post Introdução ao Gleam, uma nova linguagem de programação funcional apareceu pela primeira vez em The New Stack.