¿Deben los lenguajes de programación ser estrictos o sueltos? [cerrado]


14

En Python y JavaScript, los punto y coma son opcionales.

En PHP, las comillas alrededor de las teclas de matriz son opcionales ( $_GET[key]vs $_GET['key']), aunque si las omite, primero buscará una constante con ese nombre. También permite 2 estilos diferentes para bloques (dos puntos, o llaves delimitadas).

Estoy creando un lenguaje de programación ahora, y estoy tratando de decidir qué tan estricto debería hacerlo. Hay muchos casos en los que los caracteres adicionales no son realmente necesarios y pueden interpretarse sin ambigüedades debido a las prioridades, pero me pregunto si aún debería aplicarlos o no para fomentar la coherencia.

¿Qué piensas?


Bien, mi lenguaje no es tanto un lenguaje de programación como un lenguaje de plantillas sofisticado. Una especie de cruce entre las plantillas Haml y Django . Destinado a ser utilizado con mi marco web C #, y se supone que es muy extensible.


22
Este es un tema para una guerra santa.

1
Los pitonistas desalientan el uso de punto y coma. Francamente, no estoy seguro de si son necesarios, solo para permitir múltiples declaraciones por línea, lo que se puede evitar totalmente sin sufrir. Entonces ... estoy a favor de idiomas más estrictos. Sin embargo, a veces puede imponer cosas fuera de un lenguaje con herramientas de análisis de código, como StyleCop.
Trabajo

1
Las comillas para las claves de matriz PHP no son opcionales. Estaban en PHP2, pero las versiones posteriores autodefinieron constantes en ese momento. Sin embargo, no están permitidos en la interpolación básica de cadenas "..$_GET[raw]..".
mario

1
@Ralph: las reglas son un poco más complicadas. Es correcto escribir "xx$_GET[raw]xx": si comienza a usar llaves, entonces la clave debe estar "xx{$_GET['raw']}xx"entre comillas. Si se utilizan llaves, entonces el analizador PHP ordinario lo verifica y se aplica la sintaxis estricta. Es solo por "$_GET[x]"eso que la clave se trata como una cadena sin procesar, y esa es también una regla estricta, PHP analizaría el error "$_GET['x']".
mario

2
@mario: El hecho mismo de que incluso tengamos esta conversación significa que hay cierta ambigüedad y confusión en la forma en que se manejan las claves de matriz. Parece dentro de las cadenas, es inequívoco pero inconsistente (no puede usar comillas cuando ya está en una cadena, a menos que use llaves, entonces tiene que hacerlo, pero afuera debería). Y cadenas externas, en PHP "normal" ... bueno, es una mierda extraña como esa.
mpen

Respuestas:


19

Los diferentes tipos de idiomas tienen diferentes usos, por lo que la respuesta a esta pregunta realmente depende de para qué lo va a utilizar.

Por ejemplo, Perl es un lenguaje muy suelto, y lo encuentro muy útil para escribir arreglos rápidos o scripts de números. Para proyectos sólidos y sólidos, uso C #.

Necesita obtener el equilibrio adecuado para el uso objetivo. Cuanto más estricto sea, más tiempo necesitará pasar escribiendo el código, pero obtendrá mayor solidez, reutilización y más fácil de mantener.


26

Lo que busco en un lenguaje de programación (a diferencia de un lenguaje de programación) es la coherencia y la tipificación fuerte.

En los lenguajes de programación actuales, es posible omitir el punto y coma, por ejemplo, en ciertos lugares sin volverse ambiguo (la última expresión en un {}bloque es una). Si un lenguaje de programación le permite omitir caracteres en estos casos, un programador ahora tiene un problema adicional; Además de la sintaxis del lenguaje general, ahora tiene que saber en qué casos también está permitido omitir partes de la sintaxis.

Este conocimiento adicional no es un problema para el programador que escribe el código, pero se convierte en una carga para cualquiera que tenga que interpretar el código existente en un momento posterior (incluido el autor original después de un tiempo).

Su ejemplo de PHP abre la posibilidad de errores sutiles en un programa cuando la constante keyse agregaría en el mismo contexto. El compilador no tiene forma de saber que no es lo que se quiso decir, por lo que el problema solo se vuelve aparente en tiempo de ejecución en lugar de en tiempo de compilación.


1
De acuerdo, debe limitar las posibilidades para los desarrolladores: más posibilidades => necesidad de pensar más (debería proceder de esta manera o de esa manera) => menos tiempo para hacer el trabajo real
Kemoda

No veo qué tiene que ver la falta de conversión de tipos implícita con la sintaxis de un lenguaje.
dan_waterworth

55
Además, cuando lees $_GET[key]no sabes nada. Terminas haciendo greps todo el proyecto solo para saber si keyes una constante o no. Tal cosa ahorra 0.5 segundos de escritura y toma 20 segundos para leer.
Moshe Revah

Si su idioma le brinda opciones sin distinción, el estilo de codificación, ya sea codificado o no, tiende a estandarizarse en uno de ellos ...
Deduplicador

11

En cada lugar donde haya cierta ambigüedad, el compilador debe tener alguna forma de adivinar lo que realmente quiso decir el programador. Cada vez que esto sucede, existe la posibilidad de que el programador realmente haya querido decir algo diferente, pero no haya descartado la regla de resolución de ambigüedad.

Escribir código lógicamente correcto ya es bastante difícil. Agregar ambigüedades sintácticas puede parecer "amigable" en la superficie, pero es una invitación abierta para introducir nuevos errores inesperados y difíciles de depurar en la base de código. En pocas palabras, sea lo más estricto posible.

A partir de su ejemplo, mencionó que los puntos y comas son opcionales en Python y JavaScript. Para Javascript, al menos, esto no es del todo cierto. Los puntos y comas son tan necesarios en JS como en cualquier otro lenguaje de familia C. Pero la especificación del lenguaje requiere el analizador de JavaScript para insertar puntos y comas faltantes bajo ciertas circunstancias. Esto es ampliamente considerado como algo muy malo porque tiende a equivocar sus intenciones y arruinar su código.


6

La respuesta a lo flojo que debes hacer tu idioma es igual a la respuesta de la pregunta que se dice en un acento de Texas: "¿Qué suerte tienes, punk?".


No lo entiendo
mpen

44
Mi mal intento de broma fue que la escritura dinámica podría morderte a medida que los sistemas crecen más y más, especialmente al agregar desarrolladores inexpertos a la mezcla. En mi experiencia, los sistemas de cualquier valor tienden a crecer más y más y tienen un número creciente de desarrolladores que los desarrollan. Tener "Buscar todos los usos del símbolo" o "Cambiar nombre de todo" o "Eliminar con seguridad" o "Buscar errores en la solución" es absolutamente invaluable. El tipeo dinámico en el sentido limitado de que VB está vinculado de forma tardía y realiza una coerción de tipo extensa ha causado muchos errores en el concierto actual.
Henrik

Ergo, si te sientes afortunado con tu proyecto, por ejemplo, suerte de tener desarrolladores buenos y experimentados, o suerte en términos de escribir el código correcto; Puede usar la escritura dinámica.
Henrik

2
Ah ... pero esta pregunta nunca fue sobre tipeo dinámico :)
mpen

1
Ah, muy cierto Raplh. Solo tiendo a pensar que los lenguajes dinámicos son más flexibles, ya que generalmente son más flexibles. Sin embargo, tienes razón.
Henrik

4

Todos no tendrían que trabajar tan duro para codificar la coherencia si los idiomas no tuvieran tanta variación. No nos gusta cuando los usuarios hacen solicitudes que aumentan innecesariamente la complejidad, entonces, ¿por qué deberían preguntarse eso de nuestros lenguajes de desarrollo?


