Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Wednesday, May 30, 2012

Facebook Doesn't Have Shoppers

Facebook claims that it's worth billions because of all the money it might make selling advertising, but that plan is going to fail for one simple reason: Facebook doesn't know that much about its users' shopping habits because Facebook Doesn't Have Shoppers.

What does Facebook know? It knows my birthday. It knows my friends? It knows my interests if I took the time to tell it my favorite movies and whatnot--which probably means I already own that stuff if I want it.

What it doesn't know is my shopping habits or future shopping needs. For that matter, I barely know this stuff.

Compare Facebook to Google--the big name in Internet Advertising. When I need to buy something, I google for it. At that moment, I am telling Google what I want. That's why Google is so effective at advertising. It doesn't have to guess what I need. It doesn't have to play fortuneteller; Google only has to respond to my explicit pleas for shopping help. Facebook doesn't have this luxury; it doesn't know me as a shopper.

Compare Facebook to Amazon--the big name in Internet Retail. Amazon has a record of my shopping history. It knows what I've bought. It knows what I've looked at while shopping. It knows what I've stored in my wishlist for later shopping. It knows what I'm interested in because I've helped improve its shopping recommendations for me. Facebook doesn't have this luxury; it doesn't know me as a shopper.

What Facebook has is a bunch of data that is mostly personal and mostly crap. That's nice for putting me in contact with people from fourth grade I've totally forgotten about, but it doesn't count for much in helping me find my next purchase. It doesn't help me shop! To help me shop, Facebook must predict what I need. But how can it? It doesn't have the data you need to make those kinds of predictions because Facebook has never watched me shop!

This is why Facebook is going to fail. I buy electronics online, but Facebook doesn't know that, and even if it did, it doesn't actually know what I bought, which is crucial. I buy books and music online, but Facebook doesn't know that, and again, even if it did, it still wouldn't know what I bought. I buy toys and games online, but Facebook doesn't know that with all the problems this entails. I buy junk off of Ebay, but Facebook doesn't know that either. Google does because it helps me find all this stuff in the first place. Amazon does because it's usually where Google lands me. But Facebook doesn't have a clue.

Facebook's advertising isn't worth much. True, the website has a billion users, but it doesn't know those users' shopping habits or needs, and without that data, it cannot--in my opinion--compete with Amazon or Google. In other words, Facebook is just the latest incarnation of Geocities and Myspace: a website but not a business.

Finally, take a moment to reflect on who uses Facebook now. Who are those 1 billion strong? Why, it's none other than today's parents. Think about that... When our kids get old enough to become full citizens of the Internet--and that won't be long, just a few more years--those newly minted teens won't want to join mom and dad's website. That's uncool. They won't want their actions popping up for their parents to review. They will want their own place to hang out: someplace safe from prying parental eyes. That's not wrong; it's normal; it's unavoidable; and it's the measure of Facebook's life expectancy.

Thursday, March 22, 2012

The Failure of Programmable Programming Languages

There is this myth out there that the wave of the future is a programming language that can modify itself. This sounds odd at first, until you realize how cool that would be.  It means you could add any feature to your programming language that you need.  Right there.  Without waiting for the language designer to get around to it.

In theory...

In practice, the main languages people hold up as being capable of doing this--Lisp, Smalltalk, and Forth--seem to have totally failed.  I run both Windows and Linux and I can't think of a single application for either operating system that uses anyone of those three languages.

Let me say that again, so far as I can tell, neither Lisp (in any of its flavors: Common Lisp, Scheme, or Logo), nor Smalltalk, nor Forth are in production in any meaningful way at any level on any personal computer.

I kind of wish it weren't so because I love these languages, in theory, but in practice they always fall down.

That is about as damning as it gets.

Go ahead. Prove me wrong.

Friday, January 20, 2012

Is C++ the Language of the Future?

I've spent the last five years studying a wide array of different programming languages and paradigms and here are the big trends that I think will matter most in the near future.

