Lisp: A Language for Internet Scripting and Programming (1998) [pdf]
norvig.com
norvig.com
AOL of course destroyed Netscape after purchasing it by encumbering itself and all it touched with an East Coast Big Dumb Company mindset. It wasn't until years later when Google started seeing Microsoft as the competition that anyone else treated the browser strategically. By that time, JavaScript had won just by showing up in IE 6 and in the legacy Mozilla carried from Netscape.
What might have happened if Yahoo had decided the browser was strategic instead of living off banner ad revenue at the expense of increasing irrelevance? They had Graham and the Viaweb team, and so some manager decided to port their code to C++ and the rest, as they say, is history that never was.
[1] It is interesting to think that Apple would build its future in ways that treated the browser as a commodity - first with the iPod and then with the app store.
[2] See Slava Akhmechet's The Nature of Lisp. It's definitely worth reading: http://www.defmacro.org/ramblings/lisp.html
An association list is just a list which elements are conses. I'm fairly certain that cons, car and cdr were part of Scheme since the beginning and they are all you need to build assoc and friends. Scheme lacked a proper hashtable datatype though, which was present in some other Lisps.
assoc lists were important to implement dynamic environments simple and fast, which is not so easy with hash tables. In assoc lists you tolerate duplicates, but by putting new at the beginning you override/"shadow" the old ones, until you leave scope and use the old assoc list. and share the data! with hashes you have to actively delete or copy the tables. non-efficient and very complicated.
I have given some thought to this in the past. Has there ever been a serious attempt at this?
Sometimes the error messages for really simple mistakes (missing semicolon, wrong punctuation, etc.) are obtuse and almost completely meaningless. Of course, if it were easy to give simple, clear error message in such cases, they resulting message would be simple, so it's other complexities that get in the way. The biggest problem I see is that having labelled training data, e.g. source code that fails compilation along with the specific actual error, is unlikely, and having an expert provide small, self-contained examples is unlikely to be useful (really, enough training data to be effective) in real world errors, even when novice programs are fairly small.
Edit: I was just thinking about this, and with prudent use of a VCS, labelled training data would just be pairs of the form <commit that fails, next commit that compiles>. It would be interesting to see if it's possible to pull useful data from exiting history, or if some level of restraint is necessary in practice. Really, I'm just thinking about the precipice of supervised and unsupervised learning here.
It's not "AI" but I think it's a much more practical approach that any parser could implement, with enough work and feedback.
I haven't used Go enough to know if this technique makes a qualitative difference on the friendliness of error messages. Interested to hear opinions.
PG delivered a similar message to my undergraduate CS class in 1996/7 as a guest speaker when he was working on Viaweb and extolling the virtues of LISP for server-side web applications.
For Scheme this might hold true. But most Common Lisp programs I've seen are beyond hairy.
Plus, the (classic intro-to-LISP) notion that "it has a simple syntax with few constructs so it must be easy to program in" has to die.
Assembly has very simple syntax too. I wouldn't write a large program in it.
Suppose we amend that to simple high-level constructs?
I don't think I've ever picked up a language as fast as I picked up scheme. Not even python.
My experience from tutoring CS students in Scheme back in the day was that it usually either clicked immediately, or not at all. The folks who'd perhaps never get good at it aren't necessarily poor programmers. I don't know that any of them were great programmers, but that might be my prejudice as someone who was having a hard time teaching them a programming language. Some of them went on to get more impressive ones than the one I have, so probably definitely it was just prejudice. Anyway, the point remains, I've met a lot of people who struggled with Scheme, and it was most certainly not for want of smarts. My best guess is that it's just that the language is only suitable for people who have a certain approach to thinking that's perhaps unusual.
* And beautiful - easily one of the most lovely languages I know.
Predicates end with `?`, like `equal?`.
This naming and consistency makes it easier to learn Scheme.
What makes Common Lisp more practical is libraries. Hairy and crufty some may be, but many of them, and many of good quality. You know the old saying about how X is a badly implemented version of half of Common Lisp.
The Scheme-descendant Racket is, however, plenty practical in this regard.
Non-standard, non-portable racket libraries aren't the answer to scheme's basic nature (though I believe r7rs-large will solve a lot of these issues). More serious dealbreakers in my work are the lack of declare, no built-in OOP, and no spec for optional and keyword parameters.
Scheme has other issues too such as the inability to turn off continuations (they are great in some situations, but can cause performance issues and specifically cause increased memory usage).
Racket is, however, a great answer to "is there a Lisp that's both conceptually consistent and has lots of libraries".
What ends up mattering most is how productive you are once you're familiar with it. This is where a language like Python, and most other widely used languages, tend to be much better than Scheme for most programmers.
Scheme may be easier to learn initially, but it's generally much less useful in the long run in most cases.
Racket is the answer to schemes practicality problems.
Judging from Norvig's employment, this is at least 10 years old. And also from SILK, which later evolved to JScheme, which is now used in e.g. Scheme Droid interpreter for Android.
"LISP - a Language for Internet Scripting and Programming",
Timothy J. Hickey, Peter Norvig, and Ken Anderson
LUGM'98: Proceedings of Lisp in the Mainstream, Nov. 1998, Berkeley, CA.
As per http://www.cs.brandeis.edu/~tim/http://sisc-scheme.org/sisc-online.php
http://alex.nisnevich.com/ecmachine/
But the parent is really the right answer -- ClojureScript is actually targeted at meeting modern web development challenges and has a thriving ecosystem of powerful tools for the same.
Pure Lisp, compiled for the user's browser and OS. No Javascript anywhere.
<script src="biwascheme.js">
(console-log "Hello, world!")
</script>I would like to know how to implement and deploy a scripting engine that has no dependencies on Javascript whatsoever.
On a serious note, JavaScript and the lack of fragmentation is one of the best features of Web. You don't have to download appropriate browsers (in theory and mostly in practice) to run your website.
I mean, I can't argue that there are some things that will be nice to have. However, it seems that going with additions that are not addable as a library is contrary to the bloody web.
Or, am I wrong and the new syntactical changes will be ok?
Also... this pretty much exemplifies how/why lisp would have been awesome. Quite literally everything could be done "as a library."
But this sort of thing already happens all the time. You don't have the right flash player, or the right silverlight player, or the right version of Java. There would be very little difference in the UX between different scripting languages and the current UX w.r.t. media codexes, and the end result would be the same in both cases: there would be some repertoire of languages and codexes that everyone uses and become standard.
The alternative is to forever have to deal with a language that by design cannot even handle integer math or unicode strings properly.
That's exactly the point. Imagine dozens of them.
IMHO that would be a better world than the one we currently live in. Javascript is serviceable for its original purpose, but for serious webapps it's broken beyond redemption. NOTE: This is not to say that it is impossible to write serious webapps in Javasceript. Obviously it is possible. What I mean is that at some point the aggregate cost of dealing with Javascript's design flaws becomes greater than the aggregate cost of dealing with multiple browser scripting languages.
That's quite a stretch. There are two browser plugins that are in broad use on the web: Flash, for fallback audio/video support and some casual games, and Silverlight, for Netflix. Both are dead technologies when you consider mobile web; even if you're only thinking about laptops/desktops, both Silverlight and Flash have essentially been abandoned by their creators, and the web platform has almost entirely subsumed their original purpose for existing, currently with the exception of DRM.
Personally, what I'm hoping happens is that we get one, single better compile target, and languages can just target that — giving the web a broader selection of languages without the fragmented nightmare (and security nightmare) of introducing dozens of new plugins. This is something that browser vendors are currently working on: Google with PNACL, and Mozilla (and, to some extent, Google as well) with asm.js. I hope we end up with PNACL, but a sufficiently optimized asm.js would serve the same purpose, albeit with a more difficult debugging / performance optimization story.
That is a terrific idea in theory, but the last time anyone tried to do that the result was the JVM.
Incredible amounts of R&D devoted to optimizing its performance, broad hardware and os support, with lots of interesting languages to choose from running on top of it.
I consider the JVM to be the best part of programming in Java. The JVM is fast, lets you write very portable code, and it gives you a great debugging experience. Plenty of other languages chose to target the JVM, like Scala and Clojure, for its quality.
That's not to say the JVM is perfect. I don't like type erasure for instance (I understand C# has 'better' generics). Nevertheless - and this idea comes up frequently - imagine if browsers ran VM bytecode instead of interpreting JavaScript. The browser would be totally language-independent. You could write in any language that compiles to the browser bytecode, and deploy the precompiled bytecode 'object' files. I mean, it is a great idea in theory, and it's exactly what the JVM has succeeded in doing, except that the JVM does it for operating systems and not browsers.
Of course, this is all a fantasy at this point. There's no possible way browser vendors would ever agree on a standardized virtual machine, much less all implement it (see DartVM).
No, I'm not trolling. I was responding to someone who said that the two non-dead browser plugin technologies were flash and silverlight. Java is notably absent from that list. (Can you even interact with the DOM from a Java applet?)
I agree with you that the JVM is the best part of Java, but that's not saying much IMHO.
In an aside, the JVM has only relatively recently been an effective general-purpose compile target, and it wasn't designed as such. The JVM's failure for frontends doesn't give much indication as to where the pitfalls of targets like PNACL or asm.js might be: it died (deservedly) because of reasons that apply to neither technology — slow startup time and lack of effective sandboxing. Both PNACL and asm.js start quickly, lean on hardware-acceleration in the browser to react smoothly, are designed from the start as compile targets, and are sandboxed to the point where browser vendors don't feel the need to pop up warning boxes that scare off consumers.
For one, if you find it bad, then why would you want to add to this badness with extra web languages? If anything, what you say is a counter-example.
Second, what you describe has stopped happening to 90% of web users for like 5 years or so. Nobody caresa bout Java or Silverlight, and Flash is getting all the more obscure. Heck, major browsers like Safari don't ship it algother, and even YouTube plays without it. At worse, you lose some shitty casual games.
>The alternative is to forever have to deal with a language that by design cannot even handle integer math or unicode strings properly.
Well, we seem to be doing ok even with such a language. Besides, most languages cannot handle unicode strings properly anyway (including Java, Go, PHP, Python, Ruby and several others). There are just too many subtleties.
I don't. (Presuming that by "it" you mean "having a lot of plugins floating around".)
> Nobody caresa bout Java or Silverlight
Netflix uses Silverlight. There are an awful lot of nobodies using Netflix.
> we seem to be doing ok even with such a language
That depends on what you consider "OK". Blub users always think that things are OK.
> most languages cannot handle unicode strings properly
The problem with JS is that the standard requires strings to be represented internally as UTF-16, which cannot cover the entire unicode code point space. So JS's brokenness is worse than other languages because it is actually enshrined in its standard.
What I consider OK is that we have had great growth in the breadth, scope and capabilities of the modern web. I've been on it professionally since 1996, and followed it even before, and I don't think there's anyone who would disagree with such a statement.
From a joke environment based on plain text circa 1993-4, we know have the ability to emulate whole CPUs inside a Javascript VM, AND with usable speed. And then there's ES6 with a whole lot of additions to the language.
>Netflix uses Silverlight. There are an awful lot of nobodies using Netflix.
Well, in the US. The world is 20 times bigger than the US. I'm not even sure why US users put up with Netflix pulling this shit.
>Blub users always think that things are OK.
Well, other's have it worse. They always think that the "blub" concept, a random idea in an essay, is something that's true, universal and settled, were it's just someones opinion. The blub idea, furthermore, is about the "expression problem", and it's condescending to people by assuming that that's all that matters.
People chose to write something in C, C++, Assembly, Lisp, Haskell whatever for lots of reasons, and the success of that undertaking involves a lot more reason than "expression". Things like community, libraries, toolsets, hireability, existing codebase, documentation, speed, heck, even familiarity, play a role as much, or even more, important than the mere "expression" capability of the language.
And, statistically speaking, the oh-so-expression language people don't have much to show for it, whereas the blub C/C++ people have tens of thousands of indispensable programs used by billions. Sure, they are much less, but at one point they were much more (Lisp existed before C/C++), and they also had nice funding going on until the mid-eighties, with not much to show for it. 3-4 C people in AT&T laid the foundation for most of what we use today. Were are the equivalent non-blub people, who had an impact in fields other than PL design?
The security consultants on the 21st century know whom to thank for their jobs.
And if any browser is going to replace Javascript, it's going to be Chrome (first), not Firefox - Mozilla is doubling-down on Javascript with both asm.js and FirefoxOS. Google is doubling-down on efforts to replace and/or subvert Javascripts, with both Dart and NaCl.
Nothing uniquely qualifies Javascript now, but being the status quo is a qualification of sorts. Replacing (or adding a second option of) a scripting language for the DOM in an existing browser is going to be tough, regardless of what the existing language is (which happens to be Javascript in all modern browsers).
I'm not sure about that, DOM access is a bit of a mess and the js stdlib is not great either, it wouldn't be hard to improve on it. It's a real shame we've ended up in a situation where the only API for manipulating the DOM is in js - script tags were not initially intended to be js only. Switching language would be the perfect opportunity to create a proper standard library for the web, by looking at the organic mess which is DOM access, js animation, etc, extracting the good parts, and throwing away all the rest. If it significantly improved dev productivity, and was available as a plugin initially for all browsers, people might be willing to experiment with it.
There are political and technical problems with doing that of course, but it would be a great step forward for web development, and is not at all beyond the reach of a big browser vendor. I agree if it were to be anyone, it'd be Google.
You'll get no disagreement from me about the JS stdlib. I was shocked when I found the "correct" way to extract the day of the week from a Date object in Javascript (without third-party libraries): https://stackoverflow.com/questions/4822852/javascript-how-t... [0]
It would be a great feat if/when someone does it. But saying that "Browser makers like Mozilla have had the option, at any time, to enable the use of Lisp (or any other language) in the place of Javascript" sort of ignores the amount of work required to actually do this (properly).
[0] Of course, this code does already exist internally, as evidenced by (new Date).toString(); you just can't access it.
I think the problem has not been so much that this task is incredibly difficult, but that browser vendors have very little incentive to add a new language in addition to js - it's already a money and time sink maintaining a browser, so they're not going to volunteer to make more work for themselves without a payoff for the corporation paying the bills.
GL is easy because it requires no types. Everything that is required is included in the intersection of JavaScript and C++. More highlevel API's are harder, and that's why we don't see any wrappers for e.g. WebRTC in Emscripten.
You still need to know javascript though. Dart,CoffeeScript,Typescript,ClosureScript... IT's not like people dont have the choice today.And sourcemaps work well when debugging,usually.
Sexps are cool, but you really, really need proper tools to edit them efficiently. Without them it's very easy to make a mistake, which of course will make it to runtime, because it won't be a syntax error in most cases. That's the downside of having so little syntax.
So I think that (for CSS) we'd either build very simple sexp based DSL using macros or we'd just create a compile-to-sexps human friendly syntax. On the plus side, with Lisps, that would be one evening to implement... :)
languages like haml and jade are very close to M-expression languages and could work as drop-in replacements for S-expressions just like they are used as <html> replacements at present or s-expr could be used. In addition, in the presence of a lisp language, the code <--> data relationship can be quite convenient.
The latter implies that you are always really using Javascript. Which is also borne out by how you list only languages which are thin veneers over Javascript (Dart a possible exception)
The kind and amount of technical expertise behind the development mass that drives most of the Web nowadays does, sadly.
I remember talking with him about teaching languages to kids. Like me he has three kids. I was noticing that many of the beginner languages were quite Lispy, including Logo which I had been teaching my oldest and I asked about the suitability of various lisps beyond this (I would end up going the direction of Rebol instead at this point, but plan to come back to Lisp).
His response was that for a beginner, Lisp is nice, but Common Lisp was, in his words, "too big" to be an early programming language, so one has to start small and work up.
I can't help but wonder at this. "Simplicity in the eyes of the user" is not something I have ever associated with Lisp as a whole but it seems like part of that is jumping into Common Lisp directly.
Now, none of this means one couldn't have a lisp for the web. However, we don't have one right now.
We are at a point where JS is following the same path. Ideas like ECMAScript 4 were rejected because they would break compatibility and we are still working around the problems of JS. We need that clean break now rather than later. Such a clean break would be at it's best now rather than later. We could simply continue supporting the current JS compilers 'as is' for old code (or provide a JS to new language compiler) and replace the language with another which is designed correctly (we could perhaps break the DOM too).
While I would like to see a scheme r7rs used (except with support for OOP, built-in actors, and static typing), I suspect that M-expressions (more like dylan) would be necessary (though for the record, I've seen more nested parenthesis/braces in JS code than I've seen in a lot lisp code). Such a language could also be interpreted via JS (or compiled to JS) for old browsers (though I suspect telling people to upgrade or go without would promote suitable updating more akin to telling everyone to change to digital TV or go without).
We need a clean break and lisp is worthy of consideration rather than being cast to the side like last time.
I saw a presentation once, where they compared the amount of parenthesis/braces in mainstream languages vs Lisp, with Lisp having less in most algorithms being compared.
For example,
func_call(args) vs (func_call args)
array_access[index] vs (array_access index)
The thing is, since in other languages parenthesis/braces tend to be scattered along the source file, it looks like less than Lisp based languages.In terms of the importance attached to language aesthetics, ANSI Common Lisp is probably closer to PHP than Ruby, ML, or Python. That doesn't mean that it isn't used to write beautiful code, only that it leaves doing so solely to the programmer's discretion.
It's not that programming now "largely consists of debugging and customizing already existing code, often via frameworks". For one thing, it's only the narrow, web-constrained definition of "framework" that even vaguely works that way. Second, I'd argue that, unless the code which programmers debug has been written somewhere until the late 1990s, new code gets written often enough that programming largely consists of writing new code instead of debugging old one. That there are programmers hopelessly churning on the umpteenth bug because someone at the end of the Internet decided to change the format of their JSON objects and the mapping of their HTTP request handlers (pretentiously calling that "an API") is not a testament to how programming has evolved, it's merely a proof that not every change counts as evolution.
Instead, the choice of Python over Scheme -- which has been received with mixed feelings by almost every programmer able to write a Quicksort function without googling for compiler errors -- seems to have been driven by related, but vastly different reasons, such as:
* There are vast amounts of interactions spread over multiple languages, machines and platforms. Independently reasoning about objects, while essential to programming, is as central to teaching as integration in already existing architectures is. Unlike the early 1980s, when pretty much every new computer meant a new editor, a new set of programs and more often than not, a couple of new languages, being able to reason about existing architectures is incredibly important. Scheme is able to provide this, but requires fairly intimate knowledge of the implementation, whereas Python pretty much gives this away for free.
* A considerable deal of modern CS/CompEng research is centered around studying non-fundamental applications. It's important to have access to tools that allow people to whip up quick experiments. Whether Python does this better than Scheme is debatable, but Python does arguably score better in terms of integration and, therefore, in terms of being able to glue new fundamental discoveries to practical problems that they solve. Perl does that too, arguably better than Python, actually, but there are lines even seasoned teachers would rather not cross.
* Many of the so-called real problems come from more specific fields, are sloppier and can often be less rigorously stated than those for which SICP was initially written. Again, this is debatable, but Python is more universal and easier to convey. I don't know how much truth is behind this. I tend to disagree, because personal experience has shown me that this is the argument preferred by the kind of people who think that cool 3D data visualisation programs are a good example of a real-life problem and rotation matrices are a typical example of a useless problem that doesn't stem from real life applications.
This is why web development is so dull to me. You're always coloring by number.
A few years ago, MIT restructured their entire CS curriculum (not just the intro class) in a way that required redesigning the individual curricula of each of the classes, including the intro class. As a result, they couldn't use SICP, since it didn't cover the same topics. At this time, they ended up switching to using Python for the class.
This is sometimes presented by people who dislike functional programming as an indictment of Scheme/Lisp, though this is very misleading. Nobody made the decision to "abandon" SICP - "they" made the decision to redesign the entire curriculum (top to bottom), which meant writing new syllabi/textbooks for all/most of their classes, especially the intro class, and then "they" made the decision to write the new syllabus/book for that new intro class in Python[0].
Some schools (University of Minnesota is one) still use SICP.
Personally, I think that SICP is the best way to be introduced to both the fundamentals of computer science and programming. The only caveat is that it requires a certain level of dedication before-the-fact (something that could be reasonably assumed in an MIT intro class). So it's not the best choice for someone who "just wants to dabble" in programming and see if they like it (try Python or Ruby for that), or for someone who wants to understand computer architecture and engineering (try C for that), but for everyone else, it's unparalleled.
The nice thing about SICP is that it focuses very little on learning the nitty-gritties of Scheme (partly because there's so little to learn!), whereas most other introductory materials I've seen have to focus on Java-specific, Python-specfic, etc. features. Reading SICP feels more like reading a math textbook that "just happens" to come with a REPL for mathematical expressions, as opposed to learning the ins and outs of a given programming language or environment.
[0] Of course, "they" refers to many different people, very few of whom would be in the same "they" as it was in the 1980s when SICP was first written, so one has to keep that in mind before concluding that MIT "changed their mind".
MIT's EECS undergraduate enrollment cratered after the "dot.com" crash, more than halved, after being 40% of the student body for decades.
The department panicked.
And it was most certainly ordered that Scheme be entirely purged from the base curriculum, even while they claimed they were teaching SICP concepts and functional programming in 6.005, they were using Java, a language that's "not even wrong" for the purpose (that, at least, has been improved to Python, which is only [fill in the blank] hostile to FP).
Not one of the department's finer moments, from my no direct interest in EE at all viewpoint, but from a less biased one you can safely say a MIT EECS degree now means something quite different. And it's a damned shame for those outside the department, for whom 6.001 was truly valuable, that MIT no longer offers anything in its niche (outside of a rearguard 1 month version of it during January).
I really do recommend it for anyone trying to get into functional programming or to understand the nirvana of Lisp / Scheme.
[1]: http://racket-lang.org/ [2]: http://htdp.org/
IMO nobody [3] considered it programming. I was a geek and thought it was pure vapor [4], programming needed to be cpp with graphics or GUI or memory cells. I don't know what other people thought about it but I'd bet they forgot about it the minute they left the class. I mean pairs and cons cells ? what can you do with that ? ... beside map/fold/compose/curry. But that would need to talk about closures... can 20yo handle hot thangs like these ?
----
[1] in my days, first 2 years were 80% math/phys 20% programming
[2] casual introductory modules, at that point students don't know if they go pure science CS or IT.
[3] except the wearing IOCCC tshirts teacher
[4] infinite idiocy of my young self
Student's inability to understand this is their own failure and ignorance.
As to the topic at hand, in JS, those ideas of higher-order functions which don't exist in C (to any meaningful extent) are the primary means of abstraction. I've seen very many C++ or Java programmers think they can handle JS just fine. It's never too long before those functional concepts they considered useless (or even worse, were never taught) begin to haunt them.
[1] growing with computer as a user, what amaze you is what you can perceive : gui, games, external devices. Which are all designed to amaze. When you get to know how computers are made, your first desire is to reproduce these things. Abstraction, expressiveness aren't on your map yet.
Not only that, there are multiple levels of abstraction to fully grasp everything.
For some people thinking in the abstract way of computing is already too much.
Then those think they have mastered the basic concepts of computer abstractions like loops, decisions, data structures, there is the next level of meta-abstractions.
Meta-abstractions used to manipulate the said abstractions to fully mold the whole computer system like clay. The same way mathematical abstractions reason about the common man mathematics.
Very few are able to move between abstraction levels, and those that do forget how it was their view of the world before they fully grasped it.
I believe that first the algol genealogy suffers from the ~difficulty of crossing metalevels, secondly, the people behind these languages were able to do so and see the language as a vehicle, a mean, not an end. But beginners see the finger, not the moon and end up thinking in terms of builtin constructs. Lisp being already unrelated to any machine, and with the serendipity of sexp easy homoiconicity you see swim in this universe of abstraction levels.
> Very few are able to move between abstraction levels, and those that do forget how it was their view of the world before they fully grasped it.
I enrolled Coursera MOOC teaching scheme and sml, watching many students being emotional (anger, despair) about interpretation (especially when circular) reminded me of myself in college. The worst part is that the best I could say was "keep trying, you will understand". I wanted to tell them about the beauty and the freedom you feel but our minds were too separate and my understanding not good enough yet.
And nowadays they cannot runaway as functional programming concepts begin to infect their languages as well.
They are left with:
- stay in the past, hoping to retire before being forced into newer versions of their languages
- learn and embrace FP and get to discover how OOP and FP can work together
- try to jump to other languages that are still friendly to old school developers
The PLT Group's homepage: http://www.ccs.neu.edu/racket/
Full lecture series based on the first edition of SICP. I viewed and read after nearly 10 years programming in more mainstream languages (self-taught), and honestly think that 10 years was partly wasted because I didn't learn Scheme earlier.
Lately it seems like more people are doing compile to JS (like asm.js and Mozilla's emscripten work in Odin Monkey [2]) which fits in perfectly with LISP dialects. Programmers can still create their own DSLs, macros, compilers, etc. in LISP and use them for modern web apps today. Just because this is a less popular/documented route doesn't mean it isn't possible. I hope we'll see a rise in LISP web programming pretty soon.
It would be fun if someone could write a compiler for a new ClojureScript dialect that targets asm.js and takes advantage of CPS for recursion like Scheme does.
[1] https://github.com/jashkenas/coffee-script/wiki/List-of-lang...
[2] https://wiki.mozilla.org/Javascript:SpiderMonkey:OdinMonkey