Makes me wonder if a Terse.jl package would be worthwhile; exporting things like a little, boilerplate-reducing @singleton macro:
function f(@singleton(MY_CONST::MyType), x)
println("Can I even do this in function arg scope?")
end
# expands the @singleton arg to `::MyType` and evals the below in module scope:
struct MyType end
const MY_CONST = MyType()
I kind of miss these kind of conciseness-affordance macros from lisps.
As an educator I am against macros because they are a fundamentally more advanced concept than typical programming that most academics would be familiar with. As a developer, I realize that macros are a powerful feature of the language that can be beneficial when used correctly. But they can be brutally hard to code and debug I still dont know how to write macros after 8 years of using the language.
However, I always, absolutely, without any shadow of a doubt, am 100% against using macros when a function would do exactly the same thing with the same level of code complexity.
The @lift macro in Makie and the DataFramesMeta macros do the same thing, they let you write an expression that resolves to a function, where otherwise you’d have to write each variable at least three times. Once as an input to the function, once as an argument, and once in the function body.
@lift $observable_a + $observable_b + 10
# is equivalent to
lift(observable_a, observable_b) do obs_a, obs_b
obs_a + obs_b + 10
end
Vanilla DataFrames can be quite verbose due to this
When I was working on DuckDispatch.jl, I realized that the user would need to define multiple copies of each of the required methods for a new DuckType. One for fallback, and one that unwraps the DuckType wrapper can calls the original function. It also has a reasonably complex syntax for declaring the supertype of a new DuckType and that supertype needs to match the methods you made exactly. Then, there is a whole other set of functions that you need to define if you want to dispatch on a DuckType.
A declarative DSL driven by macros allows me to make sure all of that is synced up and throw informative errors if the user messes something up.
I plan to document exactly what the macros are producing and make all of it public, but I would see it as highly inadvisable to circumvent the macro API.