No more "minimal early Lisps", pulleezz
axisofeval.blogspot.com
axisofeval.blogspot.com
I can't wait to see this person's algebra textbook. "Integral calculus is so old and boring, puleezz. Wake me up when you've rediscovered quaternions."
And people wonder how PHP can be so popular. I could spend all day enumerating PHP's faults, but when people who have never written an X before build an X in PHP, the PHP community welcomes them with smiles, not sneers.
I wish, I really do, that one percent of one percent of the world's programmers had actually implemented a simple Lisp in Lisp, let alone reached the point where such a thing seemed boring. But lecturing us on our lameness is not going to help.
Don't measure a community by its detractors.
Further, people don't wonder why PHP is popular. Its popularity originated in ISP-friendliness, and has grown since then through network effects.
EDIT: People are still voting up the parent comment, so I probably wasn't clear enough: the parent comment is totally wrong, starting with the words "It's this". The attitude of someone who does not like Lisp is not even a single datapoint, much less evidence, as to how the Lisp community treats newbies.
I guess I didn't realize that I needed to explictly call out the existence of friendly, helpful, newb-friendly Lisp teachers on Paul Graham's Hacker News as implemented in Arc -- it is easy to forget that not everybody is steeped in the local culture -- but let me now be more explicit: There are plenty of people who are happy to help teach newbs all about higher-order programming by helping them implement their very own toy version of Lisp, and by taking joy in the results. Thank god for those people.
http://axisofeval.blogspot.com/2010/08/three-principles-of-l...
One of the author's projects is writing a lisp.
edit- actually it's right there at the top of the page on the right. Motivation: Lisp.
Yes, he has a project to build his own Lisp, because he doesn't like existing ones. That's a detractor.
http://axisofeval.blogspot.com/2010/07/c-40-industrial-respo...
In other words: CL sucks but all the other dynamic languages suck more. My semantics don't label that as "detraction" but yours may differ.
"What's more worrying is that all dynlangs, including the few acceptable ones, like Common Lisp and Factor, are starting to look horribly dated against C#. Seriously."
Lispers love their language. But they are also self-critical and open-minded. They tend to work hard to see how ideas in other programming languages can be properly integrated into their own.
Other programming languages and communities could benefit from such self-criticism.
So, of course there are some Lisp communities that regularly have a quorum of asshats, and we all know which ones those are (in general terms, perhaps). On the other hand, the generally-positive reputations of others are also fairly well-known (e.g. I've rarely had negative experiences with schemers of various stripes, and it's hard to dispute how fabulous the Clojure community is [to wit: http://wp.me/p10OJi-6a ]).
http://www.paulgraham.com/rootsoflisp.html
http://www.fogus.me/fun/lithp/
http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implem...
http://www.zogotounga.net/comp/squeak/lispkit.htm
Curse them all.
He went from that to writing a book about a Lisp (Clojure) in just 943 days (~ 2.5 years) :)
1) Specify representations for: integers, strings, symbols, and cons-es; specify a data structure for the symbol table and define INTERN properly.
2) Implement the reader, cribbing heavily from CLHS 2.1.4, 2.2. Set up constituent, whitespace, and terminating character classes, and implement reader macros for at least quote, double quote, and left/right parens.
3) Specify a representation for the environment, which will map symbols to offsets of variables on the stack frame; have a stack of these objects.
4) Figure out what special operators to handle. You can get away with just: lambda, progn, if, quote, let.
5) Starting from each top level form, walk the code recursively. Each element you encounter will either be: a) a top-level definition b) a single symbol variable reference c) a list with a symbol at its head which is a special form d) a list with a symbol at its head which is a function call
As you walk the code, push a new environment onto the stack for each lambda and let you come across, which you pop off when you're done walking the corresponding body (but make sure you save it somewhere).
5.1) In one pass, collect information on closed-over variables. Walk the code looking for variables which are referenced (5b) but are not present in the environment. In that case search up the stack. If you find it in a parent environment, it's a closed-over variable. If you don't find it at all, it's a global variable.
5.2) Use the environment structures you just collected to assign local variables to stack slots. Figure out a closure representation (use a code pointer followed by an array of closed-over variables). Use the info you collected in (5.1) to assign variables to stack slots and closure variable references to closure variable slots.
5.3) In a second pass, generate code. When you reach:
a) A TLD, emit a call to the runtime to associate a global name with a lambda b) A variable reference, emit code to either load the value from the stack slot noted in your environment structure, or from the appropriate closure slot, or emit a call to the runtime to look up a global value. c) A special form: generate function prologues/epilogs when you reach a lambda form, use labels and jumps to implement 'if', and use whatever data facilities your assembler has to handle quote-ed literals. When you reach a nested lambda, emit its code as a separate function, then at the point where it is used as a value in the parent function call a closure creation function providing it with the address of the generated code plus the values of all closed-over variables. d) A function call, emit a call to the runtime to look up the global value, then evaluate each of the arguments left to right, pushing them onto the stack. Then, jump to the body of the function.
6) Implement the runtime functions for cons handling, the global symbol table, and closure creation.
Extend as you see fit to include mutable variables, etc.
I don't understand smugness when it comes to other peoples' small projects. No one sets out to implement CLv2, just further their own knowledge via a smallish side-project.
That thing you just stepped in? That's a big pile of bullshit.
>> consider writing a Haskell, not a Lisp.
Has anyone written a Haskell (or subset) as a hobby project? I would think it would be much harder than writing a simple Lisp, which seems to be designed so that simple versions can be written almost recurvisely, where more advanced functions are decomposed into a few primatives.