-
Notifications
You must be signed in to change notification settings - Fork 14
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
Implement splitdef
/combinedef
#66
Conversation
then `nothing` will be returned for invalid definitions. | ||
""" | ||
function splitdef(ex::Expr; throw::Bool=true) | ||
def = Dict{Symbol,Any}() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not a type or a NamedTuple?
EDIT: I see you mutate it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be good with returning a type. I ended up using a Dict
to mostly keep compatibly with MacroTools' version
Codecov Report
@@ Coverage Diff @@
## master #66 +/- ##
==========================================
+ Coverage 94.44% 95.05% +0.61%
==========================================
Files 5 5
Lines 108 182 +74
==========================================
+ Hits 102 173 +71
- Misses 6 9 +3
Continue to review full report at Codecov.
|
return esc(result) | ||
end | ||
|
||
@testset "splitdef / combinedef" begin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the objective is to keep the same API as MacroTools then it might be good to make MacroTools a test dependency and also compare all the cases that should be the same and explicitly show which cases MacroTools won't handle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that would be worth the effort. The functions here definitely don't have the same API (note :type
is never returned by MacroTools.splitdef). I'll update the description to mention what isn't handled by MacroTools
I'll try to put this code into a a separate package. I think ExprTools.jl is a reasonable name. My reason for not putting back into MacroTools.jl is so that we don't have to add unnecessary dependencies here. I'll note ExprTools.jl already exists and defines |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few edge cases I think want tests still.
I realized I never benchmarked julia> using BenchmarkTools, MacroTools, Mocking
julia> def1 = @btime MacroTools.splitdef(:(f(x) = 1))
327.960 μs (543 allocations: 35.33 KiB)
Dict{Symbol,Any} with 5 entries:
:name => :f
:args => Any[:x]
:kwargs => Any[]
:body => quote…
:whereparams => ()
julia> def2 = @btime Mocking.splitdef(:(f(x) = 1))
547.733 ns (12 allocations: 1.09 KiB)
Dict{Symbol,Any} with 4 entries:
:args => Any[:x]
:body => quote…
:name => :f
:head => :(=)
julia> @btime MacroTools.combinedef($def1)
675.561 ns (11 allocations: 704 bytes)
:(function f(x; )
#= REPL[4]:1 =#
1
end)
julia> @btime Mocking.combinedef($def2)
1.524 μs (7 allocations: 416 bytes)
:(f(x) = begin
#= REPL[7]:1 =#
1
end) I investigated the slow down and it turned out to be a difference between julia> @btime MacroTools.combinedef($def1)
673.331 ns (11 allocations: 704 bytes)
:(function f(x; )
#= REPL[3]:1 =#
1
end)
julia> @btime Mocking.combinedef($def2)
442.657 ns (7 allocations: 416 bytes)
:(f(x) = begin
#= REPL[4]:1 =#
1
end) |
Applying fixups before merging. |
After looking over the usage of MacroTools in #60 I found that the proposed implementation wasn't handling the various function definitions that can occur. I found the
splitdef
andcombinedef
implementations provided by MacroTools but I discovered that those functions were not fully tested and were quite slow. Additionally, the extra dependences MacroTools added seemed unnecessary here.I think it would be good to make these functions into a separate package for general usage but for now they can live in Mocking (I'm not sure what a good name for this package would be).
A quick list of issues with the MacroTools variants:
MacroTools.splitdef
does not handle anonymous functionsMacroTools.splitdef
does not handle empty generic functionsMacroTools.combinedef
can only create long-form functionsMacroTools.combinedef
always includesExpr(:parameters, ...)