EDIT: I somehow missed the appropriate section of the manual despite skimming through several times. Please disregard.
https://docs.julialang.org/en/v1/manual/metaprogramming/#Optionally-generated-functions-1
Here’s one of the current (v1.3.1) definitions of ntuple
:
@inline function ntuple(f::F, ::Val{N}) where {F,N}
N::Int
(N >= 0) || throw(ArgumentError(string("tuple length should be ≥ 0, got ", N)))
if @generated
quote
@nexprs $N i -> t_i = f(i)
@ncall $N tuple t
end
else
Tuple(f(i) for i = 1:N)
end
end
This 0-argument version of @generated
wasn’t something I was familiar with, and it isn’t included in the @generated
docstring, so I looked it up as well.
macro generated()
return Expr(:generated)
end
This only added to my confusion as :generated
is not one of the documented symbols for the head
field of Expr
. eval(Expr(:generated))
throws ERROR: syntax: invalid syntax (generated)
, so evidently it’s not meaningful in global scope, but calling f() = if @generated; :(println("foo")) else println("bars") end
prints “foo”, so it’s not testing whether the enclosing scope is a @generated
function like I had initially assumed.
So what’s the deal with 0-argument @generated
and Expr(:generated)
? @generated
is an exported symbol, so I would assume this is included in the v1.x stability backwards-compatibility guarantee despite not being documented.