During discussion we’ve discovered Crystal has interfaces in Java sense.
Module can have abstract method, and its inclusion demands implementation:
https://play.crystal-lang.org/#/r/e1jl
module Moo
abstract def size : Int
end
struct Fix
include Moo
end
# Error: abstract `def Moo#size()` must be implemented by Fix
Containers could be specialized to modules, function/method could have argument restricted to module, and their call is correctly polymorphic:
https://play.crystal-lang.org/#/r/e1jq
module Moo
abstract def size : Int
end
class Fix2
include Moo
def size : Int; 2; end
end
class Fix3
include Moo
def size : Int; 3; end
end
def say(s : Moo)
puts "size is #{s.size}"
end
say Fix2.new
say Fix3.new
moos = Array(Moo){Fix2.new, Fix3.new}
moos.each{|f| say f}
[Fix2.new, Fix3.new].each{|f| say f}
# size is 2
# size is 3
# size is 2
# size is 3
# size is 2
# size is 3