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.