Trend #1: Processors Are Getting More Numerous But Not Faster
Anybody who witnessed the quantum leap in software since the Apple II knows how much things have improved over the past 30 years since personal computers were first released. Just take a look at these Wikipedia screenshots of flight simulator's evolution:
Flight Simulator 1 for Apple II (1980)
Flight Simulator X (2006)

Notice anything? Yeah. Me too! And Microsoft is planning a new version to be released in 2012 that looks even better.

It goes without saying that these improvements required years of programming expertise, but they also relied on explosions in processor speeds as well. Every 18-24 months, processor speeds would double and open up whole new possibilities that developers could--and did--take advantage of for their next release. This much is obvious.

What isn't so obvious is that this doubling in speed always happened on a single processor. This is incredibly important. It meant that programmers could just steadily refine their already existing programs without having to rewrite it from scratch and without having to learn a new style of programming or new programming language. If it ran now, programmers could just assume that in 18-24 months, it would run twice as fast without requiring any changes. This is the free lunch.

As Herb Sutter writes in his must-read article, The Free Lunch is Over. Individual processors have pretty much reached their top speeds. And how has Intel responded? Well, if you can't make one chip faster, just give them more than one processor instead. This is called distributed computing. Enter the dual, quad, and multicore processor computers. But there's a catch. You can no longer run your old program on a multicore and have it transparently run faster. That old program was written for a single processor in a language and programming paradigm geared for a single processor.

Distributed computing is a game changer. It means that for the first time in the history of personal computing, programmers are going to be required to write programs that spread the problem across multiple processors. That is going to require new programming paradigms and programming languages (or at least updates to current languages). To see why, go check out this video: Software for a Concurrent World.

Whatever language you choose, it seems to me that having a language designed to take advantage of multiple cores is going to be a crucial requirement for the future; otherwise, you will be stuck with a program that cannot use the full capacity of your machine. Who wants that?

At the same time, languages that can deliver code that runs quickly on individual processors will continue to be important. Some problems are inherently linear: they cannot be effectively distributed. The only way to make these applications fast is to solve them in languages that produce fast code.

Not many languages meet these dual requirements.

Trend #2: Mobile Computing Rewards Energy Efficiency
It seems like you hear a lot of advocates for various scripting languages like python, perl, and ruby say that efficient execution is no longer that big a deal. So what, they argue, if you use more memory and require more execution than languages like C++ that compile down to machine code. Computers these days are so fast and have so much memory that worrying about efficiency is a waste of time.

However, they are forgetting one important fact: computers have gone mobile. Forget laptops. I'm talking about tablet pc's and smartphones: devices that run almost exclusively off batteries. 

Every computation eats up battery life. This means that efficiency equals longer periods between charging your phone. That matters. Even if the execution speed feels the same to the user between a program written in Ruby and the same program written in Objective-C, the ruby program is probably going to use more juice, and that will get noticed. 

Differences in battery life already drives sales. As more people go mobile, battery life is increasingly going to matter, which means we are back to the good old days where languages that delivery stand-alone, executable, highly efficient programs are going to deliver higher sales. And since broadcast power remains science fiction, it looks like this bottleneck is never going away.

Trend #3: Mobile Bandwidth Is Never Enough 
There was this small innovation a few years back called the Internet. You may have heard of it. It has made many forms of communication possible; however, it has also imposed a powerful bottleneck in the form of how much you can download at a time. This isn't that a big a deal when you're at home, but I'm not worried about that. Once again, I'm thinking about mobile computing across 3G networks.

I own a smartphone. I subscribe to Verizon's network. Most days, it is only a little painful for surfing the web, which means that it is almost sufficient for most mobile devices now. But I'm looking forward here to a point where people use improved tablet pc's for more than surfing the web. My Ipad isn't quite good enough yet for managing spreadsheets or writing reports, much less a novel, but that day is coming. 

I remember a time when desktop computers were standard and laptops were weak replacements that couldn't really do much. That wasn't too long ago. Now, laptops are the standard work machine for most people I know and tablet pc's are the weak platform. Pretty soon, people will want to download more than just websites to them. Actually, they already do. And what are those programs written in: Objective-C. There will be more tablets in the future, a lot of them, and people won't have the bandwidth or patience for huge programs that take forever to download, or pain-in-the-ass programs that require a ton of dependencies to be downloaded just to make them run. Few things are more frustrating than downloading a program only to find that you also have to to download some new version of Java or the correct version of Python or some other run-time environment just to get the damn thing to run. A stand-alone binary  (.exe program) is faster and simpler any day of the week.

I should mention that tons of programmers are trying to side-step this problem by developing in HTML, CSS, and Javascript on the front end while pushing the record keeping and deep functionality to the server on the back end using PHP attached to a database programmed with SQL. Take a look at what you have to know to make that work. How many programming languages is that you have know? Four? Five? In theory, that's possible. In practice, managing all this crap quickly becomes very difficult. 

Consider the level of talent it apparently takes just to keep Gmail or Facebook online. Then take an honest look at how static these websites are compared to most of the programs sitting on your computer. The word processor in Google Docs still feels like a toy, and that's basically just a box that accepts text! We won't even discuss what most web-based spreadsheets are like. If this is the best that Google can do, what are we likely to see from everyone else.

Trend #4: We Are Drowning In Platforms
Not too long ago, you could buy a computer program secure in the knowledge that it would run on your computer, provided your machine was new enough. The world was Windows. Sure, there were other operating systems, but only fanatics owned them. Apple! Give me a break. Only artists bought Apple machines in the 90's. Linux. Don't make me laugh. Nobody except comp-sci majors ran Linux on their machines. For that matter, nobody except computer scientists had even heard of Linux back then. I'll say it again, the world was Windows.

In many ways, it's still a Microsoft universe, but you can't bet on that anymore. Developers must cater to Apple products, to Linux on android smartphones, and Windows. In that way, it feels much like the 80's again where you have to choose which platform to join.

This leaves developers of desktop applications with two possible choices: (1) put all their eggs in one basket and hope that platform will endure or (2) try to develop across all platforms and hope the added complexity doesn't kill you. 

Option 1 is scary anymore. Windows still looks strong but more and more, I see people who ten years ago would have scoffed at the idea of buying anything but Windows proudly switching to Apple. Let me say that again: proudly switching to Apple. At the same time, droids seem to be falling out of the sky. I see more droids than Iphones. The tablet PC is coming in a big way. When it gets here, people who never intended to run Linux are going to run it by default since that's what will be on their machine. Of course, Linux is already on lots of the servers that business are running. It also provides a nice way to breathe new life into old machines for people who don't feel like buying a new computer just to get the newest eye candy. Remember, we are talking about tablet PC's that are actually productive, as in, businesses will begin issuing them to employees the way they issue PC's now.

For the first time in a long time, Option 2 is starting to make some sense. As such, programming languages that ease cross-platform development are going to become increasingly valuable. So, what languages are used for serious development now. 
  • Windows: the main language seems to be C#. The runner-up is C++.
  • Apple: the main language is Objective-C. The runner-up is C++.
  • Linux: the main language is C. The runner-up is C++.
  • Android: the main language is Java. The runner-up is C or C++.
(Note: I define "serious development" as rock solid, enterprise quality software)

There are of course other languages that get used for lesser projects. Python, perl, and ruby come up a lot for scripting purposes. I suppose Visual Basic is still used too, though that seems to have fallen off the radar compared to the 90's. Lua is hot for game scripting, PHP for server programming, Javascript for browser development, and Java for business applications--the kind of stuff that used to be done in COBOL, but I'm interested in person computer productivity.

None of this is without exception; however, for getting real work done--for projects where performance is an issue--the bulleted list above is pretty definitive. Does it suggest anything to you? It does to me. No language is number 1 across the board, but there is a language that is arguably number 2 platform to platform.

