Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/aminya/typetransform.jl

Transform the given type to another type during defining a method
https://github.com/aminya/typetransform.jl

ambiguity ambiguity-error ambiguity-resolver julia macro metaprogramming method specific subtype subtypes transform type

Last synced: 15 days ago
JSON representation

Transform the given type to another type during defining a method

Awesome Lists containing this project

README

        

# TypeTransform

[![Build Status](https://github.com/aminya/TypeTransform.jl/workflows/CI/badge.svg)](https://github.com/aminya/TypeTransform.jl/actions)

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!).
```julia
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
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`
```julia
@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 `Symbol`s that contains the function names you want to be transformed.

```julia
@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:
```julia
@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
```julia
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.

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

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