Making lua case insensitive

classic Classic list List threaded Threaded
19 messages Options
Reply | Threaded
Open this post in threaded view
|

Making lua case insensitive

Falko Poiker
Hey guys,

Has anyone here modified lua to be case insensitive?  Since we have a whole
lot of designers poised to do lua scripting, I want to avoid them having to
debug capitalization errors.  As such, I'd like to modify lua so that it
ignores case - at least with variable/function names.  Is there an easy way
to do this?

Falko


Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

Bret Mogilefsky-4
On Fri, Dec 08, 2000 at 12:04:37PM -0800, Falko Poiker wrote:
> Has anyone here modified lua to be case insensitive?  Since we have a whole
> lot of designers poised to do lua scripting, I want to avoid them having to
> debug capitalization errors.  As such, I'd like to modify lua so that it
> ignores case - at least with variable/function names.  Is there an easy way
> to do this?

Better instead to put in setglobal/getglobal functions that check whether the
variable has been earlier "declared" by calling a special function.  Then
you can remove these once you're done with the code to get rid of the
performance hit.  This would take care of case mistakes as well as typos.
We started using that at the beginning of Monkey... Not only did it catch
lots of mistakes, but it encouraged people to document what variables did
at the opint where they "declared" them.

Bret
-- 
Bret Mogilefsky  ** [hidden email] **  Programmer, SCEA R&D

Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

Steve Dekorte-4
In reply to this post by Falko Poiker
Bret Mogilefsky wrote:
> Better instead to put in setglobal/getglobal functions that check whether the 
> variable has been earlier "declared" by calling a special function. 

How did you deal with locals?

Example:

function test()
  local aString = ""
  print(astring)
end

Seems like you'd need a way of looking at the stack in this case. upvalues?

Steve

Reply | Threaded
Open this post in threaded view
|

RE: Making lua case insensitive

Falko Poiker
In reply to this post by Falko Poiker
> On Fri, Dec 08, 2000 at 12:04:37PM -0800, Falko Poiker wrote:
> > Has anyone here modified lua to be case insensitive?  Since we 
> > have a whole lot of designers poised to do lua scripting, I want 
> > to avoid them having to debug capitalization errors.  As such, 
> > I'd like to modify lua so that it ignores case - at least with 
> > variable/function names.  Is there an easy way to do this?

> Better instead to put in setglobal/getglobal functions that check 
> whether the variable has been earlier "declared" by calling a 
> special function.  Then you can remove these once you're done 
> with the code to get rid of the performance hit.  This would 
> take care of case mistakes as well as typos.

Interesting idea.  Did you use the getglobal(NIL) tagmethod for this?

The difference in our game is that we're planning on exposingthe lua 
layer to mod groups so they can modify ai, as well as other scripted 
variables and functions.  Of course we could let those people run the 
game in "developer mode" that turns on the case/spelling check (with 
the accompanying performance hit).

There is also the aformentioned problem of local variables.  If 
globals are checked and locals are not, it could discourage designers 
from using local variables...

> We started using that at the beginning of Monkey... Not only did 
> it catch lots of mistakes, but it encouraged people to document 
> what variables did at the opint where they "declared" them.
How exactly does this system encourage documentation?  I think it's 
a great idea, but it's not obvious to me how this works.

Thanks!
Falko



Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

Bret Mogilefsky-4
On Fri, Dec 08, 2000 at 02:04:39PM -0800, Falko Poiker wrote:
> Interesting idea.  Did you use the getglobal(NIL) tagmethod for this?

Yes.

> The difference in our game is that we're planning on exposingthe lua 
> layer to mod groups so they can modify ai, as well as other scripted 
> variables and functions.  Of course we could let those people run the 
> game in "developer mode" that turns on the case/spelling check (with 
> the accompanying performance hit).

Yeah, that's a good way to do it.

> There is also the aformentioned problem of local variables.  If 
> globals are checked and locals are not, it could discourage designers 
> from using local variables...

