Executando verificação de segurança...
-1

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.

Carregando publicação patrocinada...
3
  • Tipagem
    Só cuidado com o NaN (e seus companheiros). Mesmo tendo uma tipagem forte e estática, o NaN pode estar presente. E pode ser um problema. Basicamente, NaN = ON ERROR RESUME NEXT (do BASIC).

  • Sintaxe
    Eu digo que o que mais evoluiu desde as primeiras linguagens de alto nível foi o editor. A verbosidade para escrever é, geralmente, bastante minimizada pelo editor. É claro que cada um vai dizer que a sua linguagem do coração é o máximo. Geralmente ela é desenvolvida facilitando o vada de quem desenvolve. Só depois vão pensar no desenvolvedor. Por exemplo, C# era int[] x1 = new int[] {1, 2, 3, 4} e agora ficou int[] x1 = [1, 2, 3, 4]. Poderiam ter feito isso antes (principalmente pelo desenvolvedor já ter passado por Pascal que tinha estrutura semelhante).

  • Macros
    Não sei até que ponto macros fazem sentido em uma linguagem OO. Só os métodos não seriam suficientes? Em outras linguagens, é possível até criar uma DSL utilizando macros, o que pode melhorar a legibilidade do programa.

  • Inferência
    É legal e em 99,9% dos casos funciona bem.

  • Ocaml
    Aqui eu discordo que seja uma linguagem apenas para AoC e outras coisinhas. É uma linguagem funcional e um dos principais motes delas é minimizar os erros em tempo de execução a, praticamente, zero. Se compilou, está correto. Em Elm (frontend) o pessoal diz que pode compilar na sexta, fazer o deploy e ir dormir. Tem suas peculiaridaes para programar, tipo: Começar a pensar de forma diferente do normal.

No mais, nenhum problema em promover a linguagem.

2

Assino em baixo. Acho que tive pouca paciência com Ocaml. A excluí mais por preferência. Já programei bastante em f# e Haskell e adoro o jeito "funcional" de resolver problemas. Haskell só ficou de fora dos testes pois já conheço o inferno que é gerenciar as versões das bibliotecas e compilers.

Macros em OO são bem situacionais mesmo. Mas dsl's em lugares específicos é revigorante devo dizer. Mas deve ser difícil de coordenar se o time não estiver em sintonia. O que é uma porcentagem bem alta das vezes. Sabia que esse item ia ser um pouco polêmico. Kkk

Obrigado pelo comentário, Foi muito bom lê -lo.

1

Em relação a produtividade, considero que ter uma vasta gama de bibliotecas disponíveis também é um ponto MUITO importante a se considerar.

Por exemplo, você pode até saber programar um algoritmo de treinamento da sua própria rede neural baseada em Transforemer, desde o início. Incluindo as derivadas parciais do backpropagation, etc. Mas ter uma biblioteca que já implementou isso pra você, ajuda DEMAIS na produtividade, né?

Outro ponto indiretamente relacionado à produtividade é trabalhar com uma linguagem que tem uma comunidade forte.

Por exemplo, pode ser que você encontre um edge case específico que ainda não foi resolvido. Quando isso acontece, você terá que: ou resolver o problema você mesmo parando de fazer aquilo que sua aplicação realmente necessita (improdutivo); ou esperar outras pessoas resolverem por você (que demora muito mais, já que tem menos gente utilizando a mesma linguagem que você).

Hoje em dia eu trabalho praticamente só com Python. Uso C/C++ quando estou em algum projeto pessoal de IoT (e passo muita raiva com o toolchain). Mas eu sigo acreditando que C# é uma das linguagens mais produtivas que já foram feitas, seguindo esses pontos que você mencionou, e somando com esses que eu mencionei. Tem seus defeitos, não é a mais performática do mundo, mas atende bem a vários requisitos que não sejam muito restritos em recursos computacionais (por exemplo, se não for pra sistemas embarcados).

Por fim, sobre seu projeto em específico, se você não quer trabalhar com um monolito, e haverá serviços grandes e pequenos, você tem a possibilidade de usar uma linguagem diferente para cada um deles. Talvez isso economize recursos e tempo (lembre-se que tempo é dinheiro).

2

Obrigado por comentar! Bibliotecas são um ponto crucial, para cada serviço eu dei uma olhada no que precisaria. Era um dos pontos extras que devia ter colocado no post. Nesse ponto, Java, C# e Golang se destacam muito.

Sobre C# em específico, tenho de dizer que ele realmente é uma exceção brilhante. Apesar da sintaxe (em partes) um pouco cansada, realmente é extremamente produtiva. Diria que parte desse sucesso está em bibliotecas muito bem pensadas. Sempre que desenvolvo uma arquitetura de server tento ser uma versão maus simples do Asp.net core.

