# "where" syntax

#1

I’m trying to update the following code (taken from an Andreas Noack talk) from to julia-0.5 to julia-0.6. The GF{P,T} type represents a finite Galois field, essentially the integers modulo P where P is prime.

``````# Scalar finite fields. P is the modulus, T is the integer type (Int16, Int32, ...)
immutable GF{P,T<:Integer} <: Number
data::T
function GF(x::Integer)
return new(mod(x, P))
end
end
``````

julia-0.6 gives the warning

``````WARNING: deprecated syntax "inner constructor GF(...) around REPL[6]:5".
``````

What is the correct revision of the `immutable GF` type declaration? I’ve read documentation and have tried a number of things, but Im afraid I can’t figure it out.

#2
``````julia> struct GF{P,T<:Integer} <: Number
data::T
function GF{P,T}(x::Integer) where {P, T}
return new(mod(x, P))
end
end
``````

#3

As suggested by the warning, you should do:

``````struct GF{P,T<:Integer} <: Number
data::T
GF{P,T}(x::T) where {P,T<:Integer} = new(mod(x, P))
end
``````

You can also add an outer constructor

``````GF{P}(x::T) where {P,T<:Integer} = GF{P,T}(x)
``````

to avoid needing to call `GF{6,Int}(7)`, and instead only specify the modulus: `GF{6}(7)`

#4

@cstjean & @jebej, thank you!

Canyou explain the difference between `GF{P,T}(x::Integer) where {P, T}` and `GF{P,T}(x::T) where {P,T<:Integer}` in your answers? Both work, but I don’t understand what the first accomplishes.

@jebej your outer constructer prevents an infinite loop that otherwise occurs during instantiation of `GF{9}(5)`, which was the next item on my agenda. Thanks for that, too.

#5

Note that with the new syntax, you can now also do

``````julia> struct GF{P,T<:Integer} <: Number
data::T
function GF{P}(x::Integer) where P
data = mod(x, P)
new{P, typeof(data)}(data)
end
end

julia> GF{4}(15)
GF{4,Int64}(3)
``````

#6

In that case I believe the two methods will be identical. I wrote it that way to be explicit that the parameter `T` will be the type of `x`.

#7

They won’t necessarily do the same thing if `typeof(x)` is not the same as `T`. The syntax `GF{P,T}(x::Integer)` allows you to specify the type of the `data` field of `GF` directly, independent of the type of `x` (but still constrains `x` to be an `Integer`, of course). So it allows `GF{4,Int64}(Int32(4))`, for example.

#8

I don’t understand the purpose of `where {P,T}` below. What information is that providing to the compiler?

I can better understand the point of `where` in @jebej’s `GF{P,T}(x::T) where {P,T<:Integer} = new(mod(x, P))`. It’s specifying that this function aapplies only when `T` is a subtype of `Integer`. But in the other case, it looks like the compiler is requiring me to provide a constraint that is empty.

I clearly don’t understand the `where` keyword. It is brought up incidentally in the Types and Methods pages of https://docs.julialang.org, but I don’t find an explanation anywhere of its purpose with simple explanatory examples of its main uses. Where should I look for that? An issue on Julia github?

#9

Stefan has a really excellent answer justifying the new where syntax on stackoverflow.

#10

The stackoverflow discussion lalso ead me to this where syntax thread on Discourse from July --which I would have found had I searched “where syntax” Discourse instead of Google in the first place. Thanks everyone for the help.