We didn't worry so much about locals because you're usually looking right
at whatever the problem is.  However, exactly recalling the way the
variable was named as a global or table element elsewhere is kind of a pain
in the butt, and that's the problem this attacks.  There's also the problem
in a large body of code because you have a bunch of unclear
dependencies... If someone changes the name or remvoes the variable
elsewhere, you don't get an undefined reference telling you what's wrong as
you would with C.  =)  With the indirection in place, things break
visibly when the variable is no longer explicitly declared, whereas you
might get reasonable behavior sometimes based on a nil value otherwise.

> > We started using that at the beginning of Monkey... Not only did 
> > it catch lots of mistakes, but it encouraged people to document 
> > what variables did at the opint where they "declared" them.
> How exactly does this system encourage documentation?  I think it's 
> a great idea, but it's not obvious to me how this works.

People tend to get organized and stick all of their variable "declarations"
at the top of a file.  At the point where you're doing that, it's pretty
easy to comment what it does or why you need it.  Otherwise people just
start using a variable name and there's no explanation but context.  I
guess it doesn't enforce it, but having all of your variables named in one
place does let you see things more clearly.


Bret
-- 
Bret Mogilefsky  ** [hidden email] **  Programmer, SCEA R&D

Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

Luiz Henrique de Figueiredo
In reply to this post by Falko Poiker
>Has anyone here modified lua to be case insensitive?  Since we have a whole
>lot of designers poised to do lua scripting, I want to avoid them having to
>debug capitalization errors.  As such, I'd like to modify lua so that it
>ignores case - at least with variable/function names.  Is there an easy way
>to do this?

The "idiomatic" Lua way would be to use get/setglobal tag methods, but this
does not handle locals or table fields, as has already been pointed.

If you really want this, the easiest route is to change readname in llex.c
(in 4.0) to lower case L->Mbuffer before returning it.

Changing the implementation of Lua is not something that I encourage, but
in this case it is the simplest solution, given that it is a single line of
code (if you have a strlower function in C).
--lhf

Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

Steve Dekorte-4
In reply to this post by Falko Poiker
Luiz Henrique de Figueiredo wrote:
> The "idiomatic" Lua way would be to use get/setglobal tag methods, but this 
> does not handle locals or table fields, as has already been pointed. 

It really would be nice to be able change how Lua looks up local variables from within Lua. This would allow variable references in object methods to automatically look in self (as in many OO languages) if a local doesn't match. 

Example:

function Person:fullName()
  return self.title.." "..self.firstName.." "..self.lastName
end

Could become:

function Person:fullName()
  return title.." "..firstName.." "..lastName
end

Steve

Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

Luiz Henrique de Figueiredo
In reply to this post by Falko Poiker
>It really would be nice to be able change how Lua looks up local variables from within Lua.

I think that having tag methods for locals would kill the performance edge
of local variables.

>function Person:fullName()
>  return self.title.." "..self.firstName.." "..self.lastName
>end
>
>Could become:
>
>function Person:fullName()
>  return title.." "..firstName.." "..lastName
>end

I don't see how ag methods for locals would help here: title, firstName,
lastName would be parsed as *global* variables.
You'd have to declare them as local, but in this case, why not write
 local title, firstName, lastName = self.title, self.firstName, self.lastName

--lhf

Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

Michael T. Richter-2
In reply to this post by Bret Mogilefsky-4
> People tend to get organized and stick all of their variable
> "declarations" at the top of a file.  At the point where you're
> doing that, it's pretty easy to comment what it does or why you
> need it.  Otherwise people just start using a variable name and
> there's no explanation but context.  I guess it doesn't enforce
> it, but having all of your variables named in one place does let
> you see things more clearly.

You can force the issue by requiring a document string on the function that
declares the variable.


Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

Eric Tetz-2
In reply to this post by Falko Poiker
I have a question about the design of Lua's for loop.

In my opinion, the syntax:

   for i = 1 to 100
     ...
   end

   for n = 79 to 0 step -1
     ...
   end

