A que especificamente se refere o poder expressivo?


34

Poder expressivo é definido pela Wikipedia como:

.. a amplitude de idéias que podem ser representadas e comunicadas nesse idioma.

"Idéias" se referem às coisas (operações, estruturas, algoritmos, etc.?) Que podemos comunicar à máquina ? Ou refere-se aos conceitos "humanos" que podem ser capturados e comunicados com a linguagem a outros humanos?

Como o poder expressivo é avaliado e medido?

Por exemplo, se adotássemos uma linguagem como JavaScript e impuséssemos uma restrição estranha nos nomes de variáveis, como variável/^_[0-9]{8}$/ , esse número deveria ser um número de 8 dígitos, precedido por um sublinhado, correspondente , perderíamos poder expressivo?

Ou isso seria apenas absurdo e irritante?


Esclarecer:

O poder expressivo é medido pelas idéias gerais inerentes à linguagem:

  • números inteiros e seqüências de caracteres
  • rotações
  • condicionais

Ou o número de idéias específicas e únicas que o idioma pode representar:

  • os inteiros 1, 2 ... 2 ^ 32
  • strings contendo "o que a raposa diz?" e "o que pah pah pah pah pah pow"
  • para cada sapo na minha coleção de sapos
  • se sapo é verde ou algo assim, faça algo

3
Deve-se notar que limitar um programa a no máximo 100 milhões de variáveis ​​em um determinado escopo impõe algum limite à expressividade. Pode tornar impossível implementar o Firefox, por exemplo. ;-)
R. ..

11
Observe que, embora você tenha marcado essas "linguagens de programação", os idiomas de programação não são o único tipo de linguagem de computador cujo poder expressivo pode ser discutido. De fato, a página à qual você vincula tem o Web Ontology Language como seu primeiro exemplo.
Jon Hanna

Respostas:


39

O artigo de referência sobre expressividade é Sobre o poder expressivo das linguagens de programação de Matthias Felleisen (1991) . Ele contém uma definição matematicamente rigorosa de expressividade da linguagem.

Intuitivamente, se todo programa que pode ser escrito no idioma A também puder ser escrito no idioma B com apenas transformações locais, mas existem alguns programas escritos no idioma B que não podem ser escritos no idioma A sem alterar sua estrutura global (ou seja, não apenas com puramente transformações locais), então a linguagem B é mais expressiva do que a linguagem A .

Uma boa propriedade dessa definição é que ela admite a possibilidade de que existem pares de idiomas em que existem programas em X que não podem ser expressos em Y e programas em Y que não podem ser expressos em X e, portanto, os idiomas são distintos, mas nenhum a linguagem é mais expressiva que a outra. Isso se encaixa bem com a nossa experiência no mundo real de que existem algumas línguas que são boas em algumas coisas e outras que são boas em outras coisas, e nem geralmente é "melhor" que o outro.


Então, (ainda não tendo analisado o artigo), expressividade é sobre o que você pode expressar para a máquina, em oposição aos leitores da fonte? É uma medida do que você pode instruir o hardware a fazer? Não é uma medida de quantas idéias "humanas" você pode preservar ou comunicar em código? ... Talvez eu precise fazer outra pergunta; mas, se for esse o caso, como isso difere da "funcionalidade" de que falamos também?
svidgen

Talvez meu exemplo no OP seja ruim. Considere os idiomas A e B, ambos com matrizes; mas, a linguagem A também possui estruturas. Em qualquer idioma, eu posso representar uma série de Points usando uma matriz de matrizes 2D. Porém, A tem a vantagem de me deixar expressar a Pointcomo um conceito mais legível por humanos. A é mais expressivo?
svidgen

