Hacker News new | past | comments | ask | show | jobs | submit login
Common Lisp Standard Draft (cvberry.com)
103 points by tosh on April 3, 2018 | hide | past | favorite | 31 comments



I'm downloading and may use this, but I've actually come to like the hyperspec.

It was overwhelming at first, and the formatting isn't great, but I got used to it, and can actually find things pretty quick now. My biggest complaint would be the lack of examples.

I also don't know if I'd call $60 for the official spec expensive, but the fact it's a scan is inexcusable.


When plenty of other languages have zero cost associated ANY cost is too much unless you want people to read about and adopt alternative choices in the time required for someone to justify the company making a purchase.


I think you're misunderstanding the point and confusing standards with documentation.

Standards are for one very narrow group of people: compiler writers. If you're not a compiler writer, you have zero reason to buy the official standard document. And if you are a compiler writer, well, it would be very bizarre to choose your target language based on the price of its spec!

Please note that the final draft of the standard is published for free on that website.


ISO Prolog (ISO/IEC 13211) doesn't have a free standard and it has hurt the Prolog language immeasurably. In this case the last freely available draft is quite different from the final standard, which makes the situation worse because not everyone is aware of this.

I have noticed a lot of Prolog programmers don't know what's in the standard and what's not - you routinely see answers given on SO that are implementation dependent when they could easily have been expressed in strictly conforming ISO Prolog.

Of course, you can get pirated versions of ISO/IEC 13211-1 and 13211-2 but even saying these exist probably makes me complicit in piracy, let alone suggesting they should be widely shared in the Prolog community. The 3 technical corrigenda that update 13211-1 are freely available[0], or at least ISO allows you to "Preview" the whole document in each case.

[0] https://www.iso.org/standard/21413.html


I would put that on the implementations not following the standard rather than the availability of the standard. How many C# devs out there have read their ISO standard?


not sure about Prolog, but afaik compiler writers are usually very good about following the standards (and they reference the standards consistently when discussing (potentially) semantic bugs). In general I think its safe to trust that any given compiler (tries to) follows the standards strictly; and then implement extensions on top.

And extensions are fine. They might be syntactic sugar, or specific hacks, or strange DSLs or whatever. Convenient, if you know you're targetting a single compiler. But you can still write standards-compliant code, when necessary.

But if the compiler doesn't make it explicitly clear, and the standards aren't easily available, then you now have people using extensions without realizing it, and if you tell them you're using an extension, there's nowhere to point to as proof. If you're trying to write code successfully against two different compilers, and get different results, there's nowhere to point to to show that compiler A has the incorrect response. Instead you file against both and assume they have access to the standard.

Also afaik C# only really runs against a single compiler (mono, i think?), doesn't it? So it makes sense that community doesn't bother with the standard; you're not writing cross-compiler-compatible code, so whatever works on mono is the standard (in practice).

The same is true for python, ruby, haskell, etc. There's practically only one compiler in existence (that you care about); those implementations are the standard, regardless of any ISO standard.

But you look at the C and C++ community, and half the SO answers directly reference the standard, despite presumably being mere "users" of the language. Because when many compiler implementations exist (and used), then extensions are much less viable, and the standards are extremely important

And afaik, CL is one of those languages with multiple major compilers, and thus an easily available standard is important.


Interesting.

Fortunately for ANSI CL the last freely available draft is language-technically not different from the published standard.

It's definitely also useful to have standards documentation lookup integrated into an IDE - which I use a lot for CL. Especially since there are versions in different formats (TeX, HTML, Info files, PDF, ...)


This assumes that nobody ever wants to drill down to figure out why their app doesn't work.

Its similar to imagining nobody who uses an app could ever benefit from having access to the source.


