
An interpreter is a concise definition of the semantics of a programming language and is easily implemented. A compiler is more difficult to construct, but the code that it generates runs faster than interpreted code. This paper introduces rules to transform an interpreter into a compiler, and then provides a concrete demonstration of the rules in the form of a derivation of a Prolog compiler, much like Norvig's, implemented in Common Lisp. This example also suggests that the approach can be applied to a wide range of interpreter implementations and related algorithms.
This document explains the motivation and fundamental ideas behind the SchemeSpheres1 project. It outlines the conceptual approach taken by this framework, given a set of requirements that are considered essential. The different sides of the key aspects that SchemeSpheres tackles are summarized, focusing especially on the set of tools supporting multiplatform/mobile app development that it provides. Current implementation supports most of the required functionality, which will be explored along with the process of building an example app. Limitations of the framework will be discussed during the tutorial, exploring possible future solutions as well current workarounds.
In this two-hour tutorial we will introduce the Gendl® project (source available at http://github.com/genworks/gendl), and we will cover the following topics: 1. Installation either through Quicklisp or though a pre-built install package 2. Basic Gendl® declarative authoring syntax 3. Example Non-geometric application 4. Example geometric application (twisty tower) 5. Example geometric application with a mechanism (4-bar link) 6. Adding a web user interface 7. Building a runtime application, including integrated web server, using ASDF3's new application delivery capabilities 8. Uploading and deploying the runtime application on a server
Common Lisp is a towering language that supports a plethora of functionality useful for both scientific and mathematical programming. However---except for a few notable systems such as Axiom, Macsyma/Maxima, and ACL2---Lisp has not taken center stage for such kinds of programming tasks. We will analyze exiting systems, including computer algebra systems, technical computing systems, and other programming languages, and their utility in scientific and mathematical programming. Such a discussion will form a foundation for comparative study. Following that, we will expound on some features of Lisp that augment the expressiveness, simplicity, and utility of programs written in the language. In particular, we do so by way of three carefully selected pragmatic examples arising in fields ranging from the theory of special functions to numerical simulation.
The study of permutations is of central importance to mathematics. Computation with permutation groups has typically been limited to systems such as GAP and Magma. In this paper we describe cl-permutation, a system for doing computations with permutation groups in ANSI Common Lisp. Homomesies, a recent concept introduced by Propp and Roby, are elaborated upon from a group-theoretic and linear-algebraic perspective. As a result, algorithms for manipulating them and better understanding their structure are presented. Finally, these algorithms are realized using cl-permutation.
The fact that CLOS is defined as a CLOS program introduces two categories of issues that must be addressed, namely bootstrapping issues and metastability issues [2]. Of the two, the latter is the more difficult one, and also the one that has the most negative impact on the elegance of the code in that it requires base cases to be handled specially. We describe satiation, a technique by which metastability issues can be turned into bootstrapping issues, thereby simplifying them and keeping the code elegant. Satiation consists of pre-loading the call history of a generic function with respect to a set of argument classes so that the base cases are handled without invoking the full protocol for computing the effective methods at runtime.
PaGe is a portable, compact and reliable LALR(1) parser generator with more general disambiguation method compared to that of traditional parser generator such as Bison. From the past to the present, very many parser generators are implemented in various programming languages. In particular, Bison in C language is a notable one due to its high efficiency and reliability. It is surely the de fact standard parser generator in C. We have recently faced with a requirement of making some parsers for relatively large languages in Common Lisp. We prefer commercial products due to its reliability and user supports. Especially, problems with such complex tool should only be solved by someone who has deep knowledge about the tool. Thus, we chose ACL (Allegro Common Lisp) which is one of the most widely used Lisp programming environment. Unfortunately, ACL does not provide official parser generator. As for free software, as far as we know, there is no such tool comparable to Bison in the above sense. Since Lisp has powerful and universal syntactic expression, namely S-expression, it is sufficient for Lispers to express and handle any syntactic objects. We suspect that that is why parser generators are not so important to Lispers. Nevertheless reliable parser generator in Lisp is needed when we develop tools dealing with anther languages, such as compilers and program analizers. This is the motivation for developing original parser generator in Lisp. One of PaGe's concept is to give a legible implementation of DeRemer's method for Look-Ahead Set. This method makes us enable to generate LALR(1)-parsing-table dircetly from LR(0)-parsing-table by computing Look-Ahead Set based on formal definitions of them. For example, DeRemer's method has used in Bison, but there is few other implementation, particularly on Lisp. Therefore we decided to give a legible implementation for who would like to understand it. Other concept is to simplify PaGe's core program for efficiency and readability as possible. As a result, PaGe is composed of parser generator engine PaGEn and its wrapper. PaGEn is a pared parser-generator engine. PaGEn's input is a grammar whose "symbols" are restricted to non-negative integer. By this restriction, we were able to establish both program efficiency and algorithm readablity, for instance we can naturally use array as function. Consequently, the role of wrapper are mainly two of translation and interpreting. A wrapper translates symbolic input such as grammar or sequence of token into numeric input for PaGEn. PaGEn get this as input and return parsing-table or result of parse, for instance. Then the wrapper interprets this result for an user or other system. Now, we have defined only the wrapper for using PaGEn in the same way for traditional parser generator. If you wish to use PaGEn for other purpose, you need only to define the wrapper. Furthermore, PaGEn can deal with ambiguous grammar i.e. it supports disambiguation. PaGEn's disambiguation method is so simple. First we give two priority to each rule for reduce-time and shift-time. If some conflict has occurred, then, we try to solve each conflicts by comparing priorities. For Reduce/Reduce-conflicts, we solve it by Reduce using the rule which has the greatest reduce-time-priority in conflicted rules. For Shift/Reduce-conflicts, 2 pattern exists. If the propagation-priority, computed from several shift-time-priorities, is greater than the reduce-time-priority of the rule, we solve by shift. If the reduce-time-priority is greater than the propagation-priority we solve by reduce. This method is more general than the method which specifies the associativity of an operator directly, in translatability sense. And, dangling-else probrem can be solved uniformly in this method.
Many aspects of modern medicine, including the administration of anesthetic agents during general surgery, remain unautomated and reliant on the vigilance of the attending clinicians. In other fields where failures can have catastrophic consequences, such as the aviation and nuclear power industry, automated control regimens have been adopted to reduce the risks and improve performance. In this paper we discuss many aspects of the implementation of a complete automated system for intravenous anesthetic drug infusion based on feedback from electroencephalography (EEG) readings. The system software in its entirety consists of approximately 22K lines of Scheme code and features a client-server implementation interfacing medical devices with a portable graphical user interface. The user interface runs on both mobile devices and dedicated medical flat panel displays. The strengths of the Scheme functional language have been leveraged to build a robust maintainable modular system with extensive testing facilities to mitigate the inherent safety hazards associated with the application.
Garbage collection algorithms are divided into three main categories, namely mark-and-sweep, mark-and-compact, and copying collectors. The collectors in the mark-and-compact category are frequently overlooked, perhaps because they have traditionally been associated with greater cost than collectors in the other categories. Among the compacting collectors, the sliding collector has some advantages in that it preserves the relative age of objects. The main problem with the traditional sliding collector by Haddon and Waite [4] is that building address-forwarding tables is costly. We suggest an improvement to the existing algorithm that reverses the order between building the forwarding table and moving the objects. Our method improves performance of building the table, making the sliding collector a better contestant for young generations of objects (nurseries).
In spite of its soundness, ease of use, and descriptive power, few hygienic macro systems have been incorporated to non-LISP programming languages. The difficulty lies in the self-describing nature of the macro system. Proposed is the design and a systematic implementation framework of hygienic macro systems for general programming languages. In addition to the standard syntax-rules macro features, our macro system incorporates handling of punctuations and keywords, introduces invisible blocks of code called phantom groups, and proposes the notion of suffix pattern to address problems due to recursive macro definitions. These features have been introduced to deal with richer syntax of general programming languages. The proposed implementation framework incorporates staged parser architecture, a parser generation technique using parsing expression grammars, and mutual conversion technique between the macro-enabled host language and Scheme that allows our macro system to delegate actual macro expansion task to a Scheme interpreter, instead of building hygienic macro expander from scratch. ExJS, our prototype implementation of a hygienic macro system for JavaScript, is implemented in less than 2,000 lines of JavaScript and Scheme, and exhibits its flexible syntactic extensibility.
Racket is a descendant of Scheme, a language that has been widely used to teach computer science. Recently, the Python language has taken over this role, mainly due to its huge standard library and the great number of third-party libraries available. Given that the development of equivalent libraries for Racket is an enormous task that cannot be currently done in an acceptable time frame, the next best option is to allow the Racket platform to use Python programs and libraries. We have been developing an implementation of Python for the Racket platform based on a source-to-source compiler. In order to provide good performance and good interoperability with the Racket platform, the runtime libraries are being implemented over Racket data-types. This, however, entails implementing all of Python's standard library on Racket and it does not provide access to popular Python libraries implemented using C module extensions (such as Numpy and SciPy). This paper presents an alternative approach that allows libraries from Python's reference implementation to be imported and used in our Racket implementation of Python, immediately providing access to all of Python's standard library and every third-party library, including NumPy and SciPy. The proposed solution involves importing Python module objects directly from Python's virtual machine, by calling the Python/C API through Racket's Foreign Function Interface, and converting them to objects usable by our Racket runtime libraries, making them compatible with the Racket platform. This compatibility layer therefore relies on relatively expensive foreign function calls to Python's libraries, but our performance tests show that the overhead introduced by them is quite low and, for most cases, it can be minimized in order to attain the same performance as Python's reference implementation.
We describe a technique for generic dispatch that is adapted to modern computers where accessing memory is potentially quite expensive. Instead of the traditional hashing scheme used by PCL [6], we assign a unique number to each class, and the dispatch consists of comparisons of the number assigned to an instance with a certain number of (usually small) constant integers. While our implementation (SICL) is not yet in a state where we are able to get exact performance figures, a conservative simulation suggests that our technique is significantly faster than the one used in SBCL, which uses PCL, and indeed faster than the technique used by most high-performance Common Lisp implementations. Furthermore, existing work [7] using a similar technique in the context of static languages suggests that perfomance can improve significantly compared to table-based techniques.
Kilns is a programming language based on the kell calculus. The kell calculus can roughly be seen as an extension of the πCalculus that adds a notion of "locality" (the kell), which provides semi-permeable boundaries that make it possible to restrict the type of communication between components (E.G., machine-local, rather than network). This kell construct also allows for very direct encodings of things like data encapsulation and security capabilities. Kilns has several unique features. While lambdas have been implemented as a library, they are not part of the core language. It also has modified versions of other features that are often considered fundamental to being a lisp. Some examples: Macros are "lazy" -- calls to macros can exist before the macro is visible in the relevant scope, and macros are only expanded when the calls exist in certain syntactic contexts (this allows embedding macro calls in mobile processes that will be expanded in some other environment). The fundamental data (and code) structure is not a list, but a multimap. These distinctions have largely come about while finding natural ways to embed the original lispisms in the kell calculus. In trying to minimize the size of the core language while making performance acceptable, I have offloaded even basic numeric representations to libraries, but provide an injection feature that is similar to Philip Wadler's "Views" -- defining a translation from a kell calculus definition (say, Peano arithmetic) to a more efficient representation. The compiler provides a set of these from standard library structures to native structures, and then programmers can define injections from their own data structures and operations to standard library structures, because transitivity. There is a lot of ongoing work on Kilns -- from developing a type system, to implementing a data-parallel version of the core match operation in OpenCL, to simply learning the right way to use it. Or even moving away from the kell calculus entirely, which is already at least the third process calculus that this language (or at least its siblings) has been built upon.
Profiler Plus is a general-purpose "natural language" analysis application implemented in Common Lisp. We discuss its capabilities in the context of two points of view which are brought together here for the first time: that of Social Science Automation which commissioned the product and programmed the rules which drive it; and that of Ravenbrook which, without ever wholly understanding what it did, successfully implemented it.
An interpreter is a concise definition of the semantics of a programming language and is easily implemented. A compiler is more difficult to construct, but the code that it generates runs faster than interpreted code. This paper introduces rules for staging an interpreter so that it generates a compiler. An extended example suggests the utility of the technique. The rules are described formally and correctness is discussed. Finally, this technique is compared to staging and partial evaluation.
We present ALPS, a personal interactive computational environment that combines the primitives and arrays of APL\360 with the syntax and semantics of early LISP. Selected features from APL\2, Scheme, Common Lisp and other extensions were incorporated over time. Both LISP and APL are among the oldest surviving programming languages. Although they were devised for different purposes they have a number of features in common. We show how using their common features as design principles, the mathematical power of APL and the flexibility of LISP are combined into a simple yet effective tool for diverse system engineering tasks. In this paper the creation, design and evolution of the system are described, illustrating some features with code samples. Following a brief discussion on some implementation details we provide performance data of a couple of sample applications on a variety of hardware.
We present a method to estimate the amount of the heap required to execute application programs on runtime systems with our replication-based incremental compacting garbage collector. Our method provides a strategy for adjusting the timing to trigger garbage collection and choosing a heap region to be evacuated during partial compaction, which moves all objects in one part of the heap to the rest of the heap. The method is also used to determing the minimum heap size that guarantees free memory never exhausts during incremental garbage collection. Furthermore, we ensure that allocation never fails due to fragmentation with the strategy. The strategy is to reserve a contiguous free area and to prohibit the allocator from allocating in that area until garbage collection is triggered. When it becomes necessary to use the reserved free area to satisfy an allocation request, we trigger garbage collection. We show that, with this strategy, an application never fails to allocate objects with a larger heap than R + 2 √(2Ra) + 3a plus space overhead caused by the heap layout, where R is the maximum amount of live objects and a is the upper bound of the possible amount of allocation during a single collection cycle.
Writing a program and writing its documentation are often considered two separate tasks, leading to several problems: the documentation may never be written; when it is, it may be an afterthought; and when the program is modified, the needed changes to the documentation may be overlooked. Literate programming (LP), introduced by Donald Knuth, views a program and its documentation as an integrated whole: they are written together to inform both the computer and human readers. LP tools then extract the code for the computer and the documentation for further document processing. Unfortunately, existing LP tools are much more suited for compiled languages, where there is already a step between coding and executing and debugging the code. Lisp programming typically involved incremental development and testing, often highly interleaving coding with running portions of the code. Thus LP tools inject an artificial impediment into this process. LP/Lisp is a new LP tool designed specifically for Lisp and the usual style of programming using Lisp. The literate programming file is the Lisp file; LP markup and text resides in Lisp comments, where it does not interfere with running the code. LP/Lisp provided the usual literate programming services, such as code typesetting, syntactic sugaring, and the ability to split the code for expository purposes (a "chunk" mechanism). LP/Lisp, itself written in Lisp, is run on the code to produce the documentation.
Whereas dynamic typing enables rapid prototyping and easy experimentation, static typing provides early error detection and better compile time optimization. Gradual typing [26] provides the best of both worlds. This paper shows how to define and implement gradual typing in Dylan, traditionally a dynamically typed language. Dylan poses several special challenges for gradual typing, such as multiple return values, variable-arity methods and generic functions (multiple dispatch). In this paper Dylan is extended with function types and parametric polymorphism. We implemented the type system and aunification-based type inference algorithm in the mainstream Dylan compiler. As case study we use the Dylan standard library (roughly 32000 lines of code), which witnesses that the implementation generates faster code with fewer errors. Some previously undiscovered errors in the Dylan library were revealed.
We introduce NST, an expressive and extensible unit testing framework for Common Lisp. Distinct features of Lisp's object system CLOS allow an elegant implementation for NST, and we describe this class model and implementation. There are over a dozen test frameworks for Lisp which are currently available, almost half of which are under active maintenance, and we compare these packages features. Development of NST is ongoing, and we conclude with a discussion of future directions for the system.