I don't understand this syntax. Documentation request

Hello,

I am cooperating with someone on a Julia package, and I have barely worked in Julia before. I can read the majority of the stuff in the package, but sometimes I get stuck on some syntax that is so different from what I have seen in other languages, that I cannot read it. And sometimes I cannot find documentation in a reasonable time. Here is an example:

isoff(data::Data{T}) where {T} = (T == Tuple{Int64,Int64} || T == Vector{Tuple{Int64,Int64}})

I know what Unionall types are, but I don’t understand any of the following

  1. What is isoff?
  2. If where defines a unionall type, why is there assignment ( = ) on this line? Or perhaps it isn’t an assignment?
  3. How can you have equality comparison on the right-hand side when it seems you are declaring some unionall type under a function isoff?
  4. Why does Tuple have two arguments and not exactly one?
  5. Why would you do boolean or on the right-hand side?
  6. What is the meaning of this line of code?

Any help would be appreciated.

Kind regards from Marius

1 Like

As far as I can tell this is a one line function defintion defining a function isoff which takes in an argument data which is a parametric type and then check whether the type parameter of that particular instance is either a Tuple{Int64, Int64} or a vector of Tuple{Int64, Int64}. Example:

julia> struct Data{T}
          x::T
       end

julia> x = Data((1, 2))
Data{Tuple{Int64, Int64}}((1, 2))

julia> isoff(data::Data{T}) where {T} = (T == Tuple{Int64,Int64} || T == Vector{Tuple{Int64,Int64}})
isoff (generic function with 1 method)

julia> isoff(x)
true

julia> x2 = Data([(1, 2), (3, 4)])
Data{Vector{Tuple{Int64, Int64}}}([(1, 2), (3, 4)])

julia> isoff(x2)
true

julia> x3 = Data("a")
Data{String}("a")

julia> isoff(x3)
false
1 Like

A function can be defined in the standard way:

function foo(x, y)
    return x + y
end

or in the one-line short form way

foo(x, y) = x + y

The short form syntax is for simple functions that can become easier to write and read when used correctly

This:

is, IMHO, a misuse of the short form syntax. It makes the code almost unreadable, especially for those who are not used to it. It is much better to write:

function isoff(data::Data{T}) where {T}
    return (T == Tuple{Int64,Int64}) || (T == Vector{Tuple{Int64,Int64}})
end

Short form syntax should only be used when it improves readability, in the above example it does not.

They are not arguments, but type parameters:

julia> typeof((10, 231))
Tuple{Int64, Int64}

It’s a type of a tuple of two Int64s.

julia> typeof((10, 231, -5))
Tuple{Int64, Int64, Int64}

julia> typeof((10, "Hello", 5.0))
Tuple{Int64, String, Float64}

etc.

2 Likes
  • What is isoff?

isoff is the function that’s being defined here. This line is basically equivalent to:

function isoff(data::Data{T}) where {T}
  return (T == Tuple{Int64, Int64} || T == Vector{Tuple{Int64,Int64}})
end
  • If where defines a unionall type, why is there assignment ( = ) on this line? Or perhaps it isn’t an assignment?

This is the short form a function definition, which uses the assignment syntax. The placement of the where sometimes throws people off, but it should be read as isoff(...) = ... i.e. the assignment is to the method signature, not to {T}.

  • How can you have equality comparison on the right-hand side when it seems you are declaring some unionall type under a function isoff?

I’m not sure what you mean here, but hopefully the previous explanation clears this one up too. The where {T} syntax is being used so that we can then check whether T belongs to one of these two types. The result of that check is the return value of the method.

  • Why does Tuple have two arguments and not exactly one?

Tuples are parametrised by the type of each element of the tuple, so Tuple{Int64, Int64} says that it’s a two-tuple with both elements being Int64s. This can also be written as NTuple{2, Int64}.

  • Why would you do boolean or on the right-hand side?

The right hand side is the return value of the function, and isoff is apparently true if T matches either of those types.

  • What is the meaning of this line of code?

Hope that’s clear from the above!

A more Julian way of writing this function would be to use dispatch:

julia> isoff(data::Data{NTuple{2, Int64}}) = true
isoff (generic function with 1 method)

julia> isoff(data::Data{Vector{NTuple{2, Int64}}}) = true
isoff (generic function with 2 methods)

julia> isoff(data::Data) = false
isoff (generic function with 3 methods)

julia> x = Data((1, 2));

julia> isoff(x)
true

julia> x2 = Data([(1, 2), (3, 4)]);

julia> isoff(x2)
true

julia> x3 = Data("a");

julia> isoff(x3)
false
3 Likes

I get it now. You three were great.

Thanks for your time.

3 Likes