Syntactic sugar for types

Is this the correct code to add syntactic sugar for types?

Base.:(|)(X::Type, Y::Type) = Union{X,Y}
Base.:(|)(X::TypeVar, Y::Type) = Union{X,Y}
Base.:(|)(X::Type, Y::TypeVar) = Union{X,Y}
Base.:(|)(X::TypeVar, Y::TypeVar) = Union{X,Y}

at first glance everything works

const Maybe{T} = T | Nothing

function foo(x::Maybe{T|S}) where {T<:Integer, S<:AbstractFloat}
    typeof(x)
end

foo(1)

x = Vector{Int|Float32}(undef, 10)

@. foo(x)

Base.@kwdef struct Foo{T<:Integer|AbstractFloat}
    x::Maybe{T} = nothing 
    y::(T|String) = "asd"
end

Foo{Int}()

How else can I test it?

1 Like

Note that technically that’s type piracy as you don’t own the function name nor the argument types, don’t do that.

4 Likes

I mean to do pull request in julia with this code

1 Like

Check this thread

5 Likes

Instead one could define a new | function in a package and import that, and it would be usable without extending Base.:| and making sure nothing broke. Would be strange to sacrifice bitwise-or for that symbol though.

1 Like

No need to sacrifice anything – MyPackage.(|) could just fall back to Base.(|) whenever arguments are not types.

2 Likes

@Mason’s InfixUnions.jl has | available with basically the same implementation in case you want to use an already-registered package instead: GitHub - MasonProtter/InfixUnions.jl

It creates a new function | rather than pirating Base.:(|). Generally you should avoid defining new methods for functions in Base on types that are also in Base. You should only do one or the other (new function on types in Base OR extend a function in Base on new types)

2 Likes

IMO, it’s unlikely to be accepted in the base language. See a long discussion here: Proposed alias for union types - #17 by stevengj

I think the main reason that these proposals have come up only recently, more than a decade into Julia’s development, is type1 | type2 syntax has recently been adopted and popularized in Python. But “spell things more like Python” has never been a huge priority for Julia, especially in cases like this where we have a longstanding existing syntax as well as a longstanding resistance to “punning” (having an operator like | mean two completely different things).

1 Like

Within the lengthy thread on this topic are some comments discussing precisely this point, so I think we should avoid rehashing things. I also have no energy left for this topic (having given up long ago)

@andrey2185 At the end of the day, the nice thing about Julia is that you can just overload | in your config/startup.jl file to use this syntax in your REPL. And if wanting to use it in a package you can just depend on InfixUnions.jl.