is more in keeping with the general look and feel of Lua's other control flow statements.  I also
find it easier to read, and more self-documenting.  'if exp,exp,exp' is reminiscent of a C 'for'
loop, but it doesn't have the same semantics.  Lua's for loop has the semantics of a 'for' loop in
Basic or Pascal, so why not the same clear, suggestive syntax?

It seems that everything in Lua has been carefully thought out, so I can only assume that the same
amount of thought went into choosing the syntax for the 'for' loop.  How was it chosen?

Curious,
Eric

__________________________________________________
Do You Yahoo!?
Yahoo! Shopping - Thousands of Stores. Millions of Products.
http://shopping.yahoo.com/

Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

John Belmonte-2
In reply to this post by Steve Dekorte-4
Steve wrote:
> It really would be nice to be able change how Lua looks up local variables
from within
> Lua. This would allow variable references in object methods to
automatically look in
> self (as in many OO languages) if a local doesn't match.
>
>function Person:fullName()
>  return self.title.." "..self.firstName.." "..self.lastName
>end
>
>Could become:
>
>function Person:fullName()
>  return title.." "..firstName.." "..lastName
>end

This could be done, if only the changes to the treatment of the global scope
that I've been whining about since April would be implemented.  Maybe you
are giving me chance here to demonstrate how the change would solve a
practical problem...

If global accesses triggered the table events of the global table instead of
getglobal/setglobal events, we could implement what you desire as follows:

1) make a wrapper for your classes methods that would back up the current
global table and replace it with your class object.  That is, when the user
calls obj:fullName() it's really first handled by a wrapper that switches
the global table and then calls the actual fullName().

2) now global accesses such as the variable "title" will just access the
fields in your object.  Make the "index" event of your class (remember, in
my fictitious world a failed global access will call the index event of the
global table) access the real global table that you backed up in the method
wrapper.

3) go have a beer, because Lua let's you do neat things like mimic the name
lookups of other languages

That's all I want.  I showed the other day how the changes could be
backwards compatible.  What's left?

-John



Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

John Belmonte-2
Ah I forgot, I described this scheme in some detail in the message entitled
"function kidnapping" from May 2000.

-John

> This could be done, if only the changes to the treatment of the global
scope
> that I've been whining about since April would be implemented.  Maybe you
> are giving me chance here to demonstrate how the change would solve a
> practical problem...



Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

Steve Dekorte-4
In reply to this post by Falko Poiker
John Belmonte wrote:
> 1) make a wrapper for your classes methods that would back up the current 
> global table and replace it with your class object.  That is, when the user 
> calls obj:fullName() it's really first handled by a wrapper that switches 
> the global table and then calls the actual fullName(). 

It seems that the cost of this step would exceed the benefit of the simpler syntax.
Is there some way to avoid this problem?

Steve

Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

Steve Dekorte-4
Luiz Henrique de Figueiredo wrote:
> >function Person:fullName() 
> >  return title.." "..firstName.." "..lastName 
> >end 
>  
> I don't see how tag methods for locals would help here: title, firstName, 
> lastName would be parsed as *global* variables. 
> You'd have to declare them as local, but in this case, why not write 
>  local title, firstName, lastName = self.title, self.firstName, self.lastName 

Sorry, I should have been clearer - by "looks up local variables",  I meant a lookups any variable reference in a function, not just variables declared as local.

