# Restrictive Type Aliases?

**URL:** <https://discourse.julialang.org/t/restrictive-type-aliases/10546>\
**Category:** Performance\
**Created:** [April 25, 2018, 10:03pm UTC](https://discourse.julialang.org/t/restrictive-type-aliases/10546 "2018-04-25T22:03:44Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![nhipsman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nhipsman/32/3263_2.png) [@nhipsman](https://discourse.julialang.org/u/nhipsman)\
**Post date:** [April 25, 2018, 10:03pm UTC](https://discourse.julialang.org/t/restrictive-type-aliases/10546/1 "2018-04-25T22:03:44Z")

</div>

Hi,

I’m trying to define a type alias in a way that is actually restrictive. For instance, distance travelled = rate \* time, where all 3 (distances, rates, and times) are inherently floats. I want to define 3 types: a “distance,” a “rate,” and a “time,” each of which is “really” just a float. However, I want to create a function (for instance, “distance\_travelled”) that must take exactly one rate, and then exactly one time. Now this particular example might be doable with primitive types, except that I actually want _vectors of floats_, not just floats, for each of the three types.

For now, my workaround is to define three structs, each of which has just a single component - a vector of floats. But I’m concerned about possible performance losses from retrieving values from those structs, as well as just lack of elegance.

Perhaps I’m missing something quite straightforward - I apologize if that’s the case.

Thanks

---

<div class="post-metadata">

**Author:** ![simonbyrne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simonbyrne/32/19_2.png) [@simonbyrne](https://discourse.julialang.org/u/simonbyrne)\
**Post date:** [April 25, 2018, 10:10pm UTC](https://discourse.julialang.org/t/restrictive-type-aliases/10546/2 "2018-04-25T22:10:36Z")

</div>

Structs should work, and the performance overhead shouldn’t be too bad as immutable containers in most cases should be elided at compile time.

Or you could just use [Unitful.jl](https://github.com/ajkeller34/Unitful.jl):

```julia
julia> import Unitful: km, hr

julia> rate = 60km/hr
60 hr^-1 km

julia> time = 3.14hr
3.14 hr

julia> rate*time
188.4 km

```

Vectors of these should mostly just work as well.

---

<div class="post-metadata">

**Author:** ![y4lu](https://avatars.discourse-cdn.com/v4/letter/y/47e85d/32.png) [@y4lu](https://discourse.julialang.org/u/y4lu)\
**Post date:** [April 26, 2018, 2:00am UTC](https://discourse.julialang.org/t/restrictive-type-aliases/10546/3 "2018-04-26T02:00:09Z")

</div>

`function x(z::Array{Float64,1})` will restrict the input arg to a 1d array of floats  
Otherwise the `.()` function variant could be used

```julia
function vdist(xrate::Float64, xtime::Float64)
  return xrate * xtime;
  end;

r1 = collect(1:1.3:10);
t1 = r1[end:-1:1];

d1 = vdist.(r1, t1);
```

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [April 26, 2018, 6:51pm UTC](https://discourse.julialang.org/t/restrictive-type-aliases/10546/4 "2018-04-26T18:51:20Z")

</div>

> [@nhipsman](#):
>
> But I’m concerned about possible performance losses from retrieving values from those structs

Don’t be. There is little to no overhead in accessing a field from a struct, as long as that field has a concrete type in the struct definition. Julia is less like Python (in which even looking up a single field involves accessing a dictionary) and more like C (in which structs exist only to help the programmer and have little to no runtime cost) in this regard.

And if you’re really concerned about performance, [GitHub - JuliaCI/BenchmarkTools.jl: A benchmarking framework for the Julia language](https://github.com/JuliaCI/BenchmarkTools.jl) is your friend 🙂

---

<div class="post-metadata">

**Author:** ![ederag](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ederag/32/4106_2.png) [@ederag](https://discourse.julialang.org/u/ederag)\
**Post date:** [June 10, 2018, 8:55pm UTC](https://discourse.julialang.org/t/restrictive-type-aliases/10546/5 "2018-06-10T20:55:40Z")

</div>

Had the same problem, for dimensionless quantities (relative dielectric function: epsilon, refractive index: n).  
Unitful.jl seems overkill here (and does not work under 0.7 yet), since these quantities are basically complex numbers.

A single field struct is ugly.

It does not seem possible to subtype from a concrete type, as explained [here](https://github.com/JuliaLang/julia/issues/9821#issuecomment-70381499).

So let’s define a primitive type such as  
`primitive type Float_n <: AbstractFloat 64 end`  
using `reinterpret` as explained in [Implementing custom primitive types in Julia - Stack Overflow](https://stackoverflow.com/a/49582867/3565696)  
allows back and forth conversions between `Float64` and the custom `Float_n`.

```julia
# base Float type for refractive index n
primitive type Float_n <: AbstractFloat 64 end
Float_n(x::Float64) = reinterpret(Float_n, x)
# back to Float64
Float64(x::Float_n) = reinterpret(Float64, x)
# allow the REPL to show values of type Float_n
Base.show(io::IO, x::Float_n) = print(io, Float64(x))
# overload operators
Base.:+(x::Float_n, y::Float_n) = Float_n(Float64(x) + Float64(y))
Base.:-(x::Float_n, y::Float_n) = Float_n(Float64(x) - Float64(y))
Base.:*(x::Float_n, y::Float_n) = Float_n(Float64(x) * Float64(y))
Base.:/(x::Float_n, y::Float_n) = Float_n(Float64(x) / Float64(y))
# In my application it makes sense for mixed arguments operations to yield Float64
# it is always possible to explicitly reinterpret the result back to Float_n
Base.promote_rule(::Type{Float_n}, ::Type{Float64}) = Float64

julia> Float_n(1.0)
1.0

julia> typeof(ans)
Float_n

```

preliminary benchmarks look fine:

```julia
julia> using BenchmarkTools
julia> @btime Float_n(1.0) + Float_n(2.0)
  0.014 ns (0 allocations: 0 bytes)
julia> @btime 1.0 + 2.0
  0.014 ns (0 allocations: 0 bytes)
@btime Float_n(1.0) + 2.0
  0.014 ns (0 allocations: 0 bytes)

```

This is not perfect:

```julia
julia> a = rand(Float_n, 10000);
ERROR: ArgumentError: Sampler for this object is not defined

```

It would be nice for `Float_n` to work as `Float64` when a method does not match.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 11, 2018, 5:54am UTC](https://discourse.julialang.org/t/restrictive-type-aliases/10546/6 "2018-06-11T05:54:44Z")

</div>

You would need to define

```julia
Base.rand(::Type{Float_n}, ...)

```

or, in `v0.7`, you can use the `Sampler` mechanism.

> [@ederag](#):
>
> It would be nice for `Float_n` to work as `Float64` when a method does not match.

I don’t think it is possible, and I don’t think it would be nice either, as `Float_n` above violates some basic assumptions about arithmetic, eg:

> [@ederag](#):
>
> ```julia
> Base.:-(x::Float_n, y::Float_n) = Float_n(Float64(x) + Float64(y))
> Base.:*(x::Float_n, y::Float_n) = Float_n(Float64(x) + Float64(y))
> Base.:/(x::Float_n, y::Float_n) = Float_n(Float64(x) + Float64(y))
> 
> ```

so an unsuspecting user would get unexpected behavior.

---

<div class="post-metadata">

**Author:** ![ederag](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ederag/32/4106_2.png) [@ederag](https://discourse.julialang.org/u/ederag)\
**Post date:** [June 11, 2018, 7:41am UTC](https://discourse.julialang.org/t/restrictive-type-aliases/10546/7 "2018-06-11T07:41:12Z")

</div>

> [@Tamas\_Papp](#):
>
> I don’t think it is possible, and I don’t think it would be nice either, as `Float_n` above violates some basic assumptions about arithmetic

Good catch, wrong copy/paste. Edited now, because it would be distracting. Thanks !

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [June 11, 2018, 8:07am UTC](https://discourse.julialang.org/t/restrictive-type-aliases/10546/8 "2018-06-11T08:07:18Z")

</div>

I’ve known it was possible to define ones own primitive types but I’ve never seen it done before.  
Nice.

I’m not sure that doing so is a good idea, but ~shrug~.

I feel like there has been a discussion of such a restrictive type alias before.  
I think it would be useful.

The properties one wants really are that  
for `XX` being a restrictive type alias of `X`,  
then `XX` is the closest subtype of `X`, and that `X` can be a concrete type.  
So `foo(::XX)` would be considered more specific than `foo(::X)` for dispatch purposes.  
You could even reasonably chain them I guess, making `XXX` a restrictive type alias of `XX`.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 11, 2018, 8:13am UTC](https://discourse.julialang.org/t/restrictive-type-aliases/10546/9 "2018-06-11T08:13:37Z")

</div>

> [@ederag](#):
>
> Unitful.jl seems overkill here (and does not work under 0.7 yet), since these quantities are basically complex numbers.

I am assuming that it will be fixed eventually for v0.7. I am not sure in what sense you consider it “overkill”, I think it is a convenient solution with nearly zero additional runtime cost (except for a bit of compilation of course).

Also, unless I want to twiddle bits, I would just define a wrapper type.

---

<div class="post-metadata">

**Author:** ![ederag](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ederag/32/4106_2.png) [@ederag](https://discourse.julialang.org/u/ederag)\
**Post date:** [June 11, 2018, 8:58pm UTC](https://discourse.julialang.org/t/restrictive-type-aliases/10546/10 "2018-06-11T20:58:37Z")

</div>

> [@Tamas\_Papp](#):
>
> I am not sure in what sense you consider it “overkill”

After reading twice the documentation, it looks like a complex package,  
and I am still unsure how to use it for these dimensionless quantities.  
I’ll try again when it is 0.7-ready.

> [@Tamas\_Papp](#):
>
> I would just define a wrapper type.

What is a “wrapper type” ? How would you do that ?

---

<div class="post-metadata">

**Author:** ![ederag](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ederag/32/4106_2.png) [@ederag](https://discourse.julialang.org/u/ederag)\
**Post date:** [June 11, 2018, 9:28pm UTC](https://discourse.julialang.org/t/restrictive-type-aliases/10546/11 "2018-06-11T21:28:01Z")

</div>

> [@oxinabox](#):
>
> I’m not sure that doing so is a good idea, but ~shrug~.

Me neither, just experimenting 😉

> [@oxinabox](#):
>
> I feel like there has been a discussion of such a restrictive type alias before.  
> I think it would be useful.

This issue (already cited) was interesting

> <https://github.com/JuliaLang/julia/issues/9821#issuecomment-70381499>
>
> I've addressed this feature multiple times, but never really got feedback on it,… so I decided to open an issue for it, as I keep coming back to it as a very elegant solution to many problems.
> I hope you can answer at least, how feasible this is, what needs to be done for it (so that I can maybe implement it myself, if no one has the time), or explain me why this is a silly idea.
> \##### What I want:
> 
> \`\`\` Julia
> \# Introducing a new type, in a typealias like fashion.
> \# first syntax idea
> hardtypealias RGB{T \<: FloatingPoint} NTuple{3, T}
> \# second syntax idea
> immutable Meter{T \<: Real} \<: T
> \# third syntax idea
> concrete FixedMatrix{T, M, N} \<: NTuple{NTuple{M, T}, N} # in constrast to abstract
> \`\`\`
> 
> Intended semantic: The first type (e.g. RGB) is a either subtype of the second (e.g NTuple), or has the type Union(RGB, NTuple).
> I'm not sure what makes more sense. But it should solve the following problem:
> 
> \> There is an already existing type and one wants to add functions to it, without adding them to the original type.
> 
> This behavior is wanted in a myriad of cases and I've seen workarounds for this situation in many packages (including mine).
> \### Examples
> 
> A few examples, which can be elegantly implemented with this feature, which assume, that NTuple implements common, simd accelerated, vector operations
> \#### Adding functions to an existing type:
> 
> \`\`\` Julia
> \# under the assumption, that NTuple implements common vector operations
> immutable RGB{T} \<: NTuple{3, T}
> 
> \# under the assumption, that getfield can be extended
> Base.getfield(c::RGB, ::Field{:r}) = c\[1\]
> Base.getfield(c::RGB, ::Field{:g}) = c\[2\]
> Base.getfield(c::RGB, ::Field{:b}) = c\[3\]
> \# which gives you the access to RGB which you'd expect from it.
> \# could also be implemented with a macro: @accessors RGB :r =\> 1, :g =\> 2, :b =\> 3 
> \# So this works:
> a = RGB(0.1,0.2,0.3)
> a+a # is implemented by NTuple
> a.r # implemented by RGB
> \#Should not work:
> (1,2,3).r
> \`\`\`
> 
> To further dwell on the point, that we can have a diversity of simd accelerated Vector types, with minimal re-implementation of common functionality, here is another example:
> \#### Adding Semantic to generic Types
> 
> \`\`\` Julia
> immutable Point{T, N} \<: NTuple{N, T}
> immutable RGB{T, N} \<: NTuple{N, T}
> 
> immutable Red{T \<: Real} \<: T
> immutable Green{T \<: Real} \<: T
> immutable Blue{T \<: Real} \<: T
> 
> red = Red(1f0) # -\> this will behave exactly like a normal Float32 value 
> \# making it unnecessary, to re-implement all the operations on it
> 
> immutable X{T \<: Real} \<: T
> immutable Y{T \<: Real} \<: T
> immutable Z{T \<: Real} \<: T
> 
> Base.getfield(c::RGB, field::Type{Red}) = Red(c\[1\])
> ...
> Base.getfield(p::Point, field::Type{X}) = X(p\[1\])
> ...
> Base.getfield(p::Matrix{RGB}, field::Type{Red}) = ... # -\> Matrix{Red}
> Base.getfield(p::Matrix{Point}, field::Type{X}) = ... # -\> Matrix{X}
> ...
> image = \[RGB(1f0, 0f0,0f0) for i=1:512, j=1:512\]
> points = \[Point(1f0, 0f0,0f0) for i=1:512, j=1:512\]
> 
> redchannel = image.Red
> zplane = image.Z
> \`\`\`
> \###### Now the big magic, won by more type information
> 
> \`\`\` Julia
> visualize(image) # -\> rgb image display
> visualize(points) # -\> point cloud 
> visualize(redchannel) # I can actually infer what the user wants to see: a red intensity image
> visualize(zplane) # Again, it's relatively clear what is expected here: a heightfield
> \`\`\`
> 
> This would be pretty much the paradise for any visualization library. Also, visual debugging is made a lot easier, as the debugger doesn't need any magic to infer how it needs to visualize some random variable.
> But this matters for more than that, as it becomes easier to do the correct thing with any value.
> I you want to see something else, for example the pixel of the image in RGB space, you can simply reinterpret the RGB to Point (which has O(1)), which can be useful to make out color clusters.
> \#### Let function bodies only do, what is implied by their function name
> 
> Compare these two implementations:
> 
> \`\`\` Julia
> \#First implementation of matrix multiplication
> function (\*)(a::Matrix, b::Matrix) 
> @assert size(a, 2) == size(b, 1) #This isn't part of the multiplication code
> #matrix multiplication code
> end
> \# This is probably a matter of taste, but I like this implementation more:
> FixedSizeArray{SZ, T, N} \<: Array{T,N}
> Base.call{T,N}(::Type{FixedSizeArray}, x::Array{T,N}) = FixedSizeArray{size(x), T,N}(x)
> function (\*)(a::Matrix, b::Matrix) 
> return (FixedSizeArray(a) \* FixedSizeArray(b))
> end
> \# Like this, in the function body is only, what is really part of the matrix multiplication:
> function (\*)(a::FixedMatrix{T, N, M}, b::FixedMatrix{T, M, P})
> # code for multiplication of matrices with well suited dimensions
> end
> function (\*)(a::FixedMatrix, b::FixedMatrix)
> \# code for multiplication of matrices with arbitrary dimensions
> \# which usually throws an error
> end
> \`\`\`
> 
> This all is mostly graphic related, which isn't a big surprise considering my background. But I'm pretty sure, that there are good use cases for other fields ;)
> But I better not iterate more use cases here, as this would turn even more into a novel.
> 
> Hope we can realize this in some way!
> 
> Best,
> Simon

but in my use case, the fragility does not matter.

> [@oxinabox](#):
>
> The properties one wants really are that  
> for `XX` being a restrictive type alias of `X` ,  
> then `XX` is the closest subtype of `X` , and that `X` can be a concrete type.  
> So `foo(::XX)` would be considered more specific than `foo(::X)` for dispatch purposes.  
> You could even reasonably chain them I guess, making `XXX` a restrictive type alias of `XX` .

Exactly.  
This would be greatly eased if defining a fallback type were possible.  
(if a method is not found for Float\_n, fall back to Float64)

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 12, 2018, 4:54am UTC](https://discourse.julialang.org/t/restrictive-type-aliases/10546/12 "2018-06-12T04:54:25Z")

</div>

> [@ederag](#):
>
> What is a “wrapper type” ? How would you do that ?

```julia
struct Float_n
    val::Float64
end

Base.:+(x::Float_n, y::Float_n) = Float_n(x.val + y.val)

```

etc.
