Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

local variables in Perl and Lua

Name: Anonymous 2011-07-22 21:32

I didnt get an answer for this in the Python thread, so I'll ask here: Why do variables have to have the local keyword to make their scope local? Why cant it just use implicit lexical scope like most any other languages?

Name: Anonymous 2011-07-22 21:47

x = 1

is that creating a new x or binding to an existing one

Name: Anonymous 2011-07-22 21:49

in Perl and Lua
You forgot Ruby and Groovy.

It's a common language design mistake. I remember Graham mentioned it in one of his Arc articles.

http://www.paulgraham.com/arclessons.html
see "Implicit local variables conflict with macros."

Name: Anonymous 2011-07-22 21:49

>>2
its a dynamic language so it could be either, it could even be changing the type if it was previously different

Name: Anonymous 2011-07-22 21:58

>>4
dynamic language
changing the type

Wrong. In dynamic languages values carry types, not names.

Name: Anonymous 2011-07-22 22:11

>>4
its a dynamic language so it could be either
there you go

local x = 1 -- new x, always
x = 1 -- rebinding to existing x
technically the second one might create a new global if there aren't visible x locals, although there's only one global scope anyway so it doesn't really matter. it could go a step further and require declaring globals as well but that isn't going to happen for a while

also, in lua 5.2 the following code relies on being able to create new locals on demand

local environment = {
    a = { x = 10 },
    b = { x = 20 },
    c = { x = 30 },
}
do
    local _G = _G
    local _ENV = environment.a
    function printx () _G.print(x) end

    local _ENV = environment.b
    function printx () _G.print(x) end

    local _ENV = environment.c
    function printx () _G.print(x) end
end
environment.a.printx()
environment.b.printx()
environment.c.printx()

this probably isn't the greatest example because if people used _ENV like this in real-world code they'd probably be flayed

sure you could put those into their own functions but working around crappy scoping rules via closures is a javascript thing

Name: Anonymous 2011-07-22 22:43

>>6
it looks like you are using a lot of syntax that is very specififac to Lua, so I dont understand what is going on. Im guessing environment is just a regular table unless it happens to be a built in variable name for storing environment variables. It looks like variables that hold a variable declaration. I dont know what the pre-underscore does in _G. Im guessing _ENV is a built in variable for holding variable state.

this is all too much for me to google

Name: Anonymous 2011-07-22 22:45

>>7
environment is just a regular table unless
The problem of most scripting languages.

Name: Anonymous 2011-07-22 23:24

>>7
like i said that wasn't a great example, because _ENV is... kind of an involved thing, but it has to do with the fact that _ENV must have that name (it's used during compilation), so if you were stuck with an ambiguous "does it create a new local or reference an old one" situation you'd either be fucked or you'd have to add more visual noise to work around it

quite similarly to the above, if i want a variable named ``x'' right now you'd damn well better let me create one even if another ``x'' already exists. closures will usually involved in this case

how this relates to perl... i don't know. probably similarly with closures and the like

Name: Anonymous 2011-07-23 0:30

Not an issue in perl. use strict;

Name: Anonymous 2011-07-23 0:36

>>10

use strict;
module Main (main) where
include namespace std;
import prelude;

Name: Anonymous 2011-07-23 1:31

>>10

Not an issue in lua:

require "strict"

Name: Anonymous 2011-07-23 2:24

>>12
unfortunately this is runtime-only, which is better than nothing i guess, but not great

Name: Anonymous 2011-07-23 2:38

>>13
well in an runtime evaluatet language it would be hard to get compile time variable checking

Name: Anonymous 2011-07-23 2:49

>>14
not really. during compile time lua knows what is a local and what isn't: it (the standard interpreter, at least) has to in order to perform register assignment and generating get/setglobal instructions

but it does start getting fuzzy when you consider that lua doesn't actually have globals. once function environments start getting involved, your "globals" in one environment suddenly don't exist in your other environments, unless you copy them over from the outside or __index them.

this doesn't really change a whole lot as far as they behave within an environment, but "global" would be a pretty bad keyword to use to declare them

Name: Anonymous 2011-07-23 3:00

Why do variables have to have the local keyword to make their scope local?
local in Perl is unfortunately named. You want the Huffmanized my. You also want use strict which (also unfortunately) isn't default to make it easier to spot perl scripts written by people who have yet to learn the language.

Name: Anonymous 2011-07-23 3:17

>>8
Lua is the only language I know of that has this property.

Name: Anonymous 2011-07-23 3:18

Let's pretend Lua had Python's scoping rules. What is happening here?

function()
  a = 0
  return function(x)
    a = x
    return a
  end
end

Where does a live? is the one in the function body a new one or is it assigning to the old one?

Name: Anonymous 2011-07-23 3:29

>>17
How else a complete noob would implement variables for his quick and dirty "Personal Home Page" language? Of course he then realizes that error of his ways, but it will be already too late and we will get the next PHP/Perl/Ruby.

Name: Anonymous 2011-07-23 3:33

>>16
local in Perl is unfortunately named. You want the Huffmanized my.
my just does what local should, make variables lexically scoped
You also want use strict
all strict does is force you to use my

which still doesnt answer the question, why cant lexical scope be default instead of having to put my in front of all variables

Name: Anonymous 2011-07-23 3:36

>>19
not the right story. Lua does it this way because it's a data description language. The designers feel that a simple file that just says "height = 50 width = 20" should be useful.

actual Lua code that is written for functionality simple doesn't include globals. It's not hard, and since the global table is a regular table, you can stick a metatable on it that stops you from making globals (for instance)

Name: Anonymous 2011-07-23 3:38

>>18
I dont get that code at all, are you defining a function called function? or is that a lambda function? And this function defines the variable a and then returns x?

Name: Anonymous 2011-07-23 3:41

>>22
it's all lambdas. you could put "foo =" before it but it wouldnt' change the point.

The point is, as you said, that without a way to call out where a variable lives, you end up with ambiguities between assignment and making a new binding. Python solves this with the ugly-as-shit "nonlocal" keyword, because Guido thinks lexical scope is bad. (because he's a goddamned retard)

Name: Anonymous 2011-07-23 3:42

JavaScript's "var" is basically the same as Lua's "local" btw

Name: Anonymous 2011-07-23 4:18

>>24
Javascript's var just identifies a new variable to avoid the mistake of assigning to a previous variable of the same name, doesnt it? In fact var is optional in Javascript

Name: Anonymous 2011-07-23 7:02

>>25
JS has pig disgusting dynamic scope mixed with lexical scope, IIRC. var declares a new variable.

Name: Anonymous 2011-07-23 11:46

>>20
But local is too long for the most common scope.

Explicit scope is a good thing for scripting languages. Having either as a default is not my cup of tea, because it's better to always see where the variable is introduced in a given scope, and which scope it is introduced to (eg my vs. our in Perl.)

In languages like C it's not such a big deal. If you're writing one of those you will be avoiding globals much more eagerly.

>>26
You think JS is bad for dynamic scope? Try writing bash sometime. Loop constructs all introduce dynamic scope, so good luck using data you've accumulated/processed in a loop.

Name: Anonymous 2011-07-23 12:05

>>21
>not the right story. Lua does it this way because it's a data description language. The designers feel that a simple file that just says "height = 50 width = 20" should be useful.
You can do the same with Lisp:
(Width 50)
(Height 20)

What is the point?

Name: Anonymous 2011-07-23 12:13

>>28
(Width 50)
(Height 20)

(dims '(50 . 20)) is much more sexy.

Name: Anonymous 2011-07-23 12:19

>>27
You think JS is bad for dynamic scope?
No, dynamic scope by default is bad.

Name: Anonymous 2011-07-23 12:25

>>29
(dims '(50 . 20)) is much more sexy.
Obfuscation is sexy?

Name: Anonymous 2011-07-23 12:38

>>27
I don't think local is too long. It would be if it were like Lisp or C where you had to introduce a new level of indentation on top of it. Every keyword in lua is long. "function" is longer than "lambda" which is longer than "fn" but really who cares? it's just a bit of typing

>>29
You'd have to define Width and Height functions. "height = 50 width = 20" works as the only Lua file. You just grab the values out of the global table, no need to bind or define anything. Just #include "lua.h" (also keep in mind Lua is meant to be embedded. It doesn't have the stuck-up Lisp bullshit of pretending it's running on a Lisp machine with a Lisp OS.)

Name: Anonymous 2011-07-23 12:44

>>32
Nope. I just (eval `(let ,file-content ,my-code))

Name: Anonymous 2011-07-23 12:46

>>32
Just #include "lua.h" (also keep in mind Lua is meant to be embedded.
And export all your 9000 of C/C++ classes and crud by hand!

Name: Anonymous 2011-07-23 12:47

>>32
You just grab the values out of the global table
no you're better off loading config files into their own environments

sure, if you're doing a small script it might not matter if you just load random shit into globals, but for larger ones it sucks

Name: Anonymous 2011-07-23 12:50

Javascript isn't dynamically scopes, it just hoists all variables to be global, just cause.

Name: Anonymous 2011-07-23 12:54

>>32
but... that's not C.
>>34
It ain't no thang, especially if you're not using C++.

Name: Anonymous 2011-07-23 12:57

>>37
If "you're not using C++", you have around 9000 global functions to export, instead of encapsulated classes.

Name: Anonymous 2011-07-23 13:03

>>32
Every keyword in lua is long. "function" is longer than "lambda" which is longer than "fn" but really who cares? it's just a bit of typing
Too verbose to read. Lambda, fun, λ are ok.

Name: Anonymous 2011-07-23 13:05

>>38
or you just have 90 global functions that take care of critical bottlenecks and write the rest in Lua.

You realize that C++ only mangles names that are still global, right? this is what makes it impossible to automate exporting of C++ and what makes it impossible to make a usable DLL. C++ completely fakes encapsulation. It has syntactic encapsulation only -- not compile time, not run time.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List