dotnet / dotnet/csharplang

[Proposal]: Relaxing shift operator requirements

Open
#4,666 15 comments 36 reactions 1 assignee Claimed by @MadsTorgersen View on GitHub
Implemented Needs ECMA Spec Proposal Proposal champion
Dominant language
C#
Stars
12.7k
Forks
1.1k
Avg merge
11h 1m
Merged PRs (30d)
3

Description

# Relaxing shift operator requirements

* [x] Proposed
* [x] Prototype
* [x] Implementation
* [x] Specification: https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/relaxing_shift_operator_requirements.md

## Summary
[summary]: #summary

The shift operator requirements will be relaxed so that the right-hand side operator is no longer restricted to only be `int`.

## Motivation
[motivation]: #motivation

When working with types other than `int`, it is not uncommon that you shift using the result of another computation, such as shifting based on the `leading zero count`. The natural type of something like a `leading zero count` is the same as the input type (`TSelf`) and so in many cases, this requires you to convert that result to `int` before shifting, even if that result is already within range.

Within the context of the generic math interfaces the libraries are planning to expose, this is potentially problematic as the type is not well known and so the conversion to `int` may not be possible or even well-defined.

## Detailed design
[design]: #detailed-design

https://github.com/dotnet/csharplang/blob/main/spec/expressions.md#shift-operators should be reworded as follows:
```diff
- When declaring an overloaded shift operator, the type of the first operand must always be the class or struct containing the operator declaration, and the type of the second operand must always be int.
+ When declaring an overloaded shift operator, the type of the first operand must always be the class or struct containing the operator declaration.
```

That is, the restriction that the first operand be the class or struct containing the operator declaration remains. While the restriction that the second operand must be `int` is removed.

## Drawbacks
[drawbacks]: #drawbacks

Users will be able to define operators that do not follow the recommended guidelines, such as implementing `cout << "string"` in C#.

## Alternatives
[alternatives]: #alternatives

The generic math interfaces being exposed by the libraries could expose explicitly named methods instead. This may make code more difficult to read/maintain.

The generic math interfaces could require the shift take `int` and that a conversion be performed. This conversion may be expensive or may be not possible depending on the type in question.

## Unresolved questions
[unresolved]: #unresolved-questions

Is there concern around preserving the "intent" around why the second operand was restricted to `int`?

## Design meetings

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.