Subset tuples with macros

I like the macro version. Why? Because you can also check (in the macro) which type of indexing is used. That is, one could call the macro with a single index, range indexing, an array of indices, …

Then I was thinking; why specify the symbol and the indexing as two arguments? There’s the @view macro, which you can also use as @view x[1:3]. I didn’t look up how it is implemented but wanted to come up with my own solution (as an exercise), and it works!

macro ntplaccess(expr)

    sym = expr.args[1] # the symbol
    idx = expr.args[2] # the index, or the indexing expression

    if typeof(idx) <: Int
        # single index
        return :($(esc(sym))[$idx])

    else
        # range, array, tuple
        elements = []

        if idx.head == :call && idx.args[1] == :(:)
            # range
            for i in (idx.args[2]:idx.args[3])
                push!(elements, :($(esc(sym))[$i]))
            end

        elseif idx.head == :tuple || idx.head == :vect
            # tuple or array
            for i in idx.args
                push!(elements, :($(esc(sym))[$i]))
            end
        end

        return :( ($(elements...),) )
    end

end

# can do...
f(y) = @ntplaccess y[1]
f(y) = @ntplaccess y[[3,5]]
f(y) = @ntplaccess y[(1,4,7)]
f(y) = @ntplaccess y[1:4]
1 Like