Please add bitwise operators (<<, >>, ~, & and |)

As a Roblox developer, it is currently difficult to make expressions that utilise chains of bitwise operators look clean.

The reasoning is because to do any bitwise operation, we need to defer to the bit32 library, rather than being able to use mathmatical equations.

Lets take a simple algorithm, decoding a ULEB128 number from a binary stream, in most high level languages, we can use the operators for bitwise AND and bitwise shifting to create this nice, clean and readable algorithm.

const decodeSignedLeb128 = (input) => {
  let result = 0;
  let shift = 0;
  while (true) {
    const byte = input.shift();
    result |= (byte & 0x7f) << shift;
    shift += 7;
    if ((0x80 & byte) === 0) {
      if (shift < 32 && (byte & 0x40) !== 0) {
        return result | (~0 << shift);
      }
      return result;
    }
  }
};

But in Luau, we need to make calls to the bit32 library, which results in this much noisier function:

local function decodeSignedLeb128(b: buffer, offset: number): number
  local result, shift = 0, 0
  while true do
    local byte = buffer.readu8(b, offset)
    result = bit32.bor(result, bit32.lshift(bit32.band(byte, 0x7F), shift))
 
    shift += 7
    offset += 1
    if bit32.band(byte, 0x80) == 0 then
      if shift < 32 and bit32.band(byte, 0x40) ~= 0 then
        return bit32.bor(result, bit32.lshift(bit32.bnot(0), shift))
      end
      return result
    end
  end
end

there may be logic errors here, using this as an example

As you can see, especially with result, we had to chain a massive statement of bit32 calls, to do something that is a lot cleaner with operators.

I’m also requesting this because it would aid in porting file parsers from other languages that run under the assumption that bitwise operators exist, and its less hassle to unwind the order of operations if I can create a 1:1 mapping with equivalent operators.

If Roblox were to address this issue it would improve my development experience because it would result in cleaner code when working with bitwise operators, and make it easier to port code from other languages.

3 Likes

Roblox can already differentiate if usage of e.g the [] computed index operator, {} table constructor, “” string constructor, etc is done in runtime or inside types, adding bitwise operators would 100% be a non-issue to implement (even though alot of type operators are bitwise operators)

I however don’t support removal of the bit32 library, both for backwards compatibility and also because bit32 has useful functions like countlz, countrz, btest, extract, etc which aren’t able to be made into operators

It’s similar to math.pow vs ^, most people don’t use the first one but it’s there anyway

1 Like

One of the main issues that gets mentioned in the reasoning for it not being added is metamehods, first of all, __idiv and __iter, but really, I dont care about metamethod support for them, its a nice features yes, but I just want readable code on complex expressions.

Another part is saying that ^ isn’t available for XOR and is inconsistent with other languages: != all over again.

I would happily take the bitwise operators getting compiled down to FASTCALLs to the bit32 library, similar to how string interp is actually string.format in disguise

2 Likes

Yeah it’s a shame we can’t get xor, I also wouldn’t want metamethods for bitwise (C++ slop all over again :V)

Alot of my more complex bit manipulation code would for sure look alot cleaner too

Lua 5.3 uses ~ for XOR. As far as I’m aware, except for ~=, the tilde is not used anywhere else in the language.

2 Likes

I just don’t see the point in making everyone use different operators and making people have to adapt, change their mindset and change all the operators in their games to these ones?

You don’t have to change your bit32 function calls to this one; ideally bit32 would stay (as it does contain functions operators can’t do), the operators would simply make code which manipulates bits

  1. More readable
  2. More easily rationalized (using bit32, operations go right to left which is extremely unintuitive :frowning: )

This would not change any existing language semantics, you can use bit32 if this change was added the same way you would now.

You could still use pairs and ipairs when generalised iteration got added, you could still wait (you shouldn’t) when task.wait got added, and you can still use coroutine when the task library as a whole got added, this would be no different.

Honestly, I’d love this. While the bit32 library functions have been a great alternative to standard bitwise operations it still isn’t quite as intuitive if you are used to these operations coming from a language other than Lua. I think a big advantage Luau can have over standard Lua is additions that directly ease switching over from other languages and workflows.

This was already decided against when the team adopted the new syntax for generic function calls:

local foo = React.useState<<number?>>(nil)

So I don’t think this is on the table anymore.

1 Like