Ao elaborar o design de um novo sistema, é melhor começar com uma linguagem de tipo estático (como Haskell) ou uma linguagem de tipo dinâmico (como Ruby)?
Argumentos em que consigo pensar:
Com uma linguagem estática, você pode criar rapidamente uma especificação e escopo para o que o programa fará. Com um idioma dinâmico, você pode criar rapidamente uma demonstração funcional para apresentar ao cliente para revisão.
Com uma linguagem dinâmica, você costuma evitar reorganizar as estruturas de dados e refatorar o código ao alterar seu design. Com uma linguagem estática, é possível definir tipos antes da implementação, mantendo o código muito pequeno.
Com uma linguagem estática, você precisa descobrir com antecedência o que seu programa fará. Com uma linguagem dinâmica, você pode começar a escrever código e deixar o design crescer organicamente. Como Paul Graham diz em Hackers and Painters :
Uma linguagem de programação é para pensar em programas, não para expressar programas em que você já pensou.
Com uma linguagem estática, o compilador pode ajudar a identificar muitos tipos de erros. Com um idioma dinâmico, você pode começar a testar e encontrar erros mais cedo.
A digitação estática e dinâmica têm vantagens e desvantagens no que diz respeito à prototipagem. No entanto, ambos me parecem abordagens igualmente válidas. Com base em suas experiências, qual é a melhor?
Notas
Prototipagem em linguagem natural
Um terceiro tipo de linguagem a considerar: linguagem natural. Em vez de prototipar no código, pode-se prototipar por escrito. O cliente pode ler sua documentação e criticar seu design desde o início, mas não pode brincar com uma demonstração funcional. Se bem escrita, a documentação pode tornar a implementação em qualquer idioma simples. Ressalvas:
A documentação pode ser entediante de ler e difícil de digerir sem poder vê-la. Especulo que um cliente prefira experimentar algo que funciona, em vez de ler uma parede de texto (e imagens).
Prototipar um aplicativo em inglês em vez de em definições de tipo é mais detalhado e menos concreto.
Os tipos Haskell são descritivos
Observe que os tipos são particularmente descritivos em Haskell, mais do que em muitas linguagens estáticas como C ++ e Java. Por exemplo, suponha que eu tenha uma função com essa assinatura de tipo no Haskell:
foo :: forall a. [a] -> a
Uma função que, para qualquer tipo a
, pega uma lista de itens do tipo a
e retorna um valor do tipo a
.
Mesmo sem saber o nome da função, sei de fato que:
Ele não executa entrada / saída nem modifica nenhum valor (bem, a menos que use incorretamente o PerfeitorIO incorretamente), porque o Haskell é puramente funcional.
Ele não pode tratar os itens como, por exemplo, números inteiros, porque precisa suportar qualquer tipo.
Ele precisa usar a lista de entradas (isso, ou lançar uma exceção ou entrar em um loop infinito). Caso contrário, de onde ele obteria um valor do tipo
a
?
Portanto, a única coisa que essa função poderia fazer (além de falhar) é extrair um item da lista de entrada e devolvê-lo. Embora eu ainda não saiba qual item ele usará, [a] -> a
me diz tudo o mais.
fonte
Respostas:
Vou abordar Paul Graham: a digitação dinâmica é mais útil para criar programas organicamente, que é exatamente o que deveria ser a prototipagem. O objetivo é fazer algo rapidamente que demonstre a funcionalidade do produto final, não o produto final em si. A digitação estática é sobre correção formal - bem, ostensivamente; pelo menos deveria ser (como em Haskell ou Agda) - mas a digitação dinâmica tem a ver com correção prática, que é o que importa mais quando você faz uma prototipagem.
No idioma correto, as dicas de tipo estático podem ser fornecidas após o fato como uma otimização (e para fornecer segurança adicional para alterações futuras) ou o protótipo pode ser reescrito em um idioma de tipo estatístico, uma vez que os requisitos tenham sido elucidados e solidificados pelo protótipo. .
fonte
Acho que o problema do tipo estático versus dinâmico não é tão importante quanto muitas pessoas pensam ser.
Eu uso os dois. Às vezes, um é simplesmente mais útil que outro em uma determinada situação. Isso geralmente é causado pela necessidade de usar alguma ferramenta / biblioteca / tecnologia específica. Então, eu escolhi o que funciona bem com os outros componentes que tenho.
Eu acho que uma das coisas que as pessoas gostam nas linguagens dinâmicas é que muitas são interpretadas; Você pode modificá-los enquanto eles estão sendo executados de maneira interativa usando um console REPL . Qualquer idioma com uma função eval ou algo equivalente pode fazer isso. Portanto, pelo menos nesse aspecto, o sistema de tipos é realmente irrelevante.
Você pode criar protótipos usando coisas que não possuem nenhum sistema formal de tipo, como scripts de shell. (Eles têm REPL embora ...)
fonte
Faça o que funciona melhor para você e para o que você está tentando fazer. Acho que atualmente protótipo melhor em uma linguagem estática. A criação de protótipos com um sistema de tipo expressivo permite fazer algumas coisas legais:
Escreva assinaturas de função sem implementações correspondentes. Meu código Haskell no estágio inicial geralmente possui declarações como:
foo :: Foo -> Bar
foo _ = erro "não definido"
Isso ocorre porque eu quero ter uma idéia do que
foo
faz quando escrevo o código que o usa, sem precisar ter uma cópia de trabalhofoo
. Em outros idiomas, isso é feito com algo comothrow new Exception()
, o que você nunca faria em código real, mas ajuda bastante nos estágios iniciais.:t
Costumo ligar para o GHCi (Haskell REPL) para descobrir o que acabei de escrever. Por exemplo, isso pode lhe dizer o quão genérico é um trecho de código, revelando os requisitos de diferentes trechos do seu código e a estrutura correspondente.Conal Elliot descreveu sua visão de Haskell para ajudar no desenvolvimento do iPhone desta maneira:
"Quando escrevi Haskell, a maquinaria imperativa sumiu de vista e não pude deixar de começar a ver padrões essenciais. Mexer com esses padrões me levou a novas idéias ... Sou grato por ter essa linguagem preguiçosa de ordem superior com recursos ricos. digitação estática como uma ferramenta de pensamento, para me ajudar a obter idéias e eliminar meus erros. É um bônus para mim que a linguagem também seja executável. " Fonte
Está certo. Um dos deuses da programação funcional pensa que o valor principal de Haskell é uma linguagem de modelagem, e não uma linguagem de implementação. Outros gurus pensam coisas semelhantes: Erik Meijer usa Haskell para ajudar a esclarecer álgebra e padrões subjacentes que acabam entrando em estruturas orientadas a objetos.
A razão mais importante para a criação de protótipos em uma linguagem estrita é que, na maioria das vezes, as coisas que se deseja "prototipar" não são os aplicativos da web em estágio inicial que Paul Graham deseja financiar. Muitas vezes, você precisa criar um protótipo:
Em cada um desses casos, você realmente deseja usar uma linguagem que seja próxima da linguagem de implementação eventual de maneiras significativas.
Um nitpick embora
não possui
undefined
instâncias "corretas" (sempre termina sem produzir um erro ou ). Isso é porqueMas nenhuma função de
[]
paraa
poderia existir poisa
ela não possui instâncias.fonte
Você quer dizer protótipos de recurso ou design ?
Os protótipos de recursos são sobre mostrar um recurso ao cliente antes de iniciar o desenvolvimento desse recurso a partir do zero na linguagem final de implementação; portanto, o objetivo é escrever esse recurso o mais rápido possível, sem se preocupar com erros ou manutenção. As linguagens dinâmicas permitem uma troca entre correção e produtividade, permitindo hackers feios que nenhuma linguagem de tipo estaticamente aceitaria, o que os torna, em teoria, mais adequados para a criação de protótipos rápidos de descarte. Obviamente, na prática, a habilidade do desenvolvedor é mais importante que a linguagem, mas um codificador igualmente habilitado em Haskell e Ruby provavelmente criaria um protótipo mais rápido no Ruby, e o código resultante seria uma bagunça.
Os protótipos de design buscam encontrar um design de programa apropriado por tentativa e erro. Os hacks feios são inúteis - apenas a capacidade de refatorar projetos rapidamente importa. Um requisito fundamental para refatoração massiva é um conjunto de testes automatizados. Em linguagens dinâmicas, esse geralmente é um conjunto de testes de unidade escritos pelo desenvolvedor, que levam bastante tempo para serem escritos. Em linguagens de tipo estaticamente, as assinaturas de tipo servem como testes automatizados e permitem que o compilador detecte quaisquer inconsistências causadas por alterações de código. Linguagens de tipo estático brilham na refatoração de maneiras que nenhuma linguagem de tipo dinâmico pode alcançar.
fonte
Dinâmico, especialmente se você souber que o produto real precisaria estar em uma das várias linguagens estáticas populares para ser rápido o suficiente para resolver o problema real na natureza. Fazer isso irá protegê-lo automaticamente de cometer o erro de usar o protótipo como produto final.
fonte
Qualquer que seja o idioma com o qual você esteja mais familiarizado.
Dinâmico vs estático realmente não importa. Funcional vs OO realmente não importa. Melhor ajuste, recursos ou o que eles geralmente não têm sentido.
O único ponto da prototipagem é a velocidade de implementação (escrita de código), porque você precisa alterar muito o programa. E você deve ser o mais rápido com o seu melhor idioma.
Se você tem duas melhores linguagens, tanto dinâmica quanto estática, eu apostaria na estática. Como o estático geralmente pode lidar com a complexidade, enquanto o dinâmico falha em algum momento. E ninguém sabe realmente como o grande protótipo crescerá.
fonte