¿Por qué Python y Ruby no hacen una distinción entre declarar y asignar un valor a las variables?

8

Dos de los lenguajes de script de escritura dinámica más populares, Python y Ruby, no hacen una distinción en la sintaxis entre la declaración de una variable y la asignación de un valor.

Es decir en ambos idiomas, declarar una variable ny asignarle un valor sería así:

n = 10

Y asignar un nuevo valor a la variable más adelante se vería igual.

Esto crea dos problemas principales:

  1. Un error tipográfico en el nombre de una variable al cambiar su valor crearía una nueva variable y causaría errores.

  2. Hace que las intenciones del código sean menos claras. Difícil saber dónde se declara y se usa una variable por primera vez, podría hacer que el código sea más confuso.

Lo que no entiendo es por qué estos idiomas no tienen una varpalabra clave para usar en la declaración, para hacer una distinción entre una declaración y una asignación. Esto no hace que el lenguaje se escriba menos dinámicamente, y no veo inconvenientes.

¿Cuál es la ventaja de no tener que definir explícitamente una variable?

Aviv Cohn
fuente
@Akash Eso no parece estar relacionado con la pregunta en absoluto, sigue siendo igualmente válido si se ejecuta s/variable/name/g.

Respuestas:

4

Como usuario (en lugar de diseñador) de Python, hay tres razones por las que estoy satisfecho con estas decisiones:

Principalmente, se lee mejor. Por supuesto, tengo que decidir conscientemente introducir una nueva variable al escribir , pero el código se lee con mucha más frecuencia de lo que se escribe. Una gran cantidad de código es simple en el sentido de que el flujo de control y el anidamiento no influyen en el significado y la existencia de variables. Cuando leo

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

entonces, por lo general, no me importa qué mención (si es que hay alguna) de un nombre lo introduce primero, solo me importa que esté allí y qué le suceda.

Tenga en cuenta que un cuerpo significativo de pseudocódigo utiliza la misma convención (sin declaración, introducción implícita a través de la asignación), y Python a menudo se describe como pseudocódigo ejecutable, solo en broma. Cuatro caracteres adicionales para cada variable local hace, a mis ojos en mal estado, se sienten como el desorden significativo en el contexto de Python, especialmente cuando no se siente como que añade ningún valor (véase más adelante); esto sería disminuido por un :=operador como en Go.

En segundo lugar, todavía tengo que encontrar un error tipográfico (debido a esta característica específica) que tampoco se mostró de otra manera clara. Tal vez cambie de opinión en unos años más cuando encuentre algunos errores de este tipo, pero hasta ahora está muy, muy abajo en mi lista de cosas que causan errores. Hay un buen número de preguntas sobre el tema UnboundLocalErrory es un poco difícil de explicar a los principiantes, pero la frecuencia y popularidad de esas preguntas, en comparación con otras trampas (parámetros predeterminados mutables, semántica de referencia, variables de clase versus instancia) indica que es un problema poco común.

Finalmente, la intención ... lo siento, pero realmente no puedo entender esto. Al leer y escribir Python, siempre está perfectamente claro: lo que se asigna se pretende como un local, a menos que se declare lo contrario en voz alta y explícita. No hay duda al respecto. Además, dado que (al menos en Python) una variable es local para toda la función o para nada , no puede tener un código complicado que use una variable local en una rama y una global en otra. ¿Ves un nombre asignado? Al instante sabes que siempre fue local desde el principio. Bueno, a menos que el código se rompa de una manera muy especial (y arrojará el temido UnboundLocalErroren tiempo de ejecución, al ingresar esos casos).


fuente
Aquí hay un ejemplo de un error en PHP causado por la falta de declaraciones, de un caso práctico: $a = [1, 2, 3]; foreach ($a as $k => &$v) $v++; foreach ($a as $k => $v) echo "$k => $v\n";
Alexander Gelbukh
@AlexanderGelbukh No conozco PHP lo suficiente como para identificar la causa, ¿te importaría explicarlo?
Por favor vea esta mi respuesta . Como puede ver, fue inesperado para muchas personas, incluido yo, por lo que tuve que experimentar mucho. Ahora imagine cuántos programas incorrectos hay por ahí debido a este error.
Alexander Gelbukh
1
@AlexanderGelbukh Tenga en cuenta que el error que describe se debe a una interacción de varias características de PHP (principalmente referencias) y IIUC no puede ocurrir de esa manera en otros idiomas que carecen de declaraciones. En cuanto a la escritura / depuración: Tenga en cuenta que la mayoría de las estrategias de depuración (desde la baja tecnología "mirándolo hasta que quede claro" hasta los depuradores sofisticados que viajan en el tiempo) incluyen una parte importante de la lectura del código que se está depurando.
1
Completamente de acuerdo: la legibilidad es extremadamente importante. Usted acepta que prevenir errores es importante. No está de acuerdo con que las declaraciones ayudan a prevenir errores. No estoy de acuerdo con que las declaraciones perjudiquen la legibilidad. Quizás podamos estar de acuerdo en no estar de acuerdo :-)
Alexander Gelbukh
-3

No es que definir una variable sea lo mismo que asignarla, es que las variables no están definidas en absoluto. Se llama Typing Dinámico .

No se puede tener un lenguaje de tipos dinámicos que permite definir una variable, porque eso es lo tipado dinámico es .

La decisión de hacer esto cambia completamente la naturaleza del analizador y da como resultado un tipo de lenguaje completamente diferente. La principal diferencia para el usuario final es que, cuando define una función, sus parámetros resultan ser de cualquier tipo ("tipear pato"), lo cual es una bendición, ya que hace que su código sea mucho más simple, y una maldición, ya que permite una multitud de nuevas formas en que su código puede fallar.

No soy un experto en compiladores, pero creo que también es cierto que Dynamic Typing tiene implicaciones importantes para el sabor de OOP que obtienes en un idioma.

Andy Jones
fuente
3
Estas en error JavaScript en modo estricto requiere que uses variables antes de usarlas. Sin embargo, se escribe dinámicamente. Uno no tiene nada que ver con el otro. La escritura dinámica significa que su variable puede contener un valor de cualquier tipo. No tiene nada que ver con si tiene que definirlo o no. Del mismo modo, un lenguaje de tipo estático con inferencia de tipos permitiría usar variables sin la necesidad de definirlas. Estas dos cosas son ortogonales.
back2dos