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

Unsigned right shift operator #1012

Open
5 tasks done
Happypig375 opened this issue May 26, 2021 · 5 comments
Open
5 tasks done

Unsigned right shift operator #1012

Happypig375 opened this issue May 26, 2021 · 5 comments

Comments

@Happypig375
Copy link
Contributor

Happypig375 commented May 26, 2021

Unsigned right shift operator

I propose we add the unsigned right shift operator to F#. Since C# is looking to add this operator, and F# already has all the bit-twiddling operators equivalent to C#, it only makes sense for F# to also add this operator for whatever C# has reasons for:

When working with signed integral value, it is not uncommon that you need to shift bits right without replicating the high order bit on each shift. While this can be achieved for primitive integral types with a regular shift operator, a cast to an unsigned type before the shift operation and a cast back after it is required. Within the context of the generic math interfaces the libraries are planning to expose, this is potentially more problematic as the type might not necessary have an unsigned counterpart defined or known upfront by the generic math code, yet an algorithm might rely on ability to perform an unsigned right shift operation.

The existing way of approaching this problem in F# is

// Quote: a cast to an unsigned type before the shift operation and a cast back after it is required.
let (>>>>) (value:int) pos = value |> uint >>> pos |> int

However, as mentioned in the quote above, this is not applicable to generic math code. Although for F# we have SRTP, it is still desirable to have this defined and built-in for standardisation.

Pros and Cons

The advantages of making this adjustment to F# are

  1. Making generic math algorithms easier
  2. Consistency with C#
  3. Consistency with OCaml: We have <<< for lsl, >>> for asr and now we finally have an equivalent for lsr.

The disadvantage of making this adjustment to F# is that this may be too niche to warrant its own operator.

Extra information

Estimated cost (XS, S, M, L, XL, XXL): XS - Just copy the implementation for >>> and use shr.un instead of shr.

Related suggestions: (put links to related suggestions here)

Affidavit (please submit!)

Please tick this by placing a cross in the box:

  • This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.

Please tick all that apply:

  • This is not a breaking change to the F# language design
  • I or my company would be willing to help implement and/or test this

For Readers

If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.

@Happypig375
Copy link
Contributor Author

@cartermp
Copy link
Member

cartermp commented Jun 6, 2021

I wouldn't be opposed to this in theory. @dsyme?

@dsyme
Copy link
Collaborator

dsyme commented Jun 7, 2021

TBH I can barely imagine a situation where someone would want generic math over the logical-shift-right-operator on signed types. I'd imagine C# are just completing a matrix as part of their generic math work.

In any case we should wait for C# to do whatever they do, since among other things they will choose an op_XYZ name for this.

@dsyme
Copy link
Collaborator

dsyme commented Apr 20, 2022

Noting that the C# name >>> is unfortunate, since that is used for signed-right-shift in F#.

-1 >>> 3;;
val it: int = -1

> uint -1 >>> 3;;
val it: uint = 536870911u

This will make porting code C# --> F# (if uses unsigned right shift) or F# --> C# (if uses right shift on signed integers) a bit unreliable.

In any case, we can add this - but what would be the operator in F#? Any suggestions? >>>> seems unfortunate, as does any other choice (.>>> etc). We could perhaps add LanguagePrimitives.UnsignedShiftRight x shift or op_UnsignedRightShift and leave it up to the user to give it a better name of they want to use it?

@smoothdeveloper
Copy link
Contributor

the bit shifting stuff having very large operator is fine to me, trying to match C terseness in this area isn't something I feel F# needs to compete with.

Porting C code, doing bitshifting, or bitshifting code in general, it seems it always require checking the fine semantics, to be done properly.

Maybe this should be the job of a translate tool, and we keep the aesthetics that went into picking the current bitshifting operators that we currently enjoy in F#, it may means >>>>> goes into FSharp.Core, and it will look a bit fun.

Through languagePrimitives only, in first place, would be the safe and conservative route, letting people define their >>>>> for now.

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

4 participants