[SOLVED] Behavior of @generated with no arguments

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.

1 Like