Ploy compiler in Swift.



writeup v0
© 2015 George King.
Permission to use this file is granted in ploy/license.txt.

# Ploy

Ploy is an experimental, general purpose programming language. It is a statically typed language, and aspires to be a pragmatic choice for both small and large-scale projects. The language design is inspired by aspects of Lisp and Scheme, as well as a variety of statically typed languages. Ploy is in an early stage of development, and is not yet practically useful.

## License

Ploy is licensed under the ISC License, a permissive open source license similar to 2-clause BSD.

## Examples

| # TODO.

# Approach

I am currently writing a bootstrap compiler in Swift, which outputs JavaScript for Node. I chose Swift because its type system has some similarities to what I imagine for Ploy, because of the convenient debugging UI built into Xcode, and because I am familiar with Apple's toolchain and platform. I chose JavaScript as the first target language because it let me defer memory management questions that I would have to address immediately with C or LLVM, and because JavaScript appeals to such a large audience.

The main limitation of this approach is that without an interpreter or just-in-time compiler, lisp-like macros are not possible. JIT capabilities could be added by linking in Node (or just V8 and adding the necessary host functions); however there would also be a lot of work involved in creating the type definitions of syntax objects that would be evaluated and then spliced back into the compiler's syntax tree.

The long term goal is to write a self-hosting Ploy compiler in Ploy, and to find an implementation strategy for macros and metaprogramming that is reasonably straightforward.

# Goals

See docs/goals.

# Progress

## Grammar and parser

The grammar has not been formally defined, but has been designed to require no backtracking in the recursive-decent parser. This greatly simplifies the implementation of the parser by hand, and I believe it also makes reasoning about the syntactic structure of code and parse errors much simpler. The language uses a small set of binary infix operators, grouped into just a few levels of precedence, and with precedence groups all operators are right-associative. These constraints on the grammar make the language simple to explain and the parser easier to implement. The parser uses an "operator precedence" style algorithm to handle infix operators.

## Type System

The type system is currently quite rudimentary. It has support for primitive and compound types (more conventionally known as "tuple" types). Compound types use conventional structural typing, meaning that two compound types are equal if they have the same shape. Struct and Enum (tagged union types) do not yet compile; these will most likely be nominitively typed, meaning that any named struct is equivalent only to itself. I am putting off issues related to subtyping for now, but eventually I would like to explore dynamic type and subtyping (and the associated questions of covariance and contravariance), notinos like set-theoretic type unions and intersections, type classes, etc.

Functional types, including higher order function types, appear to work but have been only minimally tested.

Function signatures in Ploy are defined by a single input type, and a single return type. Multiple parameters, parameter names, parameter defaults, and variadic parameters are all provided through the semantics of compound literals. This is similar to ML and Haskell, in which all functions take a single argument, but somewhat different in spirit, since those languages make heavy use of currying to pass multiple arguments, while in Ploy the convention is to pass multiple arguments as elements of a compound literal.

## Namespaces

Namespaces work, but need more testing like everything else. See docs/goals.

## Generic Functions

Generic functions are a current priority. See docs/goals.

The first step is to implement static function overloading. Dynamic, multiple dispatch (similar to Julia) would be an interesting future addition, but requires a lot of thought regarding runtime type information.

## Type Inference

There is a very limited inference system, which is necessary for the compilation of compound values, but also alleviate the need for annotating local bindings.

## Tests

The project has a custom python test script that executes `.test` files. These files are essentially python dictionary literals, which I prefer over JSON because triple-quote string literals can be used to specify multi-line expectations. More documentation around the test system is in order, but for now look at the existing tests to start, and read tools/ if issues come up.

# Requirements

Ploy is developed with the following tools:
- OS X 10.10
- Swift 2 and Xcode 7 (latest beta)
- gnu bash 3.2.57
- python 3.4.3

# Usage

  $ sh/ my-program.ploy arg1 …
  # compile to _build/my-program and run with arg1 ….

  $ sh/
  # run the tests.