Como o manuseio de quebras de linha do Python difere dos pontos-e-vírgulas automáticos do JavaScript?

41

O Javascript tem um recurso chamado Inserção automática de ponto-e-vírgula onde, basicamente, se o analisador encontrar um token inválido e o último token antes disso era uma quebra de linha, o analisador inserirá um ponto-e-vírgula onde está o quebra de linha. Isso permite basicamente escrever todo o seu código javascript sem ponto e vírgula, mas você precisa estar ciente de alguns casos de borda, principalmente se você tiver uma palavra-chave de retorno e depois o valor que deseja retornar em uma nova linha.

function test(){
    // This will return 'undefined', because return is a valid statement
    // and  "john" is a valid statement on its own.
    return 
          "john"
}

Por causa dessas armadilhas, existem dezenas de artigos com títulos como 'Inserção automática de ponto-e-vírgula é Evil', 'Sempre use ponto e vírgula em Javascript' etc.

Mas em Python ninguém usa ponto-e-vírgula e tem exatamente as mesmas dicas.

def test():
    # This will return 'undefined', because return is a valid statement
    # and  "john" is a valid statement on its own.
    return 
    "john"

Funciona exatamente da mesma forma, e ainda assim ninguém tem medo do comportamento dos Pythons.

Eu acho que os casos em que o javascript se comporta mal são poucos o suficiente para que você possa evitá-los facilmente. Retorno + valor em uma nova linha? As pessoas realmente fazem muito isso?

Alguma opinião? Você usa ponto e vírgula em javascript e por quê?

    
por Einar Egilsson 07.08.2011 / 15:33
fonte

13 respostas

62

A razão é que, no Python, as novas linhas são uma maneira inequívoca de separar linhas de código; isso é por design, e a maneira como isso funciona foi completamente pensada. Como resultado, o código python é perfeitamente legível e não ambíguo, sem quaisquer marcadores especiais de fim de declaração (além da nova linha).

O JavaScript, por outro lado, foi projetado tendo em mente uma sintaxe semelhante a C, em que as instruções são sempre terminadas com um ponto-e-vírgula. Para tornar a linguagem mais tolerante a erros, ela tenta adivinhar onde pontos-e-vírgulas extras devem ir para tornar o código correto. Como isso era meio que retroajustado na sintaxe semelhante a C, nem sempre funciona como esperado (às vezes, o interpretador de scripts supõe errado) e pode criar um código bastante contra-intuitivo. \

Ou, argumentando em termos de "explícito é melhor que implícito": Em Python, uma nova linha já é completamente explícita, enquanto em Javascript, é ambígua, então você adiciona o ponto-e-vírgula para explicitar isso.

    
por 07.08.2011 / 15:53
fonte
28

Existe uma diferença bastante fundamental da maneira como funciona em Python, eu acho. Citando o post Einar Egilsson ligado a: "um ponto-e-vírgula não está implícito no final de uma linha se o primeiro token da linha subsequente puder ser analisado como parte da mesma declaração".

No Python, uma quebra de linha sempre termina a instrução, exceto em certos casos bastante óbvios, como em uma expressão entre parênteses. O JavaScript, por outro lado, tentará analisar quantas linhas puder antes de terminar a instrução, levando potencialmente a coisas como esta:

// Define a function and name it area.
area = function(r) {
    return r * r * 3.14159
}

// Fooled you! We're actually invoking it.
(14)
    
por 07.08.2011 / 20:09
fonte
20

Costumo minimizar meus arquivos JS no modo de produção. Significa remover comentários e quebras de linha.

Sem o uso de ponto-e-vírgula, isso quebraria meu Javascript.

    
por 07.08.2011 / 15:50
fonte
5

Não funciona como você descreve.

Javascript has a feature called Automatic Semicolon Insertion where basically if the parser encounters an invalid token, and the last token before that was a line break, then the parser will insert a semicolon where the linebreak is.

Isso está errado. Exemplo:

return
  1 + 2;

1 é um token perfeitamente válido, mas o analisador ainda inserirá um ponto-e-vírgula diretamente após return .

Como você vê, nem mesmo você pode dizer exatamente onde um ponto-e-vírgula irá acontecer.

O problema com a inserção automática é duplo:

  • Por um lado, as pessoas podem deixar um ponto e vírgula onde a inserção automática não pode determinar que é necessário inserir um.
  • Além disso, um ponto-e-vírgula pode ser inserido onde não se destina, como acima.

É claro que usar ponto-e-vírgula após cada instrução ajuda apenas na primeira fonte de erros.

De qualquer forma, como você pode imaginar, acredito que a inserção automática de ponto-e-vírgula na sintaxe do tipo C seja uma má idéia.

    
por 07.08.2011 / 17:59
fonte
4

Eu declararia um motivo simples:

Javascript parece "meio java-ish" ou "meio C-ish". Claro que é uma linguagem dinâmica, então parece diferente ... mas enfrente - Há chaves. Os idiomas com chaves geralmente têm ponto e vírgula. Os reflexos naturais entram em ação e fazem com que seu dedo vá em direção à tecla de ponto-e-vírgula antes de você pressionar Enter

.

O Python, pelo contrário, mesmo de relance parece totalmente diferente. Portanto, pouca ou nenhuma analogia com as "linguagens chatas padrão" é intuitivamente formada e quando se entra no "modo python", a falta de ponto-e-vírgula é natural.

    
por 07.08.2011 / 20:44
fonte
2

