# Syntactic sugar for types

**URL:** <https://discourse.julialang.org/t/syntactic-sugar-for-types/119685>\
**Category:** General Usage\
**Created:** [September 21, 2024, 10:09pm UTC](https://discourse.julialang.org/t/syntactic-sugar-for-types/119685 "2024-09-21T22:09:27Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![andrey2185](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andrey2185/32/9889_2.png) [@andrey2185](https://discourse.julialang.org/u/andrey2185)\
**Post date:** [September 21, 2024, 10:09pm UTC](https://discourse.julialang.org/t/syntactic-sugar-for-types/119685/1 "2024-09-21T22:09:27Z")

</div>

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

```julia
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

```julia
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?

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [September 21, 2024, 10:11pm UTC](https://discourse.julialang.org/t/syntactic-sugar-for-types/119685/2 "2024-09-21T22:11:57Z")

</div>

> [@andrey2185](#):
>
> Is this the correct code to add syntactic sugar for types?
> 
> ```julia
> 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}
> 
> ```

Note that technically that’s [type piracy](https://docs.julialang.org/en/v1/manual/style-guide/#Avoid-type-piracy) as you don’t own the function name nor the argument types, don’t do that.

---

<div class="post-metadata">

**Author:** ![andrey2185](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andrey2185/32/9889_2.png) [@andrey2185](https://discourse.julialang.org/u/andrey2185)\
**Post date:** [September 21, 2024, 10:17pm UTC](https://discourse.julialang.org/t/syntactic-sugar-for-types/119685/3 "2024-09-21T22:17:11Z")

</div>

I mean to do pull request in julia with this code

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [September 21, 2024, 10:35pm UTC](https://discourse.julialang.org/t/syntactic-sugar-for-types/119685/4 "2024-09-21T22:35:52Z")

</div>

Check this thread

> [@Proposed alias for union types](https://discourse.julialang.org/t/proposed-alias-for-union-types/108205):
>
> The | character is used in a few different languages as a concise way to specify type unions, like in TypeScript, Scala, PHP 8+, Python 3.10+, and (sort of) Haskell. I was curious to hear what people’s initial thoughts would be on having this as a concise way to create Unions. This would be completely backwards-compatible of course; Union by itself would still be Union. Currently | is used for OR, which has close connections to type unions in formal logic (h/t @mkitti in [this](https://discourse.julialang.org/t/proposed-alias-for-union-types/108205/80)). Because of this …

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [September 21, 2024, 10:47pm UTC](https://discourse.julialang.org/t/syntactic-sugar-for-types/119685/5 "2024-09-21T22:47:33Z")

</div>

> [@giordano](#):
>
> that’s [type piracy](https://docs.julialang.org/en/v1/manual/style-guide/#Avoid-type-piracy) as you don’t own the function name nor the argument types,

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.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [September 22, 2024, 12:25am UTC](https://discourse.julialang.org/t/syntactic-sugar-for-types/119685/6 "2024-09-22T00:25:00Z")

</div>

> [@Benny](#):
>
> Would be strange to sacrifice bitwise-or for that symbol though.

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

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [September 22, 2024, 6:04pm UTC](https://discourse.julialang.org/t/syntactic-sugar-for-types/119685/7 "2024-09-22T18:04:13Z")

</div>

@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](https://github.com/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)

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 22, 2024, 6:28pm UTC](https://discourse.julialang.org/t/syntactic-sugar-for-types/119685/8 "2024-09-22T18:28:34Z")

</div>

> [@andrey2185](#):
>
> I mean to do pull request in julia with this code

IMO, it’s unlikely to be accepted in the base language. See a long discussion here: [Proposed alias for union types - #17 by stevengj](https://discourse.julialang.org/t/proposed-alias-for-union-types/108205/17)

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).

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [September 22, 2024, 6:46pm UTC](https://discourse.julialang.org/t/syntactic-sugar-for-types/119685/9 "2024-09-22T18:46:30Z")

</div>

> [@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

Within the lengthy thread on this topic are some comments [discussing precisely this point](https://discourse.julialang.org/t/proposed-alias-for-union-types/108205/23), 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.
