A sintaxe das linguagens de programação depende de sua implementação?

12

Embora, minha pergunta possa ser totalmente irrelevante, mas senti um padrão entre a maioria das linguagens de programação e suas implementações oficiais.

Linguagens interpretadas ( interpretadas por byte?) Como Python, Lua etc. geralmente têm uma sintaxe extremamente branda e fácil e geralmente são sem tipo ou não exigem que o desenvolvedor escreva explicitamente tipos de variáveis ​​no código-fonte;

Linguagens compiladas como C, C ++, Pascal etc. geralmente têm uma sintaxe estrita, geralmente têm tipos e geralmente requerem mais tempo de código / desenvolvimento

Os idiomas cujas implementações oficiais são compiladas por JIT, como Java / C #, geralmente são um compromisso exclusivo entre os dois acima com alguns dos melhores recursos de ambos.

Algumas das linguagens de programação compiladas mais modernas, como D e Vala (e a implementação do GNU GJC em Java), talvez sejam uma exceção a essa regra e se assemelham à sintaxe e aos recursos das linguagens compiladas por JIT, como Java e C #.

Minha primeira pergunta é: isso é realmente relevante? Ou é apenas uma coincidência que a maioria das linguagens interpretadas possua sintaxe fácil, as linguagens compiladas pelo JIT possuam sintaxe e recursos moderados, etc.

Em segundo lugar, se isso não é uma coincidência, então por que é assim? Por exemplo, alguns recursos podem ser implementados apenas em uma linguagem de programação se você estiver, por exemplo, compilando com JIT?

ApprenticeHacker
fonte
@YannisRizos desculpe, não é uma citação. Eu só queria destacar isso. Eu vou editar.
ApprenticeHacker
1
Legal, pensei que não fosse uma citação, mas poderia levar os atendentes a pensar que era uma e não tentar refutá-la (ou concordar cegamente com ela) ... notei padrões semelhantes, mas infelizmente não temos uma boa resposta. responda.
yannis
@ R.MartinhoFernandes desculpe, eu não estava ciente disso. Vou editá-lo (novamente).
ApprenticeHacker
4
Perl é digitado dinamicamente para tipos definidos pelo usuário, estaticamente em relação a matrizes, hashes, escalares e sub-rotinas distintas, e fortemente digitado por meio de uso estrito, interpretado e compilado por JIT (não ao mesmo tempo, é claro) ... Sempre que alguém tenta para dar sentido a design de linguagem, jogando em alguns Perl é sempre divertido ...
yannis
3
O que você quer dizer com "sintaxe branda" vs. "sintaxe estrita"? Todas são linguagens formais e nenhuma executará o código-fonte com erros de sintaxe.
Nikie

Respostas:

17

Não há nenhuma conexão entre semântica e sintaxe. Linguagens compiladas homoicônicas como Scheme vêm com uma sintaxe bastante minimalista. Meta-linguagens compiladas de baixo nível como Forth são ainda mais simples que isso. Algumas linguagens compiladas muito estritamente tipificadas são construídas sobre uma sintaxe trivial (pense em ML, Haskell). OTOH, a sintaxe do Python é muito pesada, em termos de várias regras de sintaxe.

E sim, a digitação não tem nada a ver com sintaxe, está no lado semântico de uma linguagem, a menos que seja algo tão pervertido quanto o C ++, onde você não pode nem analisar sem ter todas as informações de digitação disponíveis.

Uma tendência geral é que linguagens que evoluíram por muito tempo e não continham nenhuma proteção de design contra desvios de sintaxe, mais cedo ou mais tarde, evoluiram para abominações sintáticas.