@svidgen Como todas as linguagens completas de Turing são equivalentes computacionalmente, o conjunto de programas possíveis que podem ser escritos é teoricamente o mesmo para todos eles. Pela definição acima, a linguagem B é mais expressiva que A se um programa escrito em B precisar ser reorganizado para se encaixar em A. (Não apenas alterando a sintaxe linha por linha, mas introduzindo novas classes, loops etc.) Pense em reescrever um Python programa em Java 7 que usa lambdas, map, filter, primeira classe tipos / métodos / funções, talvez um pouco eval, deixe a magia sozinho metaclass ou tipos criados dinamicamente etc.
marczellm

@marczellm então, as "idéias" às quais a expressividade se refere são a própria linguagem que se constrói? Por exemplo, um condicional é uma ideia? Um loop é uma ideia? Uma linha? Número? Etc.?
precisa saber é o seguinte

11
@ Jörg Você pode dar um exemplo na sua resposta? É uma definição atraente, mas realmente não faz muito para responder à pergunta.
svidgen

10

Poder expressivo é definido pela Wikipedia como:

Vamos reler essa página. Uma das primeiras coisas a se notar é que diz "linguagem", não "linguagem de programação", e a maioria de seus exemplos não são linguagens de programação, por exemplo, o primeiro exemplo dado é uma comparação de OWL2 EL e OWL2 RL, que são ontologia línguas.

Pode-se aplicar o conceito às linguagens de programação, mas também aos idiomas de correspondência de padrões, linguagens de marcação, linguagens de consulta, idiomas da folha de estilo visual, expressões regulares (e todas as linguagens regulares a que se referem) e assim por diante. Pode-se até se referir ao poder expressivo de idiomas naturais como o inglês, que geralmente é feito de maneira informal, mas com mais seriedade ao considerar os problemas relacionados ao processamento de idiomas naturais.

"Idéias" se referem às coisas (operações, estruturas, algoritmos, etc.?) Que podemos comunicar à máquina? Ou refere-se aos conceitos "humanos" que podem ser capturados e comunicados com a linguagem a outros humanos?

Refere-se ao que pode ser expresso nessa linguagem, considerado puramente uma coisa em si.

Por exemplo, (usarei o javascript em todos os meus exemplos, porque sua pergunta indica que é um dos idiomas que você conhece) considere a instrução javascript:

var x = 3 + 4;

Isso representa que a soma dos valores 3 e 4 é calculada e o valor associado a um rótulo xdentro de um determinado escopo de espaço para nome.

Se destruíssemos todos os computadores do mundo e escrevêssemos esse código em um pedaço de papel, continuaria sendo que, em javascript, ele ainda teria o mesmo significado; não poderíamos executar esse código em nada, mas a definição abstrata da linguagem ainda é algo que poderíamos falar.

Isso pode parecer pedante, mas é realmente muito importante que as línguas sejam coisas que possam ser discutidas em abstrato sem considerar computadores reais. Por um lado, as pessoas que raciocinam sobre pontos teóricos das linguagens de computador que ainda não eram viáveis ​​na prática são uma das coisas que nos levaram aonde estamos hoje; os computadores precisam de ciência da computação, mas a ciência da computação não precisa de computadores, apenas a idéia de uma computação.

Obviamente, usamos computadores no mundo real e hoje em dia muitas pessoas os usam na prática, em vez de alguns especialistas discutindo-os em teoria. A página à qual você vinculou diz:

O termo poder expressivo pode ser usado com uma gama de significados. Pode significar uma medida das idéias expressáveis ​​nesse idioma:

  • independentemente da facilidade (expressividade teórica)

  • concisa e prontamente (expressividade prática)

O primeiro sentido domina em áreas da matemática e da lógica que lidam com a descrição formal das línguas e seu significado, como teoria da linguagem formal, lógica matemática e álgebra de processos.

Nas discussões informais, o termo geralmente se refere ao segundo sentido, ou a ambos. Esse é geralmente o caso ao discutir linguagens de programação. Foram feitos esforços para formalizar esses usos informais do termo

Desses dois usos do termo, o impacto prático do primeiro diz respeito apenas ao que pode ser transmitido ao computador.

