Quark Framework - CAL On Java

CAL On Java

The CAL compiler takes CAL source, as text or as a source model (Java object model). This is processed by the early compiler stages to desugar and analyse the source. The intermediate form, plus metadata from analysis, is processed by a number of optimisers, optionally including a full rewrite optimiser capable of function fusion, deforestation and other major optimisations that preserve semantics but improve a program operationally.

The compiler supports plugable back-ends. First amongst these is LECC (Lazily Evaluating CAL Compiler). This back-end generates Java classes and byte codes directly, emitting methods according to compiler schemes that take account of context metadata derived in the compiler, such as strictness of function arguments. LECC can package generated code in a number of ways, including as a CAL Archive (CAR), or a Java JAR. At runtime, a class loader can load an entire corpus of functions, or the Quark Framework loader can load closely connected functions according to prior dependency analysis. This latter feature is important to minimise start up times, whereby only the functions actually required by an application incur loading overhead.

The LECC back-end can also generate Java source code, which is then compiled by the regular JDK Java compiler to produce class files. Amongst other things, this is very useful when validating compiler schemes during compiler development, and provides a way to reason about the operational behaviour of CAL on the Java platform.

As well as LECC, Open Quark includes a G-machine interpreter and a compiler back-end that generates G-machine code. While considerably slower than LECC, this option is useful for experiments and may be a better fit for some deployments.

While many deployments of CAL may use the language standalone, the Quark Framework is fundamentally designed to be used within regular Java applications to provide a hybrid/multi-paradigm system. The intent is to allow transformational logic, which benefits from more algebraic representation, to be embeddable within Java OO logic handling regular (stateful) aspects of the application. To this end, CAL supports a very powerful and easy to use interface to Java, and the Quark Framework SDK allows Java code considerable control over how functions are evaluated and results produced. Java code can issue new functions to the Quark Framework for compilation, which can be immediately available for evaluation. Thus, Java can use the Quark Framework as a functional meta-programming environment. This has been a common use case for the framework, and is supported efficiently (low latency, with concurrent compilation and evaluation). On the consumption side, results can be presented to Java as lazy suspensions, so that minimal functional evaluation is performed and only when Java logic requests the 'next' output value. This feature allows data-flow logic to be constructed on-the-fly within a Java application, used on-demand and then disposed of if necessary. Both the LECC and G-machine runtimes are able to load and unload functions from memory to support a fully dynamic environment.

The 'foreign' interface between CAL and Java is able to import any Java entity into CAL and make calls on Java methods. Values are passed efficiently between the two environments, without unnecessary boxing/unboxing operations. A powerful feature called "I/O policies" allows values to be lazily marshalled between structures if required (for instance, if you have a particular Java class or data structure that you wish to produce to represent a CAL value). These policies are declared completely on the CAL side, leaving the Java side 'natural'. The default policies are usually quite sufficient to share values, so usually nothing special must be done to exchange values.

Here are some examples of CAL code that declares interfaces to Java entities:

Read more about this topic:  Quark Framework