lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> I think you are quite right. I'm a big fan of Lua too, but I've failed with
> the first larger project I tried writing completely in Lua (less than 10K
> lines). Of course, I made mistakes, but I still think that large projects
> need every possible tool to remain reasonably maintainable and bug-free.
> Static typing and compile-time checks (including warnings to the max) are
> indispensable.

I don't agree on that - like other posters on this topic, I believe
that static type checking is catching only the easy bugs. If I write a
piece of code (any language) I have to test if it works, either
manually or automatically with a test. And my experience is that most
typos are caught in that process anyway. Also, if you run into a typo
of your code later on, you will notice that you haven't tested that
piece of code at all - and this alarm is actually a good and not a bad
thing ;). If there's a typo error left, a logic error is not unlikely
as well because this code path obviously hasn't been tested at all -
so you are warned about the next possible error source... which is not
going to happen in a static language but it will eventually fail with
a much different report that will make you waste your time on finding
the real source (the untested code). With a static language you will
run into such problems in a deterministic manner where you believe
that the used code is working. In my experience, untested code is
rarely bugfree (real bugs, not typing / spelling bugs).

My personal list of time waste during programming looks different (not
only Lua specific) (in descending time wasteness - the ones that waste
most time are on top):
- missing documentations
- bad error reports on runtime errors (seg faults, no stack trace,
mindless error messages)
- catchalls, e.g. try {...} catch(e) {}
- code duplicates (copy paste code that is buggy)
- logic errors (e.g. x*x+y*z+z*z)
- compiler / linker problems with unforeseen version incompatibilities
- lack of code optimization
- mindless documentation of functions that is useless because it
doesn't tell me more on a method/function than I can read from its
name anyway, but that is cluttering the source files (e.g. javadoc for
method "addItem" doc-> "adds an Item") - and this is in my opinion a
phenomenon of IDE driven development


This is my subjective list of bad code symptoms that is causing me to
waste my time. I don't list "wrong types" - It scarcely happens to me
and is in my opinion trivial - most often at least. So what is static
typechecking really helping here? Discipline! Every time you get lazy,
your compiler is throwing you an error message on your head. If you do
mad stuff in Lua (and you can do), and you don't doc it, you are lost.
But that's also bad if you do it in C++. Static type checking is only
helping you so far that the least amount of documentation, that is
totally required, exists. And as written above, it might prevent you
later on from discovering that you are using untested code as well.
Also, in my opinion, my problem list is worse in static checked
languages and better in dynamic languages (mostly, some points are
worse with dynamic languages). For example, the debug library in Lua
allows me a much finer debug control than I am getting with Java. I
don't have to rely on an IDE to do debugging, I can do it myself with
a simple texteditor. And that grants me flexibility.

Another point for me is that my Lua code tends to be shorter than
other code. Not unreadable shorter but meaningful shorter. Closures
that I am using like macros are helping here a big deal. There is
something that I call syntax-information-ratio: Syntax is what the
language needs to run, information is logic or simply data like
strings. Repetitive patterns don't contain information. If I need
initializers and I notice I am writing something like that (made up
thing but I hope you get the point):

foo.bar.vec.x = 1
foo.bar.vec.y = 2
foo.bar.vec.z = 3

I am replacing it with something like that

set(foo.bar.vec)
 .x (1)
 .y (2)
 .z (3)

where set is

function set(tab)
	local proxy = {}
	local function kset (t,key)
		return function (val)
			tab[key] = val
			return proxy
		end
	end
	setmetatable(proxy,{__index = kset})
	return proxy
end

I am normally trying to reduce repetitive patterns in my code and I
find this more fun to do in Lua or Javascript than using macros in C.

But in my experience, the programming language is not as important as
experience in the team so I consider these arguments as weak anyway.
No language will come to your help if your team is doing a bad job.
The sooner this real problem shows up, the better. So languages that
don't delay this fact are in my opinion "better".

cheers,
Eike