Currently dm for all purely functional purposes supports using interfaces. As an example, this works exactly as intended:
/interface/explodable/proc/explode()
// This space intentionally left blank
/obj/bomb/proc/explode()
// Do explosion things
/proc/blow_up_turf_with_something(turf/place, bombtype=/obj/bomb)
var/interface/explodable/explosive = new bombtype(place)
explosive.explode()
You could take the above and make a subtype of mob that's explodable and use it in blow_up_turf_with_something(place, /mob/bomber) too, it's a nice pattern that allows types that share no internal logic but do share capabilities.
There's a problem here though, this is not compile time enforced at all and unintuitive when reading. Using this pattern currently would be a recipe for disaster if anyone ever wants to try adding functionality to the interface. You also can't easily check in user code if something actually properly implements everything needed for the interface.
Fixing this is fairly simple for syntax, and hopefully also fairly simple in the internal compiler code since I don't *think* it's doing anything particularly new. We need a few things:
* A way to specify what interfaces a type is implementing
* (Optional) A way to check in runtime code if a type/instance implements a particular interface
* (Optional) An interface type which can not be instanced or have any defined behavior or assigned values
--- Implementation syntax
The syntax for specifying which interfaces are being implemented should be able to accept more than one interface. We have two main options I see there:
Piggybacking off the existing type values and just making an interfaces variable
/obj/bomb
interfaces = list(/interface/explodable)
Or we could add a new syntax entirely more similar to how other languages do it
/obj/bomb #(/interface/explodable)
The point is though the compiler needs to know what interface a type is implementing so it know to error when that type does not implement all the expected procs and variables required by that interface.
--- Runtime checks
This is fairly simple, interface versions of istype() and ispath() would be just fine. Perhaps named isimplementor()?
--- An interface type
Very optional. An interface type which can't be instanced or have any default logic and behavior makes it a bit easier avoid strange occurrences.
There is an existing "plan" for a hasinterface() proc, but it's ancient:
252 Release Notes:
(see The Grey Book for more of these)