CONCLUSION
The trends of this essay suggest that the ideal programming language of the near future is going to have the following characteristics:
  1. Good for distributed computing
  2. Good at producing fast code for when distributed computing isn't  possible
  3. Good at producing efficient code for saving on battery life
  4. Good at producing small, stand-alone code for saving on bandwidth
  5. Good at producing cross-platform code
So who are the contenders?

Haskell--a functional programming language--comes to mind, but programming in Haskell is just too different. I don't know of a single business program or game in mainstream usage designed in Haskell. While we're at it, let's just go ahead and lump Scheme, Forth, and Common Lisp into this category as well.

Google has released Go--a procedural programming language which received some buzz when it was first released. Its developers designed it for the multicore world so that's a big plus. On the other hand, it's brand new and lacks objects. In an object oriented world, that seems like a strange and significant omission for a non-functional programming language.

Java has a good chance too, but Java seems to be settling into the role of 21st century COBOL. It is the main language for the android operating system. That will really matter--especially at first--as non-Apple tablets come online, but that "non-Apple" qualifier is the 800 pound gorilla.

Ada presents an intriguing possibility. Ada is a really powerful language that would meet all these requirements brilliantly. Designed by committee for government usage and descended from Pascal--an educational language--Ada's problem is that it was never cool. But it deserves to be considered in here.

Looking over the list, I can't honestly see a language more competitive than C++. It isn't famous for being easy or small, but it possesses many of the qualities that I think programmers are going to need in the future. It's battle tested, proven, and everywhere.

Strange. When I began this essay, I never expected to wind up here. I just wanted to work out what I thought the big trends of the future would be and which language(s) I thought would meet them. It's weird how things work out.

I guess it's time to give this post a title and publish it.

Monday, November 7, 2011

Conventional Syntax is Critical in Programming


Languages, as everyone knows, come with rules that govern when and where you can say something. Programming languages are no different. The term for such rules is syntax.

Now what amazes me is the diversity of syntax that exists among computer languages and how amazingly baroque so many of them appear.

For example, Lisp uses something called polish notation that--in English speak--puts the verb first and wraps the whole things in parens. Here's an example from Scheme, a dialect of Lisp, that displays the sum of two numbers:
(display (+ 20 30))
See what happened? I summed 20 and 30 and then printed them to the screen with the display function.

Let's compare that to reverse polish notation, which turns it all around. Here's an example from the programming language Forth that once again sums 20 and 30 and then prints them to the screen.
20 30 + . 
Boom! How does that look? Here's what happened. Forth uses a stack to store most variables and words (forth calls functions "words"). So let's trace out what I did. First, I put 20 on the stack. Then 30. Then the + word. The + word sums 20 and 30 as plus always does. Finally I put the . word on the stack which outputs the contents of whatever is on the stack.

If you want to see a larger example of Forth, read Dadgum's blog on What It's Like to Program Forth.

Here's the example in Python:
print 20 + 30
Notice anything? I do. The Lisp and Forth examples require explanation. They look tricky. They are Puzzle Languages.

In contrast, the Python code is pretty straightforward. It tracks the way most of us in the West have been reading, writing, and speaking all our lives. This is important.

Programming languages are tools. They should make problem solving easier. When they don't, they need to be replaced by tools that do. I'm going give such replacements a name: better tools.

I know that's going to be hard for some programmers to accept, but it's true. Here's why: Programming languages that track the syntax of spoken languages enable programmers to leverage their human language experience. This almost certainly accelerates comprehension when reading code and decreases the time needed to learn a given language.

Python has really been climbing the popularity charts over the past decade, and I would argue a large part of its success as a programming language is due to how simple it is to learn and remember.