O segundo refere-se mais à compreensão humana tanto na leitura quanto na escrita, embora o grau em que faz isso difira muito entre os usos, uma vez que são informais e, como tal, não são rigidamente definidos.

Por exemplo, se adotássemos uma linguagem como JavaScript e impuséssemos uma restrição estranha nos nomes de variáveis, como variável, seria um número de 8 dígitos precedido por um sublinhado, correspondente /^_[0-9]{8}$/, perderíamos poder expressivo?

Pela definição formal, não perdemos poder expressivo: estamos restritos a 100.000.000 de variáveis, mas se realmente precisássemos contornar isso, criando objetos para armazenar mais variáveis ​​dentro do namespace recém-criado. Como tal, qualquer programa escrito em javascript hoje pode ser reescrito nesta nova forma, sendo igualmente expressivo.

Pela definição informal, perdemos um pouco, mas o quanto depende de quão informal estamos sendo, o que variará porque, novamente, você não pode dizer qual é "a regra" sobre o uso informal. Podemos dizer que perdemos uma pequena quantia, porque programas com mais de 100.000.000 de variáveis ​​no mesmo espaço para nome precisam ser reescritos além de uma simples substituição. Um uso ainda mais informal novamente se referiria ao impacto mental de nomes tão desajeitadamente variáveis ​​sobre a abrangência humana.

Também vale a pena notar que as pessoas considerarão informalmente coisas que não fazem parte estritamente da linguagem. Considere as alterações no Javascript desde a sua criação até hoje.

Pela definição mais formal, houve expressividade bastante inalterada; afinal, Turing estava completo.

Por uma definição mais informal, tornou-se consideravelmente mais expressivo em certas coisas, como manipulação de array, manipulação de exceções e (talvez acima de tudo) na inclusão de expressões regulares. Eles não fazem nada que não pudesse ser feito em javascript antes, embora possam fazer algo em poucas linhas e um tempo de execução de subsegundos que levaria kilobytes de código para escrever em javascript1.0 e demoraria muito tempo para ser executado.

