Wednesday, June 29, 2011

PL nerds: learn cryptography instead

I've never studied cryptography. So when the paper Tahoe – The Least-Authority Filesystem fell in my lap, I was perplexed.

Using just two primitives, secret-key and public-key cryptography, they build an amazing solution to information storage. (Try to understand the two main diagrams in the paper. It's not hard, and it's amazing.)

Before encountering Tahoe-LAFS, cryptography was just a way to keep stuff secret to me. But cryptography also provides us with tools to design programs that wouldn't be possible otherwise.

Monday, June 27, 2011

State of Code interview

Zef Hemel has interviewed me for his weblog, State of Code: Lisp: The Programmable Programming Language. I don't feel qualified to be the "Lisp guy", but as you know, I never leave out an opportunity to blather about PLs.

Zef (@zef) is an academic developing mobl, a language for mobile apps, and is now working for a web-based IDE company, so the State of Code is a place to watch.

Wednesday, June 22, 2011

John Shutt's blog

John Shutt now has a blog: Structural insight.

John is pushing the envelope of Lisp with his Kernel programming language, a "dialect of Lisp in which everything is a first-class object". And when he says everything, he means it.

Not content with just first-class functions and continuations, John also wants first-class environments and first-class macros. Some fun LtU discussions in which John participated come to mind:

Thursday, June 16, 2011

David Barbour's soft realtime model

David Barbour is to me one of the most important thinkers on distributed programming languages and systems.

He frequently posts on LtU and on Ward's wiki.

(And he now has a blog!)

In this LtU post he describes a very interesting soft realtime programming model, reminiscent of Croquet/TeaTime:

I'm also using vat semantics inspired from E for my Reactive Demand Programming model, with great success.

I'm using a temporal vat model, which has a lot of nice properties. In my model:

  • Each vat has a logical time (getTime).
  • Vats may schedule events for future times (atTime, atTPlus).
  • Multiple events can be scheduled within an instant (eventually).
  • Vats are loosely synchronized. Each vat sets a 'maximum drift' from the lead vat.
  • No vat advances past a shared clock time (typically, wall-clock). This allows for soft real-time programming.

This model is designed for scalable, soft real-time programming. The constraints on vat progress give me an implicit real-time scheduler (albeit, without hard guarantees), while allowing a little drift between threads (e.g. 10 milliseconds) can achieve me an acceptable level of parallelism on a multi-core machine.

Further, timing between vats can be deterministic if we introduce explicit delays based on the maximum drift (i.e. send a message of the form 'doSomething `atTime` T' where T is the sum of getTime and getMaxDrift.


Previously: Why are objects so unintuitive

Sunday, June 12, 2011

Everything in JavaScript, JavaScript in Everything

We can now run Linux, LLVM bitcode, and a lot of other languages in JavaScript.

And we can run JavaScript in everything - browsers, servers, toasters, Lisp.

Like IP in networking, JavaScript is becoming the waist in the hourglass.

I don't know what it means yet, but it sure is exciting.

Friday, June 10, 2011

No No No No

// Note: The following is all standard-conforming C++, this is not a hypothetical language extension.
 assert( top( o-------o
|L \
| L \
| o-------o
| ! !
! ! !
o | !
L | !
L| !
o-------o ) == ( o-------o
| !
! !
o-------o ) );

Multi-Dimensional Analog Literals

Tuesday, June 7, 2011

WADLER'S LAW OF LANGUAGE DESIGN

In any language design, the total time spent discussing
a feature in this list is proportional to two raised to
the power of its position.

0. Semantics
1. Syntax
2. Lexical syntax
3. Lexical syntax of comments

(That is, twice as much time is spent discussing syntax
than semantics, twice as much time is spent discussing
lexical syntax than syntax, and twice as much time is
spent discussing syntax of comments than lexical syntax.)
(source, via Debasish Ghosh)

Saturday, May 28, 2011

Extreme software

Some programs are very successful with taking a paradigm to an extreme.

Emacs tries to represent every user interface as text. Even video editing.

Plan 9 tries to use filesystem trees as APIs for all applications and OS services.


It's interesting to abstract insights gained from extreme programs, and modify them.

We can ask: if Emacs is successful using plain text as user interface, what if we use hypertext?

Or: if Plan 9 is successful in using filesystem trees as APIs, what if we use activity streams?

Ouch

Few companies that installed computers to reduce the employment of clerks have realized their expectations.... They now need more, and more expensive clerks even though they call them "operators" or "programmers."
— Peter F. Drucker

Wednesday, May 18, 2011

TermKit

I happen to think that pushing beyond plain text is one of the most important tasks for programmers today, or as Conor McBride put it:
The real modern question for programmers is what we can do, given that we actually have computers. Editors as flexible paper won't cut it.
So of course I like TermKit:
It brings back memories of Apple Dylan:


It's simple: replace plain text files with collections, and lines with objects, and you get Good Things for free!

For example: Scott McKay describes the DEUCE editor:
The editor for FunO's Dylan product -- Deuce -- is the next generation of Zwei in many ways. It has first class polymorphic lines, first class BPs [buffer pointers], and introduces the idea first class "source containers" and "source sections". A buffer is then dynamically composed of "section nodes". This extra generality costs in space (it takes about 2 bytes of storage for every byte in a source file, whereas gnuemacs and the LW editor takes about 1 byte), and it costs a little in performance, but in return it's much easier to build some cool features:

- Multiple fonts and colors fall right out (it took me about 1 day to get this working, and most of the work for fonts was because FunO Dylan doesn't have built-in support for "rich characters", so I had to roll my own).

- Graphics display falls right out (e.g., the display of a buffer can show lines that separate sections, and there is a column of icons that show where breakpoints are set, where there are compiler warnings, etc. Doing both these things took less than 1 day, but a comparable feature in Zwei took a week. I wonder how long it took to do the icons in Lucid's C/C++ environment, whose name I can't recall.)

- "Composite buffers" (buffers built by generating functions such as "callers of 'foo'" or "subclasses of 'window') fall right out of this design, and again, it took less than a day to do this. It took a very talented hacker more than a month to build a comparable (but non-extensible) version in Zwei for an in-house VC system, and it never really worked right.

Of course, the Deuce design was driven by knowing about the sorts of things that gnuemacs and Zwei didn't get right (*). It's so much easier to stand on other people shoulders...

Saturday, May 14, 2011

Secret toplevel

A somewhat arcane aspect of hygienic macro systems is the notion that macro-introduced toplevel identifiers are secret.

An example of this in EdgeLisp:

The macro FOO expands to code that defines a variable X using DEFVAR, and prints its value:

(defmacro foo () #'(progn (defvar x 1) (print x)))

(#' is EdgeLisp's code quotation operator.)

Using the macro has the expected effect:

(foo)
1

But X isn't actually a global variable now:

x
; Condition: The variable x is unbound.
; Restarts:
; 1: #[handler [use-value]]
; 2: #[handler [retry-repl-request]]
; 3: #[handler [abort]]

The name X only makes sense inside the expansion of (foo). Outside, it gets transparently renamed by the hygienic macro system.

(In EdgeLisp, a UUID is attached as color (or hygiene context) to the identifier.)

Why the secrecy of toplevel variables? Well, it's simply an extension of the notion that identifiers that introduce new variable bindings (such as those in a LET) need to be treated specially to prevent unhygienic name clashes between macro- and user-written code. This secrecy completely frees macro writers from having to care about the identifiers they choose.

(Discussion of this topic on the R7RS list: Are generated toplevel definitions secret?)

Wednesday, May 11, 2011

The why of macros

Good analysis by Vladimir Sedach:
The entire point of programming is automation. The question that immediately comes to mind after you learn this fact is - why not program a computer to program itself? Macros are a simple mechanism for generating code, in other words, automating programming. [...]

This is also the reason why functional programming languages ignore macros. The people behind them are not interested in programming automation. [Milner] created ML to help automate proofs. The Haskell gang is primarily interested in advancing applied type theory. [...]

Adding macros to ML will have no impact on its usefulness for building theorem provers. You can't make APL or Matlab better languages for working with arrays by adding macros. But as soon as you need to express new domain concepts in a language that does not natively support them, macros become essential to maintaining good, concise code. This IMO is the largest missing piece in most projects based around domain-driven design.

Tuesday, May 10, 2011

Hygiene in EdgeLisp

EdgeLisp is chugging along nicely. I'll soon do a proper release.

I just implemented a variant of SRFI 72, that is a hygienic defmacro. (I wrote two articles about SRFI 72: part 1 and part 2).
(defmacro swap (x y)
#`(let ((tmp ,x))
(setq ,x ,y)
(setq ,y tmp)))
nil
(defvar x 1)
1
(defvar tmp 2)
2
(swap x tmp)
1
x
2
tmp
1
(swap tmp x)
1
x
1
tmp
2

Sunday, May 8, 2011

Compiling, linking, and loading in EdgeLisp

EdgeLisp now has first-class object files (called FASL, for Fast-Loadable) and a primitive linker:

Let's compile a FASL from a piece of code:

(defvar fasl (compile #'(print "foo")))
#[fasl [{"execute":"((typeof _lisp_function_print !== \"undefined\" ? _lisp_function_print : lisp_undefined_identifier(\"print\", \"function\", undefined))(null, \"foo\"))"}]]

(Note that EdgeLisp uses #' and #` for code quotation.)

The FASL contains the compiled JavaScript code of the expression (print "foo").

We can load that FASL, which prints foo.

(load fasl)
foo
nil

Let's create a second FASL:

(defvar fasl-2 (compile #'(+ 1 2)))
#[fasl [{"execute":"((typeof _lisp_function_P !== \"undefined\" ? _lisp_function_P : lisp_undefined_identifier(\"+\", \"function\", undefined))(null, (lisp_number(\"+1\")), (lisp_number(\"+2\"))))"}]]

(load fasl-2)
3

Using link we can concatenate the FASLs, combining their effects:

(defvar linked-fasl (link fasl fasl-2))
(load linked-fasl)
foo
3

Compile-time effects

Fasls keep separate the runtime and the compile-time effects of code.

For example, a macro definition returns nil at runtime, and does its work at compile-time (edited for readability):

(compile #'(defmacro foo () #'bar))
#[fasl [

execute:
(typeof _lisp_variable_nil !== "undefined" ? _lisp_variable_nil : lisp_undefined_identifier("nil", "variable", undefined))

compile:
((typeof _lisp_function_Nset_macro_function !== "undefined" ? _lisp_function_Nset_macro_function : lisp_undefined_identifier("%set-macro-function", "function", undefined))(null, "foo", (function(_key_, _lisp_variable_NNform){ lisp_arity_min_max(arguments.length, 2, 2); return (((typeof _lisp_function_Ncompound_apply !== "undefined" ? _lisp_function_Ncompound_apply : lisp_undefined_identifier("%compound-apply", "function", undefined))(null, (function(_key_){ lisp_arity_min_max(arguments.length, 1, 1); return (((new Lisp_identifier_form("bar")))); }), ((typeof _lisp_function_Ncompound_slice !== "undefined" ? _lisp_function_Ncompound_slice : lisp_undefined_identifier("%compound-slice", "function", undefined))(null, (typeof _lisp_variable_NNform !== "undefined" ? _lisp_variable_NNform : lisp_undefined_identifier("%%form", "variable", undefined)), (lisp_number("+1"))))))); }))) ]]

Thursday, May 5, 2011

Land of Lisp - The Music Video!



Minimal and sleek / but still so clever you'll freak.

Via Book Review: Land of LISP, by Conrad Barski via @zooko.

Wednesday, May 4, 2011

Unlimited number of runtimes

Because Lisp macros are written in Lisp, there's a runtime at compile-time. (See this previous post for more.)

Some Lisp compilers produce two separate object files for a .lisp file: A FASL file that contains the runtime effects, and a CFASL that contains the compile-time effects (such as macro definitions).

But why stop at two object files? A single file could in fact produce any number of runtimes (FASLs).

One example where this would make sense is documentation: Imagine a DEFDOC macro (for documenting variables), whose effects take place at documentation-time:

(defvar x 1)
(defdoc x "A cool variable.")

DEFDOC registers the documentation string "A cool variable." with X in some table, so that it can be looked up.

The FASL would contain (defvar x 1), and the DFASL would contain (defdoc x "A cool variable.").

Now it's up to the programmer to decide when and if to load the DFASL: in the development environment, one would always load documentation-time, but for a packaged application maybe not. There one would only ship the FASLs, not the CFASLs and DFASLs (unless the application is intended to be programmed by users).

Friday, April 29, 2011

on quotation

Some über-obvious notes:

Lisp literals (booleans, numbers, strings, ...) are sometimes called self-evaluating or self-quoting objects.

This is important because it brings to mind that other objects don't evaluate to themselves: a symbol evaluates to the value of the variable it names, and a list evaluates to the result of a call.

To actually get hands on a symbol or list, we need to quote it. Literals need no quoting, they're self-quoting.

While unquoted X looks quite similar to quoted 'X, they're utterly different. X stands for read a variable from memory, while 'X stands for construct a symbol object with the name "X" (leaving interning aside).

And that's really the use-mention distinction.

Thursday, April 28, 2011

A new Cambrian explosion

Three areas that seem to be exploding are new programming languages, new databases, and new content-centric networking protocols.

But I think all of these developments will be dwarfed by the emergence of the browser as the unified display substrate and JavaScript as the new instruction set.

The last time we had a similar event was the introduction of the GUI in the 80's/90's: millions of programmers scrambled to write every imaginable application for this new system

But the GUI explosion will be peanuts compared to the browser+JS explosion! Not only are there far more programmers today, they're also all joined by the internet now. And there's ubiquitous view source. Need I say more??

Millions of programmers are scrambling right now to write every imaginable application for the browser+JS.

If you ain't emittin' HTML and JS, you're gonna miss out on this once-in-a-geological-era event!

R7RS discussion warming up

I would still appreciate pointers as to how to implement this ;-) Anyone can implement Scheme, but only half a dozen people have implemented separate compilation with hygienically introduced toplevel bindings.Andy Wingo of Guile

For example, '幺' (U+5e7a) has Numeric_Type = 'Numeric', since the character means small or young, so it can sometimes mean 1 in some specific context (for Japanese, probably the only place it means '1' is in some Mah-jong terms.) So, when I'm scanning a string and found that char-numeric? returns #t for a character, and that character happens to '幺' (U+5e7a), and then what I do? It is probably a part of other word so I should treat it as an alphabetic character. And even if I want to make use of it, I need a separate database to look up to know what number '幺' is representing.Shiro Kawai of Gauche

Taylor Campbell's blag

Taylor Campbell's blag contains many insightful posts related to programming languages, Scheme in particular.

For example, he clears up my confusion about UNWIND-PROTECT vs Continuations:
The difference [to DYNAMIC-WIND] is in the intent implied by the use
of UNWIND-PROTECT that if control cannot re-enter the protected
extent, the protector can be immediately applied when control exits
the protected extent even if no garbage collection is about
to run finalizers.

Note that one cannot in general reconcile

(1) needing to release the resource immediately after control exits
the extent that uses it, and

(2) enjoying the benefits of powerful control abstractions such as
inversion of control.

However, if (1) is relaxed to

(1') needing to release the resource immediately after control
/returns normally from/ the extent that uses it,

then one can reconcile (1') and (2) by writing

(CALL-WITH-VALUES (LAMBDA () <resource-usage>)
(LAMBDA RESULTS
<resource-release>
(APPLY VALUES RESULTS))), or simply

(BEGIN0 <resource-usage> <resource-release>)

using the common name BEGIN0 for this idiom. (In Common Lisp, this
is called PROG1.)
(And Dorai Sitaram says: UNWIND-PROTECT "cannot have a canonical, once-and-for-all specification in Scheme, making it important to allow for multiple library solutions".)

Wednesday, April 27, 2011

What's a condition system and why do you want one?

This post attempts to explain how Lisp condition systems surpass ordinary exception handling. Condition systems don't unwind the stack by default and thus allow computations to be restarted, which is a useful tool.

Exception handling
try {
throw new Exception();
catch (Exception e) {
... // handler code
}
Everybody knows what this exception handling code in Java does: the THROW searches for a CATCH clause (a handler) that catches subclasses of Exception, unwinds the stack, and calls the handler code with E bound to the exception object.

At the moment the exception is thrown, the stack looks like this:
  • ... // outside stack
  • TRY/CATCH(Exception e)
  • ... // middle stack
  • THROW new Exception()
There's an outside stack that doesn't concern us. The middle stack is the stack between the TRY/CATCH and the THROW, which is actually empty in this example, but usually contains a whole lotta function calling going on.

Before the handler is called, the stack is unwound:
  • ... // outside stack
  • TRY/CATCH(Exception e)
  • ... // middle stack
  • THROW new Exception()
When the handler is called, the stack looks like this:
  • ... // outside stack
  • TRY/CATCH(Exception e)
  • ... // handler code
Condition systems

Condition systems in the Lisp family are based on the fundamental insight that calling a handler can be decoupled from unwinding the stack.

Imagine the following:
try {
throw new Exception();
} handle(Exception e) {
... // handler code
}
We've added a new keyword to Java, HANDLE. HANDLE is just like CATCH, except that the stack is not unwound when an Exception is thrown.

With this new keyword, the stack looks like this when the handler is called:
  • ... // outside stack
  • TRY/HANDLE(Exception e)
  • ... // middle stack
  • THROW new Exception()
  • ... // handler code
The handler runs inside the THROW statement (Common Lisp would say, during the dynamic extent of the THROW).

For many exceptions it makes sense to simply unwind the stack, like ordinary exception handling does. But for some exceptions, we gain a lot of power from the non-unwinding way condition systems enable.

Restarts

One of the most interesting aspects of not automatically unwinding the stack when an exception occurs is that the we can restart the computation that raised an exception.

Let's imagine two primitive API functions: GETVAL and SETVAL read and write a VAL variable.
Object val = null;
Object getVal() { return val; }
void setVal(Object newVal) { val = newVal; }
Now we want to add the contract that GETVAL should never return null. When VAL is NULL, and GETVAL is called then an exception is raised:
Object getVal() {
if (val == null) throw new NoValException();
else return val;
}
A user of GETVAL may install a handler like this:
try {
getVal();
} handle (NoValException e) { // note use of HANDLE, not CATCH
... // handler code
}
When GETVAL() is called and VAL is null, an exception is thrown, our handler gets called, and the stack looks like this:
  • ... // outside stack
  • TRY/HANDLE(NoValException e)
  • getVal()
  • THROW new NoValException()
  • ... // handler code
As you can see, our handler for NoValException runs, and the exception "isn't over yet", because the stack hasn't been unwound.

Thanks to the non-unwinding nature of condition systems, an application may decide to simply use a default value, when GETVAL is called and VAL is null.

We do this using restarts, which are simply an idiomatic use of non-unwinding exceptions:(1)

We rewrite GETVAL to provide a restart for using a value:
Object getVal() {
try {
if (val == null) throw new NoValException();
else return val;
} catch (UseValRestart r) {
return r.getVal();
}
}
GETVAL can be restarted by throwing a USEVALRESTART whose value will be returned by GETVAL. (Note that we use CATCH and not HANDLE to install the handler for the restart.)

In the application:
try {
getVal();
} handle (NoValException e) {
throw new UseValRestart("the default value");
}
(The USEVALRESTART is simply a condition/exception that can be constructed with a value as argument, and offers a single method GETVAL to read that value.)

Now, when GETVAL() is called and VAL is null, the stack looks like this:
  • ... // outside stack
  • TRY/HANDLE(NoValException e)
  • getVal()
  • TRY/CATCH(UseValRestart r) [1]
  • THROW new NoValException()
  • THROW new UseValRestart("the default value") [2]
The restart at [2] bubbles up, and is returned by the TRY/CATCH for the restart at [1], which means that GETVAL returns "the default value":
  • ... // outside stack
  • TRY/HANDLE(NoValException e)
  • getVal()
  • TRY/CATCH(UseValRestart r)
  • THROW new NoValException()
  • THROW new UseValRestart("the default value")
  • return r.getVal(); // "the default value"

A simple extension would be to offer a restart for letting the user interactively choose a value:
Object getVal() {
try {
if (val == null) throw new NoValException();
else return val;
} catch (UseValRestart r) {
return r.getVal();
} catch (LetUserChooseValRestart r) {
return showValDialog();
}
}
This assumes a function SHOWVALDIALOG that interactively asks the user for a value, and returns that value. The application can now decide to use a default value or let the user choose a value.

Summary

The ability to restart a computation is gained by decoupling calling a handler from unwinding the stack.

We have introduced a new keyword HANDLE, that's like CATCH, but doesn't unwind the stack (HANDLE and CATCH are analogous, but not equal, to Common Lisp's handler-bind and handler-case, respectively).

HANDLE is used to act from inside the THROW statement. We have used this to implement restarts, a stylized way to use exceptions.

I hope this post makes clear the difference between ordinary exception handling, and Lisp condition systems, all of which feature restarts in one form or another.

Further reading:
Footnotes:

(1) This is inspired by Dylan. Common Lisp actually treats conditions and restarts separately.

Tuesday, April 26, 2011

Lisp hype danger



Yesterday, "Lisp was dead".

Today, Lispers are asked to "reproduce their pre-AI Winter achievements" and there's talk of "Lisp geniuses".

I sense danger in the hype cycle!

Hypercode

I just saw this use of HTML lists and tables for syntax, and I liked it. I think that HTML is the future of all UIs, thus also of PLs.

The possibilities of using HTML instead of plain text are huge, and I wish that the syntax-obsessed would focus on HTML instead of plain text.