SK-logic
fonte
+1 por me fazer olhar para cima "homoiconic" ... E para o aceno sutil para PHP ...
yannis
1
+1, idiomas que evoluíram por muito tempo e não continham nenhuma proteção de design , isso também se refere ao Delphi / Object-Pascal?
ApprenticeHacker
1
@ThomasEding, você está errado. A mesma semântica pode ser implementada sobre uma ampla variedade de estilos de sintaxe, mesmo com uma linguagem sem sintaxe (como Lisp ou Forth). A mesma sintaxe pode ser usada com uma grande variedade de semânticas diferentes - por exemplo, a sintaxe das expressões C e Verilog é quase a mesma, mas a semântica é dramaticamente diferente.
SK-logic
1
@ SK-logic - Só porque é complexo e o Turing-complete não significa que não seja pelo menos uma parte muito grande da sintaxe do programa. A análise de várias linguagens é Turing-complete, que não faz com que a análise seja algo que "não tem nada a ver com sintaxe". A sintaxe não é sobre "escopo", é sobre regras para a estrutura de instruções em uma linguagem - sem dizer nada sobre o que essas declarações significam. A verificação de tipos e a inferência de tipos operam em árvores de sintaxe de programas sem executá-los - eles determinam as coisas sobre a estrutura do programa sem dizer nada sobre ... #
Jack
1
@ Jack, você está tentando redefinir o que é sintaxe. Não há linguagens práticas que precisam de um analisador de Turing-completo, a maioria nada mais é do que livre de contexto. E é aqui que a sintaxe deve permanecer. Por favor, não estenda essa noção (já muito esticada) em nenhum outro lugar. E eu já mencionei o isomorfismo de Curry-Howard - é tudo sobre semântica, muito além das meras regras de correção. Penso que o próprio termo " type checking" é extremamente contraproducente e não deve ser usado, é muito enganador, não reflete a natureza dos sistemas de tipos.
SK-logic
6

Principalmente isso é uma coincidência.

As linguagens de programação evoluíram com o tempo e a tecnologia de compiladores e intérpretes melhorou. A eficiência do processamento subjacente (ou seja, o tempo de compilação, a sobrecarga de interpretação, o tempo de execução etc.) também é menos importante, pois as plataformas de computação convencionais cresceram em força.

A sintaxe da linguagem faz ter um impacto - por exemplo, Pascal foi cuidadosamente projetado para que ele pudesse usar um único compilador passagem - ou seja, passar um sobre a fonte e você tem o código de máquina excutable. Ada, por outro lado, não deu atenção a isso, e os compiladores Ada são notoriamente difíceis de escrever - a maioria exige mais de uma passagem. (Um compilador Ada muito bom que eu usei há muitos anos foi um compilador de 8 passagens. Como você pode imaginar, era muito lento.)

Se você olhar para idiomas antigos como Fortran (compilado) e BASIC (interpretado ou compilado), eles têm / tinham regras muito rígidas de sintaxe e semântica. [No caso do BASIC, isso não é o faturamento do BASIC antigo, você precisa voltar antes do original.]

Por outro lado, olhando para outras coisas mais antigas, como APL (um monte de diversão), isso teve digitação dinâmica. Também foi geralmente interpretado, mas também pode ser compilado.

A sintaxe indulgente é difícil - se isso significa que você tem coisas opcionais ou que podem ser deduzidas, significa que o idioma possui riqueza suficiente para ser descartado. Por outro lado, a BASIC tinha isso há muitos anos, quando a declaração "LET" se tornou opcional!

Muitas das idéias que você vê agora (por exemplo, datilografia ou digitação dinâmica) são realmente muito antigas - aparecendo pela primeira vez nos anos 70 ou no início dos anos 80. A maneira como são usadas e os idiomas em que essas idéias são usadas mudaram e cresceram. Mas, fundamentalmente, muito do que há de novo é realmente coisas velhas, vestidas com roupas novas.

Aqui estão alguns exemplos em cima da minha cabeça:

  • APL: digitação dinâmica. Geralmente interpretado. Veio da década de 1960/70.
  • BÁSICO: digitação forte ou dinâmica. Interpretado ou compilado. 1970 e muitos outros.
  • Fortran: digitação forte. Compilado. 1960 ou anterior.
  • Algol68: digitação forte. Compilado. 1960's.
  • PL / 1: digitação forte. Compilado. 1960's.
  • Pascal: digitação forte. Compilado. 1970's. (Mas na década de 1980 havia compiladores P-System muito parecidos com os compiladores JIT!)
  • Algumas implementações do Fortran e outras do DEC nos primeiros dias foram parcialmente compiladas e parcialmente interpretadas.
  • Smalltalk: digitação dinâmica. Compilado no bytecode que é interpretado. Anos 80.
  • Prolog: mais estranheza. Funcional. Compilado (Turbo Prolog, alguém?). Anos 80.
  • C: digitação forte (ha ha). Compilado. 1960. hoje.
  • Ada: digitação super forte. Compilado. Anos 80.
  • Perl: digitação dinâmica. (Sintaxe forte). Interpretado. Anos 90 (?).

