

Ask HN: Why does learning lisp make you a better C-programmer? - morphir

from Eric Raymonds essay, How to become a hacker:<p><i>LISP is worth learning for a different reason — the profound enlightenment experience you will have when you finally get it. That experience will make you a better programmer for the rest of your days, even if you never actually use LISP itself a lot.</i><p>However, I want concrete examples (methodologies)
======
jacquesm
Ok, here is one:

Lisp makes you think in terms of higher level memory structures than just
other than bytes and pointers to structs.

The 'lists' and all the operations that you can perform on them will initially
feel _terribly_ inefficient (filter??!), but this will literally free you from
having to think about how stuff is laid out in memory.

The upshot of that is that you will see more clearly what the real solution is
to your problem.

As for functional programming, that in and of itself is a great way to get an
alternative look at your programming.

For a fantastic example of that look at the 'hashlife' code, it's written in C
but it could only have been done by someone with a profound insight in to the
benefits of functional programming.

The reverse is also true, learning C as a lisp programmer will make you a
better lisp programmer.

In fact I doubt that there is any language that does not have to contribute
some unique bit to the world of programming, and that will enrich you if you
learn it to some level of proficiency.

------
jerf
Others have already taken your challenge on directly, and that is a part of
the truth. However, I want to point out that if you want, you can sit and
nitpick each one, pointing out how C is just fine on that front, and talk
yourself into a position where it's not that big a deal, by focusing on one
thing at a time and appearing to knock out each thing one by one. For this
reason, "enlightenment experiences" tend to resist concretization; focus on
just the words and you can talk yourself right out of them without much
effort.

But the point is not the laundry list of bullet-point features, the point is
the whole totality of the experience. There isn't a thing that Lisp can do
that C can't be beaten into doing; for one thing, writing your own Lisplet
isn't that hard (and a good exercise, too!), and there you have it, "all of
Lisp" right there. But it makes those things so hard that you won't really
want to do them. You can intellectually learn the value of some of the things
that Lisp provides, but until you live for a while in an environment where
they are _easy_ you will never fully grok them.

Even though Lisp teaches nothing that could not be theoretically learned in C,
in practice you won't learn them in C. The bar is too high, and if you're
really trying to do it from scratch you'll make too many mistakes on things
that were worked out 40 or 50 years ago. Learn something like Lisp.

(Haskell is another choice on that front; Lisp will teach you better
metaprogramming, but Haskell has some advantages in _forcing_ you to
completely follow through with an alternate paradigm. Arguably Lisp is more
practical for permitting such things, but less educational.)

------
randombit
Learning new languages makes you a better programmer. It really has very
little to do with C or Lisp specifically.

The more different the language you are learning is from ones you have used in
the past, the more new approaches you learn. For instance if you already know
C++, you'll learn a lot less from learning Java than you would if you learned
Lisp (or ML, or Haskell, or Smalltalk) - purely because the delta is much
larger. Similarly, if you already knew Ruby you'd probably learn fewer new
techniques learning Smalltalk than Haskell, and if you already grok Scheme
you'll learn very little from Common Lisp.

If you are a C hacker, and especially if C is your first and primary language,
Lisp just happens to be on the far other side of the wheel of languages, so
you'll learn a heck of a lot from it. I would wager that learning C would make
a Lisp hacker better at Lisp, too, though I don't know anyone for whom Lisp
was a first language.

------
jcl
Here is an example of a programmer who was able to produce a much more
efficient and reliable C program by applying principles he learned in a Scheme
course:

<http://www.cs.indiana.edu/~jsobel/c455-c511.updated.txt>

Now, this may not be exactly what you're looking for, in that the C code he
ended up with is not what you would call idiomatic C, so whether it made him a
better C programmer _per se_ is debatable. But doubtlessly few of his
classmates were writing idiomatic C either, and his program's performance and
reliability would not have been possible if he hadn't worked through the
problem in Scheme first.

(Edit: The closing paragraph, in particular, illustrates the broadly
applicable "profound enlightenment experience" that Eric Raymond describes.)

~~~
jonsen
Thinking functionally you C better.

------
geocar
I want a pony.

Learning a new language- truly learning it- puts quux in your brain. Those
quux are unique to that language. You can try to make do by translating the
meaning of those quux into your favorite language, but the fact is that
"gravitas" doesn't really mean "formality in bearing", so there's some
difficulty in working that way.

Consider recursion: Generally accepted you can simulate it with stacks and
lists, the recursion quux is very powerful because binary tree traversal is
simply walk(t){walk(t.left);walk(t.right);}

Recursion is available in many languages, but not all languages. In _those_
languages an expert programmer won't have the quux for recursion and you'll
see lots of arrays and array resizing as the programmer simulates recursion
when it is needed- and terrible contortions when the function can be
implemented without recursion.

Without knowing more about your background, it is difficult to give a better
example than that. If you know Java and perl, this is why Java programs
written by a perl programmer look strange to a Java programmer: The perl
programmer is using "perl quux" to work out the program in their head, and is
translating them to Java syntax and grammar. I suspect that you've seen other
examples you can use here.

The important bit: Lisp has a powerful quux in it; it is powerful because it
reduces huge problems to much simpler problems. Learning lisp (or inventing it
independently) is the only way to get that quux in your brain.

However here's hope: Once that quux is in your brain, you won't see
parenthesis anymore.

------
arto
You will at least be able to recognize the symptoms of Greenspun's Tenth
(<http://lispers.org/>) in your C code and know when to cut your losses in
those cases when C is not the best possible fit to the problem domain at hand.

~~~
andrewcooke
for my money, this is the best argument here.

c memory handling is so painful, and support for higher order functions so
limiting, that there really is very little that you can carry across directly
from lisp and/or functional programming to c. on the other hand what you do
see, is how much time you are wasting due to c's constraints; something that
may help you better allocate your time and/or choose your tools.

there are other small wins too. sometimes knowing the "easy way" to solve a
problem you can then work out a compromise in c that gives you some of the
benefits without being too hard to implement. as a result you can end up using
realloc much more than other people you work with :o)

------
Hexstream
Lisp dramatically lowers the bar to make a compiler. You don't have to mess
with parser generators and do complicated parsing, the Lisp reader and
s-expressions already provide a ridiculously simple and powerful framework to
make your own syntax and semantics.

You can easily invent your own language, basically you can just represent the
structures of your language as objects and then walk that structure to
generate a tree of closures that represent the semantics, the code to execute.
With a compiler, you can give your language very "special" semantics and
performance isn't adversely affected (it might in fact be better). What's
more, if your custom language is very declarative, really close to what you
actually mean to say, your "programs" written in that language is actually
useful data you can use to make high-level debuggers and such.

And for generating that tree of objects in the first place, you can use macros
to make a nice s-expression representation that expands into object
instantiations instead of having to do objects manually, which is harder to
both read and write.

If you try this, you'll see that languages really are not that magical, that
it's within your reach to design and implement one even without investing
hundreds of hours in learning arcane skills, if you use the right tools.

------
malkia
I came to understand and appreciate exceptions better, once I learned how they
were implemented in Common Lisp. The same goes for macros, multiple-values,
dynamic binding, closures, multiple-dispatch, the REPL, and many other things.

Not all of them are available in C/C++, but in one form or another they could
be done.

The biggest revelation for me was the most of the C++ patterns, are just
weaknesses of what the language can express. This made me free of what was
expected as norm in C++, and I came to appreciate just C more and more (being
more simpler).

------
numeromancer
In every art there is a dichotomy between the practical and the theoretical,
and each has their fundamentals. In Comp. Sci., those two sets of fundamentals
are these: sets of machine instructions, which come in several varieties; and
lambda calculus, or one of the equivalent (by Church's Thesis) formal systems.
C and Lisp are similar in that they represent the first steps in each case to
reach the other: C is a level above machine code, providing some abstraction
and portability to the use of machine code, the fundamental elements of
practical computing; lisp is a level above lambda calculus, providing a
practical system for using functions, the fundamental elements of theoretical
computing.

In short, mastery of C is concomitant with the ability to measure the cost of
computation (sometimes, regardless of the value of it); mastery of Lisp is
concomitant with the ability to measure the value of computation (sometimes,
regardless of the cost).

Since C and Lisp lie on opposite borders of the universe of computation,
knowing both will allow you to better measure the scope of that universe.

------
wingo
There are counterexamples too. I feel like my C has gotten worse in some ways
(and not for lack of practice) because of Lisp -- I tend to make more
expressions and assign fewer temporary values. C code often benefits in
clarity from named temporary variables, but my Lisp style tends to eliminate
them.

------
jff
Don't fall into the trap of listening to Eric Raymond too much. He likes to
romanticize the whole thing too much, as this quote kind of demonstrates.

That said, let me echo some of the other posters: Learning any new languages
will improve your skill in all languages. Even if the only benefit you get out
of learning Lisp is a better understanding of recursion and linked lists, you
win. There is also a great deal of satisfaction for a newcomer in writing a
good solid Lisp routine, because you're thinking it'll never work, and then it
works perfectly.

Where C is so close to the machine you can taste it, for example structs and
pointers, and I love it for that, Lisp is quite far away. Maybe Lisp is also
useful to pull your head out of the MMU and think at a little higher level.

------
pmarin
lisp doesn't make you a better C-programmer, It make you a better programmer
becouse It make you think in a more high level abstractions (I am removing the
"C"). learning Assembler may make you a better (efficient) C-programmer.

------
dlsspy
Learning something new makes you better at things you already do (if it
doesn't, it's not worth learning).

------
lbj
Here's why: [http://www.bestinclass.dk/index.php/2009/11/mind-games-
ascen...](http://www.bestinclass.dk/index.php/2009/11/mind-games-ascension/)

------
anonjon
Perhaps part of it is that you will no longer feel the need for methodologies?

When programming lisp, the syntax is so regular that the patterns in your code
become very obvious. When I see patterns I pull them out into macros or high-
order functions, and name them. (Then sometimes I see patterns in the
macros/hofs, and I pull those out and name /them/).

I personally /boggle at the guys who love 'design patterns' and the like. I
mean, I understand the utility of using patterns in software, I do it all day.

The problem is that only having maybe 23 (?) different patterns seems very
limiting to me.

