Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[C# feature request] define own operators #10363

Closed
ltcomrabb opened this issue Apr 6, 2016 · 15 comments
Closed

[C# feature request] define own operators #10363

ltcomrabb opened this issue Apr 6, 2016 · 15 comments

Comments

@ltcomrabb
Copy link

Hello all.

I would like to propose the functionality to define own Operators additionally to the existing posibility to override existing Operators.

For example in searching similar Persons it would be usefull:

Persons.Where(Person => Person.FullName ~= "Max Power");

In that case it would open the posibility to define the Operator ~= with a custom build similarity search logic.

This case is now possible with Extensions:

Persons.Where(Person => Person.Fullname.SimilarTo("Max Power")); // SimilarTo contains search logic

but an user defined Operator would make it easier to write and more readable.

Thanks
Richard

@AdamSpeight2008
Copy link
Contributor

That or extend the range of custom operators to include what is allowed in F#.

@dsaf
Copy link

dsaf commented Apr 6, 2016

I only really understood what ~= means when I saw SimilarTo.

...more readable...

To the person who invented the operator.

@dsaf
Copy link

dsaf commented Apr 6, 2016

That specific sample depends on #4945

@HaloFour
Copy link

HaloFour commented Apr 6, 2016

This specific use case would depend on extension operators as well since you must currently define an operator as a static method of at least one of the operands. #4945

Considering that ~ is a valid operator today I would read that code and expect some kind of bitwise complement assignment. However, the extension method, while more verbose, is certainly more readable.

@ltcomrabb
Copy link
Author

@HaloFour ~= is only a sample - and I confess choosing not the best one. I imagine of a method where you can use any Expression as the Operator as long as it doesn't violate against a Expression of a reserved Name or Symbol.

@TheOpenDevProject
Copy link

As someone who has dealt with this for a long time in C++ I would be highly against this feature. C# is a very expressive language and allowing people to essentially hide that expressiveness is a bad idea. If you do want to go down the path of operator overloading it should only be within a set of strict parameters.

The + operator should never be able to perform the default action of the - operator

@orthoxerox
Copy link
Contributor

Custom operators complicate the parser immensely, since you cannot parse a !@#$ b %^&* c without first parsing and analyzing the properties of these two operators. I know some languages have hacks like determining precedence and associativity based on the operator name or giving all operators the properties of +, but then you lose the ability to write neat DSLs.

I don't think the cost of implementing custom operators outweighs the benefit of using them in C#. There are enough user defined operators for most cases.

@AdamSpeight2008
Copy link
Contributor

@orthoxerox
The current set of custom operators, have problems.

  • Other pre-exist usage dominate what they mean, when the technically that doesn't hold true. The programmer can customise the actual meaning.
  • The "comparision operators" can not be implemented independently eg < you to also do `=>'
    The removal of this restriction, as far as I can see it wouldn't affect any existing code. Also it would make a runtime exception, a compile-time error. It you try to implement an unsupported operator.
  • The return type isn't considered in binary operators, to see if that operator is valid.
    eg The last binary operator is an error.
Public Class Token { }
Public Class Tokens
{
static operator Tokens +(Token T0, Tokens Tx ) {}
static operator Tokens +(Tokens Tx, Tokens T0) {}
static operator Tokens +(Tokens Tx0, Tokens Tx1) {}
static operator Tokens +(Token T0, Token T1) {}
}

@ThatRendle
Copy link

Custom operators are one of those things the Ruby crowd say makes Ruby
better.

The Ruby crowd are wrong.

On Fri, 8 Apr 2016, 13:26 Adam Speight, [email protected] wrote:

@orthoxerox https://github.com/orthoxerox
The current set of custom operators, have problems.

  • Other pre-exist usage dominate what they mean, when the technically
    that doesn't hold true. The programmer can customise the actual meaning.
  • The "comparision operators" can not be implemented independently eg <
    you to also do `=>' The removal of this restriction, as far as I can see it
    wouldn't affect any existing code. Also it would make a runtime exception,
    a compile-time error. It you try to implement an unsupported operator.
  • The return type isn't considered in binary operators, to see if that
    operator is valid. eg The last binary operator is an error.

Public Class Token { }
Public Class Tokens
{
static operator Tokens +(Token T0, Tokens Tx ) {}
static operator Tokens +(Tokens Tx, Tokens T0) {}
static operator Tokens +(Tokens Tx0, Tokens Tx1) {}
static operator Tokens +(Token T0, Token T1) {}
}


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
#10363 (comment)

@TheOpenDevProject
Copy link

IMO this would be a step backwards for C#. If you have not already i would have a good go at using this in languages that do support it.

@JeffreySax
Copy link

In my view, it only makes sense to define a new operator in the language if that operator already exists in the problem domain and it has a clear, unambiguous meaning. There is no ~= operator in string handling. Worse still, it means something different ("not equal to") in some languages.

But then there are things like:

  • The exponentiation operator (**), which is used in FORTRAN, Python, F#, to name a few.
  • 'Dotted' operators, which are widely understood to represent element-wise operations. They originally appeared in Matlab. There are a lot of calculations that can be concisely expressed using dotted operators, while the method form (e.g. using ElementwiseMultiply instead of .*) is so long that it harms code clarity.

I feel the language would benefit from having an exponentiation operator (like VB) and allowing a dotted operator with the same precedence as the base operator.

In addition, compound assignment operators could use some love, too. These are currently defined as applying the base operator followed by an assignment. For example, a += b is expanded to a = a + b. So here, a is replaced with the result of adding b to it.

The problem is that this is counter to the visual semantics, which suggest that a is modified in-place by adding b to it. It is also a performance issue because a (and therefore a + b may be quite large, so the current semantics force the creation of a large intermediate value that is thrown away immediately.

I would like to see the ability to define compound assignment operators as instance methods on a class.

@gafter
Copy link
Member

gafter commented Mar 24, 2017

We are now taking language feature discussion in other repositories:

Features that are under active design or development, or which are "championed" by someone on the language design team, have already been moved either as issues or as checked-in design documents. For example, the proposal in this repo "Proposal: Partial interface implementation a.k.a. Traits" (issue 16139 and a few other issues that request the same thing) are now tracked by the language team at issue 52 in https://github.com/dotnet/csharplang/issues, and there is a draft spec at https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md and further discussion at issue 288 in https://github.com/dotnet/csharplang/issues. Prototyping of the compiler portion of language features is still tracked here; see, for example, https://github.com/dotnet/roslyn/tree/features/DefaultInterfaceImplementation and issue 17952.

In order to facilitate that transition, we have started closing language design discussions from the roslyn repo with a note briefly explaining why. When we are aware of an existing discussion for the feature already in the new repo, we are adding a link to that. But we're not adding new issues to the new repos for existing discussions in this repo that the language design team does not currently envision taking on. Our intent is to eventually close the language design issues in the Roslyn repo and encourage discussion in one of the new repos instead.

Our intent is not to shut down discussion on language design - you can still continue discussion on the closed issues if you want - but rather we would like to encourage people to move discussion to where we are more likely to be paying attention (the new repo), or to abandon discussions that are no longer of interest to you.

If you happen to notice that one of the closed issues has a relevant issue in the new repo, and we have not added a link to the new issue, we would appreciate you providing a link from the old to the new discussion. That way people who are still interested in the discussion can start paying attention to the new issue.

Also, we'd welcome any ideas you might have on how we could better manage the transition. Comments and discussion about closing and/or moving issues should be directed to #18002. Comments and discussion about this issue can take place here or on an issue in the relevant repo.

I am not moving this particular issue because I don't have confidence that the LDM would likely consider doing this.

@gafter gafter closed this as completed Mar 24, 2017
@RusMermaid
Copy link

Please create at least the ability to overloading the following operators ~=, ∨, ≡, !, :, /, , !!, ∫, ∫?, ±, ±?, ∠, ∠?, ∞, ⊗. Thank you!

@RusMermaid
Copy link

Furthermore, indexers for class[0] are not enough for custom mathematical classes. I want to bring an idea of overloading {0}, |0|, ||0||, <0>. So for any custom class i. e. we could write class<2> to get an element in some sort of a collection stored of a object property of that class.

@CyrusNajmabadi
Copy link
Member

@RusMermaid please read: #10363 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests