HaxeFoundation / haxe-evolution

Repository for maintaining proposal for changes to the Haxe programming language
111 stars 58 forks source link

constrained properties can be typed if you cheat. #56

Closed nanjizal closed 5 years ago

nanjizal commented 5 years ago

I wrongly assumed that because properties are icing that I could constrain them.

typedef Tpoint = {
  var x:Float;
  var y:Float;
}
class Cpoint {
    public var x: Float;
    public var y: Float;
    public function new( x_: Float = 0, y_: Float = 0 ){
        x = x_;
        y = y_;
    }
}
@:forward
abstract Apoint<T:Tpoint>( T ) to T from T {
    public inline
    function new(  p: T ){
        this = p;
    }
    public var prop<S:Tpoint>( get, set ):Apoint<S>;
    public inline
    function set_prop<S:Tpoint>( a:Apoint<S> ):Apoint<Tpoint> {
        this.x = a.x;
        this.y = a.y;
        return this;
    }
    private inline
    function get_prop<S:Tpoint>(): Apoint<Tpoint> {
      return new Apoint( ( { x: this.x, y: this.y }: Tpoint ) );
    }
}
class Test {
  static function main() {
    trace("Haxe is great!");
    var p0 = new Apoint(new Cpoint());
    var p1 = new Apoint(new Cpoint( 1., 2. ) );
    p0.prop = p1;
    trace('p0' + p0 );
  }
}

Now it was argued that this was not possible but it's clear that the compiler can properly check constraints if you cheat.

typedef Tpoint = {
  var x:Float;
  var y:Float;
}
class Cpoint {
    public var x: Float;
    public var y: Float;
    public function new( x_: Float = 0, y_: Float = 0 ){
        x = x_;
        y = y_;
    }
}
@:forward
abstract Apoint<T:Tpoint>( T ) to T from T {
    public inline
    function new(  p: T ){
        this = p;
    }
    public var prop( get, set ):Dynamic;
    public inline
    function set_prop<S:Tpoint>( a:Apoint<S> ):Apoint<Tpoint> {
        this.x = a.x;
        this.y = a.y;
        return this;
    }
    private inline
    function get_prop<S:Tpoint>(): Apoint<Tpoint> {
      return new Apoint( ( { x: this.x, y: this.y }: Tpoint ) );
    }
}
class Test {
  static function main() {
    trace("Haxe is great!");
    var p0 = new Apoint(new Cpoint());
    var p1 = new Apoint(new Cpoint( 1., 2. ) );
    p0.prop = p1;
    trace('p0' + p0 );
  }
}

Now the argument can be made that because I am using Dynamic types are not checked but if I try set p0.prop = 'fred' then the compiler complains so it is fully typechecked, just I am by passing a check on the actual property. So it must be feasible to support this currently. Obviously also there is the question of different return types so perhaps it's not desired but likely throws up some edge case that are not currently tied down? I would be inclined to continue to use Dynamic for this case but suspect the loop hole will be removed in future.

Simn commented 5 years ago

Wrong repo?

nanjizal commented 5 years ago

Simn I was not sure if it should become a evolution. I can add issue on haxe if you prefer.

Simn commented 5 years ago

I have no idea what this is. If you want to achieve anything here then please minimize your example and formulate what you actually think should change.

nanjizal commented 5 years ago

http://try-haxe.mrcdk.com/#704aC

nanjizal commented 5 years ago

It errors only on the second line it shows that properties can already accept constraints.

Gama11 commented 5 years ago

If I understand this correctly, the basic idea is "allow type parameters on properties".