Unexpected result of type checking

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Unexpected result of type checking

Dmitry Kosarev
Hello all!
this is a part of code.

interface II {}
class A implements II {
  public function new() {}
}
 
class Test {
  static function main() {
        var s : Array<II> = [new A()];  /// line 8
  }
}

I've expected that everything is fine, but...

Test.hx:8: characters 1-31 : Array<A> should be Array<II>
Test.hx:8: characters 1-31 : A should be II

Where a mistake is?
 
Best wishes,
Kosarev Dmitry

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected result of type checking

Cauê W.
it's a problem with the type inferencing system. Since all your instances are of type A, it infers the array to be of type Array<A>, which isn't compatible with Array<II> . Are you using the nightlies? I have the impression that Nicolas fixed that, I'm not sure though.

By now, though, you can do an unsafe cast and all will be fine : )

2011/9/2 Dmitry Kosarev <[hidden email]>
Hello all!
this is a part of code.

interface II {}
class A implements II {
  public function new() {}
}
 
class Test {
  static function main() {
        var s : Array<II> = [new A()];  /// line 8
  }
}

I've expected that everything is fine, but...

Test.hx:8: characters 1-31 : Array<A> should be Array<II>
Test.hx:8: characters 1-31 : A should be II

Where a mistake is?
 
Best wishes,
Kosarev Dmitry

--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected result of type checking

jlm@justinfront.net
Yer your typing it one way and infering it another... kind of confusing for the compiler. I think the [] is a nice short cut and passing in initial values is less verbose, but it's more proper to use new Array() and push the value on, I would try that as I think that would work, even if it would be nice if it worked the way you have it, so you can try... 

 var s : Array<II> = new Array();
s.push( new A() );
 

Cheers 

;j

On 2 Sep 2011, at 13:11, Cauê Waneck wrote:

it's a problem with the type inferencing system. Since all your instances are of type A, it infers the array to be of type Array<A>, which isn't compatible with Array<II> . Are you using the nightlies? I have the impression that Nicolas fixed that, I'm not sure though.

By now, though, you can do an unsafe cast and all will be fine : )

2011/9/2 Dmitry Kosarev <[hidden email]>
Hello all!
this is a part of code.

interface II {}
class A implements II {
  public function new() {}
}
 
class Test {
  static function main() {
        var s : Array<II> = [new A()];  /// line 8
  }
}

I've expected that everything is fine, but...

Test.hx:8: characters 1-31 : Array<A> should be Array<II>
Test.hx:8: characters 1-31 : A should be II

Where a mistake is?
 
Best wishes,
Kosarev Dmitry

--
haXe - an open source web programming language
http://haxe.org

--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

HA: [haXe] Unexpected result of type checking

Dmitry Kosarev
I understand that there is backdoor to initialize array, but my original target was to write something like LINQ to XML

new XElement("root",[
  new XElement("son",[]);
  new XAttribute("a","b")
]

Any ideas when new version of Haxe will be released?

С уважением,
Косарев Дмитрий
________________________________________
От: [hidden email] [[hidden email]] от имени [hidden email] [[hidden email]]
Отправлено: 2 сентября 2011 г. 16:25
Кому: The haXe compiler list
Тема: Re: [haXe] Unexpected result of type checking

Yer your typing it one way and infering it another... kind of confusing for the compiler. I think the [] is a nice short cut and passing in initial values is less verbose, but it's more proper to use new Array() and push the value on, I would try that as I think that would work, even if it would be nice if it worked the way you have it, so you can try...

 var s : Array<II> = new Array();
s.push( new A() );


Cheers

;j

On 2 Sep 2011, at 13:11, Cauê Waneck wrote:

it's a problem with the type inferencing system. Since all your instances are of type A, it infers the array to be of type Array<A>, which isn't compatible with Array<II> . Are you using the nightlies? I have the impression that Nicolas fixed that, I'm not sure though.

By now, though, you can do an unsafe cast and all will be fine : )

2011/9/2 Dmitry Kosarev <[hidden email]<mailto:[hidden email]>>
Hello all!
this is a part of code.

interface II {}
class A implements II {
  public function new() {}
}

class Test {
  static function main() {
        var s : Array<II> = [new A()];  /// line 8
  }
}

I've expected that everything is fine, but...

Test.hx:8: characters 1-31 : Array<A> should be Array<II>
Test.hx:8: characters 1-31 : A should be II

Where a mistake is?

Best wishes,
Kosarev Dmitry

--
haXe - an open source web programming language
http://haxe.org

--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected result of type checking

Johann Borck
In reply to this post by Dmitry Kosarev
On 09/02/2011 11:56 AM, Dmitry Kosarev wrote:
Hello all!
this is a part of code.

interface II {}
class A implements II {
  public function new() {}
}
 
class Test {
  static function main() {
        var s : Array<II> = [new A()];  /// line 8
  }
}

I've expected that everything is fine, but...

Test.hx:8: characters 1-31 : Array<A> should be Array<II>
Test.hx:8: characters 1-31 : A should be II

Where a mistake is?
 
Best wishes,
Kosarev Dmitry

Arrays in haxe are not covariant (see the link below), which is simply correct. Run the following code:

/*    start  */
using Lambda;

interface II {}

class A implements II {
  public function new() {}
  public function a_only();
}

class B implements II {
  public function new() {}
}

class Test {
 
  static function t1(){
      var a_arr : Array<A> = [new A(),new A()];
      var ii_arr : Array<II> = cast a_arr;
     
      ii_arr.push(new B());
     
      for (a in a_arr){
          a.a_only();
      }
  }
 
  static function t2(){
           
      var a_arr : Array<A> = [new A(),new A()];
      var ii_arr : Array<II> = a_arr.map(a2ii).array();
     
      ii_arr.push(new B());
     
      for (a in a_arr){
          a.a_only();
      }
  }
 
  static function a2ii(a:A):II{
      return a;
  }
 
  static function main() {
      t2();
      t1();
  }
}
/*  end  */

it will fail to execute with an "Uncaught exception - Invalid call".

The compiler doesn't complain when compiling Test.t1, because you force it to shut up by using the unsafe cast. But a *mutable* Array<A> is not a *mutable* Array<II>, because you can add non-As to an Array<II>. If it was immutable, e.g. ImmutableArray<A>, it actually would be covariant, and an instance of type ImmutableArray<II>, since there would be no way to mutate it to a non-ImmutableArray<A>. Hm.. sounds a bit like a tautology, doesn't it.  Java and C# arrays have mutable covariant Arrays, IOW they allow you to do write unsafe code, and throw exceptions at runtime, instead of complaining about the misuse of the Array at compile time. Haxe is safer in that regard.
Now look at Test.t2, no unsafe cast is used here, instead you create a new Array, that actually is of type Array<II>, and there you can safely append an Element of type B, without having to fear exceptions. Because you left the original a_arr untouched, there won't be an Invalid Call in this example, of course.
Be careful, however, when creating arrays with different types like [new A(), new B()], the haxe compiler will type that as Array<Dynamic>, and all static type safety with respect to the elements of that Array is lost.

see also here: http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)

regards,
Johann








--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected result of type checking

Jan_Flanders


On Fri, Sep 2, 2011 at 3:24 PM, Johann Borck <[hidden email]> wrote:
Hi,
There is a related (older) forum thread which never really got resolved. Could you explain the described issue or confirm that it has to be posted as a bug? (That is unless this was fixed in the mean time).
http://haxe.org/forum/thread/1040

Thanks.

Jan

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected result of type checking

Nicolas Cannasse
Le 02/09/2011 16:40, Jan Flanders a écrit :

>
>
> On Fri, Sep 2, 2011 at 3:24 PM, Johann Borck <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     __
>     Array is lost.
>
>     see also here:
>     http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
>     <http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29>
>
> Hi,
> There is a related (older) forum thread which never really got resolved.
> Could you explain the described issue or confirm that it has to be
> posted as a bug? (That is unless this was fixed in the mean time).
> http://haxe.org/forum/thread/1040

It was never reported and is still not fixed :)

The issue here is that any field of a Dynamic value is inferred as
Unknown and Unknown gets unified with Int before Float. So it will cast
points[0].x to Int before making the mult, resulting in zero.

It might be possible to fix, since strangely the parenthesizes seems to
change something. Could you post it on issues list ?

Nicolas

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected result of type checking

Jan_Flanders


On Fri, Sep 2, 2011 at 5:57 PM, Nicolas Cannasse <[hidden email]> wrote:

It was never reported and is still not fixed :)

The issue here is that any field of a Dynamic value is inferred as Unknown and Unknown gets unified with Int before Float. So it will cast points[0].x to Int before making the mult, resulting in zero.

It might be possible to fix, since strangely the parenthesizes seems to change something. Could you post it on issues list ?

Nicolas

--
haXe - an open source web programming language
http://haxe.org

Thanks for the explanation. I posted the issue. ( http://code.google.com/p/haxe/issues/detail?id=487 )

Jan

--
haXe - an open source web programming language
http://haxe.org