From 0f414e12ad95fd6686b866ea5547eaadd2ae02c6 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Thu, 12 Sep 2024 18:14:29 +0530 Subject: [PATCH 1/4] feat: add generic to `FnType` representing type of the function --- src/types.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.jl b/src/types.jl index 6dc2320e9..ff71bad3f 100644 --- a/src/types.jl +++ b/src/types.jl @@ -912,7 +912,7 @@ promote_symtype(f, Ts...) = Any #### Function-like variables #--------------------------- -struct FnType{X<:Tuple,Y} end +struct FnType{X<:Tuple,Y,Z} end (f::Symbolic{<:FnType})(args...) = Term{promote_symtype(f, symtype.(args)...)}(f, Any[args...]) From 06929d24c88ef1543b515fe5f1f8c98053b69535 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Thu, 12 Sep 2024 18:14:54 +0530 Subject: [PATCH 2/4] feat: add `@syms` syntax to specify type of symbolic function --- src/types.jl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/types.jl b/src/types.jl index ff71bad3f..683f58d44 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1021,8 +1021,16 @@ function _name_type(x) lhs, rhs = x.args[1:2] if lhs isa Expr && lhs.head === :call # e.g. f(::Real)::Unreal + if lhs.args[1] isa Expr + func_name_and_type = _name_type(lhs.args[1]) + name = func_name_and_type.name + functype = func_name_and_type.type + else + name = lhs.args[1] + functype = Nothing + end type = map(x->_name_type(x).type, lhs.args[2:end]) - return (name=lhs.args[1], type=:($FnType{Tuple{$(type...)}, $rhs})) + return (name=name, type=:($FnType{Tuple{$(type...)}, $rhs, $functype})) else return (name=lhs, type=rhs) end From 1dd611ec36419dd2277787bd39011308cbc19aa4 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Thu, 12 Sep 2024 18:13:52 +0530 Subject: [PATCH 3/4] test: test new `FnType` and macro syntax --- test/basics.jl | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/basics.jl b/test/basics.jl index 7c29162ef..70cf1819f 100644 --- a/test/basics.jl +++ b/test/basics.jl @@ -6,7 +6,7 @@ using Test @testset "@syms" begin let - @syms a b::Float64 f(::Real) g(p, h(q::Real))::Int + @syms a b::Float64 f(::Real) g(p, h(q::Real))::Int @test issym(a) && symtype(a) == Number @test a.name === :a @@ -16,9 +16,11 @@ using Test @test issym(f) @test f.name === :f + @test symtype(f) == FnType{Tuple{Real}, Number, Nothing} @test issym(g) @test g.name === :g + @test symtype(g) == FnType{Tuple{Number, FnType{Tuple{Real}, Number, Nothing}}, Int, Nothing} @test isterm(f(b)) @test symtype(f(b)) === Number @@ -32,6 +34,21 @@ using Test # issue #91 @syms h(a,b,c) @test isequal(h(1,2,3), h(1,2,3)) + + @syms (f::typeof(max))(::Real, ::AbstractFloat)::Number a::Real + @test issym(f) + @test f.name == :f + @test symtype(f) == FnType{Tuple{Real, AbstractFloat}, Number, typeof(max)} + @test isterm(f(a, b)) + @test symtype(f(a, b)) == Number + + @syms g(p, (h::typeof(identity))(q::Real)::Number)::Number + @test issym(g) + @test g.name == :g + @test symtype(g) == FnType{Tuple{Number, FnType{Tuple{Real}, Number, typeof(identity)}}, Number, Nothing} + @test_throws "not a subtype of" g(a, f) + @syms (f::typeof(identity))(::Real)::Number + @test symtype(g(a, f)) == Number end end From b959fd841f6ebeef6465ab4ed21a6b735e91a278 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Mon, 16 Sep 2024 13:38:13 +0200 Subject: [PATCH 4/4] Update Project.toml --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index fa892734d..0763848bd 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "SymbolicUtils" uuid = "d1185830-fcd6-423d-90d6-eec64667417b" authors = ["Shashi Gowda"] -version = "3.6.0" +version = "3.7.0" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"