What variable runtime values can be accessed in compile time (macro expansion)?

As how I understand it, Julia parses and evaluates code piece by piece. Thus it is possible for a macro definition to access a variable’s runtime value when the macro is expanded. Whether or not it makes sense to read or write a variable’s value when a macro is expanded depends on the order in which the program is compiled. Does there exist such a specification about the ordering?

To give a few concrete examples of my confusion:

  1. I think const global variables are bound to their value before any macro is expanded. Am I correct? I learned it from this question Macro for counting the number of times a function is called? and how Spark.jl defines @attach but I can’t yet find the documentation.

  2. If I have some code like this:

a = some_function()
@some_macro d = 1 + 2

When @some_macro d = 1 + 2 is expanded, can it reliably access a’s runtime value (the value returned by some_function?

  1. If I import a module to my program as
import SomeModule
...other code...

can I be sure that SomeModule’s global variables are bound and macros are expanded before any macro in ...other code... is expanded?

No. Only (kind of) for global scope. Not for local scope.

No.

Macro expands happens after parsing before any part of the code is run so it happens before everything else and has no access to runtime values of any local variables. Global statement are executed one by one so one global statement will be able to access any values from the previous statement. This includes macro expansion time since it also happens after the previous global statement is executed.

No.

No.

Yes, because (as you write it) they are separate global statements.

1 Like

Thanks a lot for responding!

Macro expands happens after parsing before any part of the code is run

Global statement are executed one by one so one global statement will be able to access any values from the previous statement. This includes macro expansion time since it also happens after the previous global statement is executed.

Do not mean to get you caught up in technicality, but just to be clear :slight_smile: : macro expansion happens after it’s previous global statements are executed. So this is not before “any part of the code is run”. But if a macro is expanded within a local scope then it’s before any part of the local code is run.

a = some_function()
@some_macro d = 1 + 2

If this code is in global scope, then when @some_macro d = 1 + 2 is expanded, it may access a’s value?

I did not say “any code”. “The code” here refer to the enclosing global statement.

Yes.

I see. Thanks!