Quack

Quack is a new functional programming language, centered around continuations. In Quack, continuations are not merely possible to emulate (Haskell), or a convenient control structure and a first-class value (Scheme), but in Quack there is nothing but continuations. You can see them as parameterized GOTO's. We call them Procs, for procedures. Compiled Quack code is executed by reducing Proc to Proc, until a special Proc is reached which signifies end of program. At any time, the state of the program is represented using a Proc.

Using continuations, it is trivial to implement exceptions. Actually, no exceptions as such are planned. The division proc simply calls the return continuation if it succeeds, and the divide-by-zero continuation otherwise.

Values in Quack are immutable: if you have a reference to something, directly or indirectly, then the value can't change.

Unlike Haskell, Quack is not lazy but strict, with its continuations. This is on purpose. Strict evaluation is faster if all results are needed, which is not uncommon. The sequence of reducing continuations follows the source text in most cases, so it is more natural to follow and debug than Haskell's call-by-need. The running time can be analyzed in the same way as for, say, C code. 1)

Currently, Quack is an interpreter written in Python. If you want to do I/O, you can just grab print from Python. I have yet to find out how to do this in a functional way, and let outer code capture what was printed for example. See also with-output-to-string.

Hypotheses

Things I still want to try out:

  • Is it feasible to compile this, can we reach speeds close to an equivalent C program? We may need to give some optimization hints here. In particular, if we have an array that isn't referenced elsewhere, then can we update a random element in constant time?
  • Can we extend the language/VM to make something like Haskell's ST possible?
  • Implement something like Lisp macros. Maybe if we give macros opaque code blocks. We want to make sure that we can trace back continuations to the exact place they were typed in the original source, e.g. for easy debugging. If some piece of code uses something like with-output-to-string, and we pause execution inside the macro body, we want to see the position in the original source and not the macroexpanded code.
  • Add fancy static analysis stuff. For instance, make a macro for todo and make it possible to get a list of where it is used.
  • Make a debugger that can go back in time. In principle, this should not be hard, because continuations are simply data.
  • Implement message-passing concurrency between Quack fibers.
  • Serialize program status to file. Then add a lock and a socket, and build long-running servers that can survive a reboot. This would work by waking up the program (resuming the process from file), serving a request, and suspending the program back to file when it is idle.

It is well possible that several of these are conflicting, but I want to know.

Status

I don't work on it very often, but here's the repository.

Interested? Suggestions? Flames? Drop me a line at bgeron@gmail.com. I'm also usually on IRC: bgeron in irc.freenode.net.

TODO explain Procs better.

1) The potential downside of this evaluation strategy of reducing continuations lies in optimizations. It looks non-trivial to reorder instructions if we compile to C or LLVM, or to parallellize pieces of code.
 
qck/home.txt · Last modified: 2009/08/05 17:26 by bgeron
 
Recent changes RSS feed Powered by PHP Valid XHTML 1.0 Valid CSS Debian Driven by DokuWiki