Existem vários bons motivos não para usar a inserção de ponto-e-vírgula em JavaScript.

Principalmente, é porque a inserção de ponto-e-vírgula, conforme definido no padrão ECMAScript, não é intuitiva para alguns casos. @Svante aponta um caso para return onde o uso da nova linha causará problemas.

O que ele não menciona é que ele causará problemas se você estiver usando ponto-e-vírgula também, porque a inserção de ponto e vírgula acontece quer você queira ou não.

Outra razão muito boa não para usar a inserção de ponto-e-vírgula é o controle de saída. Em muitos casos, o JavaScript é executado por meio de um minificador antes de ser usado na produção. Alguns minificadores podem lidar com casos de inserção automática de ponto e vírgula, mas não vejo razão para confiar nele funcionando perfeitamente

Além disso, para sistemas de gerenciamento de conteúdo, JavaScript inline pode ser auto-minificado, e eu vi um número de casos onde o auto-minifier simplesmente remove comentários e apara whitespace (incluindo novas linhas) do início e fim de cada linha.

Para os autores que não têm escolha de quais ferramentas estão sendo escolhidas, é muito mais fácil se ater apenas a um formato que funciona na grande maioria dos casos.

    
por 07.08.2011 / 18:25
fonte
1

Não usar ponto-e-vírgula é uma receita de falha quando você diminui os arquivos JavaScript dos arquivos. É por isso que estou com medo disso.

    
por 07.08.2011 / 18:24
fonte
1

Em Javascript, você pode escrever um programa que seria sintaticamente correto na ausência de inserção automática de ponto e vírgula, e o ASI transformará esse programa em um programa sintaticamente correto diferente (por exemplo, transformando código que retorna um valor no código que não retorna nada). Não existe um caso análogo em Python. No Python, qualquer nova linha que possa encerrar uma instrução terminará uma instrução, a menos que seja escapada com uma barra invertida. Tecnicamente, suponho que as regras do Javascript sejam igualmente deterministas, mas não sei se você poderia resumir as regras do Javascript para finalizar instruções em uma única sentença.

    
por 07.08.2011 / 19:43
fonte
1

Na maioria dos casos, o ASI do JavaScript manipula as coisas conforme o esperado. Um exemplo de ASI talvez não se comportando da maneira que você espera é isso:

var i = 0

(function() {
   // do something
})()

Isso será interpretado como chamando a função 0 com a função anônima e, em seguida, executando o resultado. Nesse caso, você provavelmente desejaria fazer uma atribuição e, em seguida, executar imediatamente a função anônima.

Para alguém que não está familiarizado com o ASI, pode ser muito confuso quando você se deparar com problemas como esse, então eu sempre recomendo que os desenvolvedores da minha equipe usem ponto e vírgula.

(Como um aparte: eu não uso ponto-e-vírgulas ao trabalhar em projetos pessoais / secundários porque sei que ninguém mais precisaria manter o código.)

    
por 07.08.2011 / 20:39
fonte
1

Como você, acho um pouco paranóico. As regras para inserção de ponto-e-vírgula são bem definidas em JavaScript, assim como são em Python e CoffeeScript. Ninguém cria Python ou CoffeeScript com ponto-e-vírgula, então por que o JavaScript é tratado de maneira diferente?

Eu acho que é uma reação exagerada ao estado infeliz do código JavaScript típico de cerca de dez anos atrás - o JavaScript era visto como uma linguagem fraca, cheia de bugs, feia e nada boa. Foi um constrangimento. Você não poderia escrever um bom código em JavaScript!

Então, as pessoas apareceram e tentaram provar que você poderia escrever um código claro e bonito em JavaScript. A regra " sempre usa ponto e vírgula" fazia parte dessa onda. E para ser honesto, isso pode deixar algumas situações um pouco mais claras.

Por que o JavaScript ainda é tratado de forma diferente?

Há inércia. E não deve ser esquecido que pessoas que apreciam código explicitamente estruturado geralmente preferem linguagens no estilo C. As pessoas que apreciam código estruturado implícito geralmente seguem em frente. para linguagens de estilo não-C (como o CoffeeScript).

    
por 07.08.2011 / 20:58
fonte
0

Eu os uso em Javascript estritamente para consistência. Se a maioria das linhas tiver

O Python os tem para casos de borda, como várias instruções em uma única linha, o javascript as possui e, como você as encontrará regularmente, eu estou em conformidade com a norma em que são usadas.

Não consigo encontrar um uso para várias instruções na mesma linha e, portanto, não prevejo o uso de ponto e vírgula.

    
por 07.08.2011 / 15:38
fonte
0

Se você usar algo como o bundle-fu e o gerenciador de ativos para seu aplicativo da web em rails, ele será danificado se não encontrar um ponto-e-vírgula no final do token em javascript. Então é uma boa prática colocar um.

    
por 07.08.2011 / 17:45
fonte
0

Não consigo lembrar qual versão exata do IE, mas há alguns casos em que o IE literalmente errará se um ponto-e-vírgula estiver faltando. IIRC é quando você tem no escopo global algo como:

var myFunc = function() {
  ...
}

Se você não adicionar o; Após a chave de fechamento, o programa falhará em algumas versões do IE. Isso, juntamente com as outras razões (inclusive a recomendação de Crockford de sempre usá-las explicitamente), levou-me a sempre usá-las explicitamente em todos os casos.

    
por 07.08.2011 / 20:51
fonte