Unfortunately, this is simply not possible at 0.3. call overloading is one of the great new features that will be available in version 0.4. This function is required to call an incompletely parameterized type of type GF{2} . Andreas seems to be using the 0.4-dev version for this demo; if you want to directly follow his demo, I would recommend doing the same.
Details and workaround:
In 0.3, you call the internal constructor of the type, just calling the type, but it must be specific (or [leaf]). This means that it must be fully parameterized if it has type parameters. In this case, this means that you will need to manually specify the integer type to call the internal constructor: GF{2,Int}(5) .
You can also define external constructors that look and behave just like a generic function that has the same base name. You can add type parameters to generic functions, but although they look similar to type parameters (especially when the names are the same), they behave differently! Function parameters define a local variable that will be used to match argument types. That's why your definition of GF{P}(x::Integer) = GF{P,Int64}(x) throws this warning: since you never use P to determine argument types, Julia will not be able to determine what P should be, and therefore, it will never be called. We could create a function that always does GF{2} :
julia> GF2{T}(x::T) = GF{2,T}(x)
Please note that I did not indicate what T should be when I called GF2 - Julia understood this. This is just confusing when you define an external constructor for a parameterized type, since GF{P}(x::Integer) = โฆ is an overlapping point where the function parameter and type parameter look the same! The function option wins, and therefore, while you can define an external constructor with parameters, these parameters mean something else, and you call the external constructor without them: GF(โฆ) . You can call the internal constructor, but there you must specify all the parameters: GF{2, Int}(โฆ) . There is no middle place at 0.3.
This changes to 0.4: now you can determine what happens when you call an arbitrary object! That function call{P}(::Type{GF{P}}, x::Integer) defines: if you call the incomplete type GF{2} , then this method will be called using P=2 . In fact, this generalizes external constructors. The external constructor (even if it is parameterized) is simply a โsugarโ for defining call(::Type{GF}, x::Integer) for type GF without any parameters. So this is how 0.4 provides all kinds of excellent call overload behavior.
If you really want to make this work 0.3, you can either define functions like GF2 above that hard code, the value of P , or you can make the type less flexible:
immutable GF{P} <: Number data::Int function GF(x::Integer) return new(mod(convert(Int, x), P)) end end
Now the internal constructor is exactly what you wanted: GF{P} , so you can directly call GF{2}(5) . But you have lost flexibility in the integer type used. There are other tricks, but at a different time.