So if you wanted to look up variables like this:
1. in the locals (I'm assuming arguments are locals too)
2. then in self table (if there is a local self variable)
3. then in the globals table

Is there an easy way to implement this in Lua?

If there we some sort of abstract table that lua put arguments and locals in while executing a function that it did variable lookups on, then a index tag on this table would do the trick.

Steve

Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

Luiz Henrique de Figueiredo
In reply to this post by Falko Poiker
>I have a question about the design of Lua's for loop.

See the full lua-l archive and enjoy the heated discussions about this in the
past (when we decided against "for") and then more recently when we added "for".

You are right: the more verbose syntax would be more natural but it would also
introduce new reserved words, such as "to" and "step", which would probably
break some programs ("step" in specially dangerous here).

In a recent interview, Dennis Richie, father of C, said:

 "if your new language does begin to grow in usage,
 it can become really hard to fix early mistakes."

 http://www.linuxworld.com/linuxworld/lw-2000-12/lw-12-ritchie.html

I consider the "for" syntax a good compromise, but yes, it looks like FORTRAN,
and this is not so bad as it may sound.
--lhf

Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

Luiz Henrique de Figueiredo
In reply to this post by Falko Poiker
>Sorry, I should have been clearer - by "looks up local variables",  I meant a lookups any variable reference in a function, not just variables declared as local.
>
>So if you wanted to look up variables like this:
>1. in the locals (I'm assuming arguments are locals too)
>2. then in self table (if there is a local self variable)
>3. then in the globals table
>
>Is there an easy way to implement this in Lua?

No. Locals are really stack objects, accessed by number, not name.
Local names are now (4.0) stored in the functions, but only for error reporting.

>If there we some sort of abstract table that lua put arguments and locals in while executing a function that it did variable lookups on, then a index tag on this table would do the trick.

Yes, that would be the way to go, now that globals are in an ordinary table.
But, like I said, performance would suffer (and I don't know how much...)

Moving globals to an ordinary table did cost some performance but Lua 4.0
ws already some much faster than 3.2 that it did not matter much and it
simplified the code a lot.
In the distant past (2.4?), globals were once accessed by number, but it was
complicated when we added loading binaries produced by luac.

What I'm saying is that in principle we could store locals in a table, but
that would require changing the virtual machine (yet again!) and would
probably cost performance, but this would have to be measured.
It all boils down to whether we want to have this complication for perhaps
a slight increase of expressive power. I don't know the answer.
--lhf

Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

John Belmonte-2
In reply to this post by Steve Dekorte-4
Steve wrote:
>
> John Belmonte wrote:
> > 1) make a wrapper for your classes methods that would back up the
current
> > global table and replace it with your class object.  That is, when the
user
> > calls obj:fullName() it's really first handled by a wrapper that
switches
> > the global table and then calls the actual fullName().
>
> It seems that the cost of this step would exceed the benefit of the
simpler syntax.
> Is there some way to avoid this problem?

I don't agree that it would be so bad.  One implementation is in the field
fullName you'd have a wrapper object whose "function" event is set to
something like:

    function wrapper(obj, ...)
        local oldtable = globals(obj.locals)
        local val = call(obj.realfunc, arg)
        globals(oldtable)
        return val
    end

This function could be implemented from C.

The thing is, you can do much more with this than just eliminate the self's
in your classes.  You could do a mean module system, closures, namespaces...

-John



Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

Steve Dekorte-4
In reply to this post by Falko Poiker
Luiz Henrique de Figueiredo wrote:
> What I'm saying is that in principle we could store locals in a table, but 
> that would require changing the virtual machine (yet again!) and would 
> probably cost performance, but this would have to be measured. 
> It all boils down to whether we want to have this complication for perhaps 
> a slight increase of expressive power. I don't know the answer. 

Yeah. I think I'd take the speed over the syntax convenience in this case too. Python, JavaScript, Perl, etc have gotten programmers used to using "self" a lot anyways. It's actually nice to know whether you're looking at a local or a instance variable if it's an ugly method.

Steve

Reply | Threaded
Open this post in threaded view
|

Re: Making lua case insensitive

Bret Mogilefsky-4
In reply to this post by Michael T. Richter-2
On Fri, Dec 08, 2000 at 07:35:22PM -0500, Michael T. Richter wrote:
> > People tend to get organized and stick all of their variable
> > "declarations" at the top of a file.  At the point where you're
> > doing that, it's pretty easy to comment what it does or why you
> > need it.  Otherwise people just start using a variable name and
> > there's no explanation but context.  I guess it doesn't enforce
> > it, but having all of your variables named in one place does let
> > you see things more clearly.
> 
> You can force the issue by requiring a document string on the function that
> declares the variable.


Good idea!  I'll do that if I ever get back to Lua programming...  =)

-- 
Bret Mogilefsky  ** [hidden email] **  Programmer, SCEA R&D