Get a login by sshing to firstname.lastname@example.org,then type verify at the command line
Then, if you haven't read the article you might not know that the dino crouches with the down arrow.
Thanks to the OP for the great article, and for the comments instructing on how we mere humans can play.
N.B. the dino game has sound for a score that is a multiple of 100, so it might not be appropriate to try during a meeting, or at least mute first
How'd they react to that one?
(defun x-find-color (rgba &key (x 0) (y 0)
(width default-width) (height default-height)
(snap-data (x-snapshot :x x :y y :width width :height height)))
This are nitpicks, the code is understandable and easy to read. Nice writeup and cool idea!
> Also if not using asdf, the quickload form should be
> wrapped in an eval-when. It will fail If I Try to
> compile the file (C-c C-k) on a fresh session.
To beat the dino game, the author played the "write a game AI" game. That's a much harder game, which is going to take a while to beat. The general gameplaying work being done at the moment stands a good chance (e.g. DeepMind's Atari playing system, AIXI approximations, etc.), although I still think Nomic is a harder game to beat than Go ;)
After that, we can start playing the "write an AI generator" game. The fun never stops!
Then again, I expected to see more Common LISP around. Paul Graham really put it right, but I guess any leverage/advantage LISP had on other languages, it waned in the 90's (maybe Viaweb was one of the last projects done in LISP, and even that was translated later to other langs...)
I don't think s-expressions are _that_ problematic. The main issue with LISP's nowadays is lack of _momentum_. Java gained its momentum by Sun, after that it just keeps rolling in the industry and apparently, there's no stopping that. Python also has its momentum from the academia, what with all the great libraries and all. But one would expect to see some _major_ projects done entirely in LISP (and not a Trojan Horse LISP like Clojure), after that, it's only a matter of time for developers to become LISPers.
Of course, one could also claim that LISP actually _did_ have like half a century to prove itself, or gain momentum. After all, Golang and ruby are relatively new, but they eat LISP's lunch at launch of new apps.
I really appreciate things like this project. It's not enough, but what is?
If Common Lisp is a failure, how is it that there are multiple commercial offerings for it?
I would take the continued presence of these commercial offerings as a sign of health in the Common Lisp ecosystem.
There are many more stories like that. I was surprised to learn that Delphi is alive and well, and people earn their bread with it writing applications for various industries.
Well, one possible explanation is that they were sufficiently popular at one point that codebases were built that are large enough to need maintaining but too large to justify re-writing.
I haven't had that experience with a Common Lisp implementation but I have with Smalltalk, Cobol and System-W (although the latter was eventually replaced at considerable expense).
Obviously, that argument fails if the commercial offerings are relatively new and not updates of old implementations.
And you say Scheme was friend-zoned by the industry. While I understand why this was, it's a shame: Scheme is a very nice language, and with several high quality implementations, some excellent FFI, and finally some good library support (CHICKEN is excellent here), not to mention Racket's deluge of features and libraries (not really a fan of it myself, and it's not scheme, but I'm willing to admit it's a good system, to say nothing of impressive), it's finally slowly reaching the point where it might be usable in an industrial environment. Although it's not there yet, you can definitely write useful things in it.
I didn't mention Chez. What's Chez got to do with it?
I don't see why Clojure is not Lisp. The only major problem with it is its memory demand, which is a problem it you don't have RAM in abundance. But it's been the first Lisp widely deployable thanks to Java, and thus all the deserved hype around it.
The one big trouble in Scheme is the too-late standard module system. In absence of a standard, everybody created their own, so intercompiler portability is hard (although I'm not all that familiar, maybe I'm mistaken). Another problem is the name, as I can't say it without a blush here in Turkey :)
Unfortunately, the module system's not enough. When R7RS-large hits, you'll hopefully finally be able to port between implementations by simply cond-expanding your FFI interactions, and adding a makefile. With the the approaching release of Red, it looks like this may finally be happening.
Clojure is definitely a lisp, but an odd one. It uses a foreign read syntax, is too close to Java for my tastes (reasonable people my disagree with my irrational hatred of Java), and it screws with Lisp tradition in ways even Scheme doesn't: Ways I don't think are necessarily for the better.
() isn't nil, nil is kinda-not-really like scheme's #f, keywords aren't symbols, nil isn't a symbol, `x isn't the same as 'x, ~ is unquote, there are not cons cells, so cons doesn't do what you think it does, car and cdr don't exist afaik, but first and rest do, lambda is fn, which is also defun (or define in scheme), = is the new equal (or equal?), collections are more generic, and the whole thing is lazy.
To conclude, the difference in spirit and ideas between Kawa and most other JVM lisps and Clojure is similar to the difference between *BSD and Linux:
Clojure is what happens when a bunch of Java hackers write a lisp for the JVM, Kawa/ABCL is what happens when a bunch of Lisp hackers port a lisp to the JVM.
That sounds "clever", but you should be aware that Hickey developed several Lisps before Clojure and was active in the Common Lisp community in the years leading up to it.
Also, some of your statements about Clojure are just incorrect; e.g., Clojure is not wholly lazy.
IMO, most of the things that make early versions of Clojure different from previous Lisps do fall out from the requirement of first-class Java interop and being opinionated about pure data being the Right Way to do multithreaded.
From that point on Clojure is its own thing, and will naturally diverge.
Note that this says nothing about their usefulness for developing software.
You said that they didn't share code, libraries, books, or community. First off, they do share community to some degree: there's a good bit of overlap between all of them. It's not all overlap, but there's plenty there.
Second off, you know what other languages don't share code, library, or books with the Common Lisp we know today? MACLisp. Interlisp. Portable Standard Lisp. Lisp 1.5. Emacs Lisp. AutoLisp. ISLISP. Eulisp. Arc. To say nothing of Hy, LFE, MDL, Newlisp, NIL, Picolisp, and yes, Clojure and Scheme. And there are countless others.
Lisp has always been a language of many different dialects. Why should we pretend it's any different now?
Same for English dialects.
For Germanic languages this is not the case. English and German are both Germanic, but knowing German does not let me read English literature.
Lisp is like English: a basic vocabulary, a basic syntax, basic semantics understood by all readers. I can look at some basic Lisp code and I will understand the program. A Lisp developer looking at Clojure code will understand very very little.
For the rest of the family, there's a lot of mutual intelligibility. And, a metaphor is a metaphor, no metaphor holds if you dig deep enough.
> A Lisp developer looking at Clojure code will understand very very little.
This is an assumption, not a fact. Java interop code and (recur) are a bit confusing in the first sight, but not undecipherable.
The prog lang that's most like English is C++: too many things are overtly overloaded, see phrasal verbs.
I would guess that 10% of its operator names come from Lisp. Okay, that's a wild guess. Let's look at the special forms:
def-, if+, do-, let+, quote+, var-, fn-, loop-, recur-, throw-, try-, monitor-enter-, monitor-exit, ...
Around three from thirteen special forms have roughly the same name/meaning in Lisp.
Let's look at printing: pr-, prn-, print-, println-, newline-. None Lisp names, either they don't exist in Lisp under that name or they do something else. PR and PRN don't exist in Lisp. PRINT prints a newline before printing the object. PRINTLN does not exist in Lisp. NEWLINE is called TERPRI. Thus even for a simple thing as basic IO the API is different.
Any modern fiction. No chance.
Not German, Clojure. Clojure is pretty easy.
user=> (list 1 2 3)
(1 2 3)
user=> (list? (list 1 2 3))
user=> (cons 0 (list 1 2 3))
(0 1 2 3)
user=> (list? (cons 0 (list 1 2 3)))
user=> (list? '(0 1 2 3))
ELISP> (listp (list 1 2 3))
ELISP> (listp (cons 0 (list 1 2 3)))
CL-USER> (listp (list 1 2 3))
CL-USER> (listp (cons 0 (list 1 2 3)))
Maclisp shared code with Common Lisp. For a lot of stuff there was a single code base at MIT for several Lisp dialects, including Maclisp. After some time Maclisp development ended and sharing ended. For example the source code for the complex LOOP macro was at one time a single file for Maclisp, NIL, Lisp Machine Lisp and Common Lisp.
People ported programs from Maclisp to CL by changing them or by translating them with tools, not by rewriting them.
There were also code bases which worked both in early Scheme and CL.
Emacs Lisp has a huge CL subset and even includes a version of CLOS. Since both Emacs Lisp and Common Lisp are coming from Maclisp, both languages are very similar anyway. Basic operators are the same, differing in various details - like dialects often do.
Common Lisp had Interlisp compatibility packages, while Interlisp was still used. There were translators, too.
Xerox had Interlisp and Common Lisp integrated in one Lisp.
Kent Pitman wrote an ISLISP compatibility package for Common Lisp.
There are compatibility packages for Portable Standard Lisp, which allow the unchanged use of PSL code in Common Lisp.
There is zero code sharing between Lisp, Clojure and Racket. Compatibility with the Lisp 1, Lisp 1.5, Maclisp, Common Lisp, Emacs Lisp, CL, ISLISP, main line of Lisp wasn't a goal for Clojure and Racket. That's fine. They got rid of historical baggage and could design new languages.
Basic rule: if a language has LISP in its name, there is some chance that it actually is a LISP.
Take a Lisp 1.5 manual, look at the function index and check which functions and special forms are provided. If most of those are absent (or doing something different), it's not a Lisp: append, atom, car, cdr, cond, cons, eq, eval, intern, list, load, map, member, pair, print, read, prog, quote, reverse, return, set, setq, trace, ...
Clojure fails at (iii), as it just propagates Java exceptions, but I don't think that is impossible to fix, so not a fundamental flaw. JVM is too heavy, and that is a problem for some. Otherwise, it's a well thought-out Lisp with a thriving community and some cool guys and a BDFL (i.e. Hickey).
Common Lisp excels at all the three of the items I listed, plus it's batteries included and has lots of libraries around. Also, it has a standard, so that you can develop on SBCL and deploy with Clozure CL or CMU CL. It's downside is there's some historical baggage and there are no DHH or Hickey or Torvalds in the community, which isn't a downside for me, even an upside.
I'm a Schemer, and Scheme IS a lisp: we don't have restarts, but we do have call/cc, and images as Lisp has them are an optimization hack in any case. And we're finally getting some well supported implementations. Yes, we have hot code loading in most implementations.
Come to the dark side, we have (lexical) cookies (encoded with the current continuation after baking, of course).
Image dumps are also a useful way to create applications or use pre-assembled program state during development. Makes faster startup times, than loading objects during start each time.
Even an editor like GNU Emacs boots up a Lisp image. Which makes it much faster than loading code at start.
I would be very irritated if my Lisp Machine on start would reopen all network connections... But it has a controlled restart process, where I tell Lisp what to restart on a reboot. Actually a Lisp Machine has a list in memory, where the restart tasks are kept. If the image is restarted, one of the tasks it does is to go through this list and execute the various restart tasks...
Anyways, Lisp images don't work like that: a lisp image is a static preloaded environment. If you redefine some functions, exit lisp, and reopen the interpreter, those redefinitions won't be there.
If I save and load an image, the new definitions are still there.
What you refer to has very little to do with imags, Smalltalk keeps a database of code in files under system control. That's also how Interlisp worked.
On a Symbolics Lisp Machine I would configure the machine, load my software and create an image. After starting that image I would on login load any changes from the code bases. If this would be too long, I would save an incremental image.
The Lisp Machine had many more image related features...
In any case, at least a few Schemes have images, so it's a moot point in that debate. It's still interesting, though.
Oh, something like LispWorks has extensive support for using images, too. It has a very extensive application/library delivery mechanism based on images.
LispWorks can also save 'sessions', even automatically as periodically timed events. Even without quitting Lisp. Sessions are basically IDE states (files, listener history, lisp image, windows, ...).
To say that there's compatability between Scheme and CL, and no compatability with Racket is ridiculus: Racket has Scheme compatability modes.
As for the language being called Lisp if it's Lisp, two of the examples you list in the "non lisp" category do so: Clojure's website claims it is a "dialect of lisp," and AIM-349 describes scheme as "essentially a full-funarg LISP."
As make no mistake, all of these languages, from Common Lisp to Clojure to Scheme, are dialects. They have the same origins, and they share many of the same ideas.
That's long ago. That was kind of true in the mid 70s.
> and no compatability with Racket is ridiculus
CL has no Racket compatibility. Zero. Racket has no CL compatibility. Zero.
Porting programs is a full rewrite.
> Clojure's website claims it is a "dialect of lisp,"
Best it is a new language, derived from Lisp and influenced by C++, C#, Common Lisp, Erlang, Haskell, Mathematica, ML, Prolog, Scheme, Java, Racket, Ruby.
'Dialect' in this case is the euphemism for 'fully incompatible' with 'random operator renames and shuffling functionality' where it kind of looked compatible.
> As make no mistake, all of these languages, from Common Lisp to Clojure to Scheme, are dialects.
Sure, but not of Lisp. Of those three, only Common Lisp is a Lisp dialect.
> They have the same origins, and they share many of the same ideas.
Less and less. As a starter: Clojure has no Lisp lists as basic data structure.
And it had better not be nil/false equality. Even McCarthy says that was, if not a mistake, then an accident.
As for Clojure not having Lisp lists, its list implementation is... eccentric, but it DOES have lists.
Actually, scratch that, its list implementation, from a Lisp perspective is broken. Psychotically broken. But it DOES have one. Even if it's insane. What, will you say the same about newlisp lists?
For that matter, is Picolisp a Lisp?
EINE: Eine is not Emacs.
ZWEI: Zwei was Eine, Initially.
SWALANI: Swalani Was A Lisp, And Now Isn't.
A dialect waiting to be invented.
What might be a recursive acronym for Scheme, though?
Oh, oh ... I just got one:
"Scheme Crams Hygiene into Every Macro Expansion."
The acronym's good though, I just didn't want anybody else thinking that was true, given how many people already do.
> As for Clojure not having Lisp lists, its list implementation is... eccentric, but it DOES have lists.
Lazy persistent sequences is the basic abstraction.
Have you looked at R7RS, the latest spec, that goes back to the drawing board on a lot of the stuff R6RS did?
In another comment, @bitwize says No. AutoCAD is written in C++. It has a crude Lisp as an extension language, [...]
Same story for emacs. It's written in C and implements something called "emacs lisp". I'm not inclined to call it crude, but few would defend it if I did... :)
But emacs is special, it's more "extension" than not. That means, the elisp-language extensions that it ships with make up the majority of the "basic" functionality of emacs.
Many/most Lisp systems have a runtime written in C and/or assembler.
Would you accept that temacs is written in C and emacs is written in emacs lisp?
I'd argue that sbcl is written in C and the sbcl common lisp implementation is written in common lisp.
Is that not the common way of viewing it?
BTW, I'm strongly against the idea of creating new OS's just because we _can_. By end-user app, I mean something along the lines of a browser, fully capable back/front-end framework, essential industrial software, etc.
Interestingly enough, KMP is on the side of "not lisp" and the thread was started by https://news.ycombinator.com/user?id=lisper
It's a real end-user applications that has nothing to do with programming. The user does not see Lisp and does not need to know Lisp.
Would Autocad qualify?
and their Lisp forum looks busy:
If we're mistaken, or if you don't want to be banned, please email email@example.com.