2 pontos por GN⁺ 2024-04-22 | 1 comentários | Compartilhar no WhatsApp
  • Racket é uma linguagem madura centrada em programação orientada a linguagens, tratando o desenvolvimento de aplicações gerais e a criação de novas linguagens dentro do mesmo ecossistema
  • O núcleo são macros e #lang, permitindo criar nova sintaxe, linguagens específicas de domínio e sintaxes superficiais existentes como bibliotecas, e usá-las por módulo
  • A biblioteca padrão, que inclui servidor web, bancos de dados, matemática e estatística, GUI e simulações científicas, além de milhares de pacotes, amplia o alcance do desenvolvimento de propósito geral
  • Typed Racket, contratos, sistema de objetos e a IDE DrRacket são fornecidos em conjunto, permitindo combinar código funcional, componentes orientados a objetos e tipagem gradual conforme a necessidade
  • Racket não é apenas uma linguagem da família Lisp, mas algo mais próximo de um ambiente de desenvolvimento que busca criar linguagens adequadas a cada domínio de problema e conectá-las a execução, edição e suporte de ferramentas

Racket para programação orientada a linguagens

  • Racket é uma linguagem de programação que se apresenta tanto como “Racket, the Programming Language” quanto como “Racket, the Language-Oriented Programming Language”
  • Racket version 9.2 está disponível
  • É um produto maduro que desde o início oferece suporte a programação gráfica multiplataforma em Windows, macOS e Linux
  • Os recursos básicos de desenvolvimento incluem gerenciamento de pacotes, GUI, binários independentes e interface externa

Escopo do desenvolvimento de aplicações gerais

  • Racket conta com um conjunto de bibliotecas que vai de aplicações de servidor web a matemática e software de simulação científica
  • A documentação representativa e o escopo das bibliotecas são os seguintes
  • Um toolkit de GUI multiplataforma e um servidor web fazem parte do ecossistema básico
  • Milhares de pacotes adicionais podem ser instalados com um único comando
    • Exemplos incluem 3D graphics, Bluetooth socket connector, color maps, data structures, educational software, games, quantum-random number generator, scientific simulations, web script testing etc.
  • O exemplo #lang racket/gui implementa um pequeno jogo de adivinhar números em um dialeto de GUI, usando vários recursos da linguagem em conjunto

Uma linguagem ampliada por macros

  • Programadores de Racket podem definir seus próprios laços e novas sintaxes com macros
  • Novas sintaxes são adicionadas como procedimentos, métodos e classes; basta criar regras que reescrevam a sintaxe personalizada como expressões ou definições de Racket
  • Macros pequenas ajudam a eliminar código repetitivo que é difícil de tratar com outros recursos
    • É possível definir uma construção time-it que mede o tempo de execução de uma tarefa
    • É possível evitar o uso repetitivo de lambda
    • Macros são exportadas de módulos como funções comuns
  • O sistema completo de macros também permite criar estruturas em que várias macros cooperam
  • Racket é uma linguagem funcional, mas desde o início oferece uma sublinguagem para classes and objects, mixins and traits
  • O sistema de classes semelhante ao Java é implementado como uma biblioteca baseada em macros, funcionando sem suporte separado da linguagem central

#lang e linguagens específicas de domínio

  • Racket se propõe a ser uma linguagem para criar linguagens, permitindo que programadores escrevam cada módulo na linguagem adequada
  • O exemplo #lang typed/racket usa union type de String e Number, occurrence typing e filtragem de listas
  • O exemplo #lang scribble/base trata de uma linguagem de documentação que gera documentos em PDF ou HTML
  • O exemplo #lang datalog usa a sintaxe de Datalog para definir e consultar relações parent e ancestor
  • Uma nova linguagem pode ser criada em uma janela da IDE e módulos dessa linguagem podem ser executados em outra janela da IDE, sem arquivos de configuração, de projeto ou ferramentas externas
  • Usuários de Racket usam principalmente a sintaxe com parênteses, mas também é possível criar sintaxes superficiais existentes que exigem vírgulas e chaves, como Datalog
  • Com parsing packages, é possível mapear uma gramática arbitrária para uma linguagem baseada em parênteses e compilá-la para Racket comum usando o sistema de macros de Racket

