2011-06-12 13 views

Respuesta

20

Según mi leal saber y entender, es completamente arbitrario. Toda la documentación de la que soy consciente simplemente la declara como un hecho, sin elaboración ni justificación.

Pero, si lo piensas bien, ¿por qué otra cosa sería mejor? De acuerdo, digamos que 10 no es suficiente. Tienes (.) que tiene la mayor fijeza y quieres algo más que se ajuste un poco más. Agrega un nivel adicional, por lo que su nuevo máximo es 10 (aunque la mayoría de las soluciones solo van a 9).

Ahora tiene 11 niveles de precedencia. (Eso es ridículo. Ni siquiera es gracioso.) ¿Cómo es esto menos arbitrario que 10? ¿Qué le impide agregar más? ¿Qué pasa si quieres niveles nuevos entre los existentes? Claro, puede seguir agregando más, hasta que finalmente se encuentre escribiendo infix↑ (ω + 2i) y preguntándose dónde salió su vida.

El hecho es que la precedencia del operador es intrínsecamente bastante arbitraria. Hay algunas convenciones, cosas multiplicativas más vinculantes que aditivas, operadores lógicos que tienen una precedencia menor que las funciones con valores booleanos, como (==), pero que son algo limitadas, y por lo general no cubren más de unos pocos niveles. De lo contrario, la única forma de recordar las precedencias del operador es ... bueno, recordarlas, como simplemente memorizar cada una. No solo es una tarea ardua, sino que también puede hacer que el código sea opaco para otros que quizás no tengan todo memorizado también. La memoria de trabajo humana es un recurso muy limitado, por lo que cuanto menos detalles exigentes necesiten recordarse durante la codificación, mejor.

La mayoría de los usos de los operadores en Haskell, donde los asuntos de precedencia caen en uno de los varios grupos ásperas:

  • operadores Pseudosyntactic como el uso común de ($), que suelen necesitar extremadamente alta o baja prioridad para evitar conflictos con otros operadores.

  • Expresiones que utilizan operadores estándar, o variaciones de los mismos, donde existen un puñado de niveles de precedencia estándar y los nuevos operadores generalmente deben compartir el mismo nivel en el que están basados.

  • Conjuntos de operadores especializados, como los de un EDSL, cuyos símbolos y niveles de precedencia se eligen típicamente para reflejar la naturaleza del EDSL y es poco probable que coexistan con otros conjuntos de operadores.

Todos ellos funcionan bien con solo unos pocos niveles de precedencia. Más importante aún, se caracterizan por ser efectivamente independientes de otros operadores o solo utilizarse junto con un conjunto muy limitado de otros operadores. Comience agregando más operadores y mezclándolos en expresiones únicas y muy pronto las personas comenzarán a usar paréntesis explícitos de todos modos porque no pueden recordar lo que ata más de cerca que qué. Hablando por mi cuenta, ya soy propenso a la paréntesis explícita al mezclar operadores de estilo EDSL (por ejemplo, los combinadores Arrow) con los operadores lógicos porque normalmente no puedo recordar los niveles de precedencia exactos que cada uno tiene.

Así pues, habiendo establecido que: 1) un montón de niveles de precedencia adicionales no serían tan útil porque es demasiado como para no perder de vista, y 2) ningún límite recogemos va a ser igual de arbitraria. ¿por qué 10?Voy a adivinar "porque los valores de corrección son solo de un solo dígito".

+3

Buena respuesta ("me pregunto dónde salió mal tu vida" en particular) pero creo que deberías haber pirateado al menos una referencia de Spinal Tap. –

+2

@mu es demasiado corto: Ah, eso sería "la mayoría de las reparaciones solo pasan a 9". :) La mayoría de los amplificadores van a 10, sin embargo, dado que los músicos de rock tienden a contar desde 1, no 0. Pero el rango es equivalente. (En realidad, mucho del fraseo en ese párrafo imitaba las líneas de Spinal Tap, pero eso es más sutil) –

+0

Supongo que cuando uno cuenta los niveles que uno necesita para los números (aditivo, multiplicativo, exponencial), operadores relacionales y operadores lógicos (&&, ||) uno ya tiene seis niveles (tal vez siete, si quiere 'a Ingo

7

La cantidad de niveles es arbitraria y, como recuerdo, la decisión fue que muchos niveles hacen difícil recordar cómo interactúan los operadores. Por ejemplo, Prolog permite 1000 niveles, pero nunca he encontrado que sea mucho mejor que Haskell.

Extender Haskell tiene precedencias con los niveles que podría imaginar cambiando a un número racional, de esa manera siempre puede adaptarse a un operador entre dos operadores existentes. Pero una mejor opción sería cambiar a las precedencias siendo un orden parcial. Entonces, dados dos operadores, pueden relacionarse y luego manejarse en consecuencia, o sin relación, lo que forzaría el paréntesis.

+0

Honestamente, el orden parcial parece más cercano a cómo realmente lo pienso. Aunque no estoy seguro de cómo eso manejaría operadores como '($)', donde solo querría que fuera "más bajo que la mayoría de los demás operadores". Simplemente tener mayores/menos precedentes únicos parece bastante inflexible. –

+1

@camccann No he visto una solución satisfactoria para esto todavía. Así que estamos atrapados con lo que tenemos, que es aún mejor que la mayoría de los idiomas. – augustss

+0

Aww, esperaba que hubieras imaginado esa parte también. :] Oh bien. La forma en que es ahora parece bastante cercana a un máximo local para la relación potencia/complejidad. –

Cuestiones relacionadas