Ponto e vírgula opcional

10

Na maioria das vezes, em uma linguagem imperativa de uso geral - ponto-e-vírgula como delimitadores de declaração é necessário ou completamente proibido (por exemplo, C e Python).

No entanto, alguns idiomas, como JavaScript, permitem optar por não delimitar suas instruções com ponto e vírgula, em favor de outros delimitadores (como uma nova linha).

Quais são as decisões de design por trás disso? Entendo que ponto-e-vírgula é essencial ao escrever várias instruções na mesma linha, mas existe outro motivo para torná-las obrigatórias (exceto após C)?

Aber Kled
fonte
1
Você precisa pensar nos terminadores de instruções (perl, c) e delimitadores de instruções (javascript, pascal).
5
No Python, ponto e vírgula pode ser usado para separar várias instruções na mesma linha. E como uma instrução "vazia" é permitida, ponto e vírgula pode ser usado no final da maioria das instruções.
Greg Hewgill
1
I understand that semicolons are essential when writing multiple statements on the same line- Depende do idioma. Meu favorito não tem esses delimitadores, a próxima declaração começa quando todos os argumentos de função foram usados.
Izkata
1
@ MichaelT: Eu não acho que suas classificações estão corretas: Perl provavelmente pertence a ambos os grupos, e o JavaScript está realmente no campo "terminadores de declarações" (já que as implementações são necessárias para inferir um ponto e vírgula antes }ou no final do arquivo).
Ruakh3
Sim, depende absolutamente do idioma. Meu palpite pessoal seria que ponto e vírgula é apenas um tipo de convenção comum, que a maioria dos designers de idiomas segue. Pelo menos faz algum sentido do ponto de vista da linguagem mais natural. Mesmo com {e} para blocos, a propósito: eles são usados ​​por muitos idiomas, no entanto, não por todos, e você realmente não precisa fazer isso. Não existe uma razão universal por trás disso.
JensG

Respostas:

24

Torná-los obrigatórios (ou proibi-los completamente) reduz o número de casos de canto, elimina uma fonte potencial de erros obscuros e simplifica o design do compilador / intérprete.

Os designers de idiomas que optaram por torná-los opcionais optaram por viver com a ambiguidade em troca de maior flexibilidade sintática.

Robert Harvey
fonte
7
@RobertHarvey Heretic! Deve haver uma maneira óbvia de fazê-lo e apenas uma. Aliás, só há uma maneira de fazer isso em perl.
1
Entre - alguns idiomas têm uma boa quantidade de redundância nas gramáticas em geral, portanto, tornar o ponto-e-vírgula opcional é apenas ocasionalmente ambíguo na prática. Dito isto, acho que o ponto-e-vírgula é a parte errada de redundância a ser descartada - gosto bastante de Haskell, onde você solta as parênteses e vírgulas para argumentos. OK, você também pode soltar o ponto-e-vírgula no Haskell, mas não é realmente a mesma coisa que o Javascript.
Steve314
2
O problema do IIRC é que eles não se encaixam no modelo formal, mas que os geradores de analisadores não produzem boas mensagens de erro. Ou seja, eles têm conhecimento limitado de erros comuns, enquanto o analisador escrito à mão pode receber uma mensagem de erro muito mais útil. O Gcc, por exemplo, costumava usar o bisonte para a gramática C. Da mesma forma, o problema é que os "casos extremos" não são casos extremos formais, mas simples - ou seja, para o analisador, o AST é claro e, para humanos, o AST "é claro", mas eles não concordam como é o AST.
Maciej Piechotka
2
@Maciej Piechotka - Eu não quis dizer que as parênteses eram opcionais em Haskell. Estou falando de deixar cair algo redundante como uma decisão de design de linguagem. O ponto é que você não usa parênteses ou vírgulas para uma chamada de função em Haskell. Você pode passar uma tupla como argumento, mas ainda é a sintaxe para uma tupla, não para passar argumentos. Haskell (e ML e outros) "eliminaram" as parênteses e vírgulas dos argumentos das funções no sentido de que existe essa convenção comum em outras línguas (desde Algol?), Mas Haskell não faz isso.
Steve314
1
@Maciej Piechotka - É claro que nunca foi realmente uma convenção universal - só porque as línguas da família Algol o fazem não significa que outras línguas se definam em relação a isso, então minha alegação "descartada" está errada nesse sentido - mas com todos nos idiomas da família C atualmente, parece um pouco com isso.
Steve314
15

JavaScript nos mostrou que esta é uma péssima idéia. Por exemplo:

return
0;

Em C, isso retorna um valor 0. No JavaScript, isso retorna undefinedporque um ponto-e-vírgula é inserido após a declaração de retorno, e não é imediatamente óbvio o motivo pelo qual o código está sendo quebrado, a menos que você saiba sobre os detalhes da inserção automática de ponto e vírgula.

Mason Wheeler
fonte
1
@ delnan: Python não foi projetado para se parecer com C. É conhecido por ser baseado em indentação e, portanto, altamente orientado a linhas, e não requer ponto e vírgula. JavaScript tecnicamente faz obrigá-los; está inserindo um quando encontra um ausente, o que transforma o que parece ser uma declaração sintaticamente válida em duas declarações distintas com semântica completamente diferente.
Mason Wheeler
7
Não é uma má idéia, é apenas confuso para as pessoas que tentam usar JavaScript sem se preocupar em aprender sobre a inserção automática de ponto e vírgula . Talvez, em vez de dizer "essa é uma péssima idéia", você possa dizer com mais precisão "tornar o ponto e vírgula opcional introduz armadilhas para programadores que não saem e aprendem todos os detalhes".
214133 #
4
@ delnan: A razão pela qual é surpreendente é que o JavaScript geralmente não insere um ponto e vírgula no final de uma linha, exceto para corrigir um programa inválido. After returné um dos poucos casos em que o JavaScript insere um ponto e vírgula, mesmo que o programa seja válido sem ele. (Mas, claro, isso compromete o ponto de Mason Wheeler O problema não é que as vírgulas são opcionais, é que as regras são inconsistentes..)
ruach
6
@TehShrike: Tornar o ponto e vírgula opcional apresenta armadilhas para todos os programadores, porque interpreta arbitrariamente erros de digitação em vez de perguntar o que você quis dizer. Todo mundo faz um erro de digitação de vez em quando.
Jan Hudec
1
O javascript mostrou que sua implementação de ponto e vírgula opcional é falha. Não mostra que ponto e vírgula opcional é ruim por si só.
precisa saber é o seguinte
4

Simplifica um pouco a gramática e o analisador para tornar os pontos e vírgulas obrigatórios. Essencialmente, ele permite ao lexer despejar todo o espaço em branco, incluindo novas linhas, e o analisador não precisa se preocupar com isso.

Por outro lado, quando você começa a querer contar ao analisador sobre espaço em branco de qualquer maneira, não é tão difícil tornar os pontos e vírgulas opcionais. Geralmente, você pode agrupá-los com um whitespacetoken e seu analisador pode lidar com isso muito bem.

Por exemplo, tente inserir o ponto-e-vírgula na seguinte série de instruções C.

functionCall(3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

Embora existam algumas coisas estranhas que você não possa mais fazer, como while(1);na maioria das vezes, é relativamente fácil com as técnicas modernas de análise determinar onde as instruções terminam sem um delimitador específico. Mesmo se você ainda deseja permitir coisas estranhas, não é tão difícil criar um newline_or_semicolonterminal.

Karl Bielefeldt
fonte
Quando o C foi desenvolvido originalmente no início dos anos 70, eram necessários terminadores de instruções para simplificar os compiladores. Em meados dos anos 90, quando o Javascript foi desenvolvido, isso era menos preocupante.
9788 Sean McSomething #
3

Os pontos e vírgulas são úteis na gramática por 2 razões. Primeiro, ele permite que você divida longas declarações em várias linhas sem ter caracteres de continuação legais (estou falando de você, Fortran e Basic). Segundo, vamos permitir que o analisador "desista" da análise quando a sintaxe fica realmente complicada devido a um erro de digitação. Roubando do exemplo de Karl Bielefeldt,

functionCall(3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

imagine que você digitou um parêntese extra aberto:

functionCall((3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

agora onde está o erro? Se você tivesse o ponto e vírgula, é mais fácil para o analisador desistir no primeiro ponto e vírgula. Poderia até continuar analisando após o ponto e vírgula, se quisesse.

functionCall((3, 4);  <- something is wrong here. emit error and keep going.
                      9 + (3 / 8); variable++; while(1) { printf("Hello, world\n"); }

Agora é mais fácil no analisador relatar um erro e mais fácil localizar a linha / coluna onde ocorreu.

Mark Lakata
fonte
1
Fortran e Basic pelo menos escolheram decentemente marcadores de continuação de linha (& e _, respectivamente). . Por pura "" OMG, o que eles estavam pensando", nada bate FoxPro Para continuar uma linha, você usou um ponto e vírgula.
DougM
2

Ponto-e-vírgula nem sempre é tudo ou nada como você mencionou na sua pergunta. Por exemplo, a gramática de Lua é cuidadosamente projetada para ser de forma livre (todos os espaços em branco, incluindo novas linhas, podem ser ignorados), mas também sem a necessidade de usar ponto e vírgula. Por exemplo, os seguintes programas são equivalentes:

--One statement per line
x = 1
y = 2

--Multiple statements per line
x = 1 y = 2

--You can add semicolons if you want but its just for clarity:
x = 1; y = 2
hugomg
fonte
0

Tirando todo o design e construção, acredito que muitos programadores vêm de diferentes origens e alguns aprenderam a usar o ponto-e-vírgula e outros não. Muitos idiomas mais novos que estão surgindo não exigem ponto e vírgula, mas ainda permitem que ele exista. Eu acho que pode ser apenas uma maneira de conseguir que mais programadores aprendam a codificar nessas novas linguagens sem ter que abandonar seus hábitos a partir de quando começaram.

HeadphoneHaxZ
fonte