Eu poderia continuar.

  • Nitpickers corner: Muitos idiomas interpretados são tokenizados ou "compilados em bytes" no momento em que a fonte é carregada / lida. Isso simplifica muito a operação subseqüente do intérprete. Às vezes, você pode salvar a versão compilada em bytes do código. Às vezes você não pode. Ainda é interpretado.

Atualização: porque eu não estava suficientemente claro.

A digitação pode variar bastante.

A digitação estática fixa em tempo de compilação é comum (por exemplo, C, Ada, C ++, Fortan, etc etc). É aqui que você declara COISA de TIPO e é assim para sempre.

Também é possível ter uma digitação dinâmica, onde a coisa escolhe o tipo que está atribuído a ela. Por exemplo, PHP e alguns BASIC e APL antigos, nos quais você atribuiria um número inteiro a uma variável e, a partir de então, era um tipo inteiro. Se você posteriormente atribuiu uma string a ela, era um tipo de string. E assim por diante.

E há digitação livre, por exemplo, PHP, onde você pode fazer coisas realmente bizarras, como atribuir um número inteiro numérico (entre aspas, portanto é uma string) a uma variável e depois adicionar um número a ela. (por exemplo, '5' + 5 resultaria em 10). Esta é a terra dos bizarros, mas também às vezes muito, muito útil.

No entanto, esses são recursos projetados em um idioma. A implementação apenas faz isso acontecer.

rapid_now
fonte
13
A digitação forte não é a contrapartida da digitação dinâmica. É a contrapartida da digitação fraca. A contrapartida da digitação dinâmica é a estática: em um, os tipos de expressões em um programa podem ser conhecidos estaticamente (ou seja, sem executar o programa); em outro, os tipos só podem ser conhecidos dinamicamente (ou seja, o programa deve ser executado).
R. Martinho Fernandes
Sim, e ambas as variantes do BASIC e APL estavam fazendo isso no final dos anos 70. Os tipos de APL não são exatamente como os entendemos hoje (são coisas como número inteiro / flutuação universalmente tipados, mas também podem ser vetores, seqüências de caracteres e matrizes multidimensionais).
quickly_now
Um intérprete de Fortran ainda é amplamente utilizado (consulte Cernlib e PAW). E seu descendente, ROOT, é construído sobre um intérprete de C ++.
SK-logic
Não estou totalmente claro como a digitação forte / fraca e estática / dinâmica está relacionada à sintaxe, para ser sincero. Mas a qualidade da resposta foi muito boa, então estou apenas evitando a votação. Classificaria a classe C digitando como "estático / fraco" (é trivial olhar para um valor armazenado como se fosse outro tipo, possivelmente entendendo errado).
Vatine
@Vatine - na verdade, eu diria forte em tempo de compilação, inexistente em tempo de execução - se você quiser dessa maneira. Você pode fazer isso usando ponteiros e seus equivalentes em vários idiomas. É até possível no pascal clássico usando registros variantes e no Ada usando UNCHECKED_CONVERSION (embora difícil, é possível).
quickly_now
2

Eu acho que é o contrário: a implementação depende da sintaxe. Por exemplo, se sua sintaxe permitir reflexão, a implementação deverá fornecer um tempo de execução que suporte isso.

StackedCrooked
fonte
@IntermediateHacker: mas está em java, então eu deveria ser incrível
veja se
2

Eu geralmente concordo com o quick_now, pois sua observação é principalmente resultado da história. Dito isto, o raciocínio subjacente se resume a algo como isto:

The more modern a language is, the more comfortable it should be to use.

(Na verdade, não é uma citação, é apenas minha própria formulação.) Quando escrevo comfortableaqui, refiro-me ao que você chamou best features of both. Mais precisamente, não quero falar a favor ou contra a digitação estática / dinâmica ou a sintaxe estrita / branda. Em vez disso, é importante observar o foco nos desenvolvedores e aumentar seu nível de conforto ao trabalhar com o idioma.

