Great question.  The reason why operators get treated differently due to things 
like:

[2, 3] * 2.0

For this call we cannot coerce the float into an int by Python semantics.  
Compare this to:

xrange(2.0)

which is allowed (but in CPython issues a warning).

So in general Python seems to be more restrictive on binary operators then it 
does on method calls.  We've mirrored this behavior in IronPython through our 
support of .NET operator overloading.  That allows us to implement the standard 
Python semantics in a manner which .NET understands - for example our List 
class implements operator * and a C# programmer could do someList * 3.  We then 
just automatically expose these operators out to Python in a way which Python 
expects - including returning NotImplemented if the parameters aren't 
compatible.

We could look at relaxing this in the future (in particular for non-Python 
types) but I think we have bigger fish to fry for the immediate future - and it 
might just make things that much more confusing as well.  If it's particularly 
troublesome I'd suggest opening a feature request on CodePlex so we can gauge 
how many people it's affecting by keeping track of the votes.

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Korbinian 
Abenthum
Sent: Tuesday, June 17, 2008 8:12 AM
To: Discussion of IronPython
Subject: [IronPython] Operator overloading, and implicit conversion from Double 
to Single in operators

Hi

I basically have the same problem as in 
http://www.codeplex.com/IronPython/WorkItem/View.aspx?WorkItemId=939

A struct like:
  public struct Test
  {
    public float a;
    public Test(float a)
    {
      this.a = a;
    }
    public static Test operator *(float lscalar, Test test)
    {
      return new Test(lscalar * test.a);
    }
    public static Test mul(float lscalar, Test test)
    {
      return new Test(lscalar* test.a);
    }
    public override string ToString()
    {
      return "Test("+a+")";
    }
  }

If I execute in IronPython:
>>> 6 * Test(1.7)
<Test object at 0x000000000000002F [Test(10.2)]>

>>> Test.mul(6.5, Test(1.7))
<Test object at 0x0000000000000030 [Test(11.05)]>

>>> 6.5 * Test(1.7)
unsupported operand type(s) for *: 'float' and 'Test'
   at _stub_$695##312(Closure , CallSite , CodeContext , Double , Object )
   at _stub_MatchCaller(Object , CallSite , Object[] )
   at Microsoft.Scripting.Actions.CallSite`1.UpdateAndExecute(Object[] args)
   at 
Microsoft.Scripting.Actions.UpdateDelegates.Update3[T,T0,T1,T2,TRet](CallSite 
site, T0 arg0, T1 arg1, T2 arg2)
   at Initialize$694##311(Closure , CodeContext )
   at Microsoft.Scripting.ScriptCode.Run(CodeContext context)
   at Microsoft.Scripting.ScriptCode.Run(Scope scope)
   at Microsoft.Scripting.SourceUnit.Execute(Scope scope, ErrorSink errorSink)
   at Microsoft.Scripting.Hosting.ScriptSource.Execute(ScriptScope scope) [...]
TypeError: unsupported operand type(s) for *: 'float' and 'Test'


The comment in the issue quoted above says that the exception is by design,
since the operator is only defined for a float. And indeed,

>>> System.Single(6.5) * Test(1.7)
<Test object at 0x0000000000000031 [Test(11.05)]>

works just fine.
What I don't understand is why there should be a difference in implicit
conversion of python numbers depending on if it's used in a constructor,
a function or an operator. Is there a reason for that?

Cheers,
 Korbinian
_______________________________________________
Users mailing list
[email protected]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
_______________________________________________
Users mailing list
[email protected]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

Reply via email to