+1: estoy totalmente de acuerdo. No veo por qué principios como KISS y YAGNI no deberían aplicarse al diseño del lenguaje.
Giorgio

2

Mi preferencia personal es la capacidad de tener la rigurosidad suficiente para detectar mis errores tipográficos, pero con la menor cantidad de repeticiones posibles. Hablo sobre este problema en http://www.perlmonks.org/?node_id=755790 .

Dicho esto, estás diseñando tu lenguaje por ti mismo. Debes hacer que sea lo que quieras que sea.


+1: ... La capacidad de tener la rigurosidad suficiente para detectar mis errores tipográficos, pero con la menor cantidad de repeticiones posibles. - Si. ¿Conoces el plan de Anders Hejlsberg para C #? Está tomando una decisión consciente para enfatizar "esencia sobre ceremonia". channel9.msdn.com/Blogs/matthijs/…
Jim G.

@ jim-g: Gracias por el pensamiento. No estoy familiarizado con nada de C #. No he trabajado en el mundo de Microsoft durante muchos, muchos años.
btilly

1

Me gusta que mis idiomas hagan lo que quiero decir. En general, eso se inclina bastante hacia suelto. También me gustaría poder etiquetar "estricto" en un elemento o bloque para poder depurar / analizar esa área limitada.


1

En general, tiendo a ponerme del lado de "Lo que me facilitaría como programador". Por supuesto, eso puede significar más de una cosa. En Javascript casi no hay verificación de tipo, lo que funciona muy bien hasta que encuentras un error extraño. Por otro lado, en Haskell hay una gran cantidad de verificación de tipos que pone más trabajo al frente pero disimula algunas clases de errores.

Para ser honesto, verificaría un montón de idiomas para ver qué hacen e intentar encontrar un nicho que ninguno de ellos encuentre.

No creo que haya una manera correcta obvia de hacerlo, o al menos si no hay algo en lo que la gente todavía haya llegado a un consenso. Entonces, al crear idiomas con diferentes sistemas de tipos, estamos aprendiendo.

Buena suerte.


1

Sugeriría que un buen lenguaje de programación debe tener reglas estrictas, que se espera que las implementaciones apliquen de manera consistente, pero las reglas deben estar escritas de tal manera que sean útiles. Sugeriría además que uno debería considerar diseñar un lenguaje para evitar casos donde la "distancia de Hamming" entre dos programas sustancialmente diferentes es solo uno. Obviamente, uno no puede lograr tal cosa con literales numéricos o de cadena (si un programador que quiso decir 123 en su lugar escribe 1223 o 13, el compilador no puede saber muy bien qué significa el programa). Por otro lado, si el lenguaje se usara para algún propósito legal, reduciría en gran medida las posibilidades tanto para tareas accidentales que se suponía que eran comparaciones,:= para asignación y ==para comparación de igualdad, y no se usara un solo=

Sugeriría que, si bien hay lugares donde es útil para los compiladores inferir cosas, dicha inferencia suele ser más valiosa en los casos más simples y menos valiosa en los casos más complicados. Por ejemplo, permitir el reemplazo de:

  Diccionario <complicadoTipo1, complicadoTipo2> elemento =
    nuevo Diccionario <complicadoTipo1, complicadoTipo2 ()>;

con

  elemento var = nuevo Diccionario <complicadoTipo1, complicadoTipo2 ()>;

no requiere ninguna inferencia de tipo complicada, pero hace que el código sea mucho más legible (entre otras cosas, usar la sintaxis más detallada solo en escenarios donde es necesario, por ejemplo, porque el tipo de ubicación de almacenamiento no coincide exactamente con el tipo de expresión crearlo, ayudará a llamar la atención adicional a los lugares que lo requieran).

