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.

Monday, April 25, 2011

Original Dylan Manual

Thanks to the Wayback Machine, I just discovered the original 1992 Dylan manual: Dylan (TM) -- An object-oriented dynamic language.

Back then, Dylan still had S-expression syntax, making its CL and Scheme heritage much more obvious.

If you want to see dynamic object-oriented PL design (as opposed to trial and error, plucking out of thin air, or other popular approaches) this is one of the few places to look.

(Here's another URL for the manual.)

Thursday, April 21, 2011

EdgeLisp progress

My hobby Lisp->JS compiler, EdgeLisp (formerly known as CyberLisp) just passed a major milestone: using multiple dispatch, a numeric tower (provided by Danny Yoo's js-numbers), and inline JavaScript, I'm able to write the > generic function as follows:
(defgeneric > (a b))
(defmethod > ((a number) (b number))
#{ jsnums.greaterThan(~a, ~b) #})
Checking it out at the REPL:
(> 200000000000000000000000000000000000000000 100000000000000000000000000000000000000000)
#t
Yay!

EdgeLisp is FAR from usable by anyone but me, but at this point I just had to blog about it. You can check it out here if you want.

Disclaimer: docs are outdated, and the project is in rapid flux.

The more I work on this, the more I respect anybody who's produced a usable PL. The sheer amount of work is unbelievable. :)

Props also to Douglas Crockford's json.js and Chris Double's jsparse.

Wednesday, March 30, 2011

Truth IS stranger than fiction

An amazing look back at Java's early days, by Chuck McManis on HN:



Tcl was the 'language to beat' amongst the new language products. Self was the 'language like no other' (or a totally new way to express what you wanted to a computer). Java was the 'language that re-used code'. C++ was kind of a joke (remember this was the late 80's, early 90's) since it took a perfectly acceptable language, C, and made writing code harder, more error prone, and less likely to produce correct code (all true at the time).

Tcl was a language of rapid expression and Java was a language which was safer, in part, because it enforced a certain level of correctness (type safety, no pointer arithmetic, Etc.).

Tcl had a "huge" installed base of developers, Java had zero developers and hoped to have 10 or 20K eventually.

Bert Sutherland (the guy running Sun Labs and Ivan's brother) got everyone in a room and said "We're going to have a 'language' day, and each of you gets to present why you think your language should exist." the issue was of course that Sun had only so much budget and we had no business reason for developing any new languages.
Surprisingly to some, Tcl 'won' that evaluation. Self was going to continue because Bill could self fund it if he wanted to, and Tcl had the developer base and momentum. The decision was taken to scrap the remains of the Java team (called the Live Oak project at the time) at the end of the Fiscal Year (June 30th, 1995). We were all set to be 're-deployed' which was Sun code for 'find a new job inside of Sun or we'll lay you off.'

What happened next was unexpected. James Gosling, with Kim Polese's help, had convinced the lawyers to allow us to release the source code for 'free' (very un-Sun like) so that we could at least point at something we had done on our resumes. The requirement was that we have a trademarkable name for it (which I believe was, in part, to prevent Apple or Microsoft from re-publishing it as their own thing). We dropped Alpha 1.1 (we had secretly released Alpha 1.0 in February) on March 23rd. Kim sent out a press release to some folks. (not sure if she used PR Newswire or not) The Mercury News put it on the front page, they got a quote from Marc Andresson over at Netscape that it was cool. When I went to the WWW conference 2.0 (as in second conference :-) in Darmstadt Germany two weeks later, everyone wanted to talk about it. I manually downloaded and installed it on all the Sparcstation 20's that the sales office had brought to the conference and gave a quick set of talking points to the sales guys. When I got back there was a storm because folks like Ed Zander were demanding to know why they hadn't been briefed before we announced it, Phil Sampire(sp?) was complaining that people kept calling the sales office to get their sales droid to come out and talk about it and they had no marketing material and no prep. May press conference was already queued up as the SparcStation 20 / Firewall-One launch event, the SS20 got the boot and they replaced it with the Java 'launch'. I spent a crazy couple of weeks creating a completely Java home page for Sun (had I known it was a portent of all flash sites to come I might have shot myself right then and there :-)

Everyone 'forgot' about how they were going to flush the team and instead everyone came out of the woodwork to claim they had supported it all along, SunSoft, SunLabs, and Sun Interactive (which had the only financial success with it at the time, competing against the Time Warner VOD bids). An entirely new 'planet' was born, called JavaSoft and the rest is history.

What Java gave Sun at that point in time was a credible threat against Microsoft. The threat was that the new desktop was the browser, and the way you coded for the browser was Java. Tcl didn't play in that space, and to their credit I don't think the Tcl folks were willing to go there just to ride the buzz.

Java's wake grew to eclipse the other language efforts and Sun never looked back.

Tuesday, March 29, 2011

Duke's Law

Raoul Duke:
As soon as somebody brings in a reference to xah lee, somebody else has to call somebody a Nazi, and then somebody else has to invoke the spirit of john harrop when he was an ocaml instead of F# bigot, etc. etc.

Syntax puns considered harmful (well, not really)

Schemers use the word "syntax" to mean at least two (and maybe even three) different things:
  • in DEFINE-SYNTAX and LET-SYNTAX, syntax means macro expander
  • in SYNTAX and QUASISYNTAX, syntax means code
  • in BEGIN-FOR-SYNTAX, syntax means compile-time (although it's debatable whether this use of syntax is really different from the first one)
There is a certain elegance in that, but in the end it's also a bit silly.

And it's problematic, as the (awesome) paper Languages as Libraries shows: because LET-SYNTAX is already taken to mean "locally bind a macro expander", they have to use WITH-SYNTAX to mean "locally bind a piece of code".

Monday, March 28, 2011

Don't diss Java - Be Happy


On the occasion of Gosling joining Google, it's Java diss time again. But most Java criticism doesn't take its raison d'être into account:
We were after the C++ programmers. We managed to drag a lot of them about halfway to Lisp. Aren't you happy? — Guy Steele
Java has many faults. But most of them are there by design. That's not something many language designers can claim.

Java was a Trojan Horse, designed to slip in a modicum of dynamic features without C++'ers getting suspicious.

That whole dynamic-language-in-the-mainstream thing may have never happened without Java.

Aren't you happy?

Computational Trinitarianism

Given that software is so utterly confusing, it's often helpful to bring in metaphors from other areas, Christianity in this case: The Holy Trinity from Bob Harper's excellent Existential Type:
The Christian doctrine of trinitarianism states that there is one God that is manifest in three persons, the Father, the Son, and the Holy Spirit, who together form the Holy Trinity. The doctrine of computational trinitarianism holds that computation manifests itself in three forms: proofs of propositions, programs of a type, and mappings between structures. These three aspects give rise to three sects of worship: Logic, which gives primacy to proofs and propositions; Languages, which gives primacy to programs and types; Categories, which gives primacy to mappings and structures. The central dogma of computational trinitarianism holds that Logic, Languages, and Categories are but three manifestations of one divine notion of computation. There is no preferred route to enlightenment: each aspect provides insights that comprise the experience of computation in our lives.

OOP, again and again and again

Nothing gets LtU's juices flowing like a good old OOP discussion. It starts with a harmless "OO is anti-modular? Really?" and runs into the right margin very quickly. It's worth a read.

In that thread there's also a quote describing OOP that's very close to my POV, by Jonathan Aldrich:
building dynamic dispatch into the language ... is the one thing that separates languages commonly considered "OO" from those that are not

Monday, March 7, 2011

That explains it

I certainly sat in lots of Scheme design meetings where I pushed for obvious things like branch cuts, error handling, and other "useful" things and was told that such things would ... make the language "too useful" [thus meaning too many people would flock to it and it would be the end of the designers' ability to do the things to the language that _they_ wanted to do].
Seriously though, this shows that the forces behind Scheme are far from obvious.

Understanding Hygiene (part 2) -- SRFI 72

My critically acclaimed Understanding Hygiene (part 1) contains the absolute baseline necessary for understanding hygienic macros.

This post is about my understanding of André van Tonder's SRFI 72 - a specific way of implementing hygiene, which differs from more widely used hygienic systems such as the venerable syntax-case.

It must be said that hygiene is still an area of active research. There be dragons. Nevertheless, van Tonder is quite confident of his design, going so far as calling it "improved hygiene". David Herman, who wrote the bookdissertation on the theory of hygienic macros is skeptical. Anton van Straaten makes some mediatory points. Matthew Flatt raises even more mind-bending questions.

That said, for a hygiene noob like me, SRFI 72 seems to be an elegant and workable design. I wrote a half-assed Lisp->C compiler that contains a SRFI 72 inspired macro system (here's a test from SRFI 72 in my Lisp that works -- phew) and the experience was quite pleasurable. Of the couple thousand lines of C in the system, only a couple dozen or so deal with hygiene.

Basically, what SRFI 72 says is this: when you create a piece of code using the code constructors syntax or quasisyntax, e.g.
(syntax (let ((x 1)) (foo x)))
the identifiers in there (let, x, foo) get a fresh hygiene context (or "color"). Thus they won't conflict with identifiers of another color -- such as those created by somebody else (e.g. another macro, or the user's source). That was the easy part.

Additionally, SRFI 72 makes such pieces of code obey a discipline that is similar to lexical scoping. That is the meaning of 72's money quote that van Tonder repeats multiple times, in the hope of hammering his point home:
the evaluation of any nested, unquoted syntax or quasisyntax forms counts as part of the evaluation of an enclosing quasisyntax.
Say we have some piece of silly code, like:
(quasisyntax (bla bla bla ,(some-unquoted-stuff (lambda () (quasisyntax (bla bla bla))))))
The outer quasisyntax constructs/quotes the piece of code. Then the "," unquotes and we call some contrived function that happens to take a lambda as argument. Then, inside the lambda there's another quasisyntax, so we're quoted again. The contrived unquoted stuff and the lambda don't matter. What matters is that there's an inner quasisyntax lexically embedded in the outer quasisyntax.

Now, SRFI 72's money quote tells us that the inner quasisyntax's bla's have the same color as the outer quasisyntax's bla's. Why? Because the inner quasisyntax is lexically nested in the outer quasisyntax, and like a lexical variable binding, the outer quasisyntax's color is "inherited" down to the inner quasisyntax.

This took me a looooooooooooooooooong while to figure out, and I hope that this post will help those trying to understand SRFI 72.

Questions?

Tuesday, March 1, 2011

Language design criticism = art criticism (?)

A comment by Sean McDirmid on LtU is spinning off into a nice PL design discussion:
We should only critique designs like we critique art, I like this and I don't like that, made from the perspective of another person's tastes. C++ is an example of a language that has a controversial rather than poor design, some people find it ugly while others find it beautiful. A good design is simply a language designed by a good designer, and it might not suit your tastes but you should appreciate it for what it is, right?

I got into some arguments recently over Scala. That I was critical of Scala and compared it to C++ led someone to think I was a Scala hater, while nothing could be farther from the truth. People tend to get very emotional about their languages (or paradigm) of choice. A good discussion involves acknowledging our biases and being objective about our and others' opinions.

Saturday, February 26, 2011

Applied Types

Chris Double is again exploring ATS, a language with a very advanced type system:
ATS did save me from some errors in my larger program that this snippet can be used to demonstrate:
  • The read call must not read more data than the size of the buffer allows.
  • The conversion to a C string in-place means we need to read one less than the size of the buffer.
  • The file must be closed after use.

All these issues resulted in compile time errors. [!]

Thursday, February 24, 2011

Emscripten

This is CPython, the standard Python implementation, compiled from C to JavaScript using Emscripten, running in your browser (without any plugins).
Highly sick.
Emscripten is an LLVM-to-JavaScript compiler. It takes LLVM bitcode (which can be generated from C/C++, using llvm-gcc or clang, or any other language that can be converted into LLVM) and compiles that into JavaScript, which can be run on the web (or anywhere else JavaScript can run).
[So will we run Emacs in X11 in the browser??]

Saturday, February 19, 2011

Wittgenstein for programmers

Harrison Ainsworth's Wittgenstein for programmers is an awesome project. And very quotable:
  • Where a proposition describes the world, a program constructs the imagination.
  • The limits of our programming-languages mean the limits of our imagination.
  • What can be designed at all can be designed precisely. What is unknown we must leave uncoded.

Browsers will let PLs break free from plain text

Programs really aren't plain text. Or they shouldn't be.

But until now there was no way out. OSes come with Ed, and Ed is the standard text editor.

But pretty soon, we'll want to do development in our browsers.

Do we really want to port our 1960's plain text infrastructure to browsers? Surely the answer must be a resounding ``No!''

Reinventing integrated development environments in the browser will make it possible to ditch plain text, and switch to the multimedial representations our programs deserve.

Finally.

Wednesday, February 16, 2011

Free as in Freedom

Vladimir Sedach just tweeted something dear to my heart:
Arguing that the #GPL is restricting your freedom is exactly the same as arguing that the 13th Amendment is restricting your freedom.
Go GNU!

BTW, I'm now also a twit at @msimoni and like to get in touch with all PL enthusiasts out there!