language-design syntactic-sugar

language design - ¿Por qué el azúcar sintáctico a veces se considera algo malo?



language-design syntactic-sugar (11)

El azúcar sintáctico, en mi humilde opinión, generalmente hace que los programas sean mucho más legibles y fáciles de entender que la codificación de un conjunto muy primitivo de primitivos. Realmente no veo un inconveniente para el buen azúcar sintáctico bien pensado. ¿Por qué algunas personas piensan básicamente que el azúcar sintáctico es, en el mejor de los casos, superfluo y, en el peor, algo que debe evitarse?

Editar: No quise nombrar nombres, pero como la gente pregunta, parece que la mayoría de los programadores de C ++ y Java, por ejemplo, francamente no se preocupan por la falta total de azúcar sintáctico de su idioma. En muchos casos, no es necesariamente que les gusten otras partes del lenguaje lo suficiente como para hacer que la falta de azúcar valga la pena, es que realmente no les importa . Además, los programadores de Lisp parecen casi orgullosos de la notación extraña de su lenguaje (no lo llamaré sintaxis porque técnicamente no lo es), aunque en este caso, es más comprensible porque permite que las facilidades de metaprogramación de Lisp sean tan poderosas como lo son.


Demasiado azúcar innecesario solo agrega hinchazón a los idiomas. Yo nombraría nombres, pero luego me incendiarían. :) Además, a veces el lenguaje emplea azúcar sintáctico en lugar de hacer una implementación real. Por ejemplo, hay un lenguaje que seguirá sin nombre, cuya "implementación de genéricos" es solo una capa delgada de azúcar sintáctico.


Disparates. Los programadores C y Lisp usan azúcar sintáctico todo el tiempo.

Ejemplos:

  • a[i] lugar de *(a+i)
  • ''(1 2 3) lugar de (quote 1 2 3)

El azúcar sintáctico puede hacer que tu programa sea más comprensible o menos. Si agrega azúcar sintáctica para cosas triviales, simplemente agrega carga cognitiva, porque el lenguaje se vuelve más complicado. Por otro lado, si puedes agregar azúcar sintáctico que de alguna manera logra ubicar un concepto específico y destacarlo, entonces puedes ganar.


El azúcar sintáctico puede, en algunos casos, interactuar de formas desagradables.

algunos ejemplos específicos:

El primero es c # (o java) específico, Auto boxing y el bloqueo / construcción sincronizada

private int i; private object o = new object(); private void SomethingNeedingLocking(bool b) { object lk = b ? i : o; lock (lk) { /* do something */ } }

En este ejemplo, la útil construcción de bloqueo que puede usar cualquier objeto como punto de sincronización, combinado con el autoboxing, conduce a un posible error. La cerradura simplemente se toma en una nueva instancia en caja de la i cada vez. Es discutible que la construcción de la cerradura sea de gran ayuda y que algún otro constructo específico sobre el cual bloquear sea mejor, pero ciertamente la combinación sigue siendo defectuosa.

Declaración de variables múltiples y punteros:

long* first, second;

Un error clásico (aunque fácil de detectar). El azúcar de múltiples variables no se ajustará a la declaración del puntero.

Algunos constructos no necesitan otros aspectos del azúcar para causar problemas, un ejemplo clásico es el operador ++. Le permite evitar escribir

i = i + 1;