Una dificultad importante de intentar una inferencia de tipos más sofisticada es que pueden surgir situaciones ambiguas; Sugeriría que un buen lenguaje debería permitir que un programador incluya información que el compilador podría usar para resolver tales ambigüedades (por ejemplo, al considerar algunos tipos de letra preferibles a otros), determinar que no importan (por ejemplo, porque aunque dos posibles las sobrecargas pueden ejecutar un código diferente, el programador ha indicado que deben comportarse de manera idéntica en aquellos casos en los que cualquiera podría usarse) o marcar aquellos (y solo aquellos) que no pueden manejarse de ninguna de las formas anteriores.


1

Para mí, la legibilidad es lo más importante.

Para alguien con experiencia en el lenguaje, el significado de un fragmento de código debe ser claro sin tener que analizar el contexto en profundidad.

El lenguaje debería ser capaz de señalar los errores con la mayor frecuencia posible. Si cada secuencia aleatoria de caracteres hace un programa sintácticamente correcto, eso no es útil. Y si las variables se crean automáticamente la primera vez que se utilizan, a continuación, escribir incorrectamente clientcomo cleintno le dará un error de compilación.

Además de la sintaxis, el lenguaje debe tener una semántica claramente definida, y tal vez eso sea aún más difícil que decidir una sintaxis decente ...

Buenos ejemplos:

  • En Java, "1"es una cadena, 1es un int, 1.0es un doble y 1Les largo. Una mirada y sabes lo que es.

  • En Java, =es la tarea. Asigna el valor para los tipos primitivos y la referencia para los tipos de referencia. Nunca copia datos complejos o compara.

  • En Java, llamar a un método necesita paréntesis y de esta manera se distingue claramente de las variables, por lo tanto, si no hay paréntesis, no es necesario buscar una definición de método, es solo leer datos.

Malos ejemplos:

  • En Java, un símbolo como clientpuede ser casi cualquier cosa: un elemento de ruta de paquete, un nombre de clase o interfaz, un nombre de clase interno, un nombre de campo, un nombre de método, una variable local, y aún más. Depende del usuario introducir u obedecer las convenciones de nomenclatura o no.

  • En Java, el punto .se usa en exceso. Puede ser un separador dentro del nombre del paquete, un separador entre el paquete y la clase, un separador entre la clase externa e interna, el conector entre la expresión de instancia y el método que se invocará en la instancia, y muchos más.

  • En muchos idiomas, las llaves de los ifbloques son opcionales, lo que lleva a errores desagradables si alguien agrega una declaración más al bloque (que no existe).

  • Operadores de infijo: a veces tengo que detenerme en una expresión numérica y pensar detenidamente lo que significa, paso a paso. Todos estamos acostumbrados a escribir expresiones matemáticas en notación infijada como a * b / c * d + e. La mayoría de las veces recordamos la precedencia de la multiplicación y la división sobre la suma y la resta (pero ¿se dio cuenta de que no estamos dividiendo por c*d, sino dividiendo solo por cy luego multiplicando por d?). Pero hay tantos operadores infix adicionales con sus propias reglas de precedencia y sobrecarga de algunos idiomas que es difícil hacer un seguimiento. Tal vez hacer cumplir el uso de paréntesis hubiera sido un mejor enfoque ...


Principalmente ha hablado de la ambigüedad, pero puede haber múltiples formas de hacer lo mismo sin crear ambigüedad. Tal vez podamos tener dos operadores de multiplicación, *y ×. Ambos 5*3y 5 × 3 'significan lo mismo, y un programador experimentado sabe exactamente lo que significan sin tener que mirar el contexto circundante. El problema, sin embargo, es que ahora hay dos formas de hacer lo mismo y alguien puede intercambiarlas a lo largo del programa. Creo que esto es lo que más me preocupaba cuando hacía la pregunta.
mpen

-2

Puede considerar una analogía con el lenguaje natural. En el correo electrónico, ¿eres un nazi de gramática? ¿O está de acuerdo con algunos errores gramaticales, como infinitivos divididos, conjunciones faltantes o modificadores extraviados? La respuesta se reduce a preferencias personales.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.