Skip to content

Transform the given type to another type during defining a method

License

Notifications You must be signed in to change notification settings

aminya/TypeTransform.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

61 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TypeTransform

Build Status

Transform the given type to another type during defining a method.

Use @transform and the function that transforms the type to another type. The function should return an Array of types that you want the method to be defined for.

For example, we use allsubtypes() type transform function to define specific methods for all of subtypes of a given type (fix ambiguity error!).

using TypeTransform
abstract type A end
abstract type B <:A end
abstract type C <:B end

@transform function foo(a, b::allsubtypes(A))
    println("a new method")
end

Since allsubtypes(A) returns the array of types [A, B, C], three methods are defined

julia> methods(foo)
# 3 methods for generic function "foo":
[1] foo(a, b::C) in Main at none:2
[2] foo(a, b::B) in Main at none:2
[3] foo(a, b::A) in Main at none:2

Note that you could use subtypes() instead of allsubtypes(), which defines methods only for the direct subtypes ([B] in this case).

Another example would be using inverse_hasmethod

@transform function foo(a, b::inverse_hasmethod(string))
    println("a new method")
end

If you want that only specific functions to be considered in transformation by @transform, give an Array of Symbols that contains the function names you want to be transformed.

@transform [:subtypes, :allsubtypes], function foo_array(a, b::allsubtypes(A))
    println("a new method")
end

It is possible to use the function names inside curly expressions like Union{A, subtypes{B}} or Type{allsubtypes{A}} or use arguments without a name:

@transform function foo_curly(a, ::Union{T,allsubtypes(A)}, c::T) where {T<:Int64}
    println("a new method")
end

Motivation

allsubtypes

The first motivation for this package was to fix ambiguity error by defining specific methods.

If you run the following program

abstract type A end
abstract type B <:A end

# my general vector method
foo(a::Vector, b::Type{<:A}) = print("vector method")

# my special B mwthod
foo(a, b::Type{B}) = print("B method")

foo([1,2], B) will give an ambiguity error, while if you use allsubtypes, you can fix the issue.

# my general vector method
@transform foo(a::Vector, b::allsubtypes(A)) = print("vector method")

inverse_hasmethod

@transform function foo(a, b::inverse_hasmethod(string))
    println("a new method")
end