Lisp suffers a bit from being too early to the party. When someone wants to learn a new programming language (one that's not literally a new one), there is usually a single obvious canonical implementation (most likely already available on all Unix-like machines) hosted on [language].org, with a set of documents that describe it.

Lisp is (and many other pioneering languages are) no such beast. Lisp.org is McCarty's page (peace be upon Him) and my Linux laptop has about half a dozen dialects of Lisp: Emacs Lisp one or two CL's, Guile, Clojure and Scheme. I love it, but it wasn't easy to start.


Meh. It makes no difference to me which languages other people use. I was merely pointing out that not everybody finds the CLHS unusable.


Common Lisp UltraSpec [0][1] is another awesome resource

[0] http://phoe.tymoon.eu/clus/doku.php [1] https://github.com/UltraSpec


And the Ultraspec is generated from the same tex sources as the PDFs in TFA. The HyperSpec is copyrighted with a license that only permits distribution if not modified, so it cannot be used as a basis for an improved version.


I got excited for a moment and thought there's a new revision in the works.


Me too. It’s too bad how stale the language has gotten.


I think for people who want to be able to have a bit of lisp into their daily lives, Clojure is where the majority of the current industry-focused mindshare is going. At least as far as new development of language features is concerned.

For people who are less industry focused, and more interested in the evolution of lisp from a CS perspective, Racket has gobbled up that mindshare.

Common Lisp, in spite of its strengths, multiple standard implementations, and historical pedigree, seems at risk of fading more if there isn't some new lifeblood injected. The problem if I understand it, is that the Common Lisp spec is so gigantic, and was itself the product of a tenuous truce between many warring tribes of lisps long forgotten. I wonder how possible a new spec even is?


I went from Scheme to Common Lisp to Clojure and back to CL. My impression is that CL is doing better than ever.


The Common Lisp spec came to under 1100 pages.

That's not a lot.

I made a small scripting language starting in 2009. The reference manual is close to 640 pages now if turned into a PDF (with no cover pages, table of contents or index). You go bit by bit, document everything, and you'll be surprised at how the pages stack up over the years.

I think Steele's ClTl (Common Lisp, The Language), a major base document, is already at > 1000.

ECMAScript (i.e. JavaScript) 2017 is 885 pages.

C11 draft: 696 pages. C hardly does anything! Just compiles some Von-Neumann-style word-pushing computation to machine code, and supplies a bare-bones library.

(The K&R2 book is 288 pages and the C90 standard is around that size also. In that K&R2 book, the authors state: "C is not a big language, and it is not well served by a big book." Ha!)

C++ ... let's not go there.


CLtL1 had around 470 pages.


I don't have a copy of CLtL1 myself (though I vaguely recall checking it out from the university library a few times many moons ago). I'm replying to you because your post was the last stop for my train of thought, but this isn't a rebuttal by any means.

CLtL2 has 1053 pages if you count the front- and back-matter, 975 if you don't.

For comparison, the ANSI C11 standard comes to 683 pages, but I think it's worth mentioning that CL leaves far fewer things unspecified, is much more "powerful", and is written in such a way that it can reasonably serve as an introduction and a reference in addition to a definition, compared to the C11 standard which, imo, doesn't serve particularly well for any use other than definition (I'm far more likely to reach for Harbison & Steele than for ANSI C if I need a C reference, and if a handful of programmers trying to learn C given only the standard were broadcast on TV, I'd set my DVR, because that would be very entertaining).

The Emacs Lisp reference manual weighs in at 1077 pages. Nobody really cares.

Standard ML (revised) comes to 583 pages between the Definition and the Basis Library, but its succinctness comes at the cost of being nigh incomprehensible to mere mortals, since the ~100 pages of the Definition are largely occupied by formal semantics; this is both a good thing (formal semantics are nice to have) and a bad thing (to understand it you have to learn the formal language first... I don't consider this a huge deal, but my experience has been that most people can't be arsed).

IEEE Scheme comes to 73 pages, but it omits a lot of things that would be considered essential for "programming in the large": modules, records, macros, &c. While I don't think it could serve as an introduction for anyone not already versed in a Lisp dialect or at least some applicative language, it does function rather well as a reference, except that 80% of the time you're better off checking your implementation's documentation (for example, the 895 pages of the Guile 2.0 reference manual).

ISLISP is 127 pages (the "official" ISO ISLISP standard is also the most expensive of all of these documents by far, but fortunately Kent did us all a solid), and suffers from some of the same "problems"[1] as IEEE Scheme.

BCPL punches at the featherweight class, containing the language definition, tutorial, examples, reference, virtual machine specification, and a source listing of a self-hosted reference compiler, all in a mere 183 pages. Despite its admirable simplicity, so few people seem to be writing any serious software in BCPL these days. I wonder why that is...

Die-hard Wirth fans like to champion the fact that the Oberon-07 report is small enough to keep in your wallet, so you can drunkenly show it to strangers at the pub and proudly tell them all about your wee little language that you haven't seen since your Wirth left you 10 years ago. It's only 17 pages, but it deals almost exclusively with matters of syntax, including only the bare minimum informal, imprecise descriptions of semantics interleaved therewith. The library reference consists of a couple lists of procedure names without even an afterthought mentioning what they actually do, all the while making even the IEEE Scheme standard library look luxurious and capacious in comparison.

The point of mentioning all this is that even after a language has been designed and documented, the act of writing it down comes with all kinds of tradeoffs. Pages numbering in the quadruple digits can be intimidating and perhaps tedious at times, but pages numbering in the double digits can be rather frustrating and just as tedious at times, too: when you find that some aspect of the language is only vaguely specified or communicated, and you have to take your best guess (which is probably wrong, as a rule of thumb); or when your program grows beyond the original intent and suddenly packages and CLOS really start looking like they're worth their weight in paper. The complexity of a programming language is many-dimensional, and there are many possible functions that can map that complexity into the single dimension of page count; some of those functions might result in standards that are great for neophytes but aggravating for professionals, others might yield results that are brilliant for implementors but absolute rubbish for students.

All things considered, I think ANSI CL (and CLtL, for that matter) approximate a sweetspot in the language standard space, not even just in terms of how they're designed but in how they're written: they're immanently accessible to regular programmers, provide thorough coverage of the language and libraries in a format that also serves as a handy reference, and (usually) offer enough detail that implementors don't have to roll any dice. They're not absolutely perfect, but having read so many language standards from so many different perspectives (learner, practitioner, implementor, and once-upon-a-time author), I've really developed an admiration for those in particular. It's not an easy task to write a language definition, especially with a language as featureful as CL, and yet they still manage to do it in a way that I consider exemplary.

[1]: Depending on your use case, they're features rather than problems. Everything would be so much better if only we could all agree on a damn use case.


Well said.

> CLtL2 has 1053 pages if you count the front- and back-matter, 975 if you don't.

Actually CLtL2 is not a book describing the standard, but a book describing a specific state during the standardization. Thus it includes lots of superseded material (plus the reasoning why it was superseded) and also material which was not part of the language (like Series) or later has been removed again (like environment access for macros). Probably (just an estimate) 1/3 of the book is not actual language documentation, but there because this special nature of the book.


Yeah. I quite like the way the second edition was conveyed, though, with additions and amendments indicated by typographic conventions, because the result is that when you have the second edition, you also kinda have the first edition. It's also cool from a historical perspective, since it is very much an intermediate "development snapshot" between CLtL1 and the ANSI standard, and the votes and discussion topics are meticulously catalogued.

But despite CLtL2 not being a standard per se, I think the ANSI standard as published retains a lot of the "spirit" of CLtL, in that it defines things precisely without resorting to obtuse formalisms or overly-dry description, and in that it is organized in a similarly versatile way.


> The problem if I understand it, is that the Common Lisp spec is so gigantic, and was itself the product of a tenuous truce between many warring tribes of lisps long forgotten

Seems you understand it wrong. Common Lisp is a mainline Lisp, based on a direct line of specific Lisp heritage. Technically Common Lisp is mainly a modernized/standardized/portable version of Lisp Machine Lisp (aka Zetalisp).

Clojure OTOH is fully incompatible with any previous identified Lisp dialect, so it is dubious to call it a Lisp.


> Seems you understand it wrong. Common Lisp is a mainline Lisp, based on a direct line of specific Lisp heritage. Technically Common Lisp is mainly a modernized/standardized/portable version of Lisp Machine Lisp (aka Zetalisp).

Sure, I’m not intimately familiar with the lisps that Common Lisp drew from to be able to say what percentage was drawn from where. On the other hand, primary source material collected here (http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/l...) would seem to suggest that CL at least considered the need to balance considerations of differing lisp communities of the time.

> Clojure OTOH is fully incompatible with any previous identified Lisp dialect, so it is dubious to call it a Lisp.

Eh, you’re certainly more expert on lisps than I am, but I have to say that the argument that Clojure isn’t a lisp because it’s not literally compatible with prior lisps seems petty to me. It looks like lisp, acts like lisp, and is commonly understood to be a dialect of lisp. Until the Grand Governing Body of Lisp Certifiers meets and declares Clojure not-a-lisp, I’ll continue being entirely not-dubious about its status as such.


> the argument that Clojure isn’t a lisp because it’s not literally compatible with prior lisps seems petty to me

Fair enough: C# is a Java, which, in turn, is a C dialect. Wee!

I just cribbed the following from a page about Javascript:

  for (i = 0; i < cars.length; i++) {
    text += cars[i] + "<br>";
  } 
it would be trivial to make it work in C++ code and carry out the same intent.

Thus Javascript is just a C++, unless you're petty.

Clojure is less compatible with Lisp than this Javascript-C++ relationship, though; yet, why split hairs.


Well, except that C isn't a family of languages. (EDIT: or rather there is a specific language with the proper name "The C Programming Language," whereas there is no specific programming language called "lisp." EDIT: except McCarthy's?) I guess if we were to follow this line of reasoning, all the languages you mention are in a family of ALGOL-like language.

