Social Problems Of Lisp

See WhyWeHateLisp (problem), XpInCommonLisp (ultimate solution).


It is often suggested that one of the SocialProblemsOfLisp is that LispUsersAreArrogant.

No, they're just perceived as arrogant by lesser beings.

("Lesser beings" being those who bathe regularly.)

The authors of these last two comments have disqualified themselves from criticism regarding social problems. Do they consider this an acceptable way to behave? Is this how they would behave in a face-to-face situation? It is truly appalling and taints both the Lisp community and its detractors.

No, it serves the practical purpose of providing clear evidence that Lisp is associated with social problems :-)

The exchange above was also a great example of the dry ironies the real world manifests, thus serving the true PrimeDirective: making me chuckle. --CraigEverett?


SocialProblemsOfLisp are a pet topic of LispHaters?.


Like many things in Lisp, the SocialProblemsOfLisp is recursive. People mostly complain about the SocialProblemsOfLisp because they hear other people complain about the SocialProblemsOfLisp.

Many of us have run into various SocialProblemsOfLisp head-on. The likely source of unfairness is that other languages have boorish twits advocating them as well; but the SmugJavaWeenies seem to be a much smaller subset of the Java community. I can't really agree with that from reading Slashdot, talking to fellow programmers, or even the news I hear from Java conferences.

ANY subset of the Java community is likely to be larger than the Lisp community in its entirety.

In all seriousness, I think the SocialProblemsOfLisp originate mostly on the other (non-Lisp) side of the fence.

Where they "originate" is hard to pinpoint - but it should be obvious that the whole topic arises as a result of interactions between the Lisp community and the non-Lisp community.

I've been reading Ellen Rose's User Error: Resisting Computer Culture (ISBN 1896357792 ), and besides being a razor-sharp culmination of criticisms of modern computer culture (I recommend it to anyone who makes software, free or not), it largely confirms the irrational basis of much of the criticism leveled against Lisp, Emacs, and user-programmable systems in general. It all comes down to a pathological struggle of developer vs. user control, with a good dash of conservative white geek thrown in. Incidentally, it also nicely explains the complex world of Free Software politics and business adoption (even though the book makes no mention at all of free or open source software). - Vladimir Sedach

Developer vs user control? "Conservative white geek"? Any supposedly-scientific treatise that depends on words (or concepts) like that definitely smells bad to me. I'm sorry, but where did you see the quotes around my statement? It's a conclusion I drew partly from the book, but mostly from my own experience. Please attack my thesis and not my sources. At any rate, while "control" may be part of the equation, it certainly doesn't explain everything. Numerous other programming communities use/advocate "free-form" programming languages, but don't have the bad reputation that the Lisp community, er, enjoys. Python is a notable example; the Python community is refreshingly free of zealotry. The Python community is also refreshingly free of history. It can honestly be said to have begun forming only 8 or so years ago. Pathologies (and reputations) take time to develop, even today.

When you see how the absolute worst LispStrawMen are thrown about on the c2 wiki, ones that even the SlashDot community has high enough standards not to repeat, you have to ask what's going on. WhyWeHateLisp and SocialProblemsOfLisp are full of simple, verifiable lies.

There's a little fictional dialogue below that's supposed to be between lispers, and when someone pointed out it made no sense, the author replied, "The story is just intended as an illustration; it's not a direct quotation." A made up story. Just like the criticism on WhyWeHateLisp that lispers refuse to "learn from other communities," because lisp doesn't have a for loop - BS, lisp has something that's kind of like all for loops in all languages rolled into one.

Anyone who has ever visited Slashdot knows that the troll community is a tiny percentage with a lot of time on their hands. They love focussing on the "human side" because it's the easiest to make up stories about, and the hardest to disprove.

Visit usenet and tell us who's a bad meanie, and we'll discuss it rationally. Pick out something real. In case someone sends a troll, I'm posting this on Sept. 8, 2004, probably a couple hours before midnight GMT. http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&group=comp.lang.lisp


Perhaps the social problems of lisp are noticeable simply because it has so few technical problems?

[Now there is a well-reasoned response. You sure showed us why the above question couldn't be true.]

That's because most of the SmugVisualBasicWeenies? are managers, whether they know it or not ('it' refers to the former - of course they know they're managers!). Market share and availability of programmer monkeys are things that are worth being smug about. No-one I know got fired for buying IBM or Microsoft. -- Vladimir Sedach


