I think "masking shift" is an incorrect name

I'm looking at the masking-shift operators on FixedWidthInteger. It took me a minute to figure out what's going on in the example. The example uses UInt8, so the shift masks out all the bits of the shift amount except for the lowest-order 3 bits. We get 3 from 8 because 3 is the base-2 logarithm of 8 (i.e. 3 = ln(8) / ln(2)).

But the point of the masking shifts is to keep the (absolute) shift amount under the type's bit width. That sounds like a modulo/remainder operation. Yes, both mod-8 and mask-keep-3 have the same effect, but the reasoning is the mod. The mask reasoning is completely inappropriate.

Worse, the mask interpretation only works when the bit width is an integral power of 2. So my UInt4 test type can do it. My UInt72 type, not so much. (Even I can't mask by an irrational number of bits.) But the conceptual model of the shift normalization operation is mod-4 or mod-72; emphasizing a mask instead is a broken model.

What to do: reword the effects in terms of mod/remainder. And we have to rename the operation.

2 Likes

This is the subject of SR-6749, and @nnnnnnnn is working on it.

“Wrapping shift” is what Rust calls the operation; alternatively, we could see if “modular shift” or some variation would be acceptable.

In general, let’s discuss bugs at bugs.swift.org, where they can be better categorized and tracked.

1 Like

You've misunderstood where the name comes from. The result is what's being masked, not the shift amount; when you shift your UInt72 value, you perform the shift as an abstract binary integer operation, then mask to 72 bits.

(Note also that the left-hand side and right-hand side of a shift may not have the same type. That may help in understanding this.)

"Wrapping shift" doesn't really make sense to me, since shifts aren't arithmetic operations.

2 Likes

@Nicole_Jacque Is there a way that you or another administrator move this thread to the "standard library" category so that future readers can find it where it belongs?