aminya / TypeTransform.jl

Transform the given type to another type during defining a method

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

About

Transform the given type to another type during defining a method

License:MIT License


Languages

Language:Julia 100.0%