es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Buscando un ejemplo muy sencillo de una macro en Racket.

Hice esto:

<h1>lang racket</h1>

<p>(define-syntax-rule (macro-expansion-seconds)
  (current-seconds))

que hace esto

> (macro-expansion-seconds)
1639244531
> (macro-expansion-seconds)
1639244532
> (macro-expansion-seconds)
1639244533

Reemplaza (macro-expansion-seconds) con (current-seconds) en el momento de la expansión, y evalúa esa forma cada vez.

Pero, ¿cómo hago que evalúe (current-seconds) en el momento de la expansión y luego haga esto?

> (macro-expansion-seconds)
1639244533
> (macro-expansion-seconds)
1639244533
> (macro-expansion-seconds)
1639244533

Sé que en este caso simplemente podría hacer esto

(define macro-expansion-seconds
  (current-seconds))

y esto

> macro-expansion-seconds
1639244766
> macro-expansion-seconds
1639244766
> macro-expansion-seconds
1639244766

(el nombre ya no tiene sentido)

pero estoy tratando de entender cómo funcionan las macros y pensé que este sería un ejemplo fácil que podría ayudarme a entender otros más difíciles.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para hacer que la macro evalúe (current-seconds) en el momento de expansión y luego use ese valor para todas las llamadas posteriores, puedes usar la forma let en la definición de la macro. Aquí tienes un ejemplo:

    #lang racket
    
    (define-syntax-rule (macro-expansion-seconds)
      (let ((current-time (current-seconds)))
        (lambda ()
          current-time)))
    

    Esto define una macro que, al ser llamada, evalúa (current-seconds) una vez y almacena el resultado en una variable llamada current-time. Luego devuelve una función lambda que, al ser llamada, devuelve el valor de current-time.

    Ahora, cuando llamas a la macro, devuelve una función que siempre devuelve el mismo valor:

    > ((macro-expansion-seconds))
    1639244533
    > ((macro-expansion-seconds))
    1639244533
    > ((macro-expansion-seconds))
    1639244533
    

    Observa los paréntesis adicionales alrededor de la llamada a la macro, ya que ahora devuelve una función en lugar de un valor directamente.

Comments are closed.