addressalign-toparrow-leftarrow-rightbackbellblockcalendarcameraccwcheckchevron-downchevron-leftchevron-rightchevron-small-downchevron-small-leftchevron-small-rightchevron-small-upchevron-upcircle-with-checkcircle-with-crosscircle-with-pluscrossdots-three-verticaleditemptyheartexporteye-with-lineeyefacebookfolderfullheartglobegmailgooglegroupsimageimagesinstagramlinklocation-pinm-swarmSearchmailmessagesminusmoremuplabelShape 3 + Rectangle 1outlookpersonJoin Group on CardStartprice-ribbonImported LayersImported LayersImported Layersshieldstartickettrashtriangle-downtriangle-uptwitteruseryahoo

The Den of Clojure Message Board › Clojure vs Common Lisp

Clojure vs Common Lisp

A former member
Post #: 44
Not to cause trouble, but . . .

I've been plowing through Paul Graham's Ansi Common Lisp (making better progress this time than the last time I tackled Lisp) and am gaining a new respect for the simplicity and consistency of the language.

In contrast, languages which heavily depend on formal Syntax (that is, everything else) are starting to irritate me.

Actually, syntax variation has been a sore point for a long time: I mean - really! - how many different variations of 'if ... else if ... else endif' do we really need? (/bin/sh: if .. elif .. else .. fi; php: if ... elseif ... else endif; ruby: if ... elsif ... else ... end; python: if ... elif ... else (end indentation); and now repeat using { }, etc)

One of the 'features' of Clojure seems to be added syntax to a Lispish language.

Question 1: Does this really help or is this something which makes us feel more comfortable because of our experience with languages based on context free grammars?

Question 2 is probably more heretical: How come Clojure uses different names for similar - if not identical language features of Common Lisp?

For example:

Common Lisp defines a generalized 'do' macro which takes a list of iteration parameters and a block of stuff to do.
It also defines the special form 'progn' to package a sequence of functions in a block which are executed once.
And it defines 'loop' which is essentially 'while true ; do sequence-of-statements ; end'

Clojure defines the 'do' special form to do precisely what 'prong' does.
Clojure then defines 'loop' do so something similar (if not the same (deferring to people who actually know)) to the Common Lisp 'do' form does.
Clojure also defines something called 'recur' which seems to be the Common Lisp 'loop'.

Does this really seem like a good idea or is it NIH?

Finally, from '':

"Clojure is a member of the Lisp family of languages. Many of the features of Lisp have made it into other languages, but Lisp's approach to code-as-data and its macro system still set it apart. Clojure extends the code-as-data system beyond parenthesized lists (s-expressions) to vectors and maps. Thus vectors and maps can be used in macro syntax, have literal reader representations etc."

Well, Common Lisp has a mature set of data types including arrays (of which vectors are a subset), hashes (or maps, if you like), sets, sequences, objects, strings, etc etc etc.

So I'm not sure I can accept that Clojure is 'extending' Lisp, as is implied by the quote.

So I guess all this boils down to one final question:

Why are we messing with Clojure when there is a mature language with almost 50 years of development behind it which already does the same stuff?

Let the flames begin!
A former member
Post #: 1
Disclosure: I don't know squat about Common Lisp. I have the Paul Graham book you are reading, but I haven't gotten to it yet.

Now that I've qualified my ignorance, I believe the reason that Clojure has gained so much hype so quickly is that it has much or all of the magic of Common Lisp, with the addition of STM and super easy Java interop. Whether we like it or not, Java has seen a huge amout of development attention and there is a lot of tooling supporting the JVM. Since I can't contrast these features with Lisp I can't really answer your question. Those are the reasons I hear sighted most often for why we should prefer Clojure to Common Lisp.
A former member
Post #: 45
I don't disagree with what you say, but that doesn't address my questions, which were:

1. Does the addition of 'syntax' help or is it a comfort blanket. I'll freely admit that a lot of my trouble learning Lisp in the past was that I wanted the comfort of a complex syntax. Now that I've become somewhat proficient at dealing with languages which use huge libraries of objects and methods (Ruby, Python, & PHP), dealing with Lisp's almost vacuous syntax isn't so much of a challenge. I'm starting to appreciate it, in fact. (besides which I'm fed up with wasting brain cycles trying to remember the precise syntax of the language I'm using at the moment as opposed to the one I was using this morning)

2. How does Clojure justify the apparently arbitrary renaming of Lisp special forms?

Clojure <-> Lisp
do <-> progn
loop <-> do
recur <-> loop

plus probably a whole bunch more.

3. Finally, I had an implied question about the validity of Clojure 'extending Lisp', given that the two examples given already exist in Common Lisp in very rich forms - along with whole bunch of other stuff.

Note: Between when I wrote the initial post and now, I Googled around a bit and found that there does exist a Common Lisp which runs on the JVM. I haven't tried it yet, but I'll probably pull it down 'real soon' and try it out. The 'real soon' really means, after I've finished Paul Graham's book and feel a bit better about pretending program in Lisp. [for reference, it's ABCL (Armed Bear Common Lisp) at­]

Now - if you've made it this far - Rich brings a couple some interesting points.

1. interaction with the JVM and the Java libraries (which means, more places to work - as the jRuby folks continue to prove and promote)

This is clearly a 'good thing'. The JVM is probably the most highly developed and maintained virtual machine in existence and provides the easiest portability of software between the various hardware-software platforms around.

Besides, anything that diminishes the creation of new Java source code can't be bad.

2. Software Transactional Memory.

A quick Google pointed to the Wikepedia article on STM which pointed to CL-STM­ - which is STM for Common Lisp.

So - if it works - this also seems to be a non-issue.

Finally - I really, really want to be clear about this: I'm not down on Clojure or Clozure or Closure or closures in general or in particular.

I'm not against incompatibility either if the benefit exceeds the pain and suffering it induces. (for example, if a new 'feature' differs significantly from an existing one and so needs a new name to remind us that it is a different, although similar facility)

I'm questioning whether the choices which the Clojure authors have a made have a technical basis or not?

Thanks for the reply. Look forward to more

A former member
Post #: 2

The addition of syntax and renaming of special forms is almost definitely a matter of preference and comfort. As best I can tell that is the reason that Scheme was written. Common Lisp isn't broken per say; Gerald J. Sussman and Rich Hickey, just wanted to create languages that they felt improved upon Common Lisp. Whether either of them succeeded depends on who you ask.

I think your questions about language extension and changes in syntax between Lisp dialects can most easily be addressed by looking at the sheer volume of programming languages in use today. Why was Ruby created when Python, Perl and TCL already existed? And for that matter why was Java created when C++ and SmallTalk already existed? Discussing the “why’s” of syntax in programming languages is tough because the justifications are almost always arbitrary, or at least highly subjective. I think Clojure’s claims to extending Lisp are valid. Yes those same extensions may be available in other Lisp dialects, but that doesn’t make those extensions any less valid.

That’s my long winded way of saying programmers are picky and curious. We gravitate towards languages we enjoy working with and in which we find the best balance of usability and power. Unfortunately there is no universal scale for comparing languages. Rather we have personal opinions running rampant, which has led to the development of over 2000 programming languages in ~70 years.

I'm not sure that this was a better answer than my previous response, although I am enjoying thinking about the topic. (I'm also getting antsy to read ANSI Common Lisp.)
A former member
Post #: 46
Regarding Scheme - I (unreliably) recall reading or being told that Scheme was developed to explore Lexical scoping - which Lisp did not have at the time. Lisp originally put all values on the global a-list, so you got whatever happened to be on top.

I actually ran into that when I wrote (setq f 12) or something similar and the Lisp interpreter I had crashed (it was something I'd gotten from the University of Illinois (written if FORTRAN, believe it or not)). Seems that the Lisp system used 'F someplace and I mucked it up. Everything was good once I changed 'F' to something else.

I believe Scheme also introduced 'if as a more succinct and limited version of 'cond. In other words, it started as an experimental language. I believe that it's evolved into a teaching language, being somewhat smaller and simpler than Common Lisp.

The point of Common Lisp is that it's not just another variant - it is an ANSI standard which has been defined by a committee composed of senior Lisp'ers over the period of many years. Reference the info in Common Lisp, by Steele - both first and second editions.

It seems to me that this is not something which should be disregarded without some technical justification.

Regarding the other point of programmers inventing languages etc etc.

Much as I dislike Java's heavy handed approach to 'making programmers write better programs', I believe it is superior to C++. I disliked Java when it first came out because, while Goslig claimed to be taking all of the good parts of C++ and discarding the bad, it seemed to me that he discarded all of the experience available from the 10 years or so of C++ development. That included the design of the libraries. We could attempt to argue about this, but rather than doing that I suggest reading The Design and Evolution of the C++ by Stroustrup and contrasting that with The Java Programming Language, Firsts Edition, by Gosling.

I think Java would have been a better language a lot sooner if they had taken Stroustrup's experience more into account.

I think Java - or something like it - was a forward step and technically sound, if not as well executed as it could have been. [early version ran so slowly that I saw terminal screens repaint them selves]

As I think about it, I can't think of any language which has been successful which has not been driven by some sound technical need - no matter how munged up the implementation has been.

Regarding the extensions: lets talk more after you've had a chance to read through PG's ANSI Common Lisp.

Thanks again for the response.
Tyler P.
Boulder, CO
Post #: 7
Nobody claims Clojure attempts to extend Common Lisp. Why should it? People come to the language from all sorts of backgrounds. Clojure is A lisp that borrows a lot from other languages too, like Haskell and Perl. When I first started using it, I found conflicts with the expectations I had acquired from working with Haskell or Scheme, but I kept at it. Soon, I found a simplicity and "flow" that reminded me of Python. Then I discovered so much more.

Unfortunately, people refer to Common Lisp as just "Lisp". In fact, it was created by committee to tame the Tower of Babel of many competing lisps into an officially blessed one. Having that ANSI stamp meant a lot in the 80's, a time when it was vital that The One True Language include all your favorite features. In these polyglot days, we need what Clojure delivers: Simplicity. What Clojure leaves out is more important than what it includes!

Clojure does add some features. For example, it has reader support for vectors [...], maps {...}, and sets #{...}. It could probably have been designed without the syntactic sugar using (vector ...) instead of [...], etc. But Perl and its descendants have amply demonstrated the benefits of including these ubiquitous data structures in the language and making them handy to use.

But here's what's important: Clojure leaves things out. Here's an example, a big one! It's Clojure's most important distinction, in my opinion, one it borrowed from Haskell: These built-in data structures are immutable. If you learn nothing else about Clojure, learn how it facilitates writing programs with minimal mutable state. Your programs will be much easier to understand, since there is no vast object graph with state propagating all over the place. The language does let you change what a reference points to, but this can only be done in a thread-safe way, and the change is guaranteed to have no effect on code that has already accessed the data. This is huge! Simple and safe by default.

Watch one of Rich Hickey's best videos: Simple Made Easy

Good luck, and keep climbing these funny new trees. Eventually you'll see the forest!
A former member
Post #: 49
Thanks for the reply Tyler,

Rant Warning: I'm afraid I've given in to irritation in this response.

I wish you had addressed the questions I asked rather than responding to something I haven't said.

I am really trying to start a technical discussion on the three (3) questions I raised in the original post. Over the <censored> years I've been writing code, these are issues I've butted up against time and time again and which I've identified as being impediments to my coding efficiency and reduced the joy of coding to abysmal frustration.

1. Whether anyone claims that Clojure extends Common Lisp.

I based that on this sentence from­ which discusses Clojure's relationship to Lisp: "Clojure extends the code-as-data system beyond parenthesized lists (s-expressions) to vectors and maps."

As you pointed out, people tend to equate Common Lisp with Lisp - and probably rightly so, given that the standard has created a common implementation definition - so it seems reasonable to read 'Lisp' as meaning 'Common Lisp' in the context of this web page.

Common Lisp (and probably other variants) supports vectors, arrays, sequences, hashes and sets as data structures, but do not provide special syntax for them in the Reader - at least as far as I know. I expect that one could write a reader macro to do something along those lines, but I'm not a good enough Lisp hacker to know.

That being the case, Clojure does not functionally extend Common Lisp; it provides Reader extensions which add syntax for some of CL's data types. While this is an extension, I don't believe it is the extension claimed in the referenced web page.

2. I'm not sure what the point of your second paragraph is but it does not sound like a technical argument. I feel you're being overly dismissive of the standards process which the committee went through to develop the Common Lisp Standard. Suggest reading the Preface to Common Lisp the Language, 2nd Ed by Guy Steel Jr.

I think you'll agree that the standard was the result of a consensus of well informed, well experienced members of the Lisp community after decades of practice using and developing the language.

It seems to me to be arrogant and foolish to disregard that experience - if the Clojure community is in fact disregarding it. Again, I'm posing this as a question - not an accusation.

So my question - again - is the Clojure community creating a not-invented-here language or is it building on the experience of the past? Again, I defer to Stroupstrup's remarks about Java which I (vaguely) recall reading The Design and Evolution of C++. He predicted modifications to Java which paralleled changes he'd been forced to make to C++ as experience with the language and OOP developed and which the original Java designers chose to ignore.

3. I agree that simplicity - in the sense of meaning 'atomic' or 'not compound' - is generally a good thing, but I would argue that Lisp has a much simpler syntax than any other language. This leads to it's un-readability without proper and automatic indentation. [see PG's Ansi Common Lisp, pg 17] [see also John McCarthy, Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I, 1960, pg 16 "This notation is writable and somewhat readable."]

However, I don't see Clojure as so much promoting simplicity as it is limiting choices.

Using your example of immutable data structures:

The only time immutability matters in when a data structure is shared. If a data structure is passed into a function, it's almost trivial to make a lexically scoped, deep copy to work with. This ensures that data is cannot be mutated while being used by the function and - when returned - can be protected from mutation by the receiver.

So Lisps which support 'let' support immutable data structures.

However, they also support mutable data, as does Python - which provides immutable tuples, mutable arrays, and - of course - dictionaries etc.

As I understand it, Clojure restricts us to immutable data structures so that we have no choice but to use them - whether needed or not.

I think it's better to provide programmers with a broad a set of tools rather than restricting them to a subset of what they may need.

I don't subscribe to the thinking which believes that it is possible to make poor programmers better by mechanically restricting what they can and cannot do and what they must and must not write. That is the school of thought which led to Java's overly verbose syntax and restrictive data structures. As I understand it, it has led to much code duplication in Java - but, inasmuch as I chose not to learn or use the language, I don't really know. I do know that experienced Java programmers groan a lot and tend to use bloated IDE's to compensate for the boiler-plate code.

Regarding software transactional memory: there is also a CL package which purports to support this. And again - I'm not a sufficiently experienced Lisp programmer to know how it compares with Clojure's support. But again, it's there and so Clojure may well not be an extension in this case either. [does anyone know?]

But what I intended was to pose this as a question to discuss, not something to argue about.

4. Neither you nor Rich nor anyone else has addressed my question regarding Clojure's creation of a whole slew of names for semantically identical methods in Lisp.

One of the greatest time wasters that language designers perpetuate is trivial variations in syntax and method names between languages with identical semantic behavior. In my original post I quoted a variety of variants of 'if ... then ... else-if ...end-if', but the practice is profligate. All it really serves to do is slow down programmers by requiring them to try to remember pointless syntactic differences between the languages they know and the one they are currently coding in.

As I said initially, I'm starting to fall in love with CL's minimalist syntax - because it's one less thing to try to remember in the vast forest (to use your analogy) of methods, functions, special forms, macros, etc that one must know in order to code in any language.

Thanks again and apologies for sounding like an ass.

Powered by mvnForum

Our Sponsors

  • Society

    Society provides us space for our regular meetups.

  • Sonian

    An EC2 instance and food for many events

  • Rally Software

    Space for the Denver ClojureBridge

People in this
Meetup are also in:

Sign up

Meetup members, Log in

By clicking "Sign up" or "Sign up using Facebook", you confirm that you accept our Terms of Service & Privacy Policy