Sobre utilizar múltiplas linguagens, acho que é completamente viável. Para o servidor principal, talvez eu crie um monólito modular. Porém ainda haverão serviços paralelos. Neles posso utilizar linguagens mais leves como tinha mensionado no post. Vamos ver como as coisas se desenrolam.

Novamente. Muito obrigado pelo comentário!

0

Quase sempre essas coisas são subjetivas demais.

Existem alguns estudos sobre isso. Todos meio subjetivos também. O que significa ser pseudociência. A maioria dos estudos não provam nada e muitos estão errados. Mas tende ser melhor que um achismo total.

A linguagem não te dá tanta produtividade quanto pode pensar. E ferramentas podem ajudar até mais. Lembre-se que o grosso do tempo do desenvolvedor ele não está programando.

Eu nunca mais achei (dá vontade de falar que eu que inventei isso :D) um artigo interessante que fala que existem só 3 balas de prata na computação:

  • Linguagem de alto nível - não programar em Assembly e sim em Fortran, Lisp e depois as várias outras que apareceram como C ou TypeScript.
  • Modularização - Principalmente criar função em vez de ter um enorme linguição, então versões posteriores de Fortran, Lisp, COBOL e quase todas as outras (BASIC original e alguns simplificados não tinha, só um exemplo).
  • Gerenciamento automático de memória - começando com Lisp, mas hoje está presente em quase todas as linguagens, assim como os itens anteriores, até mesmo em algumas que preferem falar em semi automático, como em C++ por exemplo. C puro não tem isso.

Essas coisas dão ganhos de produtividade incríveis. O resto nem tanto. Algumas coisas dão ilusões de produtividade para escrever, mas depois cobra o preço de dar manutenção. tem estudo que mostra que linguagens dinâmicas só são mais produtivas para escrever, não no longo prazo. Mas as pessoas gostam da ilusão do curto prazo.

Para escolher uma linguagem pode adotar critérios técnicos e políticos. O segundo não pode ser subestimado. A Popularidade, por exemplo, é político. E isso conta. Até já saber usar também.

Quando se fala em limitação de recursos pode já excluir quase todas as linguagens. Mas às vezes isso não é tão importante quanto pensa. Por que, mesmo muita gente jogando pedra, ainda é preferida por muita gente? Porque olhando para todos os aspectos não tem linguagem que permita ao bom programador economizar mais recursos. Vai dar trabalho, mas isso é outra questão.

Não sei se de fato precisa disso, mas não vou dizer o contrário. Eu gosto desse critério.

Exclui C#? Então tá: https://www.techempower.com/benchmarks/#hw=ph&test=plaintext&section=data-r22.

Para fazer uma boa seleção precisa de informações corretas. Se pegar dados falsos, fofocas, fakes news, etc. sobre algo, a seleção será falha.

Curiosamente eu excluiria em alguns casos por outros motivos, mas não esse.

Macro é ilusão. Quem tem experiência sabe que isso gera muito problema no longo prazo e acaba destruindo a produtividade. Claro que tem casos bons. Tem casos que é menos necessário do que parece.

C# tem mecanismo mais simples e menos poderoso, mas que atende quando é muito necessário,que é a geração de código. Não é tão elegante e bonitinho, mas isso pode ser feature, mesmo que pareça um besourinho com terninho esfarrapado (não vou postar o meme).

Deploy simples anda ficando raro. Mas ok, quase todos os casos pelo menos disfarçam bem :)
Se depois de escolher uma linguagem adequada fizer código acidentalmente complexos, com arquiteturas desnecessariamente exageradas, pra que? A capacidade do programador conta mais que a linguagem.

Inferir tipo pode ser um fator de inelegibilidade em alguns, ou muitos, casos. E isso piora a manutenção, e pode até criar problemas de robustez em casos extremos.

Não consigo ver que o sistema de tempo de vida possa impedir abstrações, mas ele cria dificuldades. Algumas pessoas alegam que mesmo que seja improdutivo no primeiro momento, depois ganha muito. Claro que não tanto quanto o gerenciamento automático e simplificado de memória, mesmo a custo de consumo de recursos e pausas indeterminadas.

Se não precisa da performance de Rust, então C# deveria estar muito dentro. Java também. E outras.

Eu gosto e desgosto de Go, mas não sei se é massante. Ficou parecendo uma coisa bem de gosto mesmo, muito subjetivo, quase um motivo inventado.

É, pode ser uma pena Swift estar na mão da Apple.