Por uma definição muito mais informal novamente, a alteração do primeiro uso do javascript nos navegadores (capaz de alterar os valores das entradas do formulário, document.writeenquanto a página está sendo analisada pela primeira vez e movida para um novo local ou para voltar ou avançar na história, mas bastante muito mais nada hoje em dia (capaz de mudar praticamente qualquer coisa na página, inclusive com base nos dados das chamadas do servidor) é absolutamente imenso, embora a maioria não esteja relacionada ao javascript, mas aos modelos de objetos e APIs criados disponível, em vez do idioma (por exemplo, o vbscript no IE se beneficiou dessas alterações igualmente).

Na minha opinião, esse último uso é tão informal que não está realmente correto, mas esse é o problema das definições informais.

Pela definição formal, realmente não se tornou mais expressivo.


2
"computadores precisam de ciência da computação, mas a ciência da computação não precisa de computadores" Eu gosto disso
chbaker0

Em relação à restrição de nomeação de variáveis, a capacidade de se referir a idéias externas (nomes de idiomas nativos para coisas) não está relacionada à capacidade do idioma de representar idéias? ... Talvez mais à raiz da pergunta: as idéias sobre as quais estamos falando expressam apenas as construções gerais da linguagem? Por exemplo, adição, subtração, negação, matrizes, classes, etc.? Ao contrário das idéias particulares que podemos expressar com a linguagem? Por exemplo, matriz chamada fishiesdo tipoFish .
Svidgen

Você pode ver minha edição para mais esclarecimentos. ... Parece que você está dizendo que é ambos (referindo-se à minha edição); mas que a primeira lista é "formal" e a segunda lista é "informal". Se for esse o caso, existe uma norma sobre como ela é usada sem ressalvas na conversa? Ou ... você apenas pede esclarecimentos?
Svidgen

4

Eu não acho que as regras de nomeação de variáveis ​​realmente capturam o que se entende por "expressividade". Eu acho que "expressividade" se refere a coisas mais fundamentais. Considere C # com Linq versus C # antes de Linq, por exemplo. Após a adição do Linq, tornou-se possível escrever consultas semelhantes a SQL diretamente no C #. Isso é muito mais elegante do que as alternativas anteriores, por exemplo, colocar SQL em literais de string e depois passá-lo para o servidor ou iterar sobre uma coleção usando "for".

Outro bom exemplo pode ser a linguagem com herança baseada em protótipo. Nessas linguagens, é possível simplesmente adicionar novos métodos a uma instância ou mesmo a uma classe (por qualquer nome que uma "classe" possa ter em um determinado idioma ...) em tempo de execução. Você realmente não pode fazer isso em C ++ ou C #. Eles não têm esse grau de expressividade em comparação com as linguagens baseadas em protótipos. (O C # tem o conceito de métodos de extensão, e certamente se pode dizer que estes acrescentam expressividade.)


0

Conforme mencionado no artigo da Wikipedia, poder expressivo refere-se ao conjunto de programas que podem ser expressos no idioma. Tudo o que você considera uma "linguagem de programação" (JavaScript, LISP, C #, Perl etc.) é essencialmente Turing completo, o que significa que eles podem expressar qualquer coisa que se diga "computável".

No entanto, deve ficar bem claro que expressões regulares não são tão expressivas quanto a linguagem de programação regular. Além disso, os curingas de shell são um pouco menos expressivos que as expressões regulares.

Uma versão do SQL com expressões de tabela comuns é mais expressiva do que uma versão sem, porque os CTEs permitem representar consultas recursivas que, de outra forma, seriam impossíveis de serem expressas no SQL.


0

Existe uma maneira mais simples e direta de entender o poder expressivo, mas primeiro precisamos estabelecer o que entendemos por idiomas. Existem duas disciplinas que estudam idiomas: lingüística e autômato. Ambos concordariam que a linguagem é um conjunto de palavras (seqüências finitas) construídas a partir de algum alfabeto finito usando concatenação. Tipicamente, linguagens interessantes (por interessante, quero dizer aquelas linguagens que podemos interpretar de uma maneira útil) também têm um conjunto de regras que governam quais palavras estão na linguagem e quais não. Observe que a expressividade só pode existir quando houver interpretação.

Por interpretação, quero dizer a existência de uma função que, dada uma palavra em uma linguagem, seleciona um objeto de algum conjunto de objetos (isso é obviamente discutível para linguagens naturais).

Não se deixe enganar pelo uso de "palavra". Um programa Java é uma palavra na linguagem Java (embora possa abranger vários arquivos contendo várias cadeias de caracteres separadas por espaços).

Seria contraproducente usar linguagens complicadas como as linguagens de programação modernas para lidar com esse conceito relativamente simples; é por isso que prefiro usar fórmulas matemáticas.

  • Vamos definir o idioma A para todas as fórmulas que envolvem adição de número inteiro.

  • Vamos definir o idioma B como o idioma de todas as fórmulas envolvendo multiplicação de números inteiros.

Nos dois casos, proibimos o uso do elemento de identidade. Assim, o idioma A contém as palavras "1 + 1", "1 + 2", "1 + 3", "2 + 3" e assim por diante. O idioma B contém as palavras "2 * 2", "2 * 3", "2 * 4", "3 * 4" e assim por diante. Também atribuímos interpretações usuais a "*" e "+" (adição e multiplicação de números inteiros) aos respectivos símbolos. Portanto, a interpretação de "1 + 1" é 2 e a interpretação de "2 * 2" é 4.

Observe agora que a linguagem A é estritamente mais expressiva que a linguagem B, pois em números inteiros é verdade que a multiplicação pode ser convertida como adição repetida, mas não há como representar adição como multiplicação em geral.


Para resumir: a linguagem A pode ser considerada mais expressiva que a linguagem B quando suas funções de interpretação compartilham co-domínio, mas a imagem da função de interpretação de B é um subconjunto apropriado da imagem da função de interpretação de A.


-1

TLDR: se um recurso estiver ausente, mas puder ser expresso de outras maneiras, não haverá falta de expressividade. Se você pode imaginar um algoritmo em sua mente ou mesmo implementá-lo em um idioma, mas outro idioma é de alguma forma estruturado de uma maneira que impossibilita a implementação do algoritmo, é um problema de expressividade *.

As restrições de nomenclatura variável não reduzem a expressividade (a menos que haja tão poucos nomes que não seja possível expressar mais todos os algoritmos e nem falsificar variáveis ​​com algo como matrizes + índices).

Um exemplo simples de falta de poder expressivo é o seguinte: você precisa do_homeworke bring_down_trash. Isso é facilmente escrito no código:

do_homework();
bring_down_trash();

Essa solução parece bem direta, mas na verdade do_homeworke bring_down_trashnão é ordenada, também se pode escrever:

bring_down_trash();
do_homework();

O que é igualmente impreciso porque não expressa que não tínhamos a intenção de fazer cumprir uma ordem. Também não queremos usar threads. Queremos dizer algo assim:

compiler_or_interpreter_pick_one(
    {
        do_homework();
        bring_down_trash();
    },
    {
        bring_down_trash();
        do_homework();
    }
);

Tanto quanto sei, isso é muito difícil de se expressar em qualquer linguagem de programação.

Um exemplo que me incomoda sem fim é que é impossível em Java ter uma matriz de objetos. Você pode fazer uma série de ponteiros para objetos, mas que não tenham o mesmo layout de memória (eficiência de fala).

Tomando um exemplo de outra resposta : C ++ não oferece suporte à adição de métodos a uma classe ou instância . Isso é verdade, no entanto, não limita a expressividade do C ++.

struct Extensible{
    std::vector<std::function<void(Extensible *)>> instanceExtensions;
    static std::vector<std::function<void(Extensible *)>> classExtensions;
};

Esta é uma classe à qual você pode adicionar, remover e chamar um número arbitrário de funções-membro para instâncias e a classe. Tecnicamente, o C ++ é provavelmente mais expressivo nesse aspecto do que as linguagens de programação que realmente oferecem suporte a esse recurso, pois no C ++ você pode escolher como armazenar as funções (vetor versus array vs forward_list).

* Alguns idiomas têm uma falta de expressividade como um recurso. Normalmente, eles tornam impossível escrever loops infinitos. Isso pode resolver o problema da parada e permitir provas automáticas de correção.


2
Estou bastante certo de que isso não está correto - pelo menos não é o que eu entendo. Gravar binário bruto em disco é expressivo por essa definição, o que é absurdo.
Telastyn 29/08/14

11
@Telastyn Por que isso seria absurdo? É claro que apenas escrever binário bruto em disco não é expressivo, mas uma linguagem que pode fazer isso é mais expressiva do que uma que não pode, sendo o resto igual.
nwp 30/08/14

Quero dizer, a "linguagem" de você usar uma interface de hardware para gravar bits brutos no computador é um exemplo da linguagem mais expressiva, pois ela pode, por definição, fazer qualquer coisa que o computador possa fazer. Pode expressar qualquer recurso ausente de outras maneiras. Acho absurdo que, por sua definição, essa seja uma linguagem expressiva.
Telastyn

@Telastyn Por que essa seria a linguagem mais expressiva? Ele não pode expressar dados de leitura ou calcular qualquer coisa ou exibir gráficos ou threads. Uma linguagem que só pode gravar bits na memória e no disco tem tão pouca expressividade que duvido que tenha alguma utilidade.
nwp 30/08/14

11
"Normalmente, eles tornam impossível escrever loops infinitos. Isso pode resolver o problema da parada" - se você não pode ter um loop infinito, por definição, seu programa deve parar.
Patrick Collins
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.