Calling a function by argument type only

I have seen functions defined without argument values, just types for dispatch as so:

function foo(::Int, n)
  return Int(n)
end

First question: What is this type-only argument style called? I can’t seem to find its documentation.

Second question: Is there a way to call such a function without passing a value for the first argument? In principle, something like foo(::Int, 4) could be possible (but I’m not sure if it’s supported or considered somehow unjulian).

Thanks!

1 Like

The usage is probably related to what’s called Traits, or Holy Traits, after Tim Holy. Check out Types · The Julia Language

1 Like

Is there a way to call such a function without passing a value for the first argument?

If the function takes a “regular” type, as opposed to a type of a type (Type{X}), then no. It all depends on the function’s type signature.

2 Likes
f(::Int)

Just means that you won’t use the value of the argument in your function. It’s otherwise the same thing as f(x::Int). If you want a function that accepts a type object, not an instance, you write g(T::Type{Int}) (or indeed g(::Type{int})).

These are called as f(3) and g(Int) respectively.

4 Likes

Aha, so I’m guessing I need to bite the bullet and refactor a little like,

function foo(type, n)
  type==Int && return Int(n)
end

function foo(::Int, n)
  return foo(Int, n)
end

Thanks! Also thanks to @nsajko for the reference to Holy Traits. I’ve seen references to this before but now might be a good time to dig into it and see if they can help me in my current project.

@jeffreyesun, I’m not totally sure what is it that you want to do, could you clarify your goal?

For example, I guess that you want to dispatch on some constant, so maybe Enums would be useful instead?

EDIT: also be aware that passing types as arguments is actually discouraged, as described in one paragraph of the manual section I linked to.

1 Like

No, dispatch is definitely the way you want to do that, but you dispatch on the type Type{Int}, rather than Int. Try typeof(Int) to see why.

And if you ever do compare Types, you probably want T <: Int rather than T == Int. It will succeed if T isa Int64 too, for instance.

2 Likes

If you want to test your program, you’d generate a random value for the first argument.
I don’t think it a good idea to allow passing in both Int itself and its instances.

1 Like