sub field_promotion (Soldier $x is rw) { $x = Private.new; # Private "isa" Soldier, allowed. } my General $y .= new; field_promotion ($y); # General "isa" Soldier, allowed. $y.order_attack(); #### void field_promotion (Soldier& x) { x = Private(); // value assignment slices object (if allowed at all) } #### void field_promotion (Soldier* &x) { x= new Private(); // allowed, and updates caller's pointer variable } void caller() { General* y= new General(); field_promotion (y); // compile-time error } #### our Soldier $x; multi sub trythisone (General $y) { # $y is a read-only alias of the caller's variable, global $x in this case. # This function chosen based on actual type of $x at the time the call was made. $x = Private.new; # what just happened to $y? $y.order_attack(); } $x = General.new; trythisone ($x);