I consider myself a Python programmer. Python was the first language I learned, and still the one I am most proficient. With the possible exception of the Bourne shell language, it's the programming language I spend the most time working with, and the language I first turn to to solve problems.
I have tried other languages; for starters, I tried Perl and Ruby. In fact, if I had started with either of those, I probably would still be using them as my primary language today. However, since I already knew Python, I never got to the point of writing idiomatic Perl or Ruby - by the time I would have learned that, I had already moved back to Python to complete some project that had stumped me in other languages.
I dabbled in other languages, both compiled and interpreted. Ultimately, only one has had a lasting effect - Lisp.
My curiosity in Lisp was piqued (like many others') when I read the essays of Paul Graham, and from other influential advocates - Peter Norvig, Eric Raymond and of course Stallman. I began to dabble in Lisp, particularly in the parts that worked more or less like Python - simple defuns, stateless recursive functions (Fibonacci, anyone?) and the like. Getting into it was rocky - I distinctly remember my first time at the sbcl shell, and being totally mystified at the debugger. I ended up having to killall sbcl to get out of there.
Another thing I noticed what that it was pretty hard to set a variable. Compared to python's var=value, Lisp didn't seem to have a straightforward way to setting variables. Defvar, defparameter, setf, setq, set, defconstant, and the list goes on. It was soon after that that I realized that the functions that I had managed to write were not actually using any variables, and I began to grasp (really, rather than just conceptually, grasp) the ideas behind functional programming. A total lack of state - a radical idea for someone coming from procedural languages. Lisp made it hard to set variables, but in some ways, this was a feature, not a bug.
Yet still, I struggled with Lisp. To practice, I began working through the problems posed by the excellent Project Euler. I could write solutions in Python far faster, but in Lisp, the solutions tended to be shorter and more general. The Lisp solution seemed, to me, to be "dense" - each line did multiple things, and the entire function - usually not more than a half-dozen lines - read more like a paragraph of text than the long, verbose functions we'd expect from C-family languages.
Sure enough, having been an Emacs user for a couple months at that point, the parentheses hardly bothered me at all. Most any editor will pair the parentheses, and I found that instinct worked well. Simply guessing how many parentheses I needed to close to get the correct logic was far faster than stepping through everything, and it worked almost every time. A well-formatted error message would tell me what my mistake was if this was not the case. In all, the syntax was, for me, very simple.
I never did get beyond trivial functions. Finding myself ill-equipped to move on to larger things, I decided to retreat back and study harder, learn more thoroughly. I read Practical Common Lisp, first online, then from the book. I watched the SICP video lectures.
And, just a little bit, I began to "get" Lisp.
Describing exactly what makes Lisp special is difficult. For starters, there's the fact that you really need to know what you're doing to really understand it. Even then, reasonable people can disagree about non-trivial points. And it can be explained in many ways that are neither incorrect nor complete; neither correct nor lacking.
One way to describing this would be to note that Lisp is written in the languages' primary data type, the list. Writing a program as a linked list results in a greatly simplified syntax, and even in the 60's, fostered the dynamicity that Lisp was known for before interpreted languages became mainstream.
Another would be to note that unlike most languages, in which source code is parsed into a syntax tree, writing Lisp is actually writing the syntax tree itself. This makes macros infinitely more powerful, since instead of modifying symbols that still must be valid symbols to be parsed later, macros can actually modify the tree itself.
Unfortunately, I have so far been unable to apply and use these concepts. I have a vague understanding of what they make possible, but every time I return to the Lisp interpreter to try to hack some code, I get hit by how unpleasant it is to use.
In some ways, it may be in the "zen" of Lisp for the implementations to be somewhat tedious to use. After all, for someone well-versed in Lisp culture, the rituals of packaging, setting up an environment, and debugging on the fly is probably near-memorized. But for a relative programming newbie, the problems become showstoppers.
I have been using the sbcl implementation of Common Lisp. The first problem I have is with the number standard symbols. Setf, Setq and all of the defvar variants still confuse me. They are not, strictly speaking, difficult to learn. Using them correctly is simply a matter of practice and discipline. And as many have said, the prize at the end is supposed to make this relatively small annoyance seem insignificant in comparison, right?
I don't know. As a new user, I can't yet see the light at the end of the tunnel; I can only compare with Python. What I've found is that what I would really like is Python, in a Lisp syntax. Common Lisp is not important to me; a fast, stable, practical Lisp with a large standard library is. Python, in fact, almost fits the bill perfectly. Many others - Norvig, for starters - have noted the similarities between Python and Lisp. While Python shares Lisp's affinity for number calculation of arbitrary size, multi-paradigm style and high-level constructs, Python lacks the defining feature of Lisp - the syntax.
I would like to propose, then, that a programmer far better than myself re-write the Python interpreter to accept a Lisp dialect as input. Keep the Python data types, the dictionaries, lists and strings; use the Lisp syntax. Eliminate Python's [], {} and () syntax's, and replace them with explicit but not tedious Lisp functions. Keep the Python backend code, but write a new parser for it. Don't worry about Common Lisp; far more important that Common Lisp is usable, useful (dare I say it, Pythonic?) Lisp.
I would argue that this intrepid programmer could even ignore, for the time being, macros, another core Lisp feature. Once the syntax has become Lisped, a macro system will evolve quickly.
There are, of course, pitfalls. The first is that Python lacks the list-centredness of Lisp. Whether this is a showstopper, I do not know. Would the source code be a Python list, or a Python tuple?
I regret that I cannot, at least now, be the person to do this. My C education is sorely lacking, although I am, slowly, working on fixing this. Nevertheless, I do not have the breadth of experience that would be necessary to do the low-level work with the Python source code to create an alternative syntax. I can offer support and a promise to write documentation to whoever wants to do this.
Comments
1521 spam comments omitted.
I am no longer accepting new comments.
Adam Gomaa
#265, 2007-08-02T04:55:37Z
Since I've written this I've found out about the E7 programing language. It's not quite what I describe here, but it is an interesting take on Python and Lisp.
Unfortunately, I haven't been able to get it to build (yet). Still, the ability to access Python libraries is very exciting.
Some guy
#267, 2007-08-30T09:07:59Z
How funny! It's quite common (on c.l.l. at least) with people trying to "fix" Common Lisps syntax with significant whitespace (to reduce the need for parantheses), infix operators etc. .. They want Lisp with Python syntax!! I agree with you though. (One of) Lisps greatest strength is its syntax (and all the cool things you can do because of it, like macros). Don't know enough Python to have an opinion on that though.
landtuna
#272, 2007-08-30T11:56:20Z
This guy tried to do what you're saying, but he seems to have abandoned the effort:
http://scarletlambda.org/
landtuna
#273, 2007-08-30T12:01:12Z
One more project that does this: Lython
Anonymous
#274, 2007-08-30T12:15:21Z
There are a couple of projects intending to mix regular syntax with full compile-time code manipulation. You can look at metalua, which extends Lua, or Converge, a language built from scratch with a superficial syntax close to python's.
The usual limitation is that you need the language's syntactic definition to be quite compact, to keep it as easy to manipulate as possible. That's the main reason why metalua's based on Lua rather than ruby or python.
Clinton
#275, 2007-08-30T12:30:37Z
Part of the problem you might be having with the SBCL repl is that the SBCL repl sucks. Try using SLIME (slime.sf.net) within emacs and life will be much easier. The hyperspec module that cocmes with SLIME is also quite useful as you can put the point over any symbol and tap C-c C-d h to look up the symbol in the Common Lisp standard.
Things like defvar vs defparameter are actually not so difficult. defvar = DEFine VARiable, and defparameter = define parameter. Defvar created a new special (dynamically scoped) variable in the current package, but if it already exists it does not overwrite the existing value. Defparameter, on the other hand, will reset the value even if the variable already exits.
Setq and setf are likewise simple. Setq = SET Quoted (i.e. its first arument is quoted unlike set which evaluates its first argument to get the symbol to set). Setf is a bit more difficult to understand, but it does follow the CL naming scheme. In CL functions that end with f take a place as their first argument. A place is a special form that denotes a place where a value can be put so you can do things like (setf (car some-list) 'foo) to replace the car some-list with 'foo. Most of the accessor procedures in Common Lisp have place setters defined whih makes setf a very powerful setting construct.
Common Lisp also has a fairly large standard library that can do a lot of things portably. In addition you can surf over to cliki.net and find a bunch of other libraries. If you're running a distro that has the common-lisp-controller you should have ASDF loaded already so you can install new libraries trivially:
(asdf:operate 'asdf:load-op :asdf-install) ; ensure that the asdf-install library is loaded (asdf-install:install :program)
That will then use the condition system of CL to prompt you for where to install the system, check gpg keys, install all dependencies, etc. Then loading the system is trivial: just use (asdf:operate 'asdf:load-op :SYSTEM).
You should check out cliki.net to get a nice overview of what is available for CL, and also try skimming through Common Lisp the Language 2 (google for it and you'll find an online copy at a few places, or apt-get install cltl if you use Debian). It has a few spots where it is inaccurate against the standard (ignore the chapter on series, and the erratta list is ~2 pages), but is overall an excellent guide to fully learning CL as a user.
eli
#276, 2007-08-30T13:21:16Z
Nice post. I've been struggling with CL's implementations in almost the same way. The most recent rant is here.
I can recommend you to consider PLT Scheme. Scheme is a Lisp, and its differences from CL are negligent. It is more consistent in naming its functions though, and PLT is a great integrated environment with many useful libraries. It somewhat reminds of the Python or Perl distribution.
Bob Ippolito
#270, 2007-08-31T02:59:33Z
Sounds like Logix
henrik
#271, 2007-08-31T08:43:42Z
I am an ex python programmer that switched to Lisp some years ago. I think that the critique of the Lisp development environment is unjustified. When I programmed in Python i used Idle and the ActiveState environment and recently the emacs python mode. Slime is on a whole different level. The cross reference makes it easy to navigate around, with fuzzy completion you don't have to remember exact names of functions and methods, the hyperspec was mentioned in a previous comment. The development environment is true client/server. I often connect to my server across the atlantic. The only thing I miss is a good single-stepper, but I have heard it might be coming.
Michael Burns
#277, 2007-08-31T17:07:21Z
Paul Graham himself is working on this: Lisp done right.
Instead of making Python more lisp-like, he is really going the other direction: making a Lisp-dialect more Pythonic. (Really, any sufficiently powerful, library-backed language).
http://www.paulgraham.com/arc.html
I'm curious to see what you think of this in-development language.
Randix
#278, 2007-09-02T02:25:29Z
I switched from Python to this, and cannot imagine going back:
http://software-lab.de/down.html
This beats Paul Graham's efforts with arc by several years, and he himself has recognized the effort.
Unfortunately, some of the best descriptive text is in German, but the language and very good documentation, tutorial, etc. are all in English. This is super easy to compile and set up, has a built in HTML GUI interface and integrated database that has actually beat most other database systems (including Oracle) in performance. There was an article in the German magazine CT about it a year or two ago.
Adam Gomaa
#279, 2007-09-02T10:53:23Z
Thanks for the info, all!
Unfortunately, Lython seems to not have a maintained homepage, although I'll definitely be looking through it's later releases to see how it did it.
Converge and Metalua both look like projects I'll have to check out... I don't (yet) know Lua, but the tables seem like a interesting data type to investigate.
Clinton: I have actually started using SLIME, but that was some months ago, not long after starting to use Emacs. I'm going to be spending a lot of time in a Scheme REPL the next few months, before going back to SBCL. I've spent some time on CLiki, but again, a lot of the problems were in the documentation; for example, I had wanted to write a CL terminal application in order to learn about asdf and packaging, but the cl-ncurses library was essentially undocumented.
Bob: Thanks! Logix looks like a very interesting project. Another approach I'm looking at is through the parser and compiler modules in the Python stdlib. Compiler.ast provides an interface to a Python AST, so if I were able to write something to parse a lisp-like syntax, I should be able to feed it into there to get what I am looking for.
Henrik: SLIME is a very powerful tool indeed, and the ability to attach and reattach REPLs is something few other languages have (their loss!).
Arc has the rather large disadvantage of not being available to the public. Browsing news.yc just doesn't feel like "using" Arc. :)
Randix: I have actually given Pico Lisp a good look in the past. The first issue is that the "HTML GUI" is actually a Java applet. That's not quite the same. But I'd be interested in a Lisp even without any GUI library, so I looked at it anyway; it unfortunately wasn't particularly stable. Although this was some months ago, the "caadr" function would segfault. I'll give another look at it today, but with Pico Lisp you're always aware that you're working just above bare metal - which isn't necessarily a bad thing.
David
#291, 2007-09-05T05:41:09Z
Really Adam, your looking for scheme. (I found scheme and then reallised I was looking for Haskell, but that's another story). Take a look at PLT Scheme. Scheme is basically a cleaned up simplified lisp and the PLT toolset is great.
Ian Jones
#1272, 2007-12-17T22:25:08Z
[latecomer] If you're on a Mac, check out Nu. It's a Lisp-like language built on Objective-C, which yields a number of the benefits you describe in this post with the significant addition of being able to talk directly to Mac OS X system libraries (ie, write graphical Mac applications).
http://programming.nu/about
Adam Gomaa
#1297, 2007-12-19T04:36:50Z
Ian: No luck there. When my laptop gives out I'll definitely be considering a Mac, but it's a Thinkpad, so don't hold your breath :)
Mark
#6371, 2008-08-26T16:40:43Z
I'm a new Lisper myself. I find that it's something that I keep dipping in and out of - more out than in! I find Python generally does everything I need. However, I recently decided to rewrite a creaky Python program in Lisp - and I'm glad to say that I am confident that I will see my project through to completion.
I think Lisp takes awhile to reach takeoff velocity. Have fun!
Andrew
#11168, 2009-01-06T16:58:40Z
I'd recommend Scheme rather than Lisp as others do. It's very similar to Lisp but cleaned up, stripped down and easier to get on with particularly with the many excellent free books online.
I'd also highly recommend the SchemeScript Eclipse plugin which brings Scheme into the 21st century and makes it a pleasure to work with.
albino
#13643, 2009-02-20T22:50:51Z
Just stumbled onto this post today.
A lisp in python called noodle: http://noodler.blogspot.com/
You can find the author in #utahpython on freenode. Next up is clojure:
http://clojure.org/
I'm after the same thing, please blog when you find bliss.