O que você considera mais produtivo em uma linguagem de programação?
Nos últimos dias vinha procurando uma linguagem de programação para iniciar um projeto pessoal que sabia que seria longo, com diversos serviços, grandes e pequenos. Nesse percurso creio que descobri que recursos me fazem mais produtivo, e gostaria de abrir uma discussão sobre isso com vocês.
Realizei testes nas mais diversas linguagens, para citar algumas: Rust, Swift, Clojure, Ocaml, Elixir, Crystal e até mesmo Common Lisp. O que buscava: produtividade e baixo uso de recursos (não, clojure nunca foi uma opção real). Em todas elas encontrei vantagens e desvantagens é claro. Porém vou definir aqui o que me fez escolher Crystal como a linguagem desse projeto.
Limitações específicas do projeto.
Todo projeto tem suas características que limitam nossas escolhas de stack. O meu em específico é utilização de recursos. Não tenho rios de dinheiro para o investimento inicial. Logo, quanto menos minhas aplicações consomem e mais disponibilidade possam oferecer pelo mesmo número de CPUs melhor. Isso de cara já exclui: Java, JavaScript, C#, Ruby, Python, e qualquer linguagem similar ou derivada dessas.
O que considero uma linguagem produtiva:
- Type system forte e de preferência estático:
Um sistema de tipos inseguro onde um final de uma pipeline de funções é undefined ou NaN sem sequer saber em qual função começou isso e nem porque nenhuma delas reportou um erro. - Sintaxe curta e expressiva:
Não me leve a mal, mas: public static string args, não é muito atrativo. Curto é melhor do que longo, se algo é muito utilizado eu não devo ter que escrever por padrão. - Alto nível de abstração (macros):
Macros são o tipo de feature que deve ser utilizada com cuidado, ou seu codebase vai virar uma bagunça. Porem. Se aplicado em pontos específicos, pode deixar sua vida um pouco mais alegre. - Inferência de tipos:
Se a linguagem tem tipagem estática, eu não quero ter que escrever o tipo de cada variável ou argumento. As anotações deveriam ser colocadas apenas onde são importantes. - Desenvolvimento e deploy simples:
A linguagem pode ter tudo que descrevi acima. Porém, se tiver um toolchain complexo ou inacessível podemos descartar essa opção de cara.
Vou te dar um exemplo do que me fez utilizar Crystal, o código que vai ver abaixo é um controller para uma aplicação web de um blog:
class HomeController < BaseController
def initialize(@pots_service : PostsService)
end
def index(env)
title = home
posts = @posts_service.get_home_posts
render "templates/home.ecr", "templates/layout.ecr"
end
def map_routes
route get, "/", index
end
end
Viu alguma anotação de tipo? Não, porém eles estão todos lá. E a inicialização das propriedades das classes? Tudo é feito ao declarar a propriedade diretamente no construtor da classe. O mapeamento de rotas é extremamente curto pois utiliza a macro route. E o contexto do template? É o próprio contexto da função. Simples e efetivo. Isso é exclusivo de Crystal, claro que não. Mas logo a seguir vou te contar o que me fez desistir de utilizar outras linguagens.
Por que não utilizei outras linguagens.
Cada uma delas a sua maneira não possui alguma das características que detalhei acima como essenciais. Vou detalhar nominalmente cada uma:
- Rust: o sistema de ownership pode impedir diversas abstrações e tornar o desenvolvimento mais longo do que o necessário. Além disso tudo. Eu não preciso de tanta performance.
- Go: é um caso curioso. É uma linguagem limpa e legível, porém extremamente massante, se eu tivesse que escrever mais um for por falta de um map eu iria ficar louco.
- Elixir: me impressiona o fato de não ser tão concisa quanto uma linguagem de script pode ser, ok, devo admitir que essa foi mais feeling do que qualquer outra coisa. Porém, como desculpa posso dizer que o uso de memória não é tão baixo quanto o desejado.
- Swift: na prática: impossível de ser utilizada no Linux, a única distro em que ela está nos repositórios a versão atual tem um erro de linkagen na biblioteca padrão. O que é uma pena. É uma linguagem incrível com uma toolchain inviável.
- Common Lisp: não me surpreende se você não conhecer, afinal estamos falando de tecnologia alienígena. Ao encontrar em Common Lisp eu penso em 35 maneiras diferentes de utilizar estrutura de dados como código e reduzir linhas de código a uma fração. Porém, quero ver você tentar um deploy dessa coisa.
- Ocaml: a queridinha de uma certa bolha da Twitch norte americana. É uma boa linguagem, para criar soluções de advent of code e hackerank. Graças ao build system e práticas muito estranhas da comunidade, considero inviável para grandes projetos. Mas eu a utilizei pouco, logo me reservo o direito de mudar de opinião no futuro.
E você? O que acha?
Sei que isso foi longo, desculpe. Porém espero ter te dado um contexto para discutir sobre o assunto. O que você considera uma característica produtiva? O que te faz largar uma linguagem na hora?
Ps: isso não é um post promovendo Crystal. Apenas atendeu minhas necessidades. Pode não atender as suas.