tags:

views:

1884

answers:

10

I was wondering for a while about this topic and i would like to hear some opinions from the community. What i am wondering about is how to explain to a non-programmer the conceptual difference between a language like C and a language like Lisp. What I find challenging about this is to translate the knowledge of the language itself into concepts that can be understood by a non-programmer and I think that it requires abstract understanding of fundamentals of both languages that I cant convey to plain English.

Any thoughts would be appreciated.

+4  A: 

In C the programmer works with primitives such as subroutines, stacks, heaps, memory pointers etc. These are all concepts that make sense when you want see exactly how the computer is going to execute your code.

In Lisp you use primitives such as functions, expressions etc. that make more sense mathematically. It's easier to see how your algorithms are structured and it's easier to work with complex algorithms but it's harder to see what actions the computer will perform to execute them.

Mendelt
A: 

C is like driving a stick-shift car, if you know what you are doing, you can get excellent performance, if you don't you can mess it up very badly. Lisp is like an automatic, it takes some load out of your shoulders making the internal machine easier to handle, it hides away some things so you don't even have to think about it.

One important difference is that an expert racer will always use a stick-shift car, but an expert programmer may use C only if he wants run-time performance; there are other kind of performances which means that Lisp is not only for non-expert, but for experts that want to go in another direction, like fast coding. It's like if you make a contest of driving-and-juggling, no matter how good you are driving, you'll take the automatic because the important thing is juggling (that would be, prototyping).

What I've just said it actually applies for any high-level-vs-low-level comparison. If you want something more specific, let me know and I'll expand in that direction.

J. Pablo Fernández
I like your explanation but two things are not really clear to me: are you implying that lisp is more slow (performance wise) from C?and cant high level code be written in C (maybe i cant overlook the c\c++ abomination)
Roman M
Lisp code can be as fast as C code or close, but you have to optimize for that; is an extra task that is not the natural thing you do when writting Lisp. It's an extra and I wouldn't go into those details for non-programmers unless asked about.
J. Pablo Fernández
I don't think high level code can be written in C. Of course it depends on your definition of high-level. C was once the high-level language in a world of assembler, but when writting C, no matter how, you still work with the processors primitives.
J. Pablo Fernández
+4  A: 

Assume a father, and a son called Peter.

Say that C is like

Take this, open the door, go to the corner and put it there, 
then come back but close the door first

Lisp is like

Please make it so that this is going to be put into the corner. 
You are allowed to open the door.

In C like languages (imperative languages), you tell the compiler precisely what to do and how to do it.

In Lisp like languages (functional languages), you tell it what you want, but not how it can be done.

For example Peter could call his friend Karl to put it, while he opens the door (doing things parallel). C cannot do this, since you've said Peter should do it.

Johannes Schaub - litb
I think in a functional language you specify how things are done. In a logic language, like Prolog. If you look at the first lesson of SICP, it is explained how mathematics is about why, and programming about how. And they do a lot of functional programming there.
J. Pablo Fernández
I was just about to say that #2 is more Prolog than Lisp. In pure Lisp, this example simply cannot be stated, as pure Lisp has no side effects, and the whole point of the example is the side effect: to change the world in such a way that "it" is down there at the corner.
Arkadiy
Now that I think about it, this deserves a new answer. see below.
Arkadiy
A: 

Well, first it might make sense to explain that they're both computer languages, and using either will get the computer to do what you've programmed.

Broadly speaking, I'd say that C is a language where you explain exactly what you want done, and in what order. Pick this up. Put that down. Add these numbers and record the sum.

In Lisp, the programmer wants to know a result, but in order to find that out, we need to ask what happens in these cases. And that depends on these other computations. Which in turn...etc. It's no wonder that Lisp gave us the if statement, as well as functions that end with 100 closing parentheses.

This is a good low-level imperative vs. high-level functional outline, but there are a lot of other topics to mention to someone more advanced. Moving bits. Playing on the stack/heap. Garbage collection. Macros (the same word in both languages, but very different). Functions (ditto). Recursion. Symbols. The list is long.

JXG
A: 

I like @litb 's answer, but I think that the # 2 applies more to Prolog-like languages or regular expressions or SQL, but not so much to Lisp. With Lisp, I'd change the explanation as follows:

Assume a father, a mother and a son called Peter. The mother says that the room needs to be tidied up. For that, the toy on teh floor needs to be put away. So the father says to the son:

Let's imagine the world where you managed to put away this toy. You need to get to the other room somehow, too. Wouldn't Mom be happy?

The end result of this conversation is the fact that we know how to make Mom happy. But we did not necessarily make her happy. To actually accomplish anything externally visible in pure Lisp, you need to break the purity and allow a side effect.

Arkadiy
+1  A: 

Specifically for C and Lisp, the main difference is that C allows you the freedom to tinker with small details to make things fast, whereas Lisp provides enough abstraction to allow you to only tinker with the details when you really need to (and at times, that means calling out to routines written in C, via a foreign function interface).

Vatine
+3  A: 

Coding is essentially communication and, often, there is a conflict of interest between expressing a solution to a problem in such a way that a machine can execute quickly and expressing a solution that a human being can understand quickly. A programming language may force you into a certain mindset, and sometimes you may choose a particular language so that you will adopt that mindset.

C is a low-level and imperative language that tends to put you into a mindset of thinking step by step and thinking at machine level. Coded skilfully, the resulting C code can be easily understood by a human being.

Lisp, specifically Common Lisp, allows you to pick and choose from a range of paradigms/approaches (including functional, imperative and object-oriented) and lets you express what you want, how you want. It does not force you into a particular mindset. I find that a functional programming style is easiest in Lisp, but not always the best approach to solve the problem at hand. A Lisp programmer will often choose to write code that is as clear, concise, and elegant as possible (from a human point of view). Coded skilfully, the resulting Lisp code can be compiled into an efficient sequence of machine instructions (with the help of 50 years of Lisp research).

For a non-trivial program, no one chooses C when they want to express a solution concisely and no one chooses Lisp when they want to minimise the use of a machine's resources.

Nelson
having a sufficiently complex problem, it's easier to create a more efficient solution to it in lisp than in c. having clean and concise code means you spend more time thinking in the problem domain, where an optimization can mean orders of magnitude, not a few percents by (marginally) faster loops
Attila Lendvai
A: 

In C, you spend your time manipulating code to work on a computer in such a way that your ideas are the result. In Lisp, you spend your time formulating abstract ideas that just happen to run on a computer. Or, in the words of Abelson and Sussman in SICP:

Programs must be written for people to read, and only incidentally for machines to execute.

In other words, with C your mindset is 'closer to the hardware', so to speak. However, by forcing you think in terms of a machine and not quasi-mathematical abstractions, C rewards you with a performance boost (although I've been hearing that a select few high-level languages like O'Caml and Haskell are actually starting to outperform C is some cases, so take that with a grain of salt).

A: 

I would agree with everyone here that C is a low-level language where you specify all the tiny details. But I disagree with what everyone is saying about Lisp.

C is a low-level sequential language that is strongly coupled to the von Neumann computer concept (which, in turn, is closely related to Turing machines). C has a lot of syntax; the evil abomination C++ (which isn't really C) is an object-oriented language strongly coupled to C with a whole lot more syntax than C. Both theoretically allow you low-level access to the internals of the computer, but in both, you have to really know what you are doing in order to get the best performance.

To me, performance isn't as much an issue as being able to write code. After all, premature optimization is the root of all evil.

Because C has a lot of syntax, it has a very primitive macro system, which is pretty much limited to text substitution. C++ gets around this by having templates, but because C++ has a lot of syntax, template metaprogramming is a scary thing.

Now, Lisp is a language strongly coupled to the concept of Lambda Calculus--which is one of three ways of viewing a computer (I can't remember what Prolog's method is called, but Prolog's is the third way). In addition, it has very little syntax: a Lisp program is primarily just a bunch of lists, where the first element of each list is treated as a function call unless otherwise noted (usually by using the "quote" operator). Because of this, Lisp has a very powerful macro system--one where you could use the language itself to re-write a program. This, in turn, allows you to mold the language to your needs, which allows you to write programs faster than in a language like C.

As for Lisp being functional, it's not, although Scheme puts special emphasis on functional programming, for educational purposes. Common Lisp has a decidedly non-functional "loop" macro that lets you do all sorts of loopy operations; it is a good example of how you could create a specialized language for your needs. Lisp is whatever you want it to be.

Alpheus
C actually has very little syntax in comparison to most imperative languages.
Simon
It's true that C has very little syntax compared to other imperative languages, but Lisp has very little syntax compared to C.
Alpheus
+1  A: 

C was intended as a replacement for assembly language, something to write operating systems and other system software in. This means that it can be easily translated into machine code, and that it's usually fairly predictable how it will be translated. It's closer than most other languages to the actual computer execution. It's also very versatile in what it produces, which can include code that will run with very little system support. It interfaces well with almost any other software. As a language, it's very inflexible. Adding object orientation requires explicit and somewhat unnatural constructs. Adding functional programming would simply not be worth it.

Lisp was intended as a mathematical way to express ideas, and how it would run on a computer was a secondary consideration, as long as it would run. To this end, it generally requires specialized support software, which provides assorted services that the operating system doesn't provide, such as garbage collection. Since it's effectively off in its own little world, it doesn't interface well with other software that may not play by its rules, and maintaining this little world takes system resources. What it gains is flexibility. It's a procedural and a functional language, and it's fairly easy to add object orientation (it's one chapter in Paul Graham's "On Lisp"), or in general any other way of programming you like.

C shines in cases where you know what you want to do, and you want to do it efficiently, economically, and portably. This makes it a natural for systems software, such as operating system kernels and network protocols.

Lisp shines in cases where you don't know what you want to do, and you want to figure out how to do it as you go along. This makes it a natural for artificial intelligence programming, or in other sorts of exploratory programming.

In C, it's easy to do things efficiently, and harder to get them right. In Lisp, it's easier to get things right, and harder to get them efficient.

David Thornley