Escrever programas em linguagens dinâmicas que vão além do que a especificação permite

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

  •  06-07-2019
  •  | 
  •  

Pergunta

Com o crescimento das linguagens digitadas dinamicamente, como eles nos dão mais flexibilidade, existe a probabilidade muito provável que as pessoas vão escrever programas que vão além do que a especificação permite.

Meu pensamento foi influenciado por esta questão, quando li a resposta por bobince: sobre métodos fatia e da emenda de JavaScript

A idéia básica é que splice, em Javascript, é especificado para ser usado apenas em certas situações, mas, ele pode ser usado em outros, e não há nada que a linguagem pode fazer para pará-lo, como a língua é projetado para ser extremamente flexível.

A menos que alguém lê através da especificação, e decide aderir a ela, estou bastante certo de que há muitas dessas violações que ocorrem.

Este é um problema, ou uma extensão natural de escrever essas línguas flexíveis? Ou devemos esperar ferramentas como JSLint a ajuda ser a polícia especificação?

eu gostei uma resposta nesta questão, que a implementação de python é a especificação. Estou curioso para saber se isso é realmente mais perto da verdade para estes tipos de línguas, que, basicamente, se o idioma permite que você faça alguma coisa, então é na especificação. Existe uma especificação da linguagem Python?

UPDATE:

Depois de ler alguns comentários, eu pensei que eu iria verificar o método de emenda na especificação e é isso que eu encontrei, na parte inferior da pg 104, http://www.mozilla.org/js/language/E262-3.pdf , por isso parece que eu possa usar tala no a matriz de crianças sem violar a spec. Eu só não quero que as pessoas se atolar no meu exemplo, mas espero que considerar a questão.

    The splice function is intentionally generic; it does not require that its this value be an Array object. 
Therefore it can be transferred to other kinds of objects for use as a method. Whether the splice function 
can be applied successfully to a host object is implementation-dependent.

UPDATE 2: Eu não estou interessado em este ser sobre javascript, mas a flexibilidade linguagem e especificações. Por exemplo, eu espero que especifica o Java especificação você não pode colocar o código em uma interface, mas usando AspectJ eu faço isso com freqüência. Esta é provavelmente uma violação, mas os escritores não prever AOP ea ferramenta foi suficiente flexível para ser dobrado para este uso, assim como a JVM é também bastante flexível para Scala e Clojure.

Foi útil?

Solução

Eu acho que esse tipo de flexibilidade é uma vantagem como interfaces desde que seus métodos são projetados em torno bem definidas, em vez de alguns metadados artificial externo "tipo". A maioria das funções de matriz só esperam um objeto com uma propriedade de comprimento. O fato de que todos eles podem ser aplicados genericamente para lotes de diferentes tipos de objetos é uma benção para a reutilização de código.

O objetivo de qualquer projeto de linguagem de alto nível deve ser o de reduzir a quantidade de código que precisa ser escrito, a fim de obter material feito- sem prejudicar a legibilidade muito. Quanto mais código que tem de ser escrito, os mais bugs ter introduzido. sistemas do tipo restritivas pode ser, (se não for bem projetado), uma mentira difundida na pior das hipóteses, uma otimização prematura na melhor das hipóteses. Eu não acho que ajuda sistemas de tipo excessivamente restritivo em escrever programas corretos. A razão é que o tipo é meramente uma afirmação, não necessariamente baseada em evidências.

Por outro lado, os métodos de array examinar seus valores de entrada para determinar se eles têm o que precisam para desempenhar a sua função. Esta é tipagem pato, e eu acredito que este é mais científica e "correta", e isso resulta em código mais reutilizável, que é o que você quer. Você não quer um método rejeitando suas entradas porque eles não têm os seus documentos em ordem. Isso é comunismo.

Outras dicas

Se a linguagem é estática ou dinâmica digitado é realmente uma pequena parte do problema aqui: a tipagem estática pode-se torná-lo ligeiramente mais fácil para o código para impor suas especificações, mas marginalmente é a palavra chave aqui. Apenas "programação por contrato" - uma linguagem que lhe permite explicitamente estado pré-condições, pós-condições e invariantes, e enforcing -los - pode ajudar a ala-lo contra os utilizadores de bibliotecas empiricamente descobrir o que exatamente a biblioteca vai deixá-los se safar, e aproveitando essas descobertas para ir além de suas intenções de projeto (possivelmente restringindo o seu futuro liberdade para mudar o design ou a sua implementação). E "programação por contrato" não é suportado em linguagens mainstream - Eiffel é o mais próximo a isso, e poucos chamaria isso de "mainstream" nos dias de hoje - provavelmente porque os seus custos (principalmente, inevitavelmente, em tempo de execução) não parecem ser justificada por suas vantagens. "Argumento x deve ser um número primo", "método Um deve ter sido previamente chamado antes método B pode ser chamado", "método C não pode ser chamado mais uma vez o método D tem sido chamado", e assim por diante - os tipos típicos de restrições que você tinha como para o estado (e ter imposto implicitamente, sem ter que gastar o tempo de programação substancial e verificação de energia para eles yourself) simplesmente não se prestam bem a ser enquadrado no contexto do que pouco compilador de uma linguagem de tipagem estática pode impor.

Eu não acho que a pergunta realmente tem muito a ver com a digitação vs. estática dinâmica. Realmente, eu posso ver dois casos: por um lado, há coisas como dispositivo de Duff que Martin Clayton mencionado; que o uso é extremamente surpreendente a primeira vez que você vê-lo, mas é explicitamente permitido pela semântica da linguagem. Se há um padrão, esse tipo de linguagem pode aparecer em edições posteriores da norma como um exemplo específico. Não há nada de errado com isso; na verdade, eles podem (a não ser em demasia) ser um grande impulso a produtividade.

O outro caso é o de programação para a implementação. Nesse caso se ser um abuso real, vindo de qualquer ignorância de uma norma, ou a falta de um padrão, ou ter uma única aplicação, ou múltiplas implementações que têm semântica variados. O problema é que o código escrito desta maneira é na melhor das hipóteses não-portáteis entre as implementações e, na pior limites do futuro desenvolvimento da linguagem, por medo de que a adição de uma otimização ou recurso iria quebrar uma grande aplicação.

Parece-me que a pergunta original é um pouco de um não-Sequitor. Se a especificação permite explicitamente um comportamento particular (como MUST, podem, devem ser ou deveria), então compilador nada / intérprete que permite / implementa o comportamento é, por definição, compatível com a linguagem. Isto parece ser a situação proposta pelo OP na seção de comentários -. A especificação JavaScript supostamente * diz que a função em questão pode ser usado em situações diferentes e, portanto, é explicitamente permitido

Se, por outro lado, um compilador / intérprete implementos ou permite comportamento que é expressamente proibido por uma especificação, então o compilador / intérprete é, por definição, operando fora da especificação.

Há ainda um terceiro cenário, e um associado, bem definido, prazo para as situações em que a especificação não define um comportamento: undefined. Se a especificação não realmente especificar um comportamento dada uma situação particular, em seguida, o comportamento é indefinido, e podem ser manuseados quer intencionalmente ou não pelo compilador / intérprete. É então da responsabilidade do desenvolvedor para perceber que o comportamento não é parte da especificação, e, se ele / ela escolhe para alavancar o comportamento, a aplicação do colaborador é assim dependente da implementação particular. O intérprete / compilador proporcionando que a implementação não está sob nenhuma obrigação de manter o comportamento oficialmente indefinido para além compatibilidade com versões anteriores e qualquer compromissos o produtor pode fazer. Além disso, uma iteração posterior da especificação de linguagem pode definir o comportamento não definido anteriormente, fazendo com que o compilador / intérprete ou (a) não conforme com a nova iteração, ou (b) saiu com um novo sistema transdérmico / versão para se tornar compatível, assim quebrar versões mais antigas.

* "supostamente" porque eu não vi o spec, eu mesmo. Eu vou pelas declarações feitas, acima.

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