Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

What is the scope of code that is outside of any function or other explicit block?

edited February 2015 in Questions Posts: 2,020

This is I think a very basic question, but I'm struggling to find documentation on it in the Lua resources, probably because this is a kind of basic principle of coding, or I don't know the proper terms for what I'm describing, other than "code outside of an explicit block".

So, code that is placed outside of any function, and outside any explicit block (any block ending in end or until), ie code that stays at column 1 when you indent. One thing I've noticed is that if you hit the restart button when the program is running, the code outside of any block is not executed again. So it seems to be once only, when you hit run. But what is the scope of local variables declared outside of any blocks? The Lua reference here says the scope of local variables declared outside of an explicit block extends to the end of the "chunk", but having also read the section on chunks, I don't understand where a chunk ends.

I use stuff outside of blocks for things like displayMode and supportedOrientations and declaring global variables that are needed for the names of functions (ie say if I'm wrapping a set of functions in a table that isn't a class), ie the scaffolding if you like of the code. But I was wondering about the other implications and use-cases of placing stuff outside of any block, and particularly about local variables declared in this way.

BTW, what does the repeated double colon mean throughout the Lua reference guide? as in

stat ::= local namelist [`=ยด explist]

I guess it's a convention that is so widespread that no-one thinks they need to explain what it is. Maybe it's because Lua is a scripting language, so the doc authors assume you must be coming to it from C# or whatever.

Comments

  • IgnatzIgnatz Mod
    Posts: 5,396

    Local variables declared outside functions are recognised anywhere in the same code tab, but not in other tabs.

  • Posts: 2,020

    @Ignatz thank you! If you restart the program, code outside of functions doesn't seem to be executed again, but variables you've declared still seem to work.

  • IgnatzIgnatz Mod
    Posts: 5,396

    That's probably because Codea only compiles code the first time, including the external local variables, and second time it just runs setup.

  • dave1707dave1707 Mod
    edited February 2015 Posts: 7,602

    @yojimbo2000 If I understand your question, your saying any code outside a function doesn't run when the replay icon is pressed. Here's some code that show otherwise. As far as I know, any code outside a function gets executed before any code inside a function. Tap the replay button.

    EDIT: Just in case I mixed up the "replay and restart", here some new code that uses restart. Tap the screen for restart. All the code is executed for restart also.


    a="code at start\n outside any function" print(a) function setup() a="code inside function setup()" print(a) end function draw() background(0) fill(255) text("tap screen for restart",WIDTH/2,HEIGHT/2) end a="code at end\n outside any function" print(a) function touched(t) if t.state==BEGAN then restart() end end
  • Posts: 2,020

    @dave1707 really? When I try your code, I see all 3 messages on the first run, but on every restart, I only see the code inside the function. Do you see all 3 messages on each restart?

  • dave1707dave1707 Mod
    Posts: 7,602

    @yojimbo2000 I see all 3 messages when I run the code, when I press the replay button, and when I tap the screen to do a restart. But then I'm also running Codea 2.2 (34).

  • Re scope: each tab is a separate "chunk" in lua terms. So local stuff in a tab is only available within that tab.

  • like @yojimbo2000 i only one message on restart (codea 2.1)

  • dave1707dave1707 Mod
    Posts: 7,602

    I ran the code on my iPad 1 with Codea 1.5.5 (21) and when I do a "run", I only see the print from setup(). If I do a replay or restart, I see all 3 messages. I altered the code so that I had different variable names for the strings outside of the setup function. I added print statements in setup to print those variables. When I ran the code, setup printed all 3 strings. So the variables got assigned, but the print didn't show.

  • Posts: 2,020

    @dave1707 Codea 2.2, cool. Are you a beta tester? I added a random number to the variable a before the setup function, and it changed with each restart. So variable declarations are re-executed on restart, although other stuff (such as print statements) are not, at least in 2.1

  • dave1707dave1707 Mod
    Posts: 7,602

    @yojimbo2000 Yes, I'm a beta tester. It's nice to get the new code early. That's what I was seeing with my iPad 1. It didn't look like print worked, but other code executed. But with 2.2, I see all the print results.

  • Posts: 61

    It's good to hear experts playing newbie tricks.

  • Posts: 61

    As a newbie I would follow the rules and stick to the two preloaded functions until advised otherwise. If rules are not followed then any attempt to maintain compatibility between successive upgrades of IOS, and newer versions of Codea or Lua would become more difficult.

  • Posts: 2,020

    @Steep there's no rule against putting code outside an explicit block, and sometimes it's essential, for instance in getting supportedOrientations to work properly

  • Posts: 1,976

    @Steep I've found putting code outside functions to be very useful, for example my 3D explosions, where I had some code that pre-rendered a short animation to use. (If I put it in a function, it would generate the animation multiple times, and it was way too expensive to calculate in realtime.)

  • Jmv38Jmv38 Mod
    edited February 2015 Posts: 3,295

    @SkyTheCoder you can have code in a function, and make so that it is played only once... (with a static variable playedOnce=false that you test and set true in your function.). But i am sure you know this.

  • Posts: 1,976

    @Jmv38 Yes, but that would require a variable playedOnce that was outside any functions, wouldn't it? (The animation's images were local to the tab, so no global variables)

  • Posts: 61

    Sorry if I am drifting off topic but again, as a newbie, I must ask can what you are doing be called jailbreaking ?

  • Posts: 1,976

    @Steep Jailbreaking is when you remove the restrictions of iOS via some third-party program so you can install applications and tweaks that were not approved my the App Store. So no, nothing in Codea has to do with jailbreaking. (I personally wouldn't recommend jailbreaking as it waivers your iDevice's warranty, and there aren't many super-useful advantages to jailbreaking, in fact it can be a bit dangerous because you could download a virus, or your iDevice could get bricked.)

  • Posts: 61

    Thanks SkyTheCoder. In my searches so far I have seen one or two calls made outside the two main functions. Some lessons are hard to learn

  • Posts: 2,020

    @SkyTheCoder you could just have an "explosion.prerender()" function, and just call it once from the setup() in your Main tab

  • Posts: 1,976

    @yojimbo2000 I wouldn't want the user to have to do anything to use the class.

  • Posts: 2,020

    @SkyTheCoder Oh I see, you're going for a totally self-contained modularity.

  • edited February 2015 Posts: 2,020

    I just ran into a really strange issue which I think is to do with this question of the scope of code that is outside any block.

    In one project I'm working on I have all my shader strings in a separate shader tab. They're not in any block. ie:

    --#Shaders
    myShader={
    vertexShader=[[ blah ]],
    fragmentShader=[[ blah ]]
    }
    myShader2={
    

    etc.

    and then call them with myMesh.shader=shader(myShader.vertexShader, myShader.fragmentShader)

    This has worked fine.

    Then, mainly because I was bored of writing out fragmentShader so many times, I thought I'd prewrap some of the strings as a shader.

    So now the tab looks like this:

    --#Shaders
    myShader=shader([[ blah ]], [[ blah ]])
    
    myShader2=shader([[ blah ]], [[ blah ]])
    

    and call them with myMesh.shader=myShader.

    And suddenly, all my objects disappear. It's really odd, I'd've expected an error ("shader expected, got nil") or something, but just a blank screen.

    The shader calls have to be inside a function it seems, they cannot be precompiled. So do this:

    --#Shaders
    function shaderSetup()
    myShader=shader([[ blah ]], [[ blah ]])
    
    myShader2=shader([[ blah ]], [[ blah ]])
    end
    

    (and call the function obviously), and everything works again.

    So why is it fine to declare the shader string outside of any block, but a shader has to be called from a function?

  • Posts: 1,976

    @yojimbo2000 This problem was brought up a while ago, I don't think it has anything to do with the scope, just that the OpenGL frame hadn't been initialized yet (before even the first frame!) and couldn't load shaders.

  • Posts: 2,020

    @SkyTheCoder OK, that makes more sense, thanks! It was with a new shader that I was introducing, and I thought that nothing being drawn was a problem with the shader, took me about an hour to figure out!

  • @SkyTheCoder you could use a function inside a function

    function draw()
        --your explosion prerender
        function draw()
            --all other code that you'd normally have in draw
        end
    end
    

    the explosion prerender would only get excecuted once, then the draw function would get overwritten by the inner one, same principal as using a flag, but... It looks cooler (imo)

  • Posts: 1,976

    @stevon8ter But it's in its own tab, and should require no setup for the user. That would have to be part of main.

  • @SkyTheCoder can't you hijack the setup function like you do with the touched function? I don't know, I'm just thinking out loud :p

  • Posts: 1,976

    @stevon8ter Actually, I'm not sure if you can hijack the setup function. But again, the code would be in main, and would require user setup.

  • Posts: 61

    Why are newbies thrown in a the deep end when they can enter Codea via the back door using some of the techniques revealed in this thread ? So much can be done outside 'FunctionDraw' just using the 'setup function

    backingMode(RETAINED)
    function setup()
       w=WIDTH/2
       h=HEIGHT/2
    
        background(5, 247, 6, 255)
    -- Draw a square the hard way
        stroke(256)
        strokeWidth(5)
        line(130,200,230,200)
        line(230,200,230,300)
        line(230,300,130,300)
        line(130,300,130,200)
        fill(233, 32, 32, 255)
        rect(w,h,100,100) -- A square made easy
        ellipse(600,200,200) -- Add a circle
    
        for x=1,10 do     -- a simple loop
            font("AcademyEngravedLetPlain")
            fontSize(64)
            fill(22, 21, 21, 255) 
            text("O",x*40,650)
        end
        text("Try text",w-100,h+150)
    end
    

    It's a pity that Codea can not be coaxed into letting Lua run full screen as a starting environment for newbies.

  • Posts: 2,020

    @Steep I don't know why my question has caused you so much anxiety! There is no requirement that "newbies" do anything suggested on this forum or anywhere! Have you not heard the expression "a bad workman blames his tools"?

    I was a "newbie" in November last year, but I don't consider myself to be one now, largely because of reading a lot on these forums, on the wiki link at the top of this page, on the blogs coolcodea (by @Ignatz) and codeatuts, and also @Ignatz 's free ebook series (which he links to in the first post on his blog). Have you read and digested his "Lua for beginners" and "Codea for beginners" books yet? If you do, you won't have to start all of your posts with "as a newbie", "as a newbie"!

    You can go fullscreen with displayMode(FULLSCREEN) or FULLSCREEN_NO_BUTTONS.

    There are lots of functions besides draw and setup. With system functions there's touched, collide, orientationChanged, keyboard (and of course there are all the functions that you declare yourself. I'm assuming you're not putting everything directly in draw and setUp...)

  • Posts: 61

    So can Codea be set up to make Lua fully functional so that a newbie can start at the beginning ? I consider myself a newbie with a long long way to go.
    http://homepage.ntlworld.com/g.steeper/Link/FirstLink.htm

  • IgnatzIgnatz Mod
    edited March 2015 Posts: 5,396

    I started, and I recommend other newbies do as well, by just using Lua and print commands from the setup function, ignoring drawing on the main screen. That allowed me to get used to the language, before tackling graphics.

    No special setup is required to do that.

  • Posts: 2,020

    I'm not exactly sure what you are asking, but Codea is a fully functioning implementation of Lua 5.2, you don't need to set anything up. What makes you think it is not fully functional? It has lots of other layers added on top, which is necessary in order for us to access the features of iOS and the iPad (multitouch, device orientation, Open GL graphics, sound etc), as well as lots of other lovely things which are lots of fun for making games (Box 2D physics, Tweens etc), but, there's no compulsion for you to use them! You are free to use as little as the instruction set as you choose!

    Here's the link to the Lua for beginners ebook:

    https://www.dropbox.com/sh/mr2yzp07vffskxt/AABlplSGGFBTu8FzQy94lteua/Lua for beginners.pdf?dl=0

  • Posts: 61

    Thanks Ignatz I feel sure that if there was a way to use Lua full screen you would have used it instead of working in the black zone in your tutorials.
    Ok - yojimbo2000 sorry for interrupting your search into the unknown. Thought it might help to take one step backward before trying to taking two steps forward.

  • IgnatzIgnatz Mod
    Posts: 5,396

    Your alternative is to install a desktop version of Lua while you are learning the language, then you can use the full screen, until you aready to come back to Codea.

  • Posts: 2,020

    @Steep OK I understand now, you were asking about whether the console area could be made fullscreen.

  • Posts: 2,020

    @Steep I would also say that a simple and clearly defined question, "what is the scope of a variable", counts as "a step back" rather than "2 steps forward" :-)

  • IgnatzIgnatz Mod
    Posts: 5,396

    I think what matters most is that we help each other where we can. Two years ago, I was a total Codea noob and got help from the forum wizards of the time. I found Codea extremely confusing, to start with, so i have a lot of sympathy with beginners, who don't always know what question to ask.

    I remember when I first tried 3D, and spent ages drawing stuff that didn't appear on the screen, until I finally learned the z axis was back to front. It was crazy things like that that led me to start writing tutorials, so other people wouldn't have the same problems. But even with tutorials, Codea can take a lot of getting used to.

    But it's worth it. Codea is just the best fun I've had in years. >:D<

  • Posts: 61

    I am really outside my comfort zone moving from a lap top running a bottom of the range Windows OS to a relatively high level Apple device running IOS-8. Perhaps I should go back and play around with a Raspberry Pi running Risc OS.
    The problem is I would loose the comfort of armchair computing.

  • Posts: 1

    @yojimbo2000 for the double colon notation, see:
    en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form

  • Posts: 2,020

    Oh cool, I was just thinking of bumping this question, thanks. It's the sort of thing that's hard to google, because symbols get stripped away from the query

Sign In or Register to comment.