Technical term for "operator inference" related to multiple dispatch

I have defined the operator < for my custom type Person:

begin
	struct Person
	    name::String
	    age::Int
	end
	
	import Base: <
	
	function <(a::Person, b::Person)::Bool
	    return a.age < b.age
	end
	
	# Example usage
	person1 = Person("Alice", 30)
	person2 = Person("Bob", 25)
	
	println(person1 < person2)  # This will print "false" because 30 is not less than 25
	println(person2 < person1)  # This will print "true" because 25 is less than 30

    # ---- inference ??????
	println(person2 > person1)  # This will print "false" because 25 is less than 30
	
end

In my last println, it seems that Julia inferred how the > operator should behave for my custom type, even though I didn’t define it, which is great. :clap:

My question is, what is this mechanism called? (By ‘mechanism’, I mean the behavior where, if the user defines operator X, Julia generates code for operator Y, given that there is a relationship between X and Y.)

N.B.: Sorry for the horrible title; I’m not sure how to express this.

This occurs because how > is implemented:

>(x, y) = y < x

I don’t know if there is any sophysticated thing to call it :slight_smile: . If you implemented > first, you would have find it less magical:

julia> struct A x end

julia> import Base: >

julia> >(a::A, b::A) = a.x > b.x
> (generic function with 4 methods)

julia> A(2) > A(1)
true

julia> A(2) < A(1)
ERROR: MethodError: no method matching isless(::A, ::A)

2 Likes

We often call these sorts of definitions “generic” or “fallback” implementations. Functions in Julia have a meaning — and in some cases it’s possible to define implementations for Any arguments based on other methods.

5 Likes

Ah, you’re right, it makes sense… I also have just found in the docs:

Generally, new types should implement < instead of this function, and rely on the fallback definition >(x, y) = y < x.

EDIT: it’s less impressive now, because I thought there is some sort of multiple dispatch mechanism that infers this, but it’s actually just the implementation

thank you

Matter of perspective :slight_smile: One could also find it impressive how easy it is to write generic, performant code. The default implementation in case implements > for all arguments exactly as fast as the hand-written counterpart < in a single line of code. Sure while this is an almost trivial example, it does still show the simplicity and power of Julia imo :slight_smile:

7 Likes

I agree, and I don’t deny that :slight_smile:
I was referring to that “imaginary/magical mechanism” that does the inference :rofl: