LanguageKit is a core part of Étoilé. It is a framework for implementing dynamic language compilers and interpreters. LanguageKit uses the Objective-C runtime to implement the underlying object model, providing transparent, toll-free, bridging.
LanguageKit allows you to mix Objective-C and higher-level languages in the same class. Objective-C is a pure superset of C and allows very low-level functionality, including inline assembly. LanguageKit allows you to combine this with higher-level languages.
The first language implemented with LanguageKit was a dialect of Smalltalk. Objective-C was designed as a hybrid language combining C and Smalltalk. Pragmatic Smalltalk removes some of the constraints of having to integrate with C.
Unlike Objective-C, Pragmatic Smalltalk is a pure object-oriented language. Primitive C types are transparently boxed by the compiler. Integers are mapped to either a
BigInt instance. The former fits inside a pointer and can be manipulated almost as quickly as a primitive integer. The latter is a boxed object using the GNU multi-precision library. Any integer arithmetic expressions that overflow are automatically turned into
BigInt objects, just as in other dialects of Smalltalk. Other primitive types are boxed using OpenStep's
EScript is an experimental front end for LanguageKit. It implements a dialect of ECMAScript for Étoilé. Unlike Pragmatic Smalltalk, Escript uses a prototype-based object model. This is implemented using the prototype support in the EtoileFoundation framework.
Because all Étoilé languages use the same object model, it's possible to write classes in Objective-C, subclass them in Smalltalk, and then use them as prototypes in EScript.
The LanguageKit framework provides a set of abstract syntax tree (AST) classes for implementing dynamic languages. These have a simple visitor mechanism that can be used to implement high-level optimisations. One example of this is the mapping of
-ifTrue: messages with a block as an argument to inline conditionals, eliminating the extra message send and overhead.
The AST codes can then be directly interpreted or compiled, either statically or with the just-in-time (JIT) compiler. LanguageKit uses LLVM to implement code generation. This allows all of the optimisations that are part of LLVM, and some custom ones written specifically for LanguageKit, to be used.
LanguageKit includes a small framework, LanguageKitRuntime, which contains all of the extra features that are required for LanguageKit, on top of the Objective-C runtime. This includes, for example, a personality function that allows the unwinding library used for zero-cost exceptions to be used for non-local returns in Smalltalk. It also includes support classes like
BigInt and the small integer implementations.
Message sends to small integers are mapped to calls to C functions in the compiler. The LLVM inlining pass then optimises these calls away so operations on small integers are very cheap. A benchmark implementing a recursive Fibonacci number generator took approximately 50% longer to complete than the equivalent Objective-C implementation. In future, with static type inference, we can probably improve on that.
The support library exists as a separate entity so code that is statically compiled with LanguageKit does not have to link against LanguageKit.
Just Too Late Compiler
When you load a LanguageKit bundle, the framework forks off a background process that statically compiles it. The next time you load the bundle, the cached version will be loaded instead, which eliminates the need to compile. This is particularly important on low-memory platforms, such as handheld systems. The LanguageKit compiler back end is loaded on demand and, because it links against LLVM, is around 20MB when compiled in release mode. On systems without much RAM, it is much better to be able to avoid this overhead. It is also convenient to eliminate the start-up time delays caused by JIT compiling everything when the program launches.
In future versions of LanguageKit, we plan on integrating profiling support into the JIT and interpreter so that code can initially be run in a profiling mode and the statically-compiled output from the JTL compiler will make use of this information.
LanguageKit is used by the EtoileBehavior bundle. Every Étoilé program that uses AppKit will have this loaded automatically. This looks in the user's home directory for bundles for each application and loads them.
Because LanguageKit uses the same object model as Objective-C, this means that you can write categories on Smalltalk and use them to replace methods in Objective-C classes in existing applications. This means that it is possible to extend applications without requiring access to the source code. The Free Software Foundation defines Free Software as software that comes with four rights. Two of them, they claim, depend on the availability of source code:
- The freedom to study how the program works, and change it to make it do what you wish (freedom 1). Access to the source code is a precondition for this.
- The freedom to improve the program, and release your improvements (and modified versions in general) to the public, so that the whole community benefits (freedom 3). Access to the source code is a precondition for this.
With Étoilé, this is not the case. You can access both of these freedoms even if you do not have the source code. The introspection in Objective-C means that you can use Code Monkey to inspect existing classes and see the method names (although not their implementations) and replace them without being able to see the code. Of course, access to the source code is still useful.
LanguageKit and the Étoilé Philosophy
LanguageKit is part of the core Étoilé philosophy, that there should be no artificial divide between the priesthood of programmers and the congregation of users. The concept of LanguageKit is inspired by the writings of Christopher Alexander, who argued that people building communities should work with the people who lived in them to construct something habitable.
Any user can modify or extend Étoilé and it is an important goal of the project to make this possible for everyone. Alan Kay demonstrated that it's possible to teach Smalltalk to small children and so supporting a high-level English-like language for development is very important. LanguageKit is not just for scripting, it can be (and has been) used for application development. There is no divide between things 'scripters' and things 'developers' do other than imagination.