Aqui estão alguns motivos que não foram mencionados nas respostas anteriores, que podem fornecer algumas idéias para você observar essas coisas (e são todos baseados no histórico de programação de desenvolvimento de linguagem):

  • Atualmente, temos centenas de linguagens de programação. Quando um novo surge, como ele pode encontrar um público amplo? Esta é a principal razão pela qual novas linguagens sempre tentam aumentar o nível de conforto dos desenvolvedores. Se o idioma pode fazer o mesmo que o anterior, mas pode ser muito mais fácil / mais simples / mais elegante / etc. você pode considerar realmente mudar.

  • A curva de aprendizado anda de mãos dadas com isso. No passado, tínhamos poucos idiomas e investir tempo para aprender um valia a pena. Mesmo que isso significasse investir muito tempo. O conforto aumenta novamente, se você criar uma linguagem que os desenvolvedores possam aprender muito rapidamente. Qualquer tipo de complexidade (por exemplo, sintaxe envolvida e complicada) é prejudicial para isso e, portanto, é cada vez mais reduzido em idiomas mais novos.

  • Os avanços tecnológicos (uma razão histórica direta aqui) são responsáveis ​​por que os construtores de compiladores agora possam colocar mais foco no conforto do desenvolvedor. Nos primeiros dias, ficamos felizes em poder construir um compilador. No entanto, isso geralmente implicava restrições pesadas. À medida que o conhecimento tecnológico aumentou, fomos capazes de levantar essas restrições novamente.

Portanto, em geral, linguagens de programação e compiladores tiveram um desenvolvimento semelhante ao de aplicativos típicos de usuário final:

  1. Fase inicial: É uma coisa legal de se ter, mas a tecnologia de ponta quase não faz com que ela funcione à custa de conforto / usabilidade / o que não.
  2. Melhoria tecnológica: podemos construir essas coisas de maneira mais robusta, rápida e fácil.
  3. O foco se volta para o usuário: Da mesma forma que o movimento Web2.0, focado na experiência do usuário, as novas linguagens de programação se concentram na perspectiva do desenvolvedor.
Frank
fonte
(Not a quote really, just my own formulation.)Bem, você formatado-lo como código, não como um blockquote, então eu não acho que alguém pensou que era uma citação :)
yannis
3
O conforto depende claramente de um gosto (que é sempre inteiramente subjetivo). A linguagem com a qual me sinto mais confortável foi projetada em 1959 e não suporto lidar com algumas das línguas que apareceram neste século.
SK-logic
1
O conforto também depende do propósito. A execução de PHP ou Prolog em um micro incorporado de 8k para um controlador de máquina de lavar pode ser "confortável" para programar, mas também é realmente difícil de ajustar e executar com desempenho aceitável.
quickly_now
0

Uma determinada linguagem de programação pode ou não expor ou restringir informações semânticas suficientes para um compilador deduzir como reduzi-la ao código executável sem decisões adicionais de tempo de execução ("que tipo é essa variável?" Etc.). Algumas linguagens são projetadas explicitamente para criar essa restrição é obrigatória ou fácil de determinar.

À medida que os compiladores ficam mais inteligentes, eles podem adivinhar ou criar um perfil de informações suficientes para gerar código executável para o (s) caminho (s) mais provável (s), mesmo para idiomas que não foram projetados explicitamente para expor ou restringir essas decisões.

Entretanto, idiomas nos quais o código (evalString ()) pode ser criado ou inserido no tempo de execução (e outras coisas que o compilador não pode deduzir ou adivinhar) podem exigir que um intérprete ou compilador JIT esteja disponível no tempo de execução, mesmo com tentativas de pré- compile-os.

No passado, uma linguagem de programação e sua implementação poderiam ter evoluído para atender a algumas restrições de hardware, como se o intérprete poderia caber em 4k ou 16k ou se o compilador poderia terminar em menos de um minuto de tempo da CPU. À medida que as máquinas ficam mais rápidas, tornou-se possível (re) compilar alguns programas anteriormente interpretados o mais rápido que o programador pode pressionar a tecla de retorno ou interpretar o código-fonte do programa compilado anteriormente mais rapidamente do que um hardware um pouco mais antigo poderia executar executáveis ​​compilados otimizados.

hotpaw2
fonte