Subtyping allows one type to use all fields and functions of another type without inheritance. It allows for breaking one type into several subtypes without changing dependent code. For example, the compiler will expand A.x into A.position.x if A is a subtype of its field position.
type Defense = object
armor: int
proc defend(defense: Defense) =
echo &"I defend for {defense.armor}"
type Item = object
defense: Defense
# ... and many more fields
converter toDefense(item: Item): Defense = item.defense
let item = Item(defense:Defense(armor:8))
item.defend()
echo item.armor # currently impossible
For example, in the above code, Item can be used as Defense anywhere.
D has a unique syntax alias field this for subtyping.
I don't know any.
I'm pretty sure this can be done with some macros, if there aren't already any.
I think it can only be achieved in compiler. How do you do that with macros?
You use the macro to traverse the type tree of the field marked for aliasing, then add generate a getter for each field, ie:
type
Defense = object
armor: int
Item = object
defense: Defense
macro compose(T: typedesc, f: untyped): untyped =
# get the type passed via T
# traverse the type tree of field with name passed via `f` with getTypeImpl(),
# then generate an accessor for each field of that composed object.
# something like this:
# template armor(i: Item): untyped = i.defense.armor
# then you can do
compose Item, defense
var i = Item()
i.armor = 10
Using macro does not feel right. I still hope there is compiler-level support.
Write an RFC for it here https://github.com/nim-lang/RFCs/issues/ if you really want to have this feature. But beware that D's alias this is not widely regarded as a good idea and that Nim already has the converter construct.