Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
5

How does Evaluation work in Lua?

Asked by 9 years ago

Short Circuiting

Now, when it comes to short-circuiting values, Lua does indeed short-circuit. For example:

function hello()
    print('hello')
    return true
end

function bye()
    print('bye')
    return false
end

if(hello() or bye()) then
    print('check to short-ciruit')
end

hello

check to short-circuit

As you can see, the bye function was not called and thus that is proof that short-circuiting occurred. Now one way to get around this short-circuiting is to preferably set a reference to the function values before-hand.

For example:

function hello()
    print('hello')
    return true
end

function bye()
    print('bye')
    return false
end

local x = hello()
local y = bye()

if(x or y) then
print('check to short-circuit')
end

hello

bye

check to short-circuit

Now, as you can see in this example, both values from the hello and bye methods were printed.

I do understand how short-circuiting occurs when you only have simple conditional statements, but when you bring other factors involved, I'm still a bit addled on it. I want to know why setting the variables before hand makes a difference, and just a more clear explanation on how evaluation in Lua works. Any links too would be really appreciated.


My Question

How does evaluation in Lua work? Why did referring to the methods before-hand cause short-circuiting not to occur?

1
You are calling the bye function when you do y = bye() NotsoPenguin 705 — 9y
0
Yes, but when I just do 'bye()', I am also calling the bye() function. DigitalVeer 1473 — 9y
1
It does not cancel out anything. You called the bye function when you set the variable. Your if statement is actually just `if true or false` NotsoPenguin 705 — 9y
0
If my statement is just 'if true or false', then why does the print statement get called? DigitalVeer 1473 — 9y

1 answer

Log in to vote
7
Answered by
Unclear 1776 Moderation Voter
9 years ago

I want to know why setting the variables before hand makes a difference, and just a more clear explanation on how evaluation in Lua works.

Alright. I'll see what I can do.

Why setting the variables before hand makes a difference.

Short-circuit evaluation is when a later operation in a boolean statement is not evaluated because a previous operation in that same boolean statement is true. It is merely where the language does the minimal amount of evaluating to figure out the result of a boolean statement.

Note in a boolean statement. When point a variable to the result of an operation before the boolean statement happens, then the operation has already been evaluated.

There are no take backs in Lua; just because the result of that operation may evaluate to false in a later boolean statement, does not mean that the operation never happened.

Notice in your code...

function hello()
    print('hello')
    return true
end

function bye()
    print('bye')
    return false
end

local x = hello()
local y = bye()

if(x or y) then
print('check to short-circuit')
end

... you set x and y to the results of hello and bye. You know this because you wrote hello() and bye().

Notice that you called both of them. That means that those variables are now pointing to the evaluated results of the functions. You can check this by inserting a print statement between your local declarations and your if statement.

Remember that there are no take backs. This means that by the time you reached that if statement if (x or y) then, you already evaluated hello and bye. This means that naturally, those functions have already run once and printed out "hello" and "bye".

This is not a matter of short-circuiting, but more of a matter of you messing something up and attributing it to short-circuiting.

Basics

Evaluating boolean statements in Lua is as logical as it gets. Everything in Lua follows the standard properties of booleans, and there are no gotcha moments when working with Lua.

That being said, since you are asking this question, I'll give you a brief overview of how Lua works with boolean statements anyway.

The following will be considered false:

  • false

  • nil

  • Any variable pointing to false or nil

Everything else is true. That means that 0, "" or '' (empty strings), and {} (empty tables / data structures) will also evaluate as true, unlike in many other programming languages.

Here are some basic truth operations and their results...

print(true and true) --> true
print(true and false) --> false
print(false and true) --> false
print(false and false) --> false
-- or returns true if BOTH statements are true
-- or returns false if ONE or more statements are false

print(true or true) --> true
print(true or false) --> true
print(false or true) --> true
print(false or false) --> false
-- or returns true if ONE or more statements are true
-- or returns false if BOTH statements are false

print(not true) --> false
print(not false) --> true
-- not returns the opposite of whatever is to the right of it
-- not takes precedence before and/or operations.. so
-- print(not true or false) will print false

Ternary

You may know that Lua does not have a true implementation of ternary operators. However, you can get by with a pseudo-ternary operation that Lua does support.

For most purposes, a and b or c will suffice. Lua will go from left to right and evaluate each statement. It will return the last statement in a combo of true statements connected by ands if the statement is true. Otherwise, it will keep going.

Here is an example...

print(true or false) --> true 
-- notice how it is the last true statement

print(1 and 2 and 3 or false) --> 3
-- 1 is true, 2 is true, and 3 is true. 
-- Notice how 3 is then followed by an or.
-- This makes 3 the last true statement in a string of true statements.

print({} and 2 or true) --> 2
-- {} is true and 2 is true.
-- Same logic as above. 
-- Even through the next statement is true,
-- 2 is the last true statement in a combo of true statements connected by ands.

print(1 and 2 and false or 3) --> 3
-- 1 and 2 are true but false is not true.
-- Therefore, we go on to the next and find that 3 is true.

print(false and nil or false or 1 and 2 and false or 3) --> 3
-- 1 and 2 may be true, but remember that false is not.
-- Therefore, 3 is returned.

Parenthesis

Note that parenthesis have a bit of priority. This means that Lua, when it encounters a parenthesis, first evaluates everything in the parenthesis before proceeding with evaluating the rest of the boolean statement. This means that you can have multiple short-circuiting effects and nested pseudo-ternary.

Here is an example...

print(1 and (false or 2) or 0) --> 2
-- 1 is true, but then we encounter a parenthesis.
-- Let's evaluate it.
-- false is false, so we look at the next statement which is just 2.
-- So, our parenthesis returns 2.
-- Our statement is simplified to...
-- print(1 and 2 or 0) 
-- Since 2 is the last statement in the combo of ands, we will return 2.

Working with functions in boolean statements

Working with a function call is similar to working with parenthesis. First, you will evaluate what is in the function when you encounter it, similarly to how you would evaluate what is in a parenthesis. Then, you will proceed with the resulting value as you would regularly.

Here is an example...

function a()
    return 2
end

print(false or a() and 3) --> 3
-- Notice how false is false, so we go to the next statement.
-- We encountered a function call a() so we will evaluate it.
-- a() returns 2 so our statement is simplified to...
-- print(false or 2 and 3)
-- We proceed regularly since 2 is true, and return 3.
0
Haha, oops. Misremembered the definition of short-circuiting. adark 5487 — 9y
1
Really detailed explanation, Sukinahito. Though I do know my true/false combinations, at least it's helpful to people who may be new to it. Cheers, mate DigitalVeer 1473 — 9y
Ad

Answer this question