The A-Z of Programming Languages: Falcon
- 09 April, 2009 11:10
Falcon creator Giancarlo Niccolai
Computerworld is undertaking a series of investigations into the most widely-used programming languages. Previously we have spoken to Larry Wall, creator of the Perl programming language, Don Syme, senior researcher at Microsoft Research Cambridge, who developed F#, Simon Peyton-Jones on the development of Haskell, Alfred v. Aho of AWK fame, S. Tucker Taft on the Ada 1995 and 2005 revisions, Microsoft about its server-side script engine ASP, Chet Ramey about his experiences maintaining Bash, Bjarne Stroustrup of C++ fame, and Charles H. Moore about the design and development of Forth.
In this interview Falcon creator Giancarlo Niccolai, took some time to tell Computerworld about the development of Falcon, the power and influence of C++, and how the new multithreading design in Falcon version 0.9 will innovate the scripting language panorama.
If you wish to submit any suggestions for programming languages or language authors you would like to see covered, please email email@example.com
What prompted the creation of Falcon?
Part of my daily job was taking care of the status of servers streaming real time data through financial networks. A scripting facility in the control application would have been a godsend, as the alert conditions were too complex to be determined, constantly shifting and requiring constant supervision. I was not new to the topic, as I previously worked on the XHarbour project (a modern porting of the xbase languages), and I also did some research in the field.
The workload was heavy; even if the logic to be applied on each message was simple, data passing through was in the order of thousands of messages per second, each requiring prompt action, and each composed of about one to four kilobytes of raw data already de-serialised into complex C++ class hierarchies.
In terms of raw calculation power, the existing engines were adequate, but they were greedy. They considered their task as the most important thing to carry on the whole application, and so they didn't care very much about the time needed to setup a script, to launch a callback, to wrap external data or to provide them with data coming from the application at a very high rate.
It was also quite hard to use them in a multithread context. The only vm designed to work in multithreading (that is, to be used concurrently by different threads – we had many connections and data streams to take care of) was Python, but it worked with a very primitive concept of multithreading forcing global locks at every allocation and during various steps of each script. My test showed that this caused rapid slow down, even in parts of the application not directly related with the script (i.e., in the parts preparing the data for the scripts before launching Python vms).
Of all the possible scripting engines, LUA was the most adequate, but using it from concurrent threads posed some problems (at the time, the memory allocator wasn't threadsafe, and needed to be refitted with wide global locks). Also, having to deal with wide integer data (prices on financial markets are often distributed as int64 with decimal divisor) I was worried about the fact that LUA provided only one type of numbers – 58-bit precision floating point. This also caused severe rounding/precision problems in the financial area, and are thus generally avoided.
There was so much work to do on those engines to make them able to meet the requirements for task that the alternatives were either dropping the idea of scripting the control application, and then the servers themselves on a second stage, or writing something new.
I hate to give up, so I started to work at HASTE (Haste Advanced Simple Text Evaluator), a scripting engine meant to be just a scripting engine, and to drive massive throughput of data with the host application.
Was there a particular problem the language aimed to solve?
The main idea behind the early development HASTE was the “integratability” with existing complex multithreaded applications and the interaction with real-time, urgent and massive data flow.
When I had something working, I soon realised that the ability to deal with raw data and the way the vm cooperated with the host application was very precious in areas where other scripting languages didn't shine like binary file parsing, image manipulation, gaming (not game scripting), and wide/international string manipulation, etc.
At the same time, I found the constructs in other scripting languages limiting. I could live with them, as imperative and prototype-based programming are quite powerful, and the "total OOP" approach of Ruby is fascinating, but now that I had HASTE working and doing fine (the HASTE vm was simpler, and slightly faster, than LUA's) I started thinking beyond the pure needs of the engine.
As a professional, that exact task for which I built HASTE was just a small part of my daily activities. Similarly to the way Larry Wall built Perl out of his needs (to parse a massive amount of unstructured log dataset), I started to feel the need for higher logic to carry on my tasks – complex analysis on structured data, pattern finding and decision making.
I used to work with many languages including C, C++, Java, Assembly, Lisp, Prolog, Clipper/Xbase, Delphi, SQL, and of course Python, Lua, Perl and PHP, and I learned through time to employ the best instruments to solve the problem at hand. I felt the need for a tool flexible enough that it could cover my daily needs and drive new ideas.
Pure ideas are useful for the machine. A pure logic language, as Prolog, can explode the rules into raw machine code, being as fast as possible in finding solutions. Pure functional languages, as Erlang, can parallelise massive calculation automatically and compile time. Pure OOP languages, such as Ruby, can treat any entity just the same, reducing the complexity of the code needed to implement them.
But purity is never a good idea for the mind. The mind works towards unification and analogy, and solutions in the real world are usually more effective when a wide set of resolutive techniques can be employed. This is true even in mathematics, where you need to apply different resolutive techniques (and often also a good deal of fantasy and experience) to solve seemingly "mechanical" problems as the reduction of a differential equation. HASTE was terribly simple, a purely procedural language with arrays and dictionaries, but it had an interesting feature – functions were considered normal items themselves. This gave me the idea of working towards a general purpose language (beyond the scripting engine of HASTE) whose “programming paradigm” was “all and none”.
So Falcon was born with the idea of having pure OOP (so that raw, hard C structures could be mapped into it without the need for a dictionary-like structure to be filled), but not being OOP, with the idea of having pure procedural structure (driven by old, dear functions and call-return workflow) but not being procedural, and with the idea of having functional constructs, but without being functional.
It was also developed with the idea to add new ideas into it besides, and throughout, the existing ideas. A set of expanding concepts to solve problems with new conceptual tools, to reduce the strain needed by the professional developer to find the right way to match its idea with the problem and to create a living solution. Not needing anymore to learn how to think in a language to have it to work out the solution, but having a language moving towards the way the programmer's mind solves problems. I needed a tool through which I could shape easily and flexibly solutions to higher logic problems, in different and ever shifting domains (one day parse gigabytes of binary data in search for behaviour patterns, the other day organising classroom “turnations” for courses in my company) and to do that fast.
If there is one thing I’m proud of in Falcon it’s that it wasn't born for the most exotic reasons, but to address the problem of integration and empowerment of massive applications on one side and the necessity do solve complex logic and highly mutable problems on the other. Or in other words, it was born as a necessary tool.
Few languages were born to address real problems, like Perl, Clipper, possibly C++ and C which actually evolved from research/didactic university projects.
Why did you choose C++ to base Falcon on, rather than a lower-level language? What are the similarities between the two languages?
I like OOP and I like the power of C. When I decided to go C++ for Falcon, I was positive that I would have used C for the low level stuff and C++ classes to shape higher concepts. All the applications I had to script were C++, or could integrate with C++. Also, I was told by a friend of mine working in the gaming industry that Virtual Calls was actually more efficient than switches, and we have lot of them in a scripting language. I tested the thing out for myself, and it turned out that modern processors are performing really well in presence of Virtual Calls, so many of the common problems were usually resolved with complex ifs, and switches could be resolved with Virtual Calls instead.
At the beginning I used also STL, which is usually much more performing than any dynamic typing based library (STL maps are at least 10 per cent faster than Python string dictionaries), but that carried on a relevant problem of interoperability with other programs. Falcon was also meant to be a scripting engine, and applications often have different ideas on which version of the STL they would like to use. Moving STL across DLLs is quite hellish and it's a deathblow to the binary compatibility of C++ modules (already less stable than C module binary compatibility by nature). Also, STL caused the code to grow quite a lot, and a lot more than I wanted; so, I temporarily switched back to dynamic typed structures, which are slower, to be sure to clear the interface across modules from external dependencies.
Recently, having found that new compilers are extremely efficient on the fast path of exception raising (actually faster than a single IF on an error condition), I have introduced exceptions where I had cascades of controls for error being generated deep inside the vm.
In short, Falcon uses C++ where it can bring advantages in term of speed and code readability and maintainability, while still being C-oriented on several low-level aspects.
This may seem like reducing the interoperability with C applications; but this isn’t the case. One of our first works as an open source project was the preparation of the FXchat scripting plugin for the famous Xchat program; as many know the Xchat plugin API is pure (and raw) C. Yet, the interface blends gracefully in the framework without any interoperability problems, and even without any particular inefficiency, as the Falcon scripting engine is confined in its own loadable module, and the FXchat module acts as a bridge. The code is even simple and direct, and it is easy to compare it against other scripting language plugins written in C that soon get much more complex than ours.
The same can be said for modules binding external libraries. We bind gracefully with both the DCOP library (written in C++) and the SDL library set (written in C), with complete interoperability and no performance or compatibility problems at all.
How is Falcon currently being adopted by developers?
Falcon is still little known on the scene, and with monsters like Python and Perl around, being fed by big institutions like REBOL and Erlang, the diffidence towards new products is great. On the other hand, it must be said that many developers who have been exposed to Falcon have been impressed by it, so much so that they didn't want to be without it anymore! Sebastian Sauer of the Kross project worked hard to have Falcon in Kross and KDE; Dennis Clarke at BlastWave is redesigning the BlastWave open source package repository Web interface with Falcon and is helping in porting all the Falcon codebase to Sun platforms – AuroraUX SunOS distro has decided to adopt it as the official scripting language (along with ADA as the preferred heavyweight development language). We receive many “congrats” messages daily, but as we practically started yesterday (we went open source and begun getting distributed a few months ago), we have the feeling that there are many interested developers taking a peek, and staring from behind the window to see if the project gets consistent enough to ensure a stable platform for future development.
On this topic, we're starting to receive interesting proposals from some formal institutions. At the moment it's just a matter of interest and work exchange, but if things go on growing with the rhythm we've been observing recently, we'll soon need to fire up an economic entity to back the Falcon PL project.
What’s the Falcon ecosystem like?
In the beginning, and for a few years, it was just me. I say “just” in quotes because Falcon wasn't meant as a spare time project, but rather a professional project aiming to interact with my daily job on high-profile computing. The fact that I have been able to sell my skills and my consulting time, rather than my software, has allowed me to separate some internal projects that cannot be disclosed, from generic parts that I have shared via open source (there are also some older libraries of mine on SourceForge, which I employed on various projects). Since early 2007, some contributors have checked out the code and occasionally provided patches, but the first contributions other than mine to the repository are from 2008.
I have a community of about 10 to 12 developers, contributors and packagers actively working on the project, either externally or providing code in the core, or subsidiary modules, or on related projects. Their contributions are still few in number and weight, but entering in a project as wide and complex as Falcon requires time. We're also preparing a sort of “mini-SourceForge” to host Falcon-based and Falcon-related projects.
If developers want to know a bit about our project style, we are as open as an open source project can be. New ideas have been constantly integrated into our engine thanks to the help and suggestions of people either being stable in the project or just passing by and dropping a line. Although it has been impossible up to date, I am willing to pass down my knowledge to anyone willing to listen and lend a hand to the Falcon PL project. So, if developers are searching for a way to make a difference, stick with us and we'll make your vote to count!
Does the language have its own repository system?
No. It may seem strange being said by me, but I really don't like to reinvent the wheel. We're using SVN, but we may switch to GIT or something more Web oriented if the need arises. In this moment, I don't consider the commit history to be very relevant (with an exception for the 0.8 and 0.9 head branches), so switching to a new repository wouldn't pose any problem.
Falcon seems to have an emphasis on speed, is this important within programming languages?
Speed is not important within programming languages – it is important for some tasks that may be solved by some programming language. As I said, I wrote HASTE out of a need for speed that wasn't addressed by any other scripting language, but Falcon evolved from HASTE for other reasons. If speed was everything, scripting languages wouldn't exist. On basic operations, the best in our class can perform about 30 times slower than C doing the same things, and that's definitely slow. Versatility, adaptability, maintainability, adequacy, integratability, complexity and many other factors play a major role in deciding which language to adopt.
Speed is the most important factor in the sense that is the prerequisite of everything, but it's not language specific. Speed is determined by the complete “input – processing – output” line, and what a scripting language does into that line is usually a small part. If your IPO line doesn't meet the requirement, nothing else is relevant; in the case of early Falcon, no other scripting engine was able to let my applications to use them in an IPO line efficient enough to do the job on time. Once your whole system meets the IPO time requirements, speed ceases to be in the equation and everything else but speed becomes relevant. It's a binary choice: your whole IPO line is either fast enough or not.
When we say “fast”, we mean that we concentrated our development towards helping the whole system around Falcon to use it as fast as possible. Vm speed is also relevant, as there are some tasks in which you want to use heavily vm based calculations, but it plays a secondary role, in our view, with respect to the "service" offered to the surrounding world (applications, modules, threads) to let them run faster. This is why we have been able to live seven years without a single optimisation on the vm itself, and this is why we're starting to optimise it now, when we have completed our reflection model and serviced the surrounding world the best we can.
How do Falcon’s compile-time regular expression compilations compare with the library routines of other languages?
Actually, compile-time regular expression was scheduled to be in by now (April 2009), but we went a bit long on the 0.9 release and this moved compile-time Regex development a bit forward in time. However the topic is interesting, because it allows me to show three mechanisms at binding level that may be useful to the users of the scripting engine.
The plan is as follows: Falcon modular system provides to C++ a mechanism called “service”. A service is a virtual class publishing to C++ what the module would publish to the scripts loading it. Since 0.8.12, the Falcon compiler has had a meta-compiler that fires a complete virtual machine on request. Once we accept the idea of meta-compilation, the compiler may also use the environmental settings to load the Regex module and use its methods from the service interface; that's exactly like calling the C functions directly, with just a virtual call indirection layer (which is totally irrelevant in the context of compiling a regular expression).
Since 0.9, items themselves are in charge of resolving operators through a function vector called item_co (item common operations). We may either introduce a new item type for strings generated as compile time regular expressions, and provide them with a item_co table partially derived from the other string item type, or just create them a string with a special marker (we already have string subtypes) and act with branches on equality/relational operators. On modern systems, a branch may cost more than a simple call in terms of CPU/memory times, so I would probably go for adding an item type (that would be also useful at script level to detect those special strings and handle them differently).
The fact that we want to use the Regex module at compile time is another interesting point for embedders. If we included regular expressions in the main engine, we would grow it some more and we would prevent the embedders from the ability of disabling this feature.
One of the reasons I wanted Falcon was to allow foreign, less-trusted scripts to be compiled remotely and sent in pre-compiled format to a server for remote execution. The executing server may want to disable some features for security reasons (it may forbid to use file i/o), and that just on some unprivileged vm, while the administrative scripts run at full power. That was impossible to do with the other scripting engines unless there were deep rewrites. Falcon modular system allows the modules to be inspected and modified by the application prior to injection into the requesting vms. So, a server or application with differently privileged script areas can pre-load and re-configure the modules it wishes the script to be able to use, preventing the loading of other modules, while letting privileged scripts to run unhindered.
Regexes are heavy, and not all embedding applications may wish their scripts to use them. In example, a MMORPG application may decide that AI bots have no use for regular expressions, and avoid providing the Regex module. At this point, the compiler would simply raise an error if it finds a r"..." string in a source, and the vm would raise an error if it has to deal with a pre-compiled Regex in a module. At the same time, as the Regex module is mandatory on any complete command line Falcon installation, command line scripts can use Regexes at the sole extra cost of dynamic load of the Regex module, which is irrelevant on a complete Falcon application, and that would be cached on repeated usage patterns as with the Web server modules.
Do you plan to develop your own REGEX library to drive your regular expressions?
No we're happy with PCRE, which is the best library around in our opinion, and even if it's relatively huge, having it in a separate module loaded on need seems the way to go. We keep updated as possible with its development, providing native binding on some systems where PCRE is available (many Linux distributions) and shipping it directly in the module code where it is not available.
Is the embeddable aspect of Falcon versatile?
I talked diffusely about that in the Regex example above, but other than the reconfigurability and sharing of pre-loaded modules across application vm, we have more. The vm itself has many virtual methods that can be overloaded by the target application, and is light enough to allow a one-vm-per-script model. Heavy scripts can have their own vm in the target application, and can happily be run each in its own thread; yet vms can be recycled by de-linking just run scripts and linking new ones, keeping the existing modules so that they're already served to scripts needing them.
The vm itself can interact with the embedding application through periodic callbacks and sleep requests. For example, a flag can be set so that every sleep request in which the vm cannot swap in a coroutine ready to run is passed to the calling application, that can decide do use the idle time as it thinks best. For instance, this allows spectacular quasi-parallel effects in the FXChat binding, where the sleep() function allows Xchat to proceed. This may seem a secondary aspect, but other engines are actually very closed on this; once you start a script or issue a callback, all that the application can do is to hope that it ends soon. With Falcon you can interrupt the target vm with simple requests that will be honoured as soon as possible, and eventually resume it from the point it was suspended and inspected.
Since 0.9 we have introduced even a personalized object model. Falcon instances need not be full blown Falcon objects; the application may provide its own mapping from data to items travelling through the Falcon vm. Compare this with the need of creating a dictionary at each new instance, and having to map each property to a function retrieving data from the host program or from the binded library.
Other classes which you can override are the module loader, which may provide Falcon modules from other type of sources, or from internal storage in embedding applications, and since 0.9 the URI providers. Modules and embedding applications can register their own URI providers, so that opening a module in the app:// space would turn into a request to get a module from an internally provided resource, or opening a stream from a script from app:// would make possible to communicate binary data via streams to other parts of the application.
Frankly, we did our best to make our engine the most versatile around. They say LUA is very versatile, as you can reprogram it as you wish. But then, that is true for any open source project.
How will the new multithreading design in version 0.9 innovate the scripting language panorama?
There are two good reasons why multithreading in scripting languages are delicate matters (that many didn't even want to face). The first is that multithreading can break things. In “good multithreading” (multithreading which is allowed to actually exploit parallel computational power of modern architectures without excessive overhead), there is no way to recover from an error in a thread. A failing thread is a failing application, and that is a bit problematic to be framed in the controlled execution concept behind scripting language virtual machines.
The second reason is, as LUA developers point out, that a language where a = 0 is not deterministic cannot be proficiently used in multithreading. Some scripting language make a = 0 be deterministic and visible across threads by locking every assignment instruction, and that is a performance killer under many aspects. It doesn't only deplete performance on the script itself, but in case of concurrent programming in an application, it may severely deplete the host application performance by forcing it to unneeded context switches.
We opted for a pure agent based threading model. Each thread runs a separate virtual machine, and communication across threads can happen only through specialised data structures. In this way, each virtual machine can run totally unhindered by global synchronisation. It is possible to share raw memory areas via the MemBuf item type, or to send complete objects created upon separate elaboration via a interthread item queue.
The point is that, in our opinion, multithreading in scripting languages cannot be seen as multithreading in low level languages, where each operation can be mapped to activities in the underlying parallel CPUs. The idea of “mutex/event”-based parallel programming is to be rejected in super-high level languages as scripting languages, as there are too many basic operations involved in the simplest instruction. Since, in complex applications written even with low level languages, those primitives are used by low to create higher level communication mechanisms, our view is that multithreading in scripting languages should provide exactly those mechanisms, without trying to force the scripts to do what they cannot proficiently do, that is, low level synchronization primitives.
When I write a server, I find myself struggling to create complex synchronisation rules and structures through those primitives, avoiding to use them directly, and I don't see why we should bestow the same struggle on script users. The realm where primitive synchronisation is useful is not a realm where scripting languages should play a direct role – it's where you would want to write a C module to be used from the scripting language anyhow.
In 0.9 we have introduced an inter-thread garbage collector that accounts for objects present in more virtual machines. This is already exploited via the sharing of MemBuf instances, but we plan to extend this support to other kind of objects. For example, it is currently possible to send a copy of a local object to another thread via an item queue (the underlying data, possibly coming from a module or from an embedding application, can actually be shared; it's just the representation each vm has of the object that must be copied). This makes it a bit difficult to cooperate on creating complete objects across threads, and even if this works in term of agent-based threading, we're planning to use the new interthread GC system to be able to send deep items across threads. Since 0.9, it is already possible to create deep data externally (i.e. in the embedding application or in a module) and send it to a vm in a different thread.
The only problem left in doing it natively across two different vms is ensuring that the source vm won't be allowed to work on the object and on any of the data inside it while the target vm is working on it. Even if this may seem a limitation, it's exactly what the "object monitor" approach to multithreading dictates, and it is perfectly coherent with our view of higher level parallel abstraction. 0.9 version also introduces the mechanism of interthread broadcasts, with message oriented programming extended to interthread operations. We still have to work that out, completely, but that's the reason why we're numbering this release range “0.9”.
Finally, as the vm have native multithread constructs now, we may also drop the necessity to have different vms for different threads, as each thread may just operate on its own local context, while common operations on the vm (as loading new modules) can be easily protected. Still, we need to consider the possibility of multiple vms living in different threads, as this is a useful model for embedding applications.
How can a software developer get into Falcon development?
Easily. We can divide the support you may give to Falcon in mainly five areas. I rank them in order of weighted urgency/complexity ratio.
1. Modules. we need to extend the available features of the language, and modules are a good place from where to start, both because they are relatively simple to write and build and because they put the writer in contact with the vm and ITEM API quite directly. At the moment we don't have a comprehensive module writer's guide, but examples are numerous and well commented, and the API of both the vm and items are extensively documented. A skeleton module is available for download from our "extensions" area on the site, and provides an easy kick-off for new projects. Some of the most wanted modules and bindings are listed here.
2. Applications. We'd welcome some killer application as a comprehensive CMS written in Falcon, but even simpler applications are welcome.
3. Extensions and embeddings. As a scripting engine, we welcome people willing to drive their applications with Falcon. For example, the binding with Kross into KDE applications. We have a cute scripting engine binding for XChat, and we'd like to have for other scriptable applications (other IM systems, editors, music players etc). We need also to extend the existing HTTP server module binding engine and to apply it to more servers. At the moment we only support Apache.
4. Falcon core. Maintaining and extending the core system, the core module and the Feathers is still quite challenging: the 0.9 development branch has just started and we need to exploit the most advanced techniques in terms of memory management and compiler optimisations existing around, or finding new ones. We'll introduce at least two more paradigms in this round; logic programming and type contract programming, and there's plenty to work to do on tabular programming. The area is still open, so if you really want to get the hands dirty on the top-level technology in the field, this is the right place and the right time to give a try at that.
5. IDE. We need an IDE for development and debugging of Falcon applications. A terribly interesting tool would be an embeddable IDE that applications may fire up internally to manage their own scripts (consider game mod applications, but also specialised data-mining tools). Falcon has a quite open engine, and integrating it directly into the environment shall be easy. I put it for fifth as an IDE is useless if the language doesn't develop the other four points in the meanwhile, but having an IDE ready when the other four points will be satisfactorily advanced would be really a godsend.
Jumping in is easy – just get the code you want to work on from our SVN (or make a complete installation of Falcon + dev files and install the skeleton module if you want to write your own extension) and do something. Then give us a voice through our newsgroup, mail or IRC, and you're in. Developers may join as contributors and enter the Committee if their contribution is constant and useful.
Have you faced any hard decisions in maintaining the language?
Yes and no. Yes in the sense that there have been many no-way-back points, and so the decisions were hard at those spots where I had to chose to do one thing rather than another. For example, when I decided to drop the support for stateful function, a cute feature of the former Falcon language which was used to build stateful machines. Stateful machines were quite useful in many contexts, and having language constructs directly supporting them was interesting. But we observed that the cost of entering and exiting EVERY function was too high due to the need to check if it was a stateful function or not, and this lead to abandon those constructs. So, while this kind of decisions were hard in terms of “harness (metallurgy)”, none of the decisions I made were difficult to take.
Every decision was taken after deep technical cost-benefit analysis, the more the “hardness (metallurgy)”, the deeper the analysis. So, with a solid base on which to decide, and having... hard evidence and data on which to work on, every decision was actually easy, as it was the only viable one or the best under technical aspects.
Looking back, is there anything you would change in the language’s development?
I would have made more of an effort to go open source sooner. The market was already quite full by the time I started, so I was a bit shy in exposing the results of my research to the public until proving that my solution was technically better in their specific application field. But this slowed down the development of subsidiary areas, like the modules. Developers may have been attracted not just by a better approach to some problem, but just by the idea of doing something fun with a new tool. I underestimated this hedonistic aspect of open source, and now I am a bit short of breath having to take care of the inner stuff alone. This is why I am so eager to pass my knowledge around and help anyone willing to carry on the project.
Where do you envisage Falcon’s future lying?
In being a good scripting language. For how tautological it may seem, this is not really the case. Many other languages, even the most prominent ones, have overgrown their scope and now are trying to invade areas that were not exactly meant for untyped, ultra-high-level, logic-oriented scripting languages. If it's true that one must find new limits, and break them, it's also true that there's pre-determination in nature. From a peach seed you will grow a peach, and a planet can be many things, but never a star.
By overdoing their design, they're not evolving, they're just diluting their potential. Our aim is to provide an ever growing potential of high-level control logic and design abstraction, at disposal of both application in need of a flexible inner variable logic engine or directly at the command of the developers; this, at an affordable cost in terms of performance (not with respect to other scripting languages, but with respect of doing things the hard-coded way).