@srbs
I do not criticize the lack of features in the language, but the way the language is designed (in other words: how you do, what you do with cbs).
Your last argument was an ad hominem argument (http://en.wikipedia.org/wiki/Ad_hominem) and therefore a rhetorical trick without being constructive at all. Please stop this, I am annoyed by this.
Your config file is that big, because the way configuration works (described below) and because of the lack of memory management (described also below). Big codebase => Big conf. This issue can not be resolved without having control of the configuration process. Sorry.
The framework is btw written with some of the issues below in mind. The usage of vars for every plugin for instance makes the whole framework much more secure.
The Points of criticism:
- Everything is a string (partially lack of types)
- Lists are space-seperated not-escaped lists
- There are too many ways to generate and modify function-strings (e.g. macros, the three braces)
- There are too many ways to call function-strings (macros, as closures...)
- Metaprogramming is just string-modification and can be applyed everywhere
- There is just a global namespace
- There are no named arguments, no function signatures
- No deallocation possible
- Unefficient config file
- Operators are functions, but the function names are symbols
- No error handling
- Lack of C++ documentation (how does it work internally?)
Why this is bad:
Everything is a string means that everything is executable, which can enable an attacker to execute code in some cases. Although it is easily possible to write forkbombs and other malware for cbs, this is probably not really an horror scenario, because masterlist-providers can inject code anyway. There other scenarios, where this can be dangerous: It can lead to data(=>code,state) corruption if random data is executed (just imagine a bug where someone executes a long string of human language). Such a corrupted block might even spread…corrupted code generated more corrupted code with metaprogramming. (I call this disease cubic cancer ;) ). Also it makes debugging a lot harder and even can hide bugs, this of course goes hand in hand with error handling: No error handling => no error on code corruption.
The problems I just described could be contained a bit if there where types and function signatures anyway (line with 8 words, can not be called for function that requires 3 args; can not call a function that requires lists for a line of human language) and again…error handling.
Now there is a lot of problems with the seperation between data and code, but there is an additional problem: The usage of complicated string manipulation methods: You can use multiple Macros of different levels, macros are hard to distinguish from actual variables and their usage varys depending on the level of rect brackets. Calling a function seems to be equivalent with accessing the string one macro level deeper. Then there are two kinds of string defining symbols: [...] and "..." witch both output a string (or you can just use none of them), there are also round braces witch evaluate the code immediately. This is apperantly still a little buggy, because some strings are not recognized as entire commands and in some cases the macro modifier is not recognized (I remember, that I tried to fill a bug report about this/talk to the devs about this, I also remember that I have been somewhat unsuccessful).
The next big block of criticism is the available variable space: Ther is only the global namespace. Not a local one, no packages/namespaces, only one. In other words: You iterate over a list using I as iterator and one other function you call does the same: You are screwed. If someone else in a completely different script decides to call his var 'roster' too...you are screwed. But not only is the cbs-namespace a mess, cubescript is also one single memory leak. no RAM at all is being deallocated, try this:
testnum = 0
testmax = 2048
buildup = [ if (*smaller* $i $m) [ s = (concatword $s $s $s $s $s $s $s $s $s $s); i = (* $i 10); sleep 1 [ buildup ] ] ]
test = [
if (*smaller* $testnum $testmax) [
s = a
i = 0
m = (pow 1024 2)
buildup
sleep 1 [ test ]
]
]
The code above builds string with the size of 1M and deletes it. It does that 2048 times. The memory consumption here shoudl not be higher than 4M (this is generous). Actually it needed about a second to fill my entire RAM.
The next thing is that the configuration is done by writing the entire state => corrupted data and functions written.
The lists are bad for the obvious reason (lets append "mapc is stupid" to the end of a list ;) ).
Operators are just badly designed, using symbols but the arithmetic of functions is inconsistent.
And at last: There are about 5 lines of comment in the entire cube engine, maybe one in the cbs code. This makes it very hard to understand the internals, even if you can read C++.
Well, I am pretty exhausted. There are some ways how you can work around this problems, I'll write them down tomorrow :) .
You said you think cbs is perfect for it's purpose, what makes you think that?
Cheers,
mapc