Welcome to: Continuations and Such

This is a page describing a project...

in: Programming Language Theory
on: (un)delimited continuations
by: Abraham "Avi" Rashin
with: Chung-Chieh "Ken" Shan
at: Rutgers University / DIMACS
sponsored by: REU
beginning in: the summer of 2007
and more particularly: See below!

Links

What is this field about?


I work on programming language theory, In other words, I study the structures of *simple* programming languages to figure out how to make things better. The changes people in this field make are:
 
1, mathematically elegant, and therefore
a. beautiful, if you appreciate that sort of thing
b. useful for understanding
i. programming
(1.) For example, how do you write big powerful programs without getting confused, and without too much redundancy? (You could do this, say, by abstracting out common structures, like "objects" in Java or "monads" in Haskell, but other notions have yet to be formalized!) What are some of these common structures that appear in programs? See a wonderful paper about "Bananas" (sort of) for some examples of recently discovered such structures.
(2.) How do you make a system in which the power of programs is still great, but in which it is possible to check, automatically (to some extent), whether programs actually do what you want them to do ("program verification" or "proof checking" -- e.g. see Coq or HOL Light)?
ii. logic
(1.) some things about the nature of human mathematical reasoning (I do not argue that this is universal -- but some of the insights apply to the way that I think about mathematics)
(2.) formal systems of deduction

2. potentially useful as additions to more complicated programming languages, to make programs easier to write and understand.
 
So, why am I doing this?
It connects simultaneously with my interests in Abstract Algebra, Category Theory (math), Logic (math and philosophy), languages and syntax (linguistics), and computer science.
 
 

What am I doing?

Project statement:

I am trying to make a dependent type system for a lambda calculus including abortive continuations (see glossary below).
 

An explanation by analogy to mathematical logic:

In the meantime, for the logicians among you, or, rather, the logician inside you:
(a.) The simply typed lambda calculus (STLC) corresponds via the celebrated Curry-Howard isomorphism (see Wikipedia) to intuitionistic propositional logic (again, for now, see Wikipedia).
(b.) Adding dependent types to the STLC corresponds to adding predicates to the language, i.e. to intuitionistic predicate logic.
(c.) Adding abortive continuations (call/cc) to the STLC corresponds to classical propositional logic.
(d.) (b) and (c) above have never been included in a single type system. Wouldn't it be great to have a nice type system for a lambda calculus that corresponds to CLASSICAL PREDICATE logic? It is also very nice for programming. That is the meaning of this project. More info will be up later.

Glossary:

(Beware, this all takes a while to explain; I hope to ultimately understand these things well enough to be able to explain them succinctly, but for now I will do my best to make really short definitions and explanations that give some inkling of what things are about. Generally, I recommend Wikipedia for this sort of thing.)
 
 
imperative programming --
Being your computer's slave master and telling it what to do, step after step.
problems:
The computer hasn't a clue what it's being asked to do, so:
1. the programmer must write lots of things explicitly.
2. it can't check that the programmer is actually doing what he wanted to do.

benefits:
1. Readability: Commands are executed roughly in the order that they were given, unless the computer is told to do otherwise.
2. Current imperative programming languages are the only ones that are suitable for serious large-scale development.

languages:

Machine language, Assembly language, BASIC, Pascal, Cobol, Fortran, ...

 
functional programming --
Making the computer do things by defining functions, applying functions, and making inquiries about expressions made of functions.
Note:
Functions here actually refer to things that take arguments and give results based only upon these arguments, and not anything else, like what the user types on the keyboard, the time of day, the contents of a file on the hard drive, or global variables containing information about the programmer's friends' phone numbers. (In fact, global variables do not exist in stripped-down functional programming languages, though they can be added in more complicated versions. There are tricks (see "monads" in Haskell) for making these functions blend in well with the basic functional paradigm.)

problems:
1. Not yet feasible for huge projects -- I suspect more things will have to be abstracted out before functional programming becomes feasible for large collaborative projects. 2. As far as I know: Very little good literature exists that teaches this style of programming. Also, very few programmers today know functional programming!

benefits:
1. Expressions, evaluation, and type systems are mathematically easy to define.
2. Mathematically beautiful.
3. Programs to concepts in mathematical logic (Curry-Howard isomorphism -- types are propositions and expressions are proofs).
4. Supports Program verification -- It is possible to prove, with certainty, that a program does what it is supposed to do, and that it always will (assuming no hardware or operating system or compiler issues)! This is the ultimate way to test a program!

languages:
Scheme, Haskell, Ocaml, lambda calculus, ...

 
logical programming --
Telling the computer what you want and helping it out by giving hints when it gets stuck or feel like it's taking too long.
problems:
The computer gets stuck or takes too long in lots of cases.

benefits:
1. You can take rests and rely on the computer to write some hard pieces of code for you (even ones that you have no idea how to).
2. Useful for assistance in proving mathematical theorems.

languages:
Prolog, Coq, HOL Light, ...

 
Lambda calculus --
One of the simplest functional programming languages ever.
Basically, all you can do are make functions (called "abstracting") and apply functions.
Expressions consist of variables, abstractions and applications.
For example:
1.     "(replace x in z) y", conventionally written "(lambda x . z) y", evaluates to z, because when you replace x by y in the expression z, you get, well, z.
2.     "(replace x in x) y", conventionally written "(lambda x . x) y", evaluates to y, because when you replace x by y in the expression x, it turns into y.
3.     If we allow numbers and arithmetic, then "(replace x in x+3) 5", conventionally written "(lambda x . x+3) 5", evaluates to 8, because when you replace x by 5 in the expression x+3, we get 5+3, which is 8.
4.     Again, if we allow numbers and arithmetic, then "(replace x in x+3) ((replace y in y*7) 2)" evaluates to

type system --
An assignment of "[data]types" to expressions. The type of an expression should always be possible to determine in finite time (i.e. without running on forever), and it is useful to have the type of an expression tell you how that expression can be used: For example, "lambda x . x+3" is a function that takes numbers and gives you numbers, so its type is "numbers to numbers". If you try to feed it strings, it will vomit, i.e. say something like "This does not make any sense; I will now fail." Wouldn't it be nice to avoid that? Just check the type! If the first part of the type of a function says that it takes numbers, then you should only feed it things that have the type "number" (like, say, "3" or "5+7*91"). Wouldn't it be nice if pets were labeled like that?

dependent type system --
A type system in which functions are permitted to take expressions as arguments and produce types as results! For example, "if you give me 1, then I will give you the type 'number', but if you give me any other number, then I will give you the type 'string'" is an expression with type "number -> TYPE". But we can get more complicated, because we can make other functions, whose output types depend on what you feed the first one. This is an explicit way to treat "polymorphism," which is handled more implicitly and less controllably in languages like Java or C++.

abortive continuations --
A way of asking about your fate, and then taking it into your hands. (A more complete explanation is forthcoming.)

 
 

 
... More will be up later.
 
For contact info and other things, see my other website.