La metaprogramación es una forma de formar un código bien construido. Si esta técnica se usa con precisión, puede dar como resultado un código más condensado y legible. Julia es un lenguaje homoicónico, lo que significa que Julia puede personificar su propio código como la estructura de datos del lenguaje mismo. Es posible que el programa reconstruya su propio código sin ningún paso de construcción adicional. Otra propiedad de Julia, de ser un lenguaje de metaprogramación, es el calibre del programa en ejecución para encontrarse dinámicamente con las propiedades de sí mismo. Las expresiones y macros son una parte vital de la metaprogramación en Julia.
Expresiones en Julia
Las expresiones son objetos de tipo excepcional en lenguaje Julia. Un código de Julia parece ser un árbol de sintaxis que se extiende desde las estructuras de datos de Julia de tipo Expr. Esto simplifica la configuración y los cambios en el código de Julia desde dentro de Julia sin deducir el texto original.
Se puede decir que cualquier fragmento de código que no haya sido evaluado es una expresión. Hay una determinada función que se utiliza para evaluar expresiones.
Por ejemplo,
El fragmento de código anterior acaba de formar un objeto ‘Expr’ y permanecerá como está a menos que alguna función tome medidas hacia ese objeto, como eval() ,
Todo esto parece ser un poco complicado ya que solo necesita sumar dos números. La razón detrás de esta expresión compleja es que revela nuevas capacidades sólidas para los programadores de Julia.
Creación de Expresiones
Hay varias formas de crear expresiones en Julia, algunas de ellas se enumeran a continuación:
usando la función Expr()
Julia proporciona una función predefinida Expr() que se puede usar para crear expresiones a elección del usuario.
Aquí, my_exp = Expr(:(=), :x, 10) es la notación de prefijo de la sintaxis, el primer argumento es head y los restantes son argumentos de la expresión. El jefe determina la operación a realizar, aquí se le asigna el valor 10 a x.
citando
La sintaxis básica para crear una expresión entre comillas es dos puntos ( 🙂 seguido de paréntesis() alrededor de la declaración única del código, es decir, :()
Puede construir esta expresión a*b+c+10 de otras formas, como usar Meta.parse y Expr
usando comillas… fin
Esto permite crear expresiones de varias líneas.
Interpolación
Julia permite que los literales se interpolen en la expresión, es decir, permite que se inserten valores en una expresión.
Ejemplo de una tupla interpolada como expresión,
Nota: si la expresión no está entrecomillada, mostrará un error en tiempo de compilación:
$permite interpolar solo una expresión, en caso de que desee insertar varias expresiones, use $(exps…), donde exps es una array de expresiones.
Evaluación de expresiones
Las expresiones se pueden evaluar utilizando el método eval() predefinido .
En el ejemplo anterior, el valor de a que se encuentra en el momento de la construcción de la expresión se trata como un valor intermedio en la expresión, por lo tanto, a=0 no importa. Aquí, el valor de a se trata como 30 .
Funciones en Expresiones
Una característica extremadamente útil de Julia es la capacidad de generar y manipular el código de Julia dentro de la propia Julia. Ya hemos visto un ejemplo de una función que devuelve objetos Expr: la función parse, que toma una string de código de Julia y devuelve el Expr correspondiente. Los objetos Expr también pueden actuar como un argumento para las funciones y la función devuelve otro Expr . Aquí hay un ejemplo,
Macros en Julia
Ahora que ya sabes, como manejar expresiones en Julia, ahora viene el paso de modificarlas y esto se hace usando una macro. Macro es una de las formas de evaluar la expresión de entrada y proporciona la expresión de salida resultante. El proceso en el lenguaje Julia funciona de la siguiente manera: primero analiza y evalúa la macro, y el código procesado producido por la macro finalmente se evalúa como una expresión ordinaria. Se puede hacer referencia a la macro como un código de código. Aquí está la sintaxis a continuación:
macro e(x) if typeof(x) == Expr println(x.args) end return x end
Las macros se ejecutan utilizando el carácter ‘@’ como prefijo,
@name exp1 exp2 ... @name(exp1, exp2, ...)
Estos son dos estilos de escritura y no deben mezclarse.
julia> @e 10 10
Al pasar un número ’10’, devuelve el número en sí porque los números no son expresiones. Aquí hay algunos ejemplos más de macro.
Ejemplo 1:
Ejemplo 2:
Hay ciertas formas de conocer el argumento de la macro. Esto se puede hacer usando la función show() dentro del cuerpo de la macro:
Veamos la macro @asset , a continuación se muestra el ejemplo:
Se puede utilizar de la siguiente manera:
El código anterior es en realidad como:
10 == 10.0 ? nothing : throw(AssertionError("10 == 1.0")) 10 == 0 ? nothing : throw(AssertionError("10 == 0"))
Toda esta expresión se coloca en el árbol de sintaxis donde se produce la llamada a la macro @assert y luego, en el momento de la ejecución, si la expresión de prueba se evalúa como verdadera, entonces no se devuelve nada, mientras que si la prueba es falsa, se genera un error que indica la afirmación. expresión que era falsa.
Veamos otra macro @eval. Debes estar pensando en eval() pero estos son diferentes de alguna manera. eval() es una función y @eval es una macro. Está familiarizado con la función eval(), primero expande y evalúa la expresión, pero @eval no hace lo mismo. No expande la expresión y si desea evaluar la expresión puede utilizar el proceso de interpolación. Esto puede hacerse de la siguiente manera:
Básicamente,
@eval $(ex) == eval(ex)
El fragmento de código anterior devolverá verdadero.