DrRacket e o ecossistema de desenvolvimento

  • Racket oferece sua própria IDE, DrRacket, com um recurso que desenha uma seta até o local da definição ao passar o mouse sobre um identificador
  • Mesmo ao usar linguagens alternativas como Typed Racket, é possível aproveitar o suporte de edição do DrRacket
  • Macros de Racket registram e propagam informações de código-fonte suficientes mesmo em macros complexas ou em macros que criam novas linguagens, permitindo que o DrRacket funcione como se entendesse os recursos da nova linguagem
  • Os principais suportes de desenvolvimento são os seguintes
  • Os recursos do ecossistema incluem download, código-fonte, relatórios de bugs, nightly snapshot builds e repositório de pacotes
  • Materiais de aprendizado e documentação incluem Quick Introduction, The Racket Guide, The Racket Reference e All Documentation
  • Os canais da comunidade incluem Discourse, Discord, Slack, Reddit, mailing lists, Mastodon, Twitter, Blog, Wiki e YouTube, além de documentação sobre Team e Contributing

1 comentários

 
GN⁺ 2024-04-22
Comentários do Hacker News
  • Fico feliz em ver Racket na primeira página. Desde 1982, usei principalmente Common Lisp para programação de pesquisa, mas hoje em dia acabo recorrendo mais ao Racket
    Há coisas de que não gosto no Racket — praticamente tudo, exceto o compilador, o sistema de gerenciamento de pacotes, o IDE gráfico, os atalhos do Emacs e o fato de ser uma linguagem prazerosa de escrever
    Não tenho muito interesse no ecossistema de pesquisa em linguagens de programação, que provavelmente é a parte que os professores de ciência da computação que lideram o projeto consideram mais importante. Ainda assim, torço para que eles tenham sucesso
    Por isso, sinto que estou pegando carona no projeto Racket. Aproveito só as pequenas partes de que gosto e ignoro o resto, e quase não contribuo. Talvez a exceção seja um pequeno livro sobre Racket que escrevi

    • Concordo com praticamente tudo isso. Por causa do sistema de gerenciamento de pacotes, do IDE gráfico com depurador passo a passo, da capacidade de escrever IDEs multiplataforma mantida pela própria equipe principal do Racket e da facilidade de gerar binários executáveis, Racket é meu Lisp favorito
      Esses recursos são realmente úteis e importantes. Gosto de Lisp, mas no trabalho só uso uma linguagem quando ela é a ferramenta mais adequada para aquela tarefa. Graças a esses recursos, Racket foi o único Lisp cujo uso consegui justificar na prática
      Pela comunidade, pelas ferramentas e pelos materiais de aprendizado, Racket é, para mim, uma linguagem fácil de recomendar a outras pessoas. Também usei bastante CL e Clojure, e há coisas de que gosto nelas, mas cada uma tem grandes desvantagens, então não costumo recomendá-las
      Eu também não me encaixo muito na parte de pesquisa da linguagem nem no recurso lang, e também não gosto muito de HtDP. Mas vejo isso apenas como projetos que não me interessam, feitos em uma linguagem de que gosto, e não como defeitos da linguagem em si, porque quase nunca esbarro nisso na prática
    • https://leanpub.com/racket-ai/read
      Acho que isso já conta como uma grande contribuição :)
    • Uso CL no dia a dia, e não é em pesquisa nem em pesquisa de linguagens de programação. Ainda não usei Racket, então fiquei curioso: você poderia explicar melhor o que não gosta no Racket em comparação com CL?
    • Fiquei curioso sobre o que exatamente significa ecossistema de pesquisa em linguagens de programação. Na distribuição do Racket, a única coisa que vejo que se encaixa claramente como pesquisa em linguagens de programação é o Redex
      A linguagem em si tem recursos de metaprogramação, mas linguagens modernas todas têm metaprogramação
      Minha experiência na comunidade foi, em geral, com pessoas falando de problemas reais
      Como Racket é usado em pesquisa de linguagens de programação e em outras pesquisas, ele aparece em artigos e apresentações de conferências relacionadas, mas não domina as discussões
      Ex.: https://racket.discourse.group/t/levin-tree-search-with-cont...
    • Usei Racket na faculdade em uma disciplina sobre o ecossistema de linguagens de programação, e essa parte também não me agradou muito. Ainda assim, Racket é fácil de começar e cumpre muito bem o seu papel. Se alguém vai entrar no mundo Lisp, pessoalmente acho que Racket é um bom ponto de partida
      Por outro lado, Clojure tem uma comunidade maior e mais sólida. Mas, por usar a JVM, a configuração é um pouco mais trabalhosa, e há mais detalhes sutis com que se preocupar
  • Racket é uma linguagem muito prática. Se ela parece só uma excentricidade acadêmica, vale ver o que Bogdan Popa faz com Racket: https://defn.io/
    Pessoalmente, quando preciso de um binário com GUI nativa, uso Racket. Ele também é bem bom para fazer parsing de coisas como JSON, XML e formatos de arquivo de texto
    O livro complementar How to Design Programs, https://htdp.org/2023-8-14/Book/index.html, também é bom. Não é exatamente um livro que ensina Racket; ele usa algumas linguagens educacionais implementadas em Racket, mas traz ideias valiosas que às vezes vale a pena revisitar
    O sistema de macros pode parecer estranho para quem vem de algo como CL, mas, depois que me acostumei, achei mais fácil manter certa sanidade ao fazer metaprogramação
    Mais alguns recursos úteis:
    https://www.greghendershott.com/fear-of-macros/
    https://beautifulracket.com/

    • Há algo no trabalho do Bogdan que se destaque especialmente? Dei uma olhada rápida e nada me chamou muito a atenção
  • Eu gosto muito da linguagem Racket, mas é difícil aceitar o fluxo de trabalho imposto. Quando programo em Python, escrevo o código no editor e o executo no shell
    Com Racket, o tempo de inicialização é longo demais para isso funcionar bem. Em vez disso, dizem que é preciso interagir com uma máquina virtual de longa duração e um REPL
    Mas, nesse caso, o código em que se está trabalhando não começa de um estado limpo; ele começa do estado que a máquina virtual tem naquele momento. É um ótimo fluxo para coisas como notebooks Jupyter, mas acho que não combina muito com programas grandes

    • Escrever código no editor e executá-lo no shell também é totalmente válido em Racket. Pela minha experiência, o tempo de inicialização é bem parecido com o do Python. É lento, mas não é fatal, e fica especialmente aceitável se você pré-compilar. É útil para arquivos em que o trabalho já acabou
      Usar racket/base como #lang em vez de racket também faz uma grande diferença. Há mais detalhes em https://docs.racket-lang.org/style/Language_and_Performance....
      A ideia de não começar de um “estado limpo” me parece mais próxima de um REPL no estilo Common Lisp do que de Racket. Em Racket, normalmente é preciso reiniciar o Racket ao recarregar um arquivo ou módulo, então você fica com um ambiente fresco. As pessoas reclamam disso, mas eu prefiro a abordagem de estado limpo do Racket à do CL
    • A parte sobre não começar de um “estado limpo” parece, pela documentação, ser algo em que o usuário pode recusar explicitamente salvar arquivos de backup
      https://docs.racket-lang.org/drracket/drracket-files.html#(p...
      Provavelmente também deve ser possível recusar a sugestão de restauração
      “Quando o DrRacket é iniciado pela primeira vez, ele verifica se há arquivos de backup restantes e, se houver, sugere restaurar os arquivos de backup”
    • É só experimentar Smalltalk :-))
    • Guile pode ser interessante. Acho que, especialmente ao depurar, ele é mais próximo de uma experiência imersiva do que Racket, e também mais parecido com Common Lisp (SBCL)
    • Bem-vindo ao mundo do Smalltalk e das Lisp Machines. IDEs modernas ainda não dão suporte direito a tudo: hot reload, salvar o estado de trabalho e controlar toda a stack de desenvolvimento em uma única linguagem
  • Quando estudei na University of British Columbia, ensinavam Racket na disciplina introdutória de ciência da computação. Achei uma excelente linguagem, e como alunos com experiência prévia em programação quase nunca tinham usado Lisp, ela colocava todos no mesmo ponto de partida
    Também achei impressionantes as bibliotecas que permitiam criar jogos simples ou visualizações com facilidade

    • Eu também fiz essa disciplina na UBC, mas tive uma impressão completamente diferente. Foi horrível e, em especial, acho que preparou muito mal os alunos iniciantes para as disciplinas posteriores de estruturas de dados e algoritmos, que eram dadas em linguagens imperativas
      Quando fui monitor, muitos alunos que haviam chegado ao segundo ano ainda não sabiam nem usar um loop for, e estavam muito atrasados em algoritmos básicos
      Só passei a ter uma appreciation mais profunda por linguagens funcionais depois da disciplina de teoria da computação no quarto ano
  • Não sei como se deve integrar todas essas “linguagens” do Racket em uma única aplicação. Vejo linguagens como typed/racket, racket/gui, scribble/base, mas não faço ideia de como criar uma aplicação GUI com código tipado e também gerar PDFs
    Já segui tutoriais de Racket várias vezes, mas ainda fico confuso sobre como juntar “linguagens” que parecem não ter relação entre si
    Pessoalmente, sinto que cada capítulo do tutorial só explica uma “linguagem” sem relação com as outras, e nunca mostra elas funcionando em conjunto. Um capítulo trata de servidor web, mas não do sistema de classes; outro capítulo trata de outra “linguagem” que oferece suporte a classes, mas não escreve um servidor web nela

    • Pense na linha #lang como uma espécie de diretiva de compilador com escopo naquele arquivo. Na prática, há muito mais coisa envolvida, mas é um bom ponto de partida. Se você quiser adicionar tipos à aplicação, uma boa estratégia é fazer isso arquivo por arquivo
      Além da linha #lang, você pode importar bibliotecas com require, então também pode colocar código de GUI e código de servidor web no mesmo arquivo. O #lang também não fica limitado a uma única linguagem por vez; se não houver conflito, é possível acrescentar mais coisas nessa linha
    • Acho a pergunta válida. Se você estiver desenvolvendo uma aplicação grande, é bem provável que quase todo o código seja escrito na linguagem "racket". Se tiver muito interesse em tipos, uma parte considerável pode estar em "typed/racket"
      É verdade que todas as linguagens compartilham uma base comum e interoperam em algum grau, mas não é nada provável que você divida o programa igualmente em cinco pedaços e use uma linguagem diferente para cada um. A documentação provavelmente será escrita em scribble
      Usar linguagens diferentes pode trazer modelos de programação fundamentalmente diferentes, e também é o que tornou possível um desenvolvimento como Typed Racket, mas isso não deve ser um obstáculo para começar
      Em resumo, basta usar Racket. Se você realmente sentir que precisa de outro recurso ou estilo de programação, aí procure se já existe uma linguagem que o ofereça. Claro, isso é tudo opinião minha
    • Pelo que sei, é possível escolher a linguagem de cada módulo separadamente
  • Este site, Hacker News, foi escrito em Arc e roda sobre Racket: https://en.wikipedia.org/wiki/Arc_(programming_language)

  • O maior problema do Racket não é a linguagem nem o ecossistema: https://news.ycombinator.com/item?id=27531508

    • Fui aluno da Racket School de 2018 mencionada no link. Todos os instrutores, incluindo Felleisen e Butterick, foram realmente prestativos e gentis dentro e fora da sala de aula.
      Mesmo que você aceite aquele link totalmente ao pé da letra e considere que Felleisen se comporta de forma maldosa, ao estilo Torvalds, em certas interações pessoais, o trabalho dele, incluindo How To Design Programs, teve um impacto muito positivo na minha vida e na vida de outras pessoas. Por isso eu não diria às pessoas para não aproveitarem esse trabalho
    • Aquilo é um conflito muito pessoal entre membros conhecidos da comunidade. A comunidade Racket mais ampla, incluindo a equipe principal, é muito acolhedora
    • Felleisen é uma pessoa difícil de aturar, mas também é fácil de evitar. Vejo isso mais como um sintoma de uma patologia do meio acadêmico do que algo do Racket em si.
      A comunidade também tem “nerds esquisitos” com opiniões fortes, que podem parecer mais presentes justamente por terem uma presença mais marcante, e portanto ser mais irritantes. Mas, como muitos espaços sociais em que o dinheiro não mantém a ordem, é simplesmente assim
  • Racket é minha linguagem favorita. É rápida, prática, tem uma base sólida e um modelo de concorrência muito bom. Ele se baseia em conceitos tomados e estendidos do Concurrent ML.
    O sistema de documentação também é excelente e integrado ao ecossistema de pacotes, então a maioria dos pacotes tem documentação de alta qualidade com referências cruzadas. A compatibilidade retroativa também é ótima; considero muito melhor do que a do Python, que uso no meu trabalho principal atualmente.
    Por isso, quando as pessoas dizem que Racket é acadêmico demais ou pouco prático, sinto que provavelmente não se aprofundaram o suficiente, ou eram estudantes que, no passado, só tiveram contato com linguagens educacionais.
    Claro que não é perfeito. A comunidade é pequena, o uso básico de memória do runtime é alto, e para fazer processamento paralelo é preciso subir uma VM Racket por thread do sistema, entre outros problemas. Ainda assim, essas coisas devem melhorar com o tempo.
    Coisas que construí com Racket nos últimos anos: um site de e-commerce[1], um app nativo de notificações para macOS/iOS publicado na App Store[2, 3, 4], um cliente desktop multiplataforma para Apache Kafka[5, 6, 7], um #lang para Lua[8]. Além disso, há várias outras coisas[9][10][11]. Acho que são coisas bem práticas.
    [1]: https://defn.io/2019/08/20/racket-ecommerce/
    [2]: https://defn.io/2020/01/02/ann-remember/
    [3]: https://defn.io/2024/04/09/ann-remember-for-ios/
    [4]: https://github.com/bogdanp/remember
    [5]: https://defn.io/2022/11/20/ann-franz/
    [6]: https://defn.io/2023/10/15/ann-franz-for-windows/
    [7]: https://defn.io/2023/08/10/ann-franz-source-available/
    [8]: https://defn.io/2022/11/12/ann-racket-lua/
    [9]: https://docs.racket-lang.org/http-easy/index.html
    [10]: https://docs.racket-lang.org/deta/index.html
    [11]: https://docs.racket-lang.org/gui-easy/index.html

    • Bogdan também é o autor de gui-easy e http-easy, indispensáveis no ecossistema Racket.
      Ele também é muito ativo nos fóruns da comunidade e dá muitíssimas respostas úteis.
      Eu o considero um herói anônimo dessa linguagem e queria muito mencioná-lo. Dá para dizer que suas bibliotecas executam código que torna a vida de usuários que não sabem nada muito mais fácil :)
      https://docs.racket-lang.org/http-easy/index.html
      https://docs.racket-lang.org/gui-easy/index.html
      https://racket.discourse.group
    • Acho que a compatibilidade retroativa é um ponto realmente importante. Usei Python intensamente por anos, mas fiquei profundamente decepcionado ao ver, na transição 2/3, o quanto os desenvolvedores principais e a comunidade não se importavam com compatibilidade retroativa, e isso não melhorou depois.
      Talvez seja por causa das áreas em que Python é usado principalmente hoje. A transição Numeric/Numpy por volta de 2000 foi completamente diferente.
      Quebrar coisas a cada poucos anos pode ser aceitável para startups unicórnio ou empresas que se movem rápido e literalmente quebram coisas. Mas há muitos programas valiosos para pessoas e organizações que não têm como reescrever algoritmos maduros a cada poucos anos, ou que não veem isso como prioridade
  • Uso Racket de vez em quando e gosto dele. Mas acabei percebendo que alguns Lisps, especialmente Common Lisp e talvez também Guile, são mais subestimados do que eu imaginava
    Gostaria de perguntar a quem conhece melhor: quais recursos do Racket, que a princípio não parecem práticos, relevantes ou úteis, acabam sendo surpreendentemente úteis para programação quando você os usa?

  • Cerca de 20 anos atrás, trabalhei em um software comercial de segurança de e-mail que usava MzScheme como linguagem base, antes de ele virar PLT Scheme. O código era multiplataforma, rodando em Solaris, Linux e HP-UX, e o código específico de cada sistema operacional tinha cerca de mil linhas em C
    As regras de filtragem eram compiladas para o próprio Scheme. Incluindo até a UI baseada na web, o código todo tinha cerca de 30 mil linhas, e havia apenas 5 ou 6 desenvolvedores
    Mais tarde, depois de emigrar, entrei em uma empresa com um produto parecido, mas com menos recursos; esse produto tinha centenas de milhares de linhas em C++ e mais desenvolvedores