There's more to logical operators than you think

Hey, I’ve realized most beginner scripters don’t learn this simple concept often. Logical Operators are a simple concept that you probably use a lot while using if statements. You probably didn’t know this, but you can use them outside of if statements.

Disclaimer : I am likely going to use some incorrect terminologies but you should get what I mean.

print(not true) -- false

That is probably one of the most known use. You could use that to make a close/open UI button with the not operator.

local UI = UIDirection
local Button = ButtonDirection

Button.MouseButton1Down:Connect(function()
    UI.Visible = not UI.Visible
end)

not is very useful. You can do more than just change a UI’s visibility. Also if you already know you can use not to see if something is nil or not. You can do the same with bool values as well.

if not nil then
    print("hi") -- this would print because not nil == true and if statements need the value to be true to run the code.
end

if not false then
    print("hi as well") -- this would print as well.
end

Though, nil isn’t equal to false. nil gets turn into true when it gets negated.

print(nil == false) -- false
print(not not nil == false) -- false, you can negate the true value so it turns into faulty value

Doing not to an existing value would make it faulty.

print(not 1) -- false
print(not workspace) -- false

Now let’s talk about the or operator

or is used when the first condition is faulty. So if your first condition is false, you can use the or operator to make sure the other is truthy and run the code below.

local Bool = false

if Bool or true then
    print("epic") -- this would print
end

print(Bool and "cool" or "not so cool") -- "not so cool" would print since the first condition is false.

Yes you can do the method I used above to prevent if statements since it uses if statements and if statements are supposedly more expensive than a couple of operators being used in terms of resources.

You can also use the or operator to make default values.

local Character = Player.Character or Player.CharacterAdded:Wait()
-- Since the code is likely to run before the character is added you use this to prevent busy waiting which is not good to use.
-- So incase the Character is nil, it would wait for the character to be added. Since CharacterAdded returns the added character you could use that.

Lastly, the and operator

The and operator is pretty powerful. You can use all of these operators to prevent if statements and make cleaner and more optimized code. You can use the and operator to make sure a condition is true and run code or change the value of something. I am going to show an example.

local Health = 30
local Damage = 10

Health -= (Damage > Health and Health or Damage) -- 20

Damage = 25

Health -= (Damage > Health and Health or Damage) -- 0 instead of -5

I am aware that math.clamp can be used but I feel like that calling a function would use more resources(probably minimal difference) than using operators in my opinion.

Use

So what can you do with the operators that you’ve just learned about? You can make way cleaner code and likely more optimized as well. I am going to show how to make UI appear the same way before but reposition if the position is not at the default one.

local MainFrame = MainFrameDirection
local Button = ButtonDirection

local DefaultPos = UDim2.new(0.5, -250, 0.5, -250) -- pls dont bully bc I used offset for UDim2

Button.MouseButton1Down:Connect(function()
	MainFrame.Visible = not MainFrame.Visible or MainFrame.Position ~= DefaultPos -- Set the visibility to false if the MainFrame's Position is equal to DefaultPos or make it visible.
	MainFrame.Position = MainFrame.Visible and DefaultPos -- If the MainFrame is visible, then it would set the MainFrame's Position to DefaultPos.
end)

Hope this helps you understand how you could use logical operators effectively.

29 Likes

I mean, many people know this already, but I do want to say that I learned that any value paired with not is always false (if it’s not false or nil itself). I guess that’s interesting, but I don’t see how common its implications are.

However, with in-line conditionals, it can get quite hard on readability. So, this comes down to a balance between the number of lines and readability.

For example:

function a(b)  --say b is a dictionary, but it isn't required, so we need to nil check

    val = b.Value --this would error if b doesn't exist
    val = b and b.Value or "Default" --but this wouldn't; if doesn't exist, then set to "Default"

end

However, if it comes down to a long chain of not, and, and or statements, then it’s better to use more lines than create such poor readability. One way to check for this is if the code is horizontally overflowing so that the scroll bar shows. If so, then just drop a few lines, don’t cram it in one.

Why don’t we explain in Lua:

action = not horizontal_overflow and "Multiple lines" or "In-line"
print(action)
6 Likes

print(not not nil == false) prints true

The not is evaluated before the other operators, so you end up with false == false.

6 Likes

yeah thanks for pointing it out. I meant

print(not not nil == false) -- true

Since not turns the nil value into a truthy and the other not negates it so it turns into a faulty.

1 Like

You just changed my life. Awesome guide.

1 Like

I believe the inline conditionals would be called ternary expressions, and in the way you’re using and & or they would be called ternary operators. Here’s a thread relating to ternary expressions.

1 Like

Something else that can be useful is creating a boolean variable from those operators

local RunSpeedThreshold = 20
local Velocity = Vector3.new(1,8,3) -- Character's ΔS in a second I guess

local IsRunning = Velocity.Magnitude > RunSpeedThreshold
print(IsRunning) -- true or false

That variable can then be used for various things later on in the script

1 Like