Emacs Lisp is also pretty darned incompatible with Common Lisp. Is Emacs Lisp not a lisp? How about Scheme? Is Scheme not a lisp?

The way you refer to Lisp, capitalized and as a proper noun, suggests to me that you are simply using "Lisp" as an abbreviated form of "ANSI Common Lisp."

If one chooses a definition of lisp that only includes Common Lisp, then no other lisp can be a lisp unless it implements the ANSI Common Lisp spec (is SBCL a lisp? I hear they added TCO, which isn't in the spec). But most people consider Emacs Lisp, Scheme, and indeed Clojure a lisp.

I've seen the lisp means Common Lisp argument elsewhere before, but at this point it just sounds like sour grapes coupled with an odd minority viewpoint around semantics.


> Emacs Lisp is also pretty darned incompatible with Common Lisp

Not true, both have the core of McCarthy's Lisp and are in the Maclisp line...

> If one chooses a definition of lisp that only includes Common Lisp

Nobody does that.

> , then no other lisp can be a lisp unless it implements the ANSI Common Lisp spec (is SBCL a lisp? I hear they added TCO, which isn't in the spec).

How is that relevant? Garbage Collection is also not in the spec. Lot's of random stuff is not in the spec.

> But most people consider Emacs Lisp, Scheme, and indeed Clojure a lisp.

Since "most people" don't even know what Lisp is, nothing follows from this.

> I've seen the lisp means Common Lisp argument elsewhere

Defintely elsewhere. It hasn't been made here.

First rule: if the thing has not Lisp in its name, it probably is not a Lisp.

Second rule: if it is not somewhat compatible with Lisp 1, then it is not a Lisp.

From that you can infer that languages like Lisp 1, Lisp 1.5, Lisp 2, Maclisp, BBN Lisp, UCI Lisp, VAX Lisp, Spice Lisp, New Implementation Lisp, Zetalisp, Franz Lisp, Standard Lisp, Interlisp, Eulisp, LeLisp, Mulisp, Emacs Lisp, Xlisp, Common Lisp, various Common Lisp derived languages, ISLisp, are all direct Lisp dialects.

See here: http://www.softwarepreservation.org/projects/LISP/


C is certainly a family of languages: K&R "Classic" C, GNU C, ISO {C90, C99, C11}, MS Visual C, Borland Turbo C, ... interpreters like EiC. There are many C toolchains from all sorts of embedded vendors: like for Microchip's PIC, Atmel AVR.

C++ is in the C family; many C programs run as C++ with only small modifications and some cases no modifications at all.

Objective C is another C family member.

I maintain a fairly large FOSS project in such a way that although it is written in C, you can configure to use a C++ compiler; effectively, C++ is a target platform to which the code is portable. It's just another C dialect.


Common Lisp the Language:

https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node6.html#SE...

> Compatibility: Unless there is a good reason to the contrary, Common Lisp strives to be compatible with Lisp Machine Lisp, MacLisp, and Interlisp, roughly in that order.

Zetalisp is a Maclisp dialect. The is basically very little compatibility to Interlisp. This leaves us with Zetalisp as its main predecessor.

When CL was designed, Zetalisp, NIL, Spice Lisp and S-1 Lisp (the ones mentioned mostly in the CL history) were active implementations. They are now forgotton, because they were superseded with a language directly based on their heritage or, in the case of Spice Lisp, they are now actually Common Lisp.

If you actually look at Zetalisp, the main predecessor, it was actually as large or even larger than Common Lisp - and Common Lisp looks larger, because the language includes part of a library and it was documented in more detail than other Lisp languages.

> it looks like Lisp

But it does not run ANY prior Lisp application and basically no substantial, beyond (+ 1 2), Lisp application can run in Clojure without being rewritten. Not ported. Rewritten. Clojure does not have any compatibility to the Lisp from McCarthy - not in the language itself and not even as a compatibility layer. It does not have most of its functions and if the functions have the same name, they mostly do something different. Even if you look at basic numerics, it does not do what one would expect from a Lisp, but uses the host language semantics (Java/JVM, Javascript, ...).

It's base data structure is not the linked list, like every other Lisp dialect.

A sheep has four legs, but it is still not considered to be a dog - it can't even bark.

For me the general concept of being a Lisp is so vague, that I prefer a more strict definition: a language and its successors which strive to be compatible in syntax, semantics, pragmatics and community.

If we take being a Lisp in a broad meaning, then it includes languages like Logo, Dylan, maybe even ECMAscript/Javascript. Which makes it a meaningless term, IMHO. Sure it make you sometimes feel well to be included in a family - but often enough this sets expectations which can not be fulfilled: like reading a Lisp book and then trying the example code in those languages - and then it does not work...

CL is a specific branch of the Lisp tree. Clojure is a new tree, based on roots in Java (runtime and interop), Lisp (various ideas, like expressions, macros, ...), FPLs (ideas like 'persistent' data structures, ...


> like reading a Lisp book and then trying the example code in those languages - and then it does not work...

Does SICP work in Common Lisp these days? Or is Scheme also not sufficiently a lisp?

> CL is a specific branch of the Lisp tree. Clojure is a new tree, based on roots in Java (runtime and interop), Lisp (various ideas, like expressions, macros, ...), FPLs (ideas like 'persistent' data structures, ...

I would definitely agree with this.

EDIT: It occurs to me that maybe the difference of opinion is around the whole acceptance of the notion of lisp as a family vs. Capital Lisp as a species.

It seems like the idea of strict compatibility with Common Lisp is more akin to the definition of a species (i.e. more or less able to interbreed). On the other hand, if one accepts the premise that lisp can be a family, then incompatible evolutionary changes should be expected.

Whether one considers Clojure a lisp probably depends on whether they think it bears sufficient resemblance to other accepted lisps as to constitute a family. Lions and house cats are pretty different and aren't biologically compatible from a reproductive standpoint, but share a lot in common such as a similar morphology and common ancestor. Common ancestor is a sticky point, because presumably some Common Lisp implementations don't literally share code with prior lisps... A clean room Common Lisp couldn't meet that standard, for example.

Fun discussion for sure.


> Does SICP work in Common Lisp these days?

With a few macros and compatibility functions there is not much in SICP Scheme which does not work in similar ways in Common Lisp. SICP is using a rather primitive version of Scheme - which actually does not even run in newer Scheme dialects without changes. SICP does not even use macros. Later Scheme languages diverge much more and thus form their own language family. There is still a core in Scheme, which is relatively close to Lisp.

Take for example this function from SICP:

    (define (make-stack)
      (let ((s '()))
        (define (push x)
          (set! s (cons x s)))
        (define (pop)
          (if (null? s)
              (error "Empty stack -- POP")
              (let ((top (car s)))
                (set! s (cdr s))
                top)))
        (define (initialize)
          (set! s '())
          'done)
        (define (dispatch message)
          (cond ((eq? message 'push) push)
                ((eq? message 'pop) (pop))
                ((eq? message 'initialize) (initialize))
                (else (error "Unknown request -- STACK"
                             message))))
        dispatch))
The equivalent Common Lisp is roughly this:

    (defun make-stack ()
      (let ((s '()))
        (labels ((push (x)
                   (setq s (cons x s)))
                 (pop ()
                   (if (null s)
                       (error "Empty stack -- POP")
                     (let ((top (car s)))
                       (setq s (cdr s))
                       top)))
                 (initialize ()
                   (setq s '())
                   'done)
                 (dispatch (message)
                   (cond ((eq message 'push) #'push)
                         ((eq message 'pop) (pop))
                         ((eq message 'initialize) (initialize))
                         (t (error "Unknown request ~a -- STACK"
                                   message)))))
          #'dispatch)))
You can see that CL uses two namespaces and some of the operators are named differently (like EQ in Lisp and EQ? in Scheme, SETQ in Lisp and set! in Scheme).

But beyond that and even without a compatibility layer, the SICP code has 1 to 1 direct equivalents in CL: function definition, s-expressions, local functions, local lexical variables, setting variables, creating cons cells, testing for a NIL value, symbols, equivalence of symbols, raising an error, cond operator, ....

With minor compatibility macros we can write:

    CL-USER 6 > (define (make-stack)
                        (let ((s '()))
                          (labels ((push (x)
                                     (set! s (cons x s)))
                                   (pop ()
                                     (if (null? s)
                                         (error "Empty stack -- POP")
                                       (let ((top (car s)))
                                         (set! s (cdr s))
                                         top)))
                                   (initialize ()
                                     (set! s '())
                                     'done)
                                   (dispatch (message)
                                     (cond ((eq? message 'push) #'push)
                                           ((eq? message 'pop) (pop))
                                           ((eq? message 'initialize) (initialize))
                                           (else (error "Unknown request ~a -- STACK"
                                                        message)))))
                            #'dispatch)))

    CL-USER 7 > (make-stack)
    #<interpreted function (SUBFUNCTION (LABELS DISPATCH) :UNKNOWN) 406000135C>

    CL-USER 8 > (let ((s (make-stack)))
                  (funcall (funcall s 'push) 1)
                  (funcall (funcall s 'push) 2)
                  (print (funcall s 'pop))
                  (print (funcall s 'pop)))

    2 
    1 
Above still has to respect that CL is a Lisp 2, but we are getting closer.

If we have a more complete Scheme emulation in Common Lisp, we can use it directly and unchanged from SICP:

    CL-USER 2 > (ps:scheme)
    This is Pseudoscheme 2.12.

    SCHEME 3 > (define (make-stack)
                 (let ((s '()))
                   (define (push x)
                     (set! s (cons x s)))
                   (define (pop)
                     (if (null? s)
                         (error "Empty stack -- POP")
                       (let ((top (car s)))
                         (set! s (cdr s))
                         top)))
                   (define (initialize)
                     (set! s '())
                     'done)
                   (define (dispatch message)
                     (cond ((eq? message 'push) push)
                           ((eq? message 'pop) (pop))
                           ((eq? message 'initialize) (initialize))
                           (else (error "Unknown request -- STACK"
                                        message))))
                   dispatch))
    make-stack defined.

    SCHEME 4 > (let ((s (make-stack)))
                 ((s 'push) 1)
                 ((s 'push) 2)
                 (s 'pop)
                 (s 'pop))
    1



OTOH if you look at Clojure, it lacks the basic cons cell data structure and then one needs to use operators from a different data structure. LET / SET! does something else in Clojure - reading the documentation about that is confusing enough.

> A clean room Common Lisp couldn't meet that standard, for example.

It's not about that an implementation actually uses code from others (though it might), it is about actually being able to run Lisp applications/libraries or have them ported without the need to rewrite them.

Take for example Macsyma. It has its roots in mathematics code written in Lisp in the 60s. It was then further developed in Maclisp. It was then ported to Zetalisp and Franz Lisp (IIRC). Then it was ported to Common Lisp and still runs in various Common Lisp implementations. I have myself ported it to a Common Lisp implementation it never ran before in a day. This is an example of a substantial and non-trivial Lisp program which didn't need to be reimplemented, since it has been moved to new Lisp dialects to be able to be run on current hardware. A version of it now runs on Android devices...

The LOOP macro was actually maintained at MIT as a single file for multiple Lisp dialects for some time.

You can take a Lisp book from the 60s and run its examples in CL without effort. There is code from McCarthy from 1960 which runs mostly unchanged today, with a minimal compatibility layer. You can't run anything from McCarthy in Clojure because it lacks the most basic things like cons cells. All the list processing stuff needs to be rewritten to fit into Clojure's idea for 'persistent sequences' or other concepts.


nice. whenever i am in between jobs, and are plotting the next thing to do - i turn to lisp :|




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: