Melhores práticas na construção e implantação de aplicações de clojure: Bons tutoriais?

StackOverflow https://stackoverflow.com/questions/2391711

Pergunta

Sou novo no Clojure e estou começando a experimentar a construção de uma aplicação.

Até agora, tudo o que vi sobre os tutoriais sobre a compilação de programas de clojure envolve interatividade. Por exemplo, "Carregue o REPL e TIPE (FALHO DE LOAD" isto ou isso "para ser executado. Tudo bem, mas não é suficiente.

Estou tão acostumado com os idiomas de edição-compilada de idiomas como C ou Delphi, que sou instintivamente conduzido a fazer edições e depois clicar em "MX Compile".

O problema é que "Lein Uberjar", que eu entendo que é equivalente a "fazer", é dolorosamente lento para executar mesmo para um mundo olá. Então, vou ter que descobrir como esse material de "desenvolvimento interativo" funciona, pare de usar o Uberjar como é uma marca rápida e salvá -lo apenas para o final do dia.

Outra coisa que notei durante a construção (usando Lein Uberjar) é que o pequeno aplicativo da GUI que estou trabalhando em quadros pop -up no processo de compilação, como se estivessem executando durante a compilação. Parece um pouco contra -intuitivo para mim; Não é tão análogo a "fazer" como eu pensava.

Sei que a maneira Lisp de desenvolver as coisas está trabalhando interativamente na REPL, e não estou tentando mudar isso: gostaria de me adaptar a esse modo de vida. Infelizmente, vi pouco na forma de documentação sobre como fazê -lo. Por exemplo, como redefinir o estado atual da máquina. Parece meio confuso continuar compilando trechos individuais em tempo real sem poder fazer algum tipo de redefinição.

A maioria dos tutoriais que eu vi no Clojure (e Lisp) em geral parece se concentrar em invadir o REPL. As melhores práticas sobre a implantação de aplicativos continuam sendo um mistério para mim. Meus usuários vão ser usuários; Eles não serão desenvolvedores que carregarão arquivos em um REPL.

Então, aqui está a minha pergunta: algum recurso para obter boas informações ou tutoriais sobre todo o processo de criação de uma aplicação de clojure, incluindo a implantação?

(Nota: tenho todos os pré -requisitos instalados e funcionando (por exemplo, emacs, lodo, leiningen etc.), então isso não é uma pergunta sobre isso).

Foi útil?

Solução

Algumas dicas rápidas, depois alguns links:

Não use lein uberjar durante o desenvolvimento; preferir lein jar. A diferença é que lein uberjar coloca todas as suas dependências no gerado jar (incluindo a própria clojure), para que seu frasco único seja um pacote totalmente independente com seu aplicativo dentro; lein jar Apenas diminua seu próprio código. o uberjar A abordagem tem benefícios óbvios para a implantação, mas para o desenvolvimento, você poderá usar apenas o caminho de classe apropriado ao executar seu aplicativo, economizando o tempo necessário para preparar um Uberjar. Se você não quiser gerenciar manutenção à mão para as execuções de teste, confira o lein run plugar.

Além disso, provavelmente a maioria do seu código não deve ser compilada aot. O AOT é necessário em alguns cenários de interope Java, mas na maioria das vezes traz um leve impulso na velocidade de inicialização e problemas irritantes com compatibilidade binária com diferentes liberações de clojure. Suponho que a última questão não é relevante para um uberjar-Ed App independente tipo de projeto, mas qualquer código da biblioteca pelo menos deve ser deixado para ser possível, se possível. Com Leiningen, você pode colocar um :namespaces Cláusula no defproject forma em project.clj para determinar quais espaços de nome devem ser compilados; O que você deixar de fora será atualmente Jit-Ed por padrão. Versões mais antigas de Leiningen costumavam compilar tudo por padrão, o que é realmente um bom motivo para atualizar!

Quanto às janelas que surgem durante a compilação, eu acho que você está executando o código de cappagem de janelas durante o tempo de expansão da macro ou fora de qualquer definição de função ou construto semelhante. (Algo como um (println "Foo!") no nível superior.) Isso é algo que você não deve fazer, suponho - a menos que você esteja planejando executar seu código como um script. Para evitar o problema, envolva o código de efeito colateral nas definições de função e forneça um ponto de entrada para o seu aplicativo usando o :main Cláusula em project.clj. (Se você diz :main foo, então o -main função do foo O namespace será usado como ponto de entrada para o seu aplicativo. Esse é o padrão, de qualquer maneira, e pelo menos o acima mencionado lein run Parece ter o nome codificado - não tenho certeza sobre o próprio Lein.)

Quanto à redefinição do estado do Repl - você pode apenas reiniciá -lo. Com o Slime, o MX Slime-Restart-Inferior-Lisp fará exatamente isso, mantendo todo o outro estado da sua sessão do EMACS.

Veja também essas discussões sobre o grupo Clojure Google:

  1. Clojure para administração do sistema
  2. Preparando Clojure para embalagem (era: Re: Clojure para administração do sistema)
  3. Leiningen, Clojure e Bibliotecas: O que estou perdendo?

Outras dicas

Não, você não insere funções no REPL.

Você edita seus arquivos de origem, como sempre. A vantagem do LISP é que você tem o sistema em execução em segundo plano ao mesmo tempo, para que você possa compilar funções individuais do seu arquivo de origem e colocá -las no sistema em execução ou até substituí -las lá.

Se você usa lodo, você pressiona C-c C-c no seu arquivo de origem para compilar e carregar a função no ponto. Em seguida, você pode mudar para o repl para testar e explorar, mas tudo o que deseja persistir como fonte, você coloca seus arquivos de origem.

Os tutoriais geralmente começam digitando coisas no REPL, porque não há muito que você precisa configurar para isso, mas o desenvolvimento sério integra o sistema em execução e o gerenciamento de arquivos de origem.


Só para ilustrar, meu fluxo de trabalho usual (estou usando o Lisp comum, mas o clojure é semelhante) é assim:

  • Inicie emacs
  • M-x slime Para começar o slime, o sistema Lisp e conectar os dois via Swank
  • , (comando) load-system foo para carregar o projeto atual (compilando apenas se necessário) na imagem
  • C-x b Mude para um buffer de origem
  • C-c ~ Faça do diretório de origem o diretório atual e o pacote de origem, o pacote atual do REPL

Agora, estou configurado com meu sistema em segundo plano. Trabalhar é então:

  • Alterar ou adicionar uma função ou definição de classe
  • C-c C-c Para compilar e carregá -lo na imagem
  • mudar para repl, teste
  • depurar

Não há pausas de compilação significativas, porque eu nunca compilei tudo de uma só vez, apenas definições individuais.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top