And don't ignore that "remember" bit. It's in bold for a reason. Just learning a language isn't enough; you also must remember the language when you need it. Ten years ago, Perl was the language everybody used for scripting, but not anymore. Perl's syntax is tricky and hard to remember, which is probably why other languages like Python, Ruby, and PHP have been stealing away so many programmers who would likely have counted themselves as Perl programmers back around 2000. For that matter, many of them were Perl programmers back then. But not anymore.

I'm arguing that straightforward syntax is one of the most important features a programming language can have and that lacking such syntax can result in the language declining in popularity or never really getting adopted at all.

This is actually coming up in my own experience. One of my favorite languages right now is Erlang. It's pretty fast, really powerful, and has a ton of features that make programming easy. But it's syntax is a mess. Just a mess. (Pop quiz: what's the lesser-than term look like in Erlang?) That worries me. It's a problem. It means that given a choice between Erlang or another language with more conventional syntax, Erlang might fail to gain mind share--even if it's technically superior--and that's the death sentence for programming languages. Not right away of course. Languages don't die suddenly. It's more like a creeping death where new programmers don't bother to learn the language and old programmers slowly migrate away.

But it's death all the same.

Programming Languages are for Humans

Take a look at the title of this post: Programming Languages are for Humans.

That ought to be obvious, but you still find people arguing all the time that it's the job of the programmer to mould themselves to the machine rather than the other way around. Of course, they don't mean to do this--often they don't even realize that's what they're saying. After all, few people deliberately search for obstacles to place in their own way, but that doesn't change the fact that people--and especially program language designers--still accidentally do it all the time. So, here's the question: How do you know when a programming language is preferencing the machine over the programmer?

Answer: Anytime a programming tutorial tries to justify a feature because of the machine's needs, it's probably a mistake. The best example of this kind of mis-feature is zero based indexing.

For those new to programming, picture an array of five objects: [1,2,3,4,5].  Now, let's assign that array a name:
array = [1,2,3,4,5]
Ok, so far so good. Now, let's pull out the third item from that array. How do we do it? Well, if you didn't know anything about how most programming languages work, you might guess something like this:
print array[3]
But that's actually wrong for arrays with zero based indexes because what that means is that you start counting at ZERO instead of one. So, the code above (print array[3]) would actually print the FOURTH item in the array, not the third. Which means that every time you want the third item, you have to actually ask for the second one instead like so:
print array[2] 
Let me say that again, To get the third item in the list, you have to ask for the second.

If you are new to programming, this looks like sheer lunacy. And most of the time it is. Zero based indexing is horribly unintuitive. Human beings just don't count this way. Now, it may still offer some advantages if you are worried about every byte being produced by your compiler. So, if you program in Assembly, C, or C++, then I exempt you from this essay. But that's it. Everyone else should start counting items at one. So who am I talking to?

If your programming language runs in an interpreter or virtual machine then I'm talking to you. If your programming language claims to abstract away pointers and manual memory management for the sake of increased productivity then I'm talking to you. If your programming language doesn't have pointers at all, then I'm definitely talking to you.

In other words, if you program in Python, Perl, Awk, PHP, Ruby, or Javascript then I'm talking to you.

Now, some languages already index their arrays at one. Here's a few: Cobol, Fortran, Pascal, Ada, Lua, Matlab, Smalltalk, Erlang.

Notice anything? These are warhorses: industrial strength programming languages designed so that non-expert programmers could solve industrial strength problems. That's amazing. That's putting the human first.

Those languages might not be as fashionable as Python or Ruby, but so what? They work. And what's more, they eliminate a whole area of confusion and potential bugs simply by playing to the programmers intuition.

This should be the battle cry of every programmer. We should constantly challenge every feature in programming languages to make sure they always play to the human's strengths--not the machine's. We should be embarrassed every time a language tutorial has to explain a certain feature as being necessary because that's how the computer thinks.

What? If this is just about how computers think, then let's just stick to Assembly. Otherwise, let's admit that we don't think like computers and build our tools for ourselves instead, and every time someone says something to the contrary, just ask who they think the programming language is for.

Their answer might be illuminating.

Friday, November 4, 2011

Arbitrary Precision Everywhere

Math should just do "the right thing" when programming.

Once upon a time, computers were slow and desperately short on RAM, and programmers were forced to cut corners everywhere they could just to get their programs to run. It made sense to specify, down to the byte, how much memory to set aside for every variable. That micromanagement really got you something. These constraints still apply in the world of embedded programming or for building really foundational programs like operating systems and the like, but for everything else, modern computers are awash in clock cycles and RAM.

So why do I still see programming languages that can't do arbitrary precision math?

Futzing with ints and doubles today is just premature optimization. It just increases the program's complexity and makes it more likely to crash. To be fair, more and more languages are baking in arbitrary precision arithmetic, but I still see a lot of languages that really ought to have it but don't. (Perl I'm looking at you!) Unless the language in question is designed to compete with C or act primarily as an embedded language like Lua, there is no reason for it to come with limited arithmetic facilities.

Arbitrary precision math should also be transparent. Don't make me go looking for a bignum module or a special set of math functions. Design your language so that math just does the right thing. The default should be arbitrary precision; the special library should be ints and doubles.

Given how much RAM we already have, running out of memory is hard to do and getting harder every day. Ten years from now, when we're all sitting on hundreds of gigabytes (if not terabytes) of RAM, exceeding the computer's capacity will be quite an accomplishment.

For that matter, it already is.

Here's an experiment for you Linux users. Type the following at your command line:
time python -c 'print 2 ** 100000'
For those who don't know python, this program computes 2 to the 100,000th power and then prints it to your command line. Here's the output (minus printing the digits):
real 0m0.768s
user 0m0.736s
sys 0m0.004s
Look at those numbers. This program runs in less than a second. That's over 30,000 digits in less than a second! Let's see what happens when you cut out the print statement:
real 0m0.031s
user 0m0.024s
sys 0m0.004s
Wow! Just wow!

So let's run through this again. Computers are lightning fast and stuffed full of RAM. You don't have to justify arbitrary precision anymore; you have to justify its absence.

Thursday, November 3, 2011

Seven Plus Or Minus Lisp

Have you ever heard of that psychological study that claims the working memory of your average human is seven things, plus or minus two? What this means is that most people can remember, on average, seven "chunks" of information.

So what does this have to do with Lisp?

Many programming languages can be read (and thus programmed) in a very orderly fashion: top down and left to right.

Lisp programs don't seem to follow this convention. Instead, you sometimes finding yourself reading right to left (because of returning function values) as well as left to right, and also bottom-up (again, function returns) instead of just top-down. Lisp programs feel a lot more interconnected to me than many other languages. I always find myself looking for breakpoints where I know the state of the program and can take a breather. Lisp doesn't give you many of these.

Tracing through a Lisp program feels like following an M.C. Escher picture. Things go everywhere and loop back again inexplicably, which is tough when your goal is to understand it.

Making matters worst, the Lisp culture appears perfectly content with this complex style of coding. You don't really notice this until you examine other programming cultures, such as Forth, which have the same potential for abuse, but try to avoid it by explicitly encouraging a very concise style of programming. Forth programmers shoot for only 2-3 lines of code per function (word in Forth speak). I don't see this same cultural value is Lisp where verbose, multi-stage functions appear perfectly normal.

Which brings us back to that working memory limit I mentioned earlier. All this complexity increases the amount of program state that programmers must keep in working memory in order to understand their programs. Think about that!

I bet that if you tested many of the programmers who promote Lisp, you would probably find that they have excellent memories or have discovered some memory scheme for conceptualizing their programs. Maybe they've just learned to ignore the parts of a function they aren't working on. I don't know. I do read comments by other programmers which mention that memory is a key feature they look for in other programmers.

Here's this blogs thesis: Requiring programmers to keep track of more than five or six non-linear details at the same time will render a programming language more difficult than its competitors and lead to reduced usage.

Programming languages should be designed with this limit in mind and programming cultures should consciously promote it.

Lisp Needs A Domain of Its Own


Go anywhere on the web that discusses programming and after a while someone will claim that Lisp is the ultimate programming language. Almost immediately others will likewise pile on to support this claim with statements that Lisp is the ultimate--the Alpha and Omega--the One True Programming Language. Famous programmers are usually named who program only in Lisp followed by famous books on programming that use Lisp to illustrate their programs.

The thesis for most of these arguments is this: Lisp is the ultimate programming language because it is a programmable programming language. By "programmable programming language" they mean that you can actually program Lisp in Lisp.  

In most languages, if the language doesn't have a particular feature you need, you have only three options: 
  1. Beg the developers to add the feature you want
  2. Figure out a way to do without
  3. Go find some other language that solves your problem
Lisp adds a fourth option. It lets you add the feature yourself. This sounds cool. It sounds like you need never learn another language again. You just add it to Lisp and keep on trucking. This makes it the ultimate general purpose programming language. It can be anything!

So great. We've done it. We have found The One True Programming Language.

There's just one little wrinkle: Lisp is basically nowhere.

So far as I can tell, I don't use a single program written in this ultimate programming language.  

None of the office programs I use every day are programmed in Lisp. Nor are the web browsers that make up the rest of my computing experience. None of the major operating systems are written in Lisp. Not Windows. Not Mac. Not Linux. None of the most popular servers than run most of the internet are written in Lisp. Nor are the databases that store those websites' information. Do any smart phones run Lisp? My Android doesn't. Nor does my Apple Ipad or my Ipod or any other Apple devices as far as I know. None of them are written in Lisp. Not one.

For the ultimate programming language, that's not a very good showing.

Programming languages are designed to solve specific problems. Assembly provides better mnemonics than raw machine code. Fortran is more human readable than assembly. C is more human readable than assembly and more portable than assembly too. Awk has more tools for text processing than raw C. Perl has more tools for text processing than raw Awk. Python has more tools and is (arguably) cleaner than all of them. Erlang can be made more fault tolerant than other languages. Javascript is more ubiquitous for client-side web programming than other languages. Lua is easier to embed in C programs for scripting purposes than other languages. PHP is more ubiquitous (and maybe has more tools) for server-side web programming than other languages. Etc...

Obviously you can argue these points, but the designers of these languages would largely support what I just said as primary rationales for why they designed these languages in the first place.

So what again was Lisp's advantage? What problem does it specially solve?

Oh yeah: Lisp has more tools for programming Lisp than other languages.  

Hmmmm...  Is that a problem that needs solving? I don't think so, and I think this answers the question of why we don't see Lisp actually being used very often: it doesn't provide an advantage for solving the problems programmers need solved. To use Lisp as its acolytes direct: you first need to reprogram Lisp into a domain specific language targeted at a particular problem. But as the list above suggests, others have already been working in those domains and have already gone a long way towards building special tools for them.

What this means is that vanilla Lisp isn't good enough. Nor is merely--and that's a big merely--reprogramming Lisp for a certain problem space good enough. It isn't enough to make Lisp just as good as Perl for text processing. You have to make it better.  You have to reprogram Lisp into a domain specific language that is better than what others have already built.

THAT. IS. A. TALL. ORDER.

Here is my thesis: The Cambrian explosion of domain specific programming languages is a better solution to most problems than a general purpose Lisp.

I wrote this essay to find out what I thought Lisp's future is going to be.  People still argue--and quite convincingly--that Lisp is The Next Big Thing coming down the pipe, but I'm going to respectfully disagree unless we see a new generation of Lisp Machines emerge with parentheses going all the way down.

Because then Lisp will finally have a domain of its own.

(Note: For the purpose of this article I'm lumping Scheme, Common Lisp, Dr. Racket, and other Lisp like dialects together)