Skip to content

Commit 125e6ea

Browse files
Alessandro CheliAlessandro Cheli
authored andcommitted
adjust interface
1 parent ad7e667 commit 125e6ea

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

src/TermInterface.jl

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,20 +69,30 @@ export operation
6969
7070
Returns the arguments to the function call in a function call expression.
7171
`iscall(x)` must be true as a precondition.
72+
73+
Depending on the type and internal representation of `x`,
74+
`arguments(x)` may return an unsorted collection nondeterministically,
75+
This is to make sure to retrieve the arguments of an expression when the order of arguments does not matter
76+
but the speed of the operation does.
77+
To ensure to retrieve arguments in a sorted manner, you can use
78+
and implement the function `sorted_arguments`.
7279
"""
7380
function arguments end
7481
export arguments
7582

7683
"""
77-
unsorted_arguments(x::T)
84+
sorted_arguments(x::T)
7885
79-
If x is a expression satisfying `iscall(x)` and your expression type `T` provides
80-
and optimized implementation for storing the arguments, this function can
81-
be used to retrieve the arguments when the order of arguments does not matter
82-
but the speed of the operation does.
86+
Returns the arguments to the function call in a function call expression, in a **sorted fashion**.
87+
`iscall(x)` must be true as a precondition. Analogous to `arguments`,
88+
but ensures that the operation is deterministic and always returns
89+
the arguments in the order they are stored.
90+
91+
By default, this redirects to `arguments`, therefore implementing
92+
it is optional.
8393
"""
84-
unsorted_arguments(x) = arguments(x)
85-
export unsorted_arguments
94+
sorted_arguments(x) = arguments(x)
95+
export sorted_arguments
8696

8797

8898
"""

test/runtests.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,27 @@ using Test
2020
@test !iscall(ex)
2121
@test ex == maketerm(Expr, :ref, [:arr, :i, :j], nothing)
2222
end
23+
24+
@testset "Unsorted arguments" begin
25+
struct Sum
26+
d::Dict{Int, Any}
27+
Sum(xs...) = new(Dict{Int, Any}(xs...))
28+
end
29+
30+
TermInterface.isexpr(s::Sum) = true
31+
TermInterface.head(::Sum) = (+)
32+
TermInterface.operation(s::Sum) = head(s)
33+
TermInterface.arguments(s::Sum) = [:($coeff * $val) for (coeff, val) in s.d]
34+
TermInterface.children(s::Sum) = sorted_arguments(s)
35+
TermInterface.sorted_arguments(s::Sum) = [:($coeff * $val) for (coeff, val) in sort!(collect(pairs(s.d)))]
36+
37+
s = Sum(1 => :A, 2 => :B, 3 => :C)
38+
@test operation(s) == head(s) == (+)
39+
args = arguments(s)
40+
@test :(1A) in args
41+
@test :(2B) in args
42+
@test :(3C) in args
43+
44+
@test sorted_arguments(s) == [:(1A), :(2B), :(3C)]
45+
@test children(s) == sorted_arguments(s)
46+
end

0 commit comments

Comments
 (0)