Tejido de código de bytes vs macros de Lisp


11

He estado leyendo sobre las bibliotecas que la gente ha escrito para lenguajes como Java y C # que utilizan el tejido de código de bytes para hacer cosas como interceptar llamadas a funciones, insertar código de registro, etc. También he estado leyendo sobre macros Lisp / Clojure en un Intente comprender mejor cómo utilizarlos. Cuanto más leo sobre las macros, más parece que proporcionan el mismo tipo de funcionalidad que las bibliotecas de tejido de código de bytes. Por funcionalidad, me refiero a la capacidad de manipular código en tiempo de compilación.

Ejemplos de bibliotecas que he estado viendo serían AspectJ, PostSharp y Cecil.

¿Hay algo que se pueda hacer con uno y no con el otro? ¿Realmente resuelven los mismos problemas o estoy comparando manzanas y naranjas?


2
código de bytes de tejer es una solución alternativa cuando se necesita un lenguaje dinámico, pero está atascado con un lenguaje de tipos estáticos
Kevin Cline

2
@kevincline, ¿en serio estás tratando de comenzar esta vieja pelea?
Jonathan Henson el

Respuestas:


10

El tejido de código de bytes y las macros son dos cosas diferentes.

El tejido de código de bytes es una forma de interceptar llamadas a funciones, para que pueda inyectar algún tipo de funcionalidad (generalmente una preocupación transversal como el registro) en una llamada a funciones, ya sea antes o después de que se ejecute la función. El tejido de código de byte se realiza a nivel de código de byte, lo que significa que ocurre después de la compilación. La función en sí no se ve afectada. Esta es una de las técnicas que utiliza la Programación Orientada a Aspectos .

Las macros son una forma de extender la sintaxis de un lenguaje. En su forma más simple, una macro es simplemente una forma de grabar pulsaciones de teclas y luego reproducirlas con una tecla de acceso rápido. Las macros de lenguaje funcionan de manera similar; una palabra clave u otra construcción de sintaxis sustituye a algún tipo de expansión macro. Esto está demasiado simplificado, por supuesto; Un mejor ejemplo de una macro específica para Lisp se puede encontrar aquí .


+1 por mencionar que esta es una forma clave de implementar AOP.
Jonathan Henson el

Y las transacciones ... no olvidemos las transacciones.
Jonathan Henson el

3
Las macros LISP no se parecen en nada a 'una forma de grabar pulsaciones de teclas'.
Kevin Cline

1
Bueno, algunos conceptos fundamentales faltan en la respuesta IMO, esos podrían ser: AST, reflexión, Metacircularidad.
AndreasScheinert

2
@AndreasScheinert: El OP no preguntó sobre ninguna de esas cosas. Esto no es una disertación; Es solo una respuesta a la pregunta del OP.
Robert Harvey

5

Aunque pueden usarse para el mismo fin, las macros LISP son bastante diferentes de los complementos de tejido de código de bytes de Java. Las macros LISP extienden la sintaxis LISP en el nivel del código fuente LISP. Dado que las macros LISP se escriben al mismo nivel que otros códigos LISP, son una característica de lenguaje de uso común.

Los complementos de tejido de código de bytes Java funcionan en el nivel JVM. Mientras que muchos programadores de Java pueden usar complementos de tejido de código de bytes escritos por otros, muy pocos programadores de Java escriben sus propios complementos de tejido de código de bytes.

Parte del trabajo realizado por los complementos del compilador Java se realiza muy fácilmente en lenguajes dinámicos. La intercepción de llamadas de función es particularmente simple.


Entiendo las diferencias técnicas entre los dos. Intentaba mirar la pregunta desde un punto de vista de alto nivel. ¿Pueden ambas herramientas manipular el código para lograr los mismos objetivos? ¿Hay algún problema que las macros no puedan resolver que la manipulación de bytecode puede (de una manera sensata y rentable)? Eso es más de lo que estaba buscando.
mortalapeman

@mortalapeman: las manipulaciones posibles en Java y C # a través de la modificación del código de bytes se pueden hacer directamente en lenguajes como Lisp, Ruby, Python, Lua, Javascript ... Es presumiblemente posible hacer todo lo que una macro LISP puede hacer a través de byte -la manipulación del código, pero en la práctica eso no sucede.
Kevin Cline

4

Las macros de Lisp funcionan a nivel de código fuente. Si envuelve alguna macro alrededor de un fragmento de código, puede hacer muchas cosas. Incluyendo analizar el código fuente, insertar código, reescribir código, etc.

Si desea modificar las llamadas a funciones, Lisp generalmente usa dos mecanismos:

  • símbolos vinculantes tardíos. Puede modificar la función vinculada a un símbolo. Cada llamada a una función que pasa por un símbolo, luego usa la nueva función.

  • Las implementaciones de Lisp a veces proporcionan una característica llamada 'consejo'. Esto permite ejecutar código antes, después o alrededor de las llamadas. Por ejemplo en LispWorks: Asesoramiento .

Por lo tanto, puede interceptar llamadas sin manipulación de código de bajo nivel.

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.