Usually it’s pretty rare to see macros that act on variables believed to exist in the current scope by the macro creator. In your case, you want @landcover to act on variables pos and model which have to exist already, otherwise the user will get a pretty obscure UndefVarError (they’d go looking where they’d written pos or model and not find anything).
But anyway, let’s assume you continue with that approach. In any code that is returned from a macro, symbols refer to things in the module containing the macro definition, unless they’re escaped. If they are escaped, they refer to things in the context where the macro is used.
macro habitat(body) quote function($(esc(:pos)), $(esc(:model))) if $(esc(body)) return true else return false end end end end
This doesn’t work because in an anonymous function expression, the variable names in the definition are declared for use in the function body. What you’re trying to do is to make the function arguments be the same thing as the variables pos and model outside. It’s a bit confusing for me what you actually want to do here, because you’re not using pos and model in the function at all. If you want to close over them (refer to them in the body of the function) use them inside and escape them there. If you want to call the function with the variables, leave alone the input arguments and then separately call the function with the escaped variables.
Maybe this helps you as well https://jkrumbiegel.com/pages/2021-06-07-macros-for-beginners/#whats-escaping