User Tag List

Page 1 of 2 1 2 LastLast
Results 1 to 7 of 10

Thread: [Lua] 'goto' statement.

  1. #1
    Esteemed Member <span style='color: #4169E1'>Grandelf</span>'s Avatar
    Join Date
    Oct 2014
    Posts
    104
    XP
    64,547
    Level
    78
    Thanks
    18
    Thanked 110 Times in 45 Posts

    [Lua] 'goto' statement.

    Hello there,

    I am making this topic because since Lua 5.2 we have acces to this amazing thing called a 'goto' statement,
    which is absolutely awesome in my opinion. I haven’t seen anyone using it yet, which can either be that most of the people here
    doesn’t exactly know how it works or haven’t heard of it yet, or it can simply be that no one has found any use for it.
    Either way I felt like making a small tutorial for it.

    What is a goto statement exactly?

    A goto statement is much like a 'return' or 'break' statement, it basically stops some code from running.
    However a goto statement skips code rather than completely stopping all the code in a loop (break) or function (return).
    To skip code and 'goto' a certain point in your code however, you need something so the goto statement knows where to go to.
    This is called a label.

    A goto statement jumps the execution of a program to a corresponding label.
    How do I use a goto statement?

    Knowing all this, it is clear that goto needs some kind of variable passed into it, and a label has to be made somehow,
    somewhere in the code. As an example I decided to use the 'continue' statement from languages like C++ or Java.
    Before the goto statement was introduced there was no way to replicate this behavior in Lua.
    For those of you who don’t know what a continue statement does, it basically skips to the next iteration inside a loop.

    The continue statement passes control to the next iteration of the nearest enclosing do, for, or while statement in which it appears, bypassing any remaining statements in the do, for, or while statement body.
    To illustrate this I have written a small code, that will show you the use of continue.
    Code:
    int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    for (int i = 0; i < arr.length; i++) do {
    	/* If the index = 3 then we skip this iteration and go to the next iteration
    	which has an index of 4. */ 
    	if (i == 3)
    		continue; 
    	
    	arr[i] = arr[i]*2;
    }
    The array will now contain the following: {2, 4, 3, 8, 10, 12, 14, 16, 18, 20}. As you can see it multiplied every number by 2,
    except for the third element, because a continue statement was called and it skipped the rest of the code.

    The continue statement in Lua.

    Now lets implement this behavior in Lua, using a goto statement. Like I said before,
    a goto statement requires a label which will be the argument for goto. Now how do you make this label?
    That may be more easy than you would’ve expected. To make a label you simply use 2 colons, followed by the label name followed by two more colons.
    After making the label you will have to place it inside your code, keep in mind that wherever you put this label,
    that is where the goto statement will jump to as seen later in the continue example which we will be making.

    Now we know what a goto statement is, and how we make a label it is time use the goto statement. To start making our continue statement,
    we’re going to need a label name. Because we’re making a continue statement, I am going to call this label continue.
    Code:
    ::continue::
    The code we’re going to use will be the same as the previous example, but in Lua.
    Code:
    local arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    for i=1, #arr do
    	if (i == 3) then
    	        -- The continue statement, which we do not have yet.
            end
    
            arr[i] = arr[i] *2;
    end
    Now to implement a continue statement, we will have to add the continue label in the code on a place where we want the code to jump to.
    Seeing as we want to skip that iteration and go to the next one, we can simply place the label after ‘arr[i] = arr[i] *2;’.
    Then it will skip to the end of the iteration and continue the next iteration. After that, all that is left to do is call the ‘goto labelname’ and we’re done.
    Code:
    local arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    for i=1, #arr do
    	if (i == 3) then
    	        goto continue;
            end
    
            arr[i] = arr[i] *2;
            ::continue::
    end
    The goto statement outside a loop.

    Do note that unlike a continue statement, a goto statement does not have to be called inside a loop. Another simple example to illustrate a goto statement outside a loop would be:
    Code:
    local a = 0;
    local b = 0;
    
    -- 50% chance of going to codeA otherwise codeB.
    if math.random(2) == 1 then
    	goto codeA;
    else
    	goto codeB;
    end
    
    ::codeA:: do
    	a = a + 10; return print(a, b);
    end
    ::codeB:: do 
    	b = b + 10; return print(a, b);
    end
    In this code, we simply start off by deciding what code to run, it has a 50% chance to run codeA, otherwise it will run codeB.
    Therefor there are two possible outcomes, that it will print to the console. This will either be, ’10, 0’ or ’0, 10’ depending on whether it ran codeB or codeC.
    Note: The return statement will actually do the job of stopping the code from running both codeA aswell as codeB.

    For those of you, who would like to see more examples of how this works, you can check out this link: http://lua-users.org/wiki/GotoStatement.

    I hope this was useful to some people, in my opinion this is a really powerful tool that can be useful in a lot of situations.

    Grandelf.

    Edit: There seems to be some kind of debate going on whether to use this or not, so I am simply going to say this:
    Everyone should decide for themselves if they want to use this or not, knowing about goto on the other hand
    isn't going to harm you, and that's exactly the point of this tutorial.

    In this tutorial I gave two examples, the first one using continue, is something I would use and is actually really helpful in my opinion.
    The second example in this tutorial is purely there to illustrate a goto statement outside of a loop.

    To illustrate the use of goto a bit more I have written a small script that will generate a code under two conditions.
    In this script I used two labels 'continue' and 'redo', note that I could've used only continue however this way
    you're basically making sure something is how you want it to be, before processing it. Also will it illustrate that you can
    jump backwards aswell instead of just forward like in the previous examples.
    Code:
    -- A simple script that will generate a code under two conditions, 
    -- you can't have 2 of the same digits in a row and we are only
    -- using even numbers.
    local codeLength = 10;
    local function generateCode()
    	local str = "";
    	while #str ~= codeLength do
    		::redo::
    		local number = math.random(9);
    		-- The number must be different from the last one before 
    		-- it will be taken into consideration.
    		if number == tonumber(str:sub(#str, #str)) then 
    			goto redo; -- Obviously we could've used continue here aswell.
    		elseif number %2 ~= 0 then -- Number is different so we consider using it.
    			goto continue; -- Number declined.
    		end
    		str = str .. number;
    		::continue::
    	end
    	return str;
    end
    print(generateCode());
    Last edited by Grandelf; 11-09-2014 at 05:34 PM.
    Achievements:
    1 year registered Level XL Level LXX
    Awards:
    Support

  2. The Following 3 Users Say Thank You to Grandelf For This Useful Post:


  3. #2
    Moderator / Eluna Dev <span style='color: #FF0000'><span class='glow_8B0000'>Rochet2</span></span>'s Avatar
    Join Date
    Apr 2013
    Location
    Finland
    Posts
    1,859
    XP
    13,487
    Level
    35
    Thanks
    95
    Thanked 591 Times in 418 Posts
    Additional reason: Backwards compatibility

    Quick note; codeC gets executed when codeB is executed
    This way C is always 10 and A is always 10, but B keeps changing
    The example is so annoyingly put to farm mislogic even if explained xd, the comments are "wrong"

    Example:

    Code:
    goto U
    print("_Y")::Y::print("Y_")
    print("_U")::U::print("U_")
    print("_I")::I::print("I_")
    All 3 prints after the label U get printed, so U_ _I I_
    Last edited by Rochet2; 11-09-2014 at 03:09 PM.
    Awards:
    Support LOL Scripter Facepalm! Raffle Winner

  4. The Following 2 Users Say Thank You to Rochet2 For This Useful Post:


  5. #3
    Original Poster
    Esteemed Member <span style='color: #4169E1'>Grandelf</span>'s Avatar
    Join Date
    Oct 2014
    Posts
    104
    XP
    64,547
    Level
    78
    Thanks
    18
    Thanked 110 Times in 45 Posts
    Oops, you're right. Yea I really made that just on top of my head, maybe I should've tested it.. oh well.

    Edit: That actually made me realise how stupid that code was, I actually misinterpreted something which I didn't know until now,
    so thanks for that, I guess =P.
    Last edited by Grandelf; 11-09-2014 at 03:40 PM.
    Achievements:
    1 year registered Level XL Level LXX
    Awards:
    Support

  6. #4
    Super Moderator <span style='color: #FFFF00'><span class='glow_000000'>Kaev</span></span>'s Avatar

    Join Date
    Jan 2014
    Location
    Germany
    Posts
    535
    XP
    2,925,342
    Level
    335
    Thanks
    76
    Thanked 102 Times in 70 Posts
    Never, never, never, NEVER use Goto. Never.
    There is a reason, why you never see it.
    Achievements:
    Shopper Member 1 year registered Level XL Level C
    Awards:
    Raffle Winner Member of Staff Support LOL Drunk Donator


    Read the rules before posting.

    Do you have an unsolved issue? Give us more informations about your problem.

    Do you have problems with compiling or installing TrinityCore? Unknown96's Tutorial will help you.

    Visit our other helpful sites:
    EmuDevs SQL Generator

  7. #5
    Original Poster
    Esteemed Member <span style='color: #4169E1'>Grandelf</span>'s Avatar
    Join Date
    Oct 2014
    Posts
    104
    XP
    64,547
    Level
    78
    Thanks
    18
    Thanked 110 Times in 45 Posts
    Quote Originally Posted by Kaev View Post
    Never, never, never, NEVER use Goto. Never.
    There is a reason, why you never see it.
    And why's that? =O There is also a reason why they implemented this in the first place =P.

  8. #6
    Super Moderator <span style='color: #FFFF00'><span class='glow_000000'>Kaev</span></span>'s Avatar

    Join Date
    Jan 2014
    Location
    Germany
    Posts
    535
    XP
    2,925,342
    Level
    335
    Thanks
    76
    Thanked 102 Times in 70 Posts
    Google it. It's a veeery bad practice. And a good code NEVER needs GoTo.
    Pic related.
    Achievements:
    Shopper Member 1 year registered Level XL Level C
    Awards:
    Raffle Winner Member of Staff Support LOL Drunk Donator


    Read the rules before posting.

    Do you have an unsolved issue? Give us more informations about your problem.

    Do you have problems with compiling or installing TrinityCore? Unknown96's Tutorial will help you.

    Visit our other helpful sites:
    EmuDevs SQL Generator

  9. #7
    Original Poster
    Esteemed Member <span style='color: #4169E1'>Grandelf</span>'s Avatar
    Join Date
    Oct 2014
    Posts
    104
    XP
    64,547
    Level
    78
    Thanks
    18
    Thanked 110 Times in 45 Posts
    Google on the other hand, isn't always right =P. I must disagree with this, I find goto very useful in situations where I want
    to have some sort of continue or redo construction. True enough there are situations in which I wouldn't use it, the second
    example I gave is not how I would do such a thing, but it does illustrate the use of goto.

    I guess this quote from 'Programming in Lua' would describe pefectly of what is going on here =P
    There has been a long going debate about goto, with some people arguing
    even today that they are harmful to programming and should be banned from
    programming languages. Nonetheless, several current languages offer goto,
    with good reason. They are a powerful mechanism and, when used with care,
    can only improve the quality of your code.
    Last edited by Grandelf; 11-09-2014 at 04:02 PM.
    Achievements:
    1 year registered Level XL Level LXX
    Awards:
    Support

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •