Cursed Custom Infix Operators

Reading this StackExchange page on custom infix operators got me thinking about Julia’s special casing for infix operators and if there was any way to get that kind of expressiveness. Regular macros won’t work since you need to source expression to be parseable.

Then, a totally cursed way to do this occurred to me.

julia> abstract type Infixable <: Function end

julia> struct Infixed{T,O}
           x::T
           op::O
       end

julia> Base.rem(x, op::Infixable) = Infixed(x, op)

julia> Base.rem(infixed::Infixed{<:Any, O}, y) where O = (infixed.op::O)(infixed.x, y)

julia> struct f <: Infixable end

julia>(::typeof(f))(a,b)=a+b

julia> 2 %f% 3
5

julia> 2 %f% 3 + 5
10

I checked to make sure that % doesn’t have any methods that aren’t typed with some kind of Number or Date, so I’m reasonably certain this doesn’t cause any invalidations, but I didn’t check any of the other operators.

That said, you can pick your precedence by changing the operator you use as the wrapper.

PS I’m not saying this advisable… But I am saying Julia’s type system is dope.

6 Likes

In fact, this was already discussed in julia#24404 and julia#16985, inspired by a similar hack in Python, and was implemented in GitHub - Ismael-VC/InfixFunctions.jl: Julia infix function hack.

4 Likes

Awesome! I searched the forum and couldn’t find mention of this. Sorry for the redundant post.