Eu acho CLisp mosca branca demais, mais que Crystal. Eu até uso mosca branca, mas por motivos de legado ou pra algo pessoal.

OCaml é legal, mas cai quase no mesmo problema. Eu até adotaria F# que é Ocaml "melhorada" para .NET.

Conheço pouco de Crystal, mas já investiguei um pouco. Não sei se ela é tudo isso que acha que é. Eu acho que tem um verniz que esconde os problemas. Por quase não ser usada, não sabemos direito dos problemas. Eu só tenho percebido os erros de Python agora, e eu já usei a linguagem há quase 20 anos. Popularidade ajuda a perceber melhor os problemas.

Se o meu caso fosse o seu eu iria de C#, até porque eu não precisaria aprender outra coisa e tem várias vantagens. Se eu quisesse mais economia de recursos, eu pensaria em Rust, daria um esbarrão em Go, e não descartaria C ou C++ em alguns casos. E se tivesse tempo, ainda tentaria Carbon.

Curiosamente uma linguagem que já usei muito e hoje em dia quase ninguém ouviu falar, é muito mais economia de recursos em vários critérios (mas não todos). Poder entregar aplicação com KBs em vez de MBs é ótimo né? (acabei de lembrar do cara que entrou praticamente 4 CRUDs em Laravel e a aplicação tinha 1GB). Liberar a memória assim que não precisa mais sem se preocupar também, né? Não ter uma VM maluca que demora de algumas dezenas ou centenas de vezes mais que o nativo, é a cereja no bolo, mesmo que ainda não tenha toda vantagem do nativo.

Uma coisa que eu acho engraçado quando a pessoa fala em economia de recursos e faz aplicação para web :D

Mas eu sempre gosto de ouvir mais sobre linguagens que eu não conheço bem. Obviamente não algo raso, ou óbvio (que está no site dela, na Wikipedia, doc, etc.)

Uma coisa que eu sempre vejo é as pessoas acreditarem que passaram todo o cenário, contexto, requisitos. Quase 100% das pessoas falham nisso. Eu mesmo já falhei inúmeras vezes. E muitas vezes ela não passa porque ela não tem (ou acham que já tem todos). Então a escolha será falha.

Parece que criou os critérios/requisitos para Crystal ganhar, ou seja, eles foram criados depois de saber o que Crytal tem. Parece licitação pública.

Faz sentido para você?

Espero ter ajudado. Em geral estou à disposição (sem abusos :D)


Farei algo que muitos pedem para aprender a programar corretamente, gratuitamente. Para saber quando, me segue nas suas plataformas preferidas. Quase não as uso, não terá infindas notificações (links aqui).

2

Bom. Na verdade C# foi minha primeira opção eu a deixei de fora pois é minha linguagem principal, logo era injusto comparar com minhas pesquisas Durante a semana. E sim eu faria nela se pudesse pagar pelos recursos. Não pretendo criar um monólito e preciso de no mínimo 3 serviços para iniciar. O que em c# me custaria muita memória (cerca de 500mb em pico). Mais do que posso pagar, o que no momento é: 0.

Sobre os critérios, acho que essa impressão sobre crystal ficou muito mais pela falta do que excesso. Ahh e se a linguagem tem defeitos. Tive que fazer questão de deixar no fim um disclaimer sobre. De forma alguma quero que alguém a escolha por isso. Eu sei dos riscos e do que posso tolerar da linguagem. C# por exemplo, apesar de não possuir um sistema de inferência de tipos mais forte, é sempre minha primeira opção pela solidez.

Porém, o post no geral era realmente sobre o que as pessoas consideram: "produtivo". E respeito bastante o argumento de que abordagens mais conservadoras podem a longo prazo serem mais benéficas ao processo.

Contudo, tenho que discordar em parte sobre dois pontos: o sistema de macros, ressaltei é claro que esses devem ser ínfimos, e aplicados cirurgicamente. E sobre o sistema de lifetime. Esses sim tenho que reforçar, criar abstrações em certos aspectos em rust é doloroso. Leva muito tempo, esforço e aumenta a complexidade de forma absurda. Existem frameworks em rust em que um simples http response tem 4 argumentos genéricos com 2 sendo de lifetime.

E pra finalizar, diria que só tenho duas tristezas nessa vida: Swift estar na mão da Apple e Scala ter sido criada sob a JVM.

1

Ficou mais estranho ainda querer evitar monólito (o Stack Overflow não evitou, pode atender demanda de um dos 30 sites de mais acessados no mundo com um servidor, tudo em C#, porque eles não tinham rios de dinheiro, sem contar os inúmeros casos de serverless).

Não entendi de onde vem esses 500MB do C#, nem que Crystal atende o critério de poder pagar 0, muito menos como Crystal consegue ser segura (se não for temo opções melhores), não ter controle de tempo de vida (obrigatório para ser seguro sem GC), coletor de lixo (porque só assim vai gastar muito menos memória que C#), mas eu sempre gosto de aprender (GC baseado no Boehm é extremamente ineficiente, gastador de memória e causa vazamentos, foi ele que deu má fama aos GCs). Nem deveria ter uma linguagem com GC na conversa quando o requisito é estrito consumo de memória. Se falar que vai desligar o GC, C# também pode, mas em qualquer caso consome mais memória ainda, e se for gerenciar a memória na mão, não consigo imaginar porque não usar outras coisas inseguras. (avabei de descobrir que atualmente ela vaza memória em hello world).

Nem imagino que ganho terá em quebrar os executáveis, ou quanta economia fará (em geral isso é custo). E espero que não esteja falando de arquitetura de microsserviços, a não ser que esqueceu de falar que está trabalhando em um dos maiores projetos do mundo, e onde vai achar tanto programador e Crystal.

Acho que se apega a pontos pouco importantes e não está observando casos reais, misturando coisas, que me fez pensar desde o início que estava fazendo cherry picking. Pelo menos espero que já domine Crystal. Dominar e ter um ecossistema forte d~´ao mais produtividade que detalhes pequenos (eu diria minísculos pelo que foi indicado).

Eu acho que você tem uma visão equivocadas de algumas coisas e escolheu ter essa visão (não por falta de conhecimento técnico), eu poderia ficar argumentando, mas eu sei pouco do que realmente quer fazer (inicialmente falou de algo e depois mudou na (t)replíca) para argumentar melhor e parece que não será produtivo.

Mas estou sempre aberto a aprender, por isso bato muito na tecla que não consigo ver, imaginar, entender sobre certas decisões.

2

Não quero ser muito aguerrido nessa discussão pois tenho que dizer: sim, eu testei C#. Sim, eu testei outras linguagens. Lembre, você não sabe qual projeto estou trabalhando. E não, C# não consegue atender meus requisitos de memória uma vez que apenas para subir uma instância da clr com Aspnet é necessário 80mb de memória enquanto Crystal ou Go gastam 3. A escolha da arquitetura não é por moda e sim por praticidade. Não é um site apenas, logo não consigo manter tudo em um servidor. Então compreenda que fiz uma escolha apropriada pra mim. Não recomendei a ninguém que faça a mesma. Mas esses pontos se disponíveis em uma linguagem simplesmente me fazem escrever rapidamente um código extremamente limpo. E aposto que concorda com a maioria já que c# e f# apresentam quase todas as características que citei.

0

Por isso ficou improdutivo, parece que só queria desabafar, não dá detalhes e pede para opinarmos.

De qualquer forma agora veio mais algumas informações que confirmam vários aspectos do que eu disse, principalmente de fazer cherry picking sobre o que eu disse e do que responder. E mais uma, que é sobre a apostagem não ser sobre ser produtivo.

É claro que Crystal gasta menos memória inicial, porque gasta mais depois, afina usa um GC ingénuo, que é quase um mock, por isso dizem que vão mudar, e vai gastar mais memória e aí perde a vantagem pretendida por não ter controle sobre isso.

Eu fui ver mais sosbre Crystal e percebi que a comunidade dela é bastante ingênua, parecido com o que acontece com V, e acreditam em coisas que a computação não permite e acabam fazendo marketing para si mesmos de que fizeram a escolha certa. E acabam convencendo outras disso.

Não estou dizendo que Crystal seja uma linguagem ruim, eu já havia avaliado antes e sei que tem méritos e eu poderia usar em algum cenário, mas ela não é tão boa quanto alguns acham. Fazem parecer que ela é mágica, quando apenas não estão vendo o truque.

Faltou decidir se queria produtividade, baixo consumo real de memória ou outra coisa.

No fundo a maioria dos projetos nem precisam de muito cuidado, a pessoa faz de um jeito que não o ideal, mas funciona, e fica todo mundo feliz, não importa se é produtivo, se não atende requisitos que nem precisavam existir.

Por tudo isso não tenho mais o que dizer. Boa sorte no seu projeto.

2

Eu respeitei sua opinião de que o impacto do que apontei pode ser subestimado. Desde o primeiro comentário. Rebati alguns pontos. Mas essa insistência em falar sobre o projeto em si me cansa. O post nunca foi sobre isso. Ainda sim agradeço por tudo. Quem sabe um dia eu perceba que você está completo de razão, ou não. Isso só o futuro determina. Obrigado por comentar.