One problem is a very anti-newbie attitude. It's not so much that SmugLispWeenies don't try to encourage newcomers to get involved with Lisp - it's that they cannot agree with each other for five seconds on (loop) vs (do), CommonLisp vs SchemeLanguage, whether metamacros are horrible style or occasionally justifiable,... they fight over everything except indenting style, since the language makes that one a null issue. So when somebody comes to a group of two or more SLWs asking for advice, it goes something like this:

Just to be clear since this has confused some people: The following is a dramatization; not a transcript of any actual conversation that occurred. Take the following with a grain of salt.

Newbie: Hi. I've been using Lisp for about half a year now, programming for three years. I discovered this group and wondered if you could help me out with a problem I'm having?

Smug: Hi! Always glad to have new blood. Sure thing, just ask.

Snide: Heya New! You bet, ask anything and we'll try to help.

Newbie: Okay, I'm trying to filter a list, something like Perl's grep. I want to set up a predicate and have the new list be only those elements from the old list that satisfy it. I know there's some standard idiom for doing this, I just can't find it anywhere...

Smug: Perl's grep was inspired by Lisp's higher-order functions, you know. :)

Newbie: Oh, cool. :)

Smug: But it's inferior since it has balky syntax.

Snide: You can do it with (mapcan (lambda (item) (when (predicate item) (list item))) list).

Newbie: Sounds good, where can I look up how to use mapcan?

Smug: You could do it that way, if you were brain-damaged and didn't care about readability. It would be better to write the macro (collecting) and then do (collecting (mapc (lambda (item) (when (predicate item) (collect item))) list)

Snide: Collecting is for wimps.

Snoozer: Newbie, you're trying to use (collecting)? That's a mistake, it's non-standard. Yes it is portable, but it's hard to read because new people don't know it.

Newbie: What does (collecting) do?

Snoozer: If you don't know, why are you trying to use it?

Snide: You know, I had to do something like this last month, for my commercial Lisp program which I was paid to do. I did it with (mapcan).

Smug: Well I guess some of us just aren't that lucky then.

Newbie: And can anyone tell me please, where do I look up documentation for how to use (mapcan) or (collecting) or whatever it is?

Snoozer: You're a lamer, Newbie, go away.

Smug: Snoozer, don't be rude. Snide, both ways are perfectly good.

Newbie: So....?

Smug: So, you should use (collecting), because it's a helpful macro and will make your code more readable.

Snide: No, you shouldn't.

Smug: This whole debate is only happening because you accept the Kantian metaphysics.

I would have just told the guy to use:
 (defun collection (pred lat)
(cond ((null lat) '())
((funcall pred (car lat)
(cons (car lat) (collection pred (cdr lat))))
(t (collection pred (cdr lat)))))

One of the SmugLispWeenies would have pointed out that your function isn't TailRecursive, then pointed out how to transform it to a TailRecursive style with an accumulator, then someone would have said to use the LOOP macro, and then the permanent LOOP macro FlameWar brigade would have swooped down to duke it out, and then there would be a fight between the people who favor recursion and those who prefer the DO form, and the newbie would have some nice learning experience prior to the head explosion. I'll give SmugLispWeenies one thing: if you can stand them, they can be pretty informative when they bicker over the best way to answer a newbie's question.

But above code does not even work. Now what? Converting it to use an accumulator is useless, since Common Lisp does not support tail call removal. The best hint would be (as said below) to use REMOVE-IF-NOT, which is a standard function in Common Lisp. LOOP is fine: (loop for element in lat when (funcall pred element) collect element).

Amusing story but at least one of the SmugLispWeenies would have mentioned REMOVE-IF-NOT, which is the built-in higher-order function to do what the Newbie wanted. (Good point. The story is just intended as an illustration; it's not a direct quotation.)

For a genuine (non-fiction) story of a newbie to CeePlusPlus facing "experts" who natter on and duke it out, see CeeProgramsForBeginnersDiscussion. There it's not the newbie's head that explodes but the newbie's computer!


Rather than complaining about experienced lisp users with different opinions on a subject i would be quiet happy watching once more the perfect adaptability of lisp to one's tastes. The newbie should just RTF(awesome)M. Programming in lisp for a long time, consists mostly in making a language that is as close as possible to your native way of thinking.I prefer that to absolute formality even if it's not newbie-friendly. -- SteliosKokkalis?


Amusing story, but I observe exactly the same behaviour on every IRC channel I've used and most of the newsgroups I read too. Is it really so much worse for Lisp?

Go not unto the Usenet for advice, for you will be told both yea and nay (and quite a few things that just have nothing at all to do with the question).

(author unknown)

[No, it isn't notably worse for lisp. There is a skew towards experts in the community, relative to some others - which may have some effect.]


Whether the above is a problem or not is questionable. People are learning Lisp all the time (I only started two years ago, by accident, in my spare time) and enjoying it quite well. Personally, I pay close attention to Usenet threads with scenarios with the premise as shown above - I've never been disappointed. I always find that I either learn to do a new thing, an old thing in a new way, or a new thing in many new ways, but most importantly I learn all about their applications and trade-offs. I've never found a community quite so expert and detail-oriented in any other field. - Vladimir Sedach


Another problem is a tendency to reinvent the wheel. It grates on Lispers that they have to link with other languages to be competitive nowadays. They try to avoid this by rewriting absolutely everything in Lisp, even if they can't possibly hope to compare with existing C software. They never seem to get around to debugging the FFIs of their Lisp implementations, either.

Java has this problem too. It just doesn't matter for Java because the industry is so big that somebody out there has probably already done the rewrite in question.

The rewrites generally have technical reasons. Code linked in from other languages doesn't support the superior debugging and error-handling Common Lisp users are used to. Multi-methods and multiple inheritance are also a problem with many object-centered languages. That could be viewed as an FFI deficiency. FFI deficiency? I don't see how an FFI is supposed to add multi-methods to C++, a condition system to C, or higher-order functions to Pascal.

The scope of the rewrites is just not worth it, though. Rewriting a parser generator, or make, sure. Those make sense. An X11 window manager? Nope. There are already a sufficient supply of good window managers, and maintaining one of those is hard and constant work.

Window managers are an interesting example: the Sawfish window manager, written in a Lisp dialect called rep, has been an absolute smash-hit in recent years. I'm sure this is in large part due to its convenient extensibility through Lisp, which appeals directly to Emacs-loving lisp hackers, and indirectly to other people who can use the resulting new features. -- LukeGorrie

Ok, let's go through all of the Lisp-based and scriptable X11 window managers I know about. Luke Gorrie already mentioned Sawfish, which is quite popular on it's own merits. There's GWM, which was written in the early 90s, when there wasn't much of a wheel to re-invent. Both of those only use Lisp as a scripting language. Of the window managers written natively in Lisp, two are academic projects: Eclipse (Common Lisp - undergrad term project at U of Bordeaux), Scheme Constraint Window Manager (Scheme - graduate project at MIT). The third one (I just found out about it), is the Stump Window Manager - it's a lot like Ratpoison, only extendable at run-time, so it does have it's own niche (it's a single-author project, and I don't think he did it just to reinvent the wheel). And if you haven't noticed, there are dozens C-based window managers around, with new ones popping up every few months. So, where is this sinister Lisp wheel-building conspiracy again? - Vladimir Sedach


It's amazing (and sad) that Lisp attracts these feelings. My experience with the Scheme community has been much more pleasant so I really wonder how objective the above protestations are.

As the author of much of the above, I can assure you that I do not intend to besmirch the language itself; I am an avid user of it, and sometime advocate. I also recognize that it is impossible to make statements like this which will apply to all individuals in a group the size of the greater Lisp/Scheme community. This page is called SocialProblemsOfLisp, and I view the page as a tool for describing these problems and discussing their causes, relationships, and solutions. Because these problems exist in SOME subcommunities, they are worth discussing. I really don't view the negative comments I wrote as protestations at all. Does that help your assessment of them any?

It is indeed sad.


I may have been the (unwitting) cause of this page, with this line which I wrote in XpInCommonLisp:

Dunno. I think Lisp and XP are orthogonal. Lisp has many problems, but every one of them is social, not technical.

But the social problems were not those referred above (i.e. of newbies finding a hostile community). Rather I think Lisp suffers from

-- AlainPicard


Stuff moved to IsSchemeLisp


If I could throw in my two cents, the "new" Lisp community is starting to develop one more problem - a growing association with DebianGnuLinux and the Debian way of doing things. I still can't figure out how to use asdf or asdf-based software. Why can't I just shove all the dependencies together in the same directory and have it work? I don't know. What does that have to do with Debian?

This threw me for a minute too (I'm new to lisp, and don't use debian). Turns out all you have to do is load "asdf.lisp" from wherever, and you are good to go. For example, here is how I set up for loading uffi: in my .cmucl or whatever:

  (load "/home/foo/lisp/asdf")
  (push "/home/foo/lisp/uffi/" asdf:*central-registry*)
Then when I need to use uffi:
  (asdf:oos 'asdf:load-op :uffi)
It will (re)-build uffi automagically if needed.

As a relatively new common lisper I've found the asdf stuff to be great. Dump the source for packages wherever you like and symlink the .asd files into a directory somewhere. Push the directory into asdf:*central-registry* as above and then it all just works - asdf works out where it's supposed to build and load the packages from through the symlinks. Defining your own systems with asdf is a little tricky at first [ the (:module foo :components ("filename")) stuff], but then you can drop a :depends-on into the definition and have the dependencies for your app loaded automatically. Then you only need to (asdf:oos 'asdf:load-op 'my-program) and you're good to go.

What has that to do with translating from a lisp source file to a native code file? (The equivalent of "cc file.c" for C)


Lisp is so bendable as a language that a particular Lisp developer(s) will tend to create a style/library that fits the way they think. A different Lisp person may come along and be really annoyed by the techniques and styles employed. Personal preferences are magnified under Lisp. This is perhaps why it is called a "hacker language". Corporations like consistent standards and conventions because they want easily-exchangeable developers. A "creative" language makes this harder.

It doesn't seem that a good lisp program written using idioms that are somewhat unfamiliar to some random lisp hacker would make that program all that much harder to read for said hacker. If the idioms are appropriate for the problem at hand, it should be straightforward to learn them, and the resulting succinctness of the rest of the program will make up for the time spent learning them. Does this really impact developer exchangeability, except in the messed up logic of a bad, misinformed manager? Unless, of course, you mean exchanging expert hackers for naive, incapable hackers, (say, as a project is switching into "maintenance mode" - riiiiight,) which won't work in any case.

The situation is worse in languages like C, where it takes a much more close and careful reading of a program to grok it. It's easier to write spaghetti code in C, C#, or Java than in lisp, if only because the programs in those languages generally use more lines of code.

Give me a choice between maintaining a 1,000,000 line lisp program and a 1,000,000 line C/C++/Java program (not the same program; pick any two) and I won't hesitate to choose the lisp program.

Speaking from personal experience, I've always been kind of bad a reading others' code. Of course, the code I've had to read has been in VB6, which is a terrible language, aesthetically. Then again, I've had trouble with C++ and C# programs, too. When I learned lisp, on the other hand, I found I could suddenly read others' code. ("Like magic appears...") I can only attribute this to the malleability of the language: when it starts to get in the way of you expressing an idea clearly and naturally, you can push it out of the way instead of having to add lots of comments to explain some weird hack you had to make because there's no better way to put the concept you were trying to express. It seems the malleability of the language, far from making code more tied to the hacker that created it, is what allows it to attain heights of readability mostly unknown to the programming world. -- Chris Capel

On the other hand, if you were simply talking about small idioms such as indention style, variable naming, using loop instead of one of the do's, I'd say that the differences between various C programmers w.r.t. brace style is just as much of a problem. Consistent standards and conventions of this sort are just as easy to impose in lisp (and indeed, are already more standard across the users of the language) as in any language.

Consider the issue of a consultant walking into a company to work on some existing code. At least you know how the control structures of most Algol- or C-derived languages work. However, if every shop and/or developer reinvents their own variations of control structures, then the consultants will consume several hours and maybe days just learning and getting used to the custom ones.

[Every shop does this already with libraries. Learning a new control structure is no different from learning a new object in a library. Consultants have to spend time either learning the local controls structures or learning the local library, there is no difference.]

The first any consultant should do is learn the problem domain. I don't see how you can even think about control structures until you understand just what it is you're supposed to build.

Ideally you are right, but we don't live in an ideal world. People are put into less-than-ideal situations all the time and have to make the best of what they have.

And a Lisp program is likely to be framed in the terms of the problem domain; that's the whole point of macros.

Sometimes stuff is "invented" because the programmer is bored, not because they are looking for the ideal abstraction. I guess what I am saying is that Lisp makes MentalMasturbation perhaps too easy.

Control structures are the least important part of the problem; you've got to learn all the existing APIs and libraries and components and data structures anyway. WhyIsDomainKnowledgeNotValued?

Aside from that, CommonLisp already has a pretty rich set of control structures. It matches everything in C/Algol, at least. If a Lisp program is inventing a new control structure, it's because there's duplicated code that can be abstracted away. Think of how many times you write "for(int i = 0; i < array.length; ++i) { ... }" or "while(e.hasMoreElements()) { ...e.nextElement() }", both of which are abstracted under mapcar in Lisp. This makes things more uniform, not less, as there's a standard mechanism to iterate over elements of the container. -- JonathanTang


Algol Syndrome

It is hard to break away from the Algol-family control structures (while, for, if) and conventions. One has to overhaul the way they think about control blocks and blocks in general under Lisp. Yes, it is probably good for us, like green leafy vegetables, but many are just not in the mood for a brain overhaul. Most algorithms and literature are designed around the Algol-style. Yes, it is probably QwertySyndrome, but hey, it just goes that way. I wish Lisp was forced on me in school so that I could mentally convert early and be over with it. But now I am old and lazy and would rather play with other equal or more interesting concepts instead. If API's are designed right, the Algol style is not that much more bloated anyhow. The Lisp improvement is relatively minor, just like the Dvorak keyboard. But you are welcome to prove me wrong. Show me consistent simplification and coding savings that approach 50% instead of just 5% or 10%, and I might change my mind. How about show up QueryAndLoop. The body of the loop is usually where the code bulk is anyhow, not the loop setup. Until then, have a QWERTY day.


I'm not sure how seriously to take the diatribe at the start of this page, but let's take one of the concrete statements it contains: "You have to literally describe files using a form of Chinese Calculus just to open a damned file! I'm not making this up either!" It's unclear to me what "literally" means there - certainly not literally "literally" - but:

 (with-open-file (f "foo.txt")
... do something with the open file f ...)
doesn't seem to me like "a form of Chinese Calculus". CommonLisp has some hairy facilities for manipulating names of files and directories as structured objects, and those facilities don't happen to match the present-day world of Windows and Unix very well, but you can get by quite well without using them and working with strings like you do in other languages. -- GarethMcCaughan


Cet animal est tres mechant: quand on l'attaque, il se defend. Trolling produces some responses. Big surprise. If you think it proves anything about Lisp users that when you say "Lisp users are arrogant know-it-alls, and their language sucks", backing your claims up with blatant falsehoods, and some people are offended or correct the falsehoods ... well, then I'm afraid you're a twit as well as a troll. You'd get the same results from users of C++, or Java, or Visual Basic, or Perl.

But, yes: Something about Lisp is really weird sociologically. So many people have a bizarre and irrational love or hatred of the language and of (other) people who use it. I'm sure there must be reasons for this, but it's far from clear to me what they are. Does it really all go back to the AI Winter thing? -- GarethMcCaughan

It occurs to me that whoever has used lisp loves it and whoever just sees lisp code just hates it. It has to do with those "alien" concepts behind lisp which are so damn simple and beautiful though. As for the lisp "veteran"'s attitude one assumption would be that there is such a powerful language in his hands but so few big lisp projects that could give him the world's respect (cyc, emacs or the viaweb case coming first into my mind).This behaviour from your environment tends to make you quiet unsocial.Anyway that was only as a probable answer to your question which hasn't been true for myself. After having read the great Hyperspec from Xanalysis and all the free online books on lisp any question i made in #lisp was immediately answered by guys that i never thought i could speak with. It's insolent to demand ready food anyway. -- Stelios Kokkalis

That's the IfYouDontLikeItYouDontUnderstandIt fallacy rearing its ugly head again.

While dislike of Lisp does not imply unfamiliarity with Lisp, perhaps it is the case that familiarity [or coding experience] with Lisp is a prerequisite for liking Lisp? That is, If you don't understand it, you probably won't like it.


Lisp is for experimentation, expression and it's also powerful enough to use for the hard problems. Obviously it could do the grunt work better than the rest of the mob but who wants the kludges needed to facilitate that? Main-streaming lisp will box it. The constant yells to do so is a Lisp social problem.


I disagree with the above- Cl is certainly good for hard problems. It is also good for easy problems (which sometimes turn out to be not _that_ easy). What CL lacks is one of the following:

  1. a huge user community writing open source packages, like Perl or
  2. the backing of a huge company like Sun.

All that's needed to do the grunt work are some good libraries, and they have been turning up a lot lately- see clsql, for instance...

I'm not sure what you mean when you say above that kludges are needed to facilitate grunt work. Care to expand on that?

It's also clear that CL is in fact being used for more and more grunt work all the time. For an amusing but trivial example see the source of http://www.booble.com (NotSafeForWork? - it's a search engine for pornography, and it may create pop-up porn ads). Booble's meta tags list the following technologies:

  cmucl-19a
  cl-html-template
  CL <-> Postgres
  Emacs


An interesting article on a relatively well-known blog: http://www.troutworks.com/Timlog/timlog.php?y=2002&m=11&d=12


And another, referencing this page, on the Lisp blog LemonOdor?: http://lemonodor.com/archives/000902.html#comments. It ain't too friendly to the content of this page. :)


Just had to share this from comp.lang.lisp. A Lisp novice asked for advice on writing a simple function, and got several answers showing different ways to do it, some very extensively describing the reasoning process. Also, the usual complement of commentary on the solutions offered. The original poster then wrote this:

  Thanks a lot for your hints and explanations. They were way more than
  I was hoping for! I haven't quite gotten a firm grasp of what you
  wrote, but I'm going to study up on them this weekend. I'm guessing
  you'll be hearing more from me in the immediate future since this is
  such a good resource for beginners like myself. Thanks again!
Obviously, the poor fellow hasn't read this page. If only he knew...

And that gave me an idea...

According to Google, the phrases "thanks a lot" or "thank you very much" appeared in about 360 messages from beginning of the year 2000 to now (mid-September 2004). The words "twit", "idiot", or "jerk" appeared in about 310 messages in the same period. These numbers are provided for amusement only.


NewLisp users have some social problems, too: http://www.alh.net/newlisp/phpbb/viewtopic.php?t=1630

Not very smug, but very psycho-weenie.


A good index of the SocialProblemsOfLisp actually is to compare the Lisp communities with the HaskellLanguage community, which, IMHO, has managed to dodge the biggest social problems dogging Lisp and Scheme.


I am the developer of a language that looks a lot like pseudo code. It compiles to byte code which looks very similar to the source code of Lisp. This statement on the surface seems to validate the claim that Lisp is the universal language but I think it suggests the opposite. The simple syntax of Lisp makes writing a compiler (not the libraries) for Lisp extremely easy. If fact a simple Lisp compiler was printed on a single page in some early Lisp publication. It is absolutely correct that Lisp syntax is easily translated for the computer but is it great for humans? I believe that source code should be good for the programmer and produce exacting code for the computer. If some people want to use their mind to compile their program, good for them, but I would prefer that the compiling was done by the compiler, rather than me.

A great thing about Lisp is that it has great extensibility but Lisp's biggest problem is that it can be easily extended! When a group of people learn a language, they can communicate using commonly known constructs. They can also make custom code but that code uses "sets" of commonly known constructs. There is nothing wrong with extending the functionality of a language but it should be done in a way that shows a programmer what is the "commonly known" code and what they have created themselves. In Lisp, it is difficult to even see the "structure" of the program. Where is the "looping", "conditions" etc? I know that Lisp has all these things (structure) but they aren't obvious to me. I love the idea of Lisp's "compile time" macros and I am implementing them in my language as well. This is a great mechanism for creating small DSL modules inside your code.

Some people, smart or otherwise, might have trained their brain to overcome the intrinsic deficiencies of Lisp syntax but calling Lisp a good language or the "mother of all languages" flies in the face of reality.

The mother of all languages is assembler, not Lisp. Who would say that after the invention of Assembler, all other languages have no merit? -- DavidClarkd


The Bipolar Aspects of Lisp:

http://www.lambdassociates.org/blog/bipolar.htm


See: LispIsTooPowerful

CategoryLisp


EditText of this page (last edited May 19, 2014) or FindPage with title or text search