Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@traitfn on callable types #86

Open
MilesCranmer opened this issue Jun 16, 2023 · 5 comments
Open

@traitfn on callable types #86

MilesCranmer opened this issue Jun 16, 2023 · 5 comments

Comments

@MilesCranmer
Copy link

There is a workaround for this but in case you'd like to support it, the following syntax does not work. My use-case is to build a generic constructor for any type D satisfying some trait:

@traitfn (::Type{D})(args...) where {D; IsMyTrait{D}} = f(args...)

This will raise the following error:

ERROR: syntax: invalid "::" syntax around /Users/mcranmer/.julia/packages/SimpleTraits/WyNKl/src/SimpleTraits.jl:338
Stacktrace:
 [1] top-level scope
   @ REPL[27]:1

The workaround is to pass a symbol:

@traitfn (d::Type{D})(args...) where {D; IsMyTrait{D}} = f(args...)

which works.

@MilesCranmer
Copy link
Author

As in #87, maybe I should just avoid doing stuff like this, since it will invalidate functions in Base.

@mauro3
Copy link
Owner

mauro3 commented Jun 20, 2023

Yes, this is also a bit iffy. Again, similar reasoning to #87 should mean that it should work in principle (i.e. don't forget to define the Not version, preferably before the not-Not version). But again, I may not have thought this through.

Regarding the syntax error: it would be ok to fix this as it could be use for more benign applications too. PR welcome.

@MilesCranmer
Copy link
Author

MilesCranmer commented Jun 20, 2023

Yeah it seems impossible with current Julia. I can't see any way around the invalidations from stuff like this. I was trying to think if there is some way to write a AbstractTraitWrapper and have it wrap other abstract types, so that users can do, e.g.,

struct MyFloat <: AbstractTraitWrapper{AbstractFloat}
    x::Float64
end

and somehow have this struct inherit all methods on AbstractFloat (so that users can still use their abstract types while also using traits), as well as enabling, e.g.,

Base.:+(x::T, y::T) where {T<:AbstractTraitWrapper; IsMyFloat{T}} = T(x.x + y.x)

so that it wouldn't invalidate other Base methods. But unless there's a way to modify multiple dispatch itself (throughout Julia) to check the parametric type of AbstractTraitWrapper, it doesn't seem possible...

@mauro3
Copy link
Owner

mauro3 commented Jun 20, 2023

I'm not following here:

But unless there's a way to modify multiple dispatch itself (throughout Julia) to check the parametric type of AbstractTraitWrapper, it doesn't seem possible...

You don't refer to above example with that, right?

@MilesCranmer
Copy link
Author

Sorry I was thinking of the example in #87, not the one in here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants