Por que Python e Ruby não fazem distinção entre declarar e atribuir um valor a variáveis?


8

Duas das linguagens de script de tipo dinâmico mais populares, Python e Ruby, não fazem distinção na sintaxe entre a declaração de uma variável e a atribuição de um valor a ela.

Em ambos os idiomas, declarar uma variável ne atribuir um valor a ela seria assim:

n = 10

E atribuir um novo valor à variável posteriormente pareceria o mesmo.

Isso cria dois grandes problemas:

  1. Um erro de digitação no nome de uma variável ao alterar seu valor criaria uma nova variável e causaria bugs.

  2. Isso torna as intenções do código menos claras. Difícil saber onde uma variável é declarada e usada pela primeira vez pode tornar o código mais confuso.

O que não entendo é por que esses idiomas não têm uma varpalavra-chave para usar na declaração, para fazer uma distinção entre uma declaração e uma atribuição. Isso não torna o idioma menos dinamicamente digitado e não vejo desvantagens.

Qual é a vantagem de não ter que definir explicitamente uma variável?



@ Akash Isso não parece relacionado à questão, permanece igualmente válido se for executado s/variable/name/g.

Respostas:


4

Como usuário, e não designer, do Python, há três razões pelas quais estou feliz com essas decisões:

Principalmente, ele lê melhor. É claro que tenho que decidir conscientemente introduzir uma nova variável ao escrever , mas o código é lido com muito mais frequência do que está escrito. Muito código é simples no sentido de que o controle do fluxo e do aninhamento não tem influência no significado e na existência de variáveis. Quando eu li

it = Snark()
message = "A letter, not signed"
if random.random() > 0.5:
    hunt(it)
    message += " (by the Knave)"
return [it, message]

então geralmente não me importo com qual (se houver) menção de um nome o introduz pela primeira vez, apenas me importo que ele esteja lá e o que acontece com ele.

Observe que um corpo significativo de pseudo-código usa a mesma convenção (sem declaração, introdução implícita por atribuição), e o Python é frequentemente descrito como pseudo-código executável, apenas de brincadeira. Quatro personagens extras para cada variável local que, aos meus olhos mimadas, sentir como desordem significativa no contexto do Python, especialmente quando não se sentir como ele adiciona qualquer valor (ver abaixo); isso seria diminuído por um :=operador como em Go.

Segundo, ainda não encontrei um erro de digitação (devido a esse recurso específico) que também não se mostrou de outra maneira clara. Talvez eu mude de idéia daqui a alguns anos, quando encontrar alguns erros desse tipo, mas até agora está bem na minha lista de coisas que causam erros. Há um número razoável de perguntas UnboundLocalErrore é um pouco complicado de explicar para iniciantes, mas a frequência e a popularidade dessas perguntas, em comparação com outras dicas (parâmetros padrão mutáveis, semântica de referência, classe versus variáveis ​​de instância) indicam que é um problema raro.

Finalmente, a intenção ... desculpe, mas eu realmente não consigo entender essa. Ao ler e escrever Python, é sempre perfeitamente claro: o que você atribui se destina como local, a menos que seja declarado em voz alta e explicitamente o contrário. Nenhuma pergunta sobre isso. Além disso, como (pelo menos em Python) uma variável é local para toda a função ou não existe , você não pode ter um código complicado que use uma variável local em um ramo e uma global em outro. Você vê um nome sendo atribuído? Você sabe instantaneamente que sempre foi local desde o início. Bem, a menos que o código seja quebrado de uma maneira muito especial (e jogará o temido UnboundLocalErrorem tempo de execução, ao entrar nesses casos).


Aqui está um exemplo de um bug no PHP causado por falta de declarações, a partir de um caso prático: $a = [1, 2, 3]; foreach ($a as $k => &$v) $v++; foreach ($a as $k => $v) echo "$k => $v\n";
Alexander Gelbukh

@AlexanderGelbukh Não conheço PHP o suficiente para identificar a causa, você se importaria de explicar?

Por favor, veja esta minha resposta . Como você vê, foi inesperado para muitas pessoas, inclusive eu, de modo que tive que experimentar muito. Agora imagine quantos programas incorretos existem por causa de um bug desse tipo.
Alexander Gelbukh

1
@AlexanderGelbukh Observe que o bug que você descreve deve-se a uma interação de vários recursos do PHP (principalmente referências) e o IIUC não pode ocorrer dessa maneira em outros idiomas sem declarações. Quanto à gravação / depuração: Observe que a maioria das estratégias de depuração (de baixa tecnologia "olhando para ela até que fique claro" a fantasia de depuradores que viajam no tempo) incluem uma parte significativa da leitura do código que está sendo depurado.

1
Concordo totalmente: a legibilidade é extremamente importante. Você concorda que a prevenção de erros é importante. Você não concorda com as declarações que ajudam a evitar bugs. Não concordo que as declarações prejudiquem a legibilidade. Talvez possamos concordar em discordar :-)
Alexander Gelbukh

-3

Não é que definir uma variável seja o mesmo que atribuí-la - é que as variáveis ​​não são definidas. Chama-se Digitação dinâmica .

Você não pode ter uma linguagem de tipo dinâmico que permita definir uma variável, porque é isso que é a digitação dinâmica .

A decisão de fazer isso muda completamente a natureza do analisador e resulta em um tipo de idioma completamente diferente. A principal diferença para o usuário final é geralmente que, ao definir uma função, seus parâmetros acabam sendo de qualquer tipo ("digitação de pato"), o que é uma bênção, pois torna seu código muito mais simples e uma maldição, pois permite uma infinidade de novas maneiras pelas quais seu código pode falhar.

Não sou especialista em compiladores, mas acho que também é verdade que a digitação dinâmica tem implicações importantes para o sabor do OOP que você obtém em um idioma.


3
Você está errado. O JavaScript no modo estrito exige que você use variáveis ​​antes de usá-las. No entanto, é digitado dinamicamente. Um não tem nada a ver com o outro. Digitação dinâmica significa que sua variável pode conter um valor de qualquer tipo. Não tem nada a ver com a necessidade ou não de defini-lo. Da mesma forma, uma linguagem de tipo estaticamente com inferência de tipo permitiria o uso de variáveis ​​sem a necessidade de defini-las. Essas duas coisas são ortogonais.
back2dos
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.