21 нояб. 2009 г.

Lua vs. C++ for large programs

Mature C++ programmers often argue against intense Lua usage in the large programs.

They say that C++ is fast, Lua is slow. C++ has excellent tools to provide compile-time validation, while Lua is too dynamic and, therefore, unreliable.

Some time ago there was a related discussion on Lua mailing list. I hear these arguments so often, that I've decided to post a small essay in reply. Now I'm posting a slightly edited version of this essay here.

* * *

Several years before, when I came to Lua, my professional programming experience was almost all C++, without much of dynamic languages experience. Indeed, in C++, with careful design, compile-time validation can give very good correctness guarantees.

At first it was quite hard to write code in Lua — without compile time validation, without static types, it felt as if I try to stand on a blob of wobbly jelly instead of a good solid rock.

However, the price of such validation is quite high. Not to mention longer compile times. You need to spend much time on the design itself. Sometimes much more time than you'd spend solving the problem that you write code for. You need highly skilled and disciplined architector paying constant attention to the each part of the project all the time. You need highly-qualified programmers.

If you have a hammer, try to avoid looking on everything as a nail.

I quite understand if that amount of effort is spent on the low-level "foundation" code in the system (application, library etc.). It is usually written once, must be of high quality and work fast. But to waste it on the business logic, that mutate every day to the whim of the high command?

You want to be able to write cheap business logic code. Okay, it should be reliable enough and fast enough. But it is usually comes in huge quantities, and you should be able to change it quick. You should not need extra skilled programmers to write it — or your budget will bust.

Lua is perfect here — it is reliable, quite fast and easy to grasp.

Compile-time guarantees are not possible to achieve with pure Lua. As we know, Lua compiler is dumb (and this is a good thing — since it is also fast and simple).

I do hope that, in time, we would get Metalua-based static code validation tool, powerful enough to do something like that. But there is no such tool now.

However, there is a simple solution. Write tests.

Any static analysis tool may only catch such generic errors, that it has heuristics for. Even C++ compile-time validation will catch only so much of wrong logic — and the more it may catch, the greater the price you have to pay for the code.

To give a sense of scale: My last project had 160+ KLOC of Lua code. 80 KLOC of it were tests for our Lua and C++ code (we had 90+ KLOC of C++ in total). Most of our tests were declarative and consist of table-structured input / expected output data, they were significantly sparser than the usual code, so the price per LOC is lower.

Tests catch more (you may tune them exactly to the behaviour you expect), they cost less (you may employ less sophisticated programmers), they help refactoring at least as much as the static compile checks.

If we compare Lua with "test-time" validation and C++ with its compile-time checks, to me Lua is the winner (for the business logic at least).

* * *

Do not be afraid to use Lua in large-scale applications! It is at least as easy to write reliable code in Lua as in C++.

Of course, you have to write tests, but you should write them anyway. Lua is powerful enough and is fast enough (especially with LuaJIT 2) to make you happy. Yet it is simple enough so you don't have to force guru-level programmers to write tons of mind-numbing business-logic code.

1 комментарий:

petrenkov комментирует...
Этот комментарий был удален администратором блога.