Un constructo ampliamente utilizado (y que tiene un alcance para los errores, ya que debe recordar actualizar ambas variables si desea cambiar el uso de i). Sin embargo, dado que esto es fácil de integrar en otras expresiones, el problema del prefijo y el postfijo aparece. Cuando se usa dentro de un ciclo for, esto no importa, la evaluación ocurre fuera de cualquier otra evaluación, pero usada en otro lugar puede ser una fuente de confusión (ya que puede incluir un aspecto muy importante del cálculo (ya sea el actual o el siguiente valor debe usarse) en una forma muy pequeña y fácil de perder.

Todo lo anterior (excepto tal vez el bloqueo / caja uno que el compilador realmente debería detectar para usted) son casos donde el uso puede estar bien, o los programadores experimentados pueden pensar "eso está perfectamente claro para mí", pero existe la posibilidad de confusión, sin duda para programadores principiantes o aquellos que se mueven a una sintaxis diferente.


Es más tipeo y más capas de abstracción. Prefiero usar un lenguaje que está diseñado para tener niveles más altos de abstracción que un lenguaje con azúcar sintáctica añadida para hacer un trabajo pobre de imitar características que otros idiomas han incorporado.


La sintaxis, en general, hace que un lenguaje sea difícil de aprender, y mucho menos maestro. Por lo tanto, cuanto menor sea el conjunto de sintaxis, más fácil será aprenderlo e intentar dominarlo. Esta es una de las razones principales por las que muchos lenguajes nuevos toman prestada la sintaxis de los lenguajes populares existentes.

Además, si bien simplemente puedo evitar aprender ciertas características que no me interesan por alguna razón, eventualmente me encontraré leyendo el código de otra persona a quien le gusta esa característica y luego tendré que ir a aprender esa característica solo para entender su código.


Posiblemente porque lleva a la confusión en los programadores que no saben lo que realmente está sucediendo detrás de escena, lo que a su vez podría conducir a un código ineficiente o mal escrito. Solo una conjetura, no creo que sea algo "malo". " ya sea.


Siempre he entendido el "azúcar sintáctico" para referirme a cualquier sintaxis añadida a un idioma existente que no amplíe las capacidades del lenguaje. De lo contrario, cualquier cosa menos directa que el lenguaje de máquina binario podría llamarse azúcar sintáctica.

Aunque no amplían las capacidades de un idioma, aún pueden ser muy útiles.

Por ejemplo, LINQ es azúcar sintáctica porque no agrega nuevas capacidades a C # 3 que no eran ya posibles en C # 2. Pero hacer lo mismo que una simple expresión LINQ en C # 2 requeriría mucho más código para lograr y sería mucho más difícil de leer.

Por el contrario, los genéricos no son azúcar sintáctico, porque puedes hacer cosas con ellos en C # 2 que fueron imposibles con C # 1, como crear una clase de colección que puede contener cualquier tipo de valor sin boxeo.


Vea la Ley de las Extracciones Furtivas : demasiada azúcar y simplemente úsela sin comprender o sin saber lo que está sucediendo, y esto hace que sea cada vez más difícil depurar si algo sale mal. No es tanto que el "azúcar sintáctico" sea algo malo, sino que muchos programadores confían en él sin ser realmente conscientes de lo que están protegidos, y luego, si el azúcar sintáctico se encuentra con problemas, se arruinan.


El azúcar sintáctico causa cáncer del punto y coma. Alan Perlis

Es difícil razonar sobre el azúcar sintáctico si el razonamiento tiene lugar sin referencia a un contexto. Hay muchos ejemplos de por qué el "azúcar sintáctico" es bueno o malo, y todos carecen de sentido sin contexto.

Mencionas que el azúcar sintáctico es bueno cuando hace que los programas sean legibles y fáciles de entender ... y puedo contrarrestar eso diciendo que, a veces, el azúcar sintáctico puede afectar la estructura formal de un lenguaje, especialmente cuando el azúcar sintáctico es un apéndice tardío durante el diseño de un lenguaje de programación.

En lugar de pensar en términos de azúcar sintáctico, me gusta pensar en términos de lenguajes bien diseñados que fomenten la legibilidad y la facilidad de comprensión, y lenguajes mal diseñados.

Saludos,


Personalmente, siempre me pareció ambiguo el término "azúcar sintáctico". Me refiero a si quieres obtener información técnica, casi cualquier cosa que no sea la aritmética básica, una declaración if, y un goto es azúcar sintáctica.

Creo que lo que la mayoría de las personas quiere decir cuando descartan el "azúcar sintáctico" es que una característica del lenguaje hace que algo complicado sea demasiado simple. El ejemplo más notorio de esto es Perl. Pero como no soy un experto de Perl, te daré un ejemplo de lo que estoy hablando en Python (tomado de esta pregunta ):

reduce(list.__add__, map(lambda x: list(x), [mi.image_set.all() for mi in list_of_menuitems]))

Este es un intento obvio de hacer que algo más simple haya salido horriblemente mal.

Sin embargo, eso no quiere decir que estoy del lado de eliminar esas características. Creo que esas características solo deben usarse con cuidado.