Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can someone explain how this code works? #7

Open
Qiyamah opened this issue Dec 26, 2017 · 3 comments
Open

Can someone explain how this code works? #7

Qiyamah opened this issue Dec 26, 2017 · 3 comments

Comments

@Qiyamah
Copy link

Qiyamah commented Dec 26, 2017

Hi,
Can someone explain how x::Integer::Small works? What does it mean?
When I macro expand this code:

@traitor function howbig(x::Integer::Small)
    "Teensy..."
end

I get the following expansion. Can some one explain to me how the following code works?

quote
    $(Expr(:stagedfunction, :(howbig(x::Integer)), quote
    dict = Traitor.get_trait_table(howbig, Tuple{Integer})
    f = Traitor.trait_dispatch(dict, Tuple{x})
    (Core._expr)(:block, $(Expr(:copyast, :($(QuoteNode(:($(Expr(:meta, :inline)))))))), (Core._expr)(:call, f, :x))
end))
    function _howbig{::Integer::Tuple{Small}}(x::Integer) # REPL[10], line 2:
        "Teensy..."
    end
    d = Traitor.get_trait_table(howbig, Tuple{Integer})
    d[Tuple{Tuple{Small}}] = _howbig{::Integer::Tuple{Small}}
end

Thanks

@andyferris
Copy link
Owner

Hi!

Thanks for your curiosity. Please keep in mind that this only works on Julia v0.4. :)

The basic idea is that it creates a generated ("staged") function that handles a custom dispatch algorithm in a static way. Traitor keeps a dispatch table per function (the set of matching methods are returned by get_trait_table) and the "most specific" method is chosen by trait_dispatch. The generated function then simply calls f.

The part starting with function _howbig... creates a function for each traitor method (note that the function name is a special Symbol("_howbig{::Integer::Tuple{Small}}") - you can't actually type it with normal syntax) and finally adds that function as a method of the Traitor dispatch table. This is only evaluated once per @traitor macro.

In Julia v0.5 onwards, the rules for generated functions became more restrictive and this approach stopped working (you can think of the reason as being that the compiler does a better job of optimizing by making certain assumptions, and letting generated functions do arbitrary things broke some of those assumptions. In v0.6 onwards there are also further assumptions about conditional recompilation, which means the above approach may become "stale" as methods are added and called).

@datnamer
Copy link

datnamer commented Jul 2, 2019

How is this looking for 1.x then? Is it possible to reactor to make it work with comparable functionality?

@andyferris
Copy link
Owner

See #10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants