Runtime: LINQ.Expressions Power operator and BigInteger or Complex or custom

Created on 18 Jan 2018  路  16Comments  路  Source: dotnet/runtime

_From @DjArt on May 26, 2017 8:58_

Building expression with two BigInteger or Complex variables will fail, because it's call Math.Pow method. How about add new operator op_Power for overloading and call it when we use Power in LINQ?

_Copied from original issue: dotnet/coreclr#11931_

api-suggestion area-System.Linq.Expressions

All 16 comments

Adding a op_Power would be a deep change to the runtime, since the set of operator special names has been pretty much fixed since 1.1 and we'd be waiting on catch-up from the various types that can call it.

Expressions already provides a means to use a method other than Math.Pow():

C# var parB = Expression.Parameter(typeof(BigInteger)); var parE = Expression.Parameter(typeof(int)); var expr = Expression.Lambda<Func<BigInteger, int, BigInteger>>( Expression.Power(parB, parE, typeof(BigInteger).GetMethod("Pow", BindingFlags.Public | BindingFlags.Static)), parB, parE); var func = expr.Compile(); var result = func(10, 4); // BigInteger value of 10000

If we were to add op_Power this would be a CLR change. About the only thing to do in S.L.Expressions is either:

  1. Special-case these types to have better defaults for Power. I'm inclined against that unless there seems to be a very high demand. Special-cases are bad, and those who need to do such power expressions can do so as per the above, today.
  2. Maybe a better error message. The error message given relates to a step in the implementation and so pretty much complains to the user that they tried to use Math.Pow() with types it won't match, rather than tried to use Expression.Power() without giving a method for types that need them to give a method, which is a message that would better guide people to fixing their code.

However, the op_Power overload operator is used in Visual Basic and the op_Exponetiation overloaded operator is used in F# (although it requires a static Pow member). Other similar expressions from Linq.Expressions are bound to operators, and this expression is a special case. I propose either to implement this operator at the level of system types, or to check for this operator when calling Expressions.Power.

My C# bias is showing. Taking a look, it's op_Exponent in VB. That F# went with op_Exponentiation is unfortunate (someone likewise wasn't aware of the prior art on op_Exponent perhaps).

I agree that expressions should look for those, to better support VB and F#.

There's a few parts to this, then.

  1. Support op_Exponent and op_Exponentiation in S.L.Expressions. I'll open a separate issue for that.
  2. Support op_Exponent and/or op_Exponentiation in BigInteger and Complex, which as well as the use with expressions would make for better support in VB and F# too.
  3. Perhaps direct support for using and overloading this method in C#, which is already issue dotnet/roslyn#4594.

(I'm certainly not in favour of op_Power considering there two other names in use for this, which is already one name too many).

Incidentally the remaining part of this (part 2 in my list above) is an API change and hence requires to follow the procedures for that.

More pointedly. Full support for such an operator, including having it as a special name would require dotnet/roslyn#4594 to be done first 馃槩

The second part I can do in the coming week. It is fundamental and will help in the implementation of both the first and third parts.

Not really. First part is already done in dotnet/corefx#26413 since there can already be types produced in VB or F# that would benefit. Third part is needed before second part since BigInteger and Complex are written in C# and C# can't produce a special-named operator that isn't yet supported in C#.

Wow, ok. Thanks.

@DjArt you probably want to keep an eye on https://github.com/dotnet/roslyn/issues/4594 since that's where the third part will be decided upon.

If there is dependency on Roslyn feature, I would suggest to close the issue and reopen it when the Roslyn feature is approved / gets in.

Third part is needed before second part since BigInteger and Complex are written in C# and C# can't produce a special-named operator that isn't yet supported in C#.

Why can't BigInteger declare a static method with the name op_Exponent? As far as I know the compiled result is indistinguishable from actually using the operator keyword.

Thanks @svick! Added to my list for my ApiContractGenerator project.

So there is no longer a dependency on the Roslyn/C# feature, correct?

TIL. Thanks @svick. That makes it independent of the Roslyn issue, then.

Was this page helpful?
0 / 5 - 0 ratings