
I finally understand why I'm not allowed to use Lisp - gnosis
http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/41c23db25ddcd899
======
j_baker
I learned something a long time ago. It's far, far easier to dismiss others'
code as "complex", "unmaintainable", or "clever" than it is to try and
understand the code well enough to figure out whether that code was written
that way for a valid reason. It's true whether you're new and approaching a
codebase for the first time or whether you're reviewing someone else's code.

And no, I'm not saying that it's ok for code to be overly complex or
unmaintainable. I'm saying that your first impression of code is probably
wrong and you need to understand it before you dismiss it.

~~~
Joeri
It's always twice as hard to read code as it is to write code. For that reason
alone, clever code is usually unmaintainable.

~~~
raganwald
_It's always twice as hard to read code as it is to write code._

True.

 _For that reason alone, clever code is usually unmaintainable._

How does this follow logically from the first statement? And more importantly,
what alternative do you suggest? Are you positing that for a given problem,
there is always some alternative solution that is "less clever" and "more
maintainable?"

If you've never seen folding and unfolding before, code that makes heavy use
of "map," "each," "select," and so on looks clever. But in reality, it is
simpler and less bug-prone than fooling around with for loops and off-by-one
errors. To my eye, for loops are clever and unmaintainable.

Moving up the scale, what about recursive combinators?

[https://github.com/raganwald/homoiconic/blob/master/2008-11-...](https://github.com/raganwald/homoiconic/blob/master/2008-11-23/recursive_combinators.md)

They look very clever. But then again, rolling your own recursion from scratch
every time you need it makes the person reading your code do a lot of work to
figure out what you're doing. Is it "clever" to separate the concerns of how
to implement recursive algorithm from the code that does something
recursively? Or is it clever to roll your own code every time?

WHat about parser combinators? Clever or not? How about rolling your own
interpreter for a DSL? That's an official pattern from the GoF book. Can I do
that and write maintainable code?

Anyhow, I'm saying the same thing over and over. What is "clever?" Making use
of a language feature or algorithm or well-known practice that someone else
hasn't seen before and is too lazy to learn? And what is the alternative?
Greenspunning the same functionality in an under-specified, bug-prone one-off
way?

~~~
rapind
I'd say clever is defined by your audience. If you're writing something that
others on your team would consider clever, then you're responsible for making
sure they understand it. Even if that means losing whatever time you saved by
writing something clever (the advantage is still creating a smarter team
though).

Responsible developers write a lot less clever code because it means they feel
obliged to comment the crap out of it and find the time to go through it with
other team members.

Unfortunately there's a lot more clever code that only one person really gets.
If you're too clever for your team, then quit slumming it and find a smarter
team. You're going to be toxic to a team that isn't as clever as you are
unless you assume the role of mentor and all of the responsibility that comes
with it... and the required patience.

~~~
raganwald
Your response assumes that clever code exists to save time writing programs,
and that for any problem there are a wide range of equally good solutions
possible from "takes a long time to write but is easily readable and
maintainable" to "quick to write but impossible to read and maintain by those
who don't have doctorates in functional programming idioms."

I don't dispute the existence of code that is unnecessarily clever, but I
suggest that sometimes what appears to be "clever" for a given audience is in
actuality the local optimum. Attempting to optimize it for readability without
further study will worsen the code in some way, such as conflating concerns
that have been carefully separated or introducing dependencies.

~~~
stcredzero
_I suggest that sometimes what appears to be "clever" for a given audience is
in actuality the local optimum. Attempting to optimize it for readability
without further study will worsen the code in some way, such as conflating
concerns that have been carefully separated or introducing dependencies._

If "clever" is often necessary to avoid things like _conflating concerns_ or
_introducing dependencies_ , I think this points us in the direction we need
to take in improving programming languages. (Off the top of my head, this
applies to both Ruby and Smalltalk.) Though, I've also observed that bolt-ons
to programming languages to address these issues are often a bit too "clever"
themselves. (Example: The original implementation of Objects in Perl.)

~~~
raganwald
_If "clever" is often necessary to avoid things like conflating concerns or
introducing dependencies, I think this points us in the direction we need to
take in improving programming languages._

I agree!!!! As a rough rule of thumb, "horizontal" or "general purpose"
libraries are a potential source of inspiration for language improvements.

In my own case, I think #andand is a terrible kludge. But if I were designing
a new programming language, one question I would ask myself is, "How do I make
this go away?"

I might add support for monads, Or maybe I would decide that null is a bad
idea. I don't know, but I would certainly give it some thought.

------
acangiano
> I work in C# (worst language EVER!)

You lose all credibility right there. C# is far from the worst language ever,
and a pretty decent one among mainstream object oriented languages.

~~~
city41
As soon as I read that I looked for the date of the post. May, 2007. This is
before C# 3.0 was released and chances are he was even using 1.0 based on
impressions from his boss.

C# isn't half bad now, but back then, I agree it was fairly crummy.

~~~
barrydahlberg
IIRC generics came in 2.0 which narrows it a little.

------
enjo
I remember running into this early on at Quickoffice. I was tasked with
essentially re-writing the entire application stack as the existing code was
in pretty rough shape.

C++ was mandated by the platform, but I spent a lot of time getting the STL
and Boost up and running. The entire thing relied heavily on templates,
including some of the more advanced meta-programming techniques. In each case
the 'cleverness' was warranted as it greatly reduced the complexity and
redundancy of the code.

My boss at the time raised concerns over how maintainable this all was. How
we're junior programmers going to be able to work on it? Being all of 22 I
naively responded "well, lets just hire people who can handle it."

Interestingly, that's exactly what we did. We were much more thorough in our
hiring process precisely because we needed folks who could rise to the level
of the code we had written.

It seems to me that people (and companies) tend to rise to the level of the
expectations that you set. In this case, making the decision to use LISP means
that you're consciously making the decision to hire the caliber of talent that
can use lisp. That may be a good thing (it was in the case above for sure).

I suppose it really comes down to making sure that the complexity of the
application warrants the use of the more advanced abstraction. A simple web-
site for someone selling tractors might warrant a different ("easier") tool
than something inherently more complex.

------
gsivil
I find nothing interesting in the original post to be honest. Just somebody
that has a superficial impression about C# is complaining. Even the first 25
comments that I read are of no particular interest.

Meta: I wildly guess the HN post gets all the upvotes because initally people
think that it will be about a google employee not allowed to use Lisp in
google.

~~~
Johngibb
For this reason, I wrote a chrome extension that shows more of the subdomain
on hacker news:
[https://chrome.google.com/extensions/detail/amenlkcfjlmchdpo...](https://chrome.google.com/extensions/detail/amenlkcfjlmchdpogjmdolblcjlcmdbp)

------
fleitz
A better question is whose going to maintain all those for-loops that are
buggy because human error means even a basic thing like a loop will get
screwed up. Managers are always talking about code reuse but as soon as you
pass a function, they are like "Woah thats crazy how can we maintain that"

Only managers would think that

    
    
      int accum;
      for(int i = 0; i < arr.length; i++){
        accum += arr[i];
      }
    

is more readable and maintainable than...

    
    
      arr.sum(x => x)
    

Oh look and even though I've written a million for loops depending on the
language there is a bug because i didn't intialize accum.

~~~
fauigerzigerk
Are you explaining the difference between code you have to write and debug and
code that someone else has already written and debugged?

~~~
fleitz
What I'm saying is that passing functions (or functional programming) allows
you to reuse a lot more code than typical imperative programs with a lot less
effort. I personally find the functional style to be much more readable and
don't understand why everyone has such a problem with the maintainability of
code written in a functional style even if it's a mostly imperative language.

------
apl

      > They follow where We the Blessed Gurus lead them. But
      > this time it is to the slaughterhouse, because the
      > world needs only fifty Lisp programmers to write All
      > the Code.
    

Oh comp.lang.lisp. Why did I even bother to read the replies?

------
DougBTX
I was going to tell him off for missing Enumerable.Aggregate, but then I
noticed that he posted 6 months before that was included in the standard
libraries, so I'm going to have to let him off.

------
hessenwolf
Somebody uses the following line in the thread: "not because they are good
programmers, but rather because they are good communicators".

Hell yeah. Overly-abstract code can be like using variable names x1 to x267
because it is more efficient to type. Time I spend grokking your code is time
our website spends offline.

------
arnoooooo
This reminds me of PG's essay on Java, in which he wrote "Java's designers
were consciously designing a product for people not as smart as them.".

Ben says that smart people should also work with these languages because non-
smart people might have to work with the code. I think that is actually what
happens a lot in the industry. Smart people who know Lisp, Ruby, Python, etc.
still end up coding in Java because that's the language everybody else knows.

What I don't like about this is that it's basically saying that people can't
become good at programming. It's accepting that the majority of professional
developpers can't learn to use languages like Lisp correctly or to understand
a Lisp program that uses powerful abstractions.

Maybe the ones who really can't are not in the right business ?

~~~
IDisposableHero
I take the point about "Java's designers were consciously designing a product
for people not as smart as them."

But, consider the reverse - The C++ spec always seemed to as if the language
designers were showing off - competing to add fatures that showed off how
clever they were, without as much regard for the readability and
maintainablity of the resulting code in the language. I don't think that
strategy is optimal either.

Also, if you think only simple code can be done in C#, have a look at the Rx
framework. C# as a language is suffering from a bit of bloat too, but not as
bad as C++.

------
dan00
I think the problem of Lisp is, that it's very powerful and very dynamic. As
long you're working alone, that's not that much of an issue, but with more
developers you need to add more security nets, without the aid of a powerful
type system.

Most people love dynamic typing, because they hate the static typing of
languages like C++ or Java. Powerful languages also need a powerful type
system, that the developer can fully express his intentions, with the aid of a
compiler validating them. Mainstream languages should start looking at type
systems of languages like Haskell.

~~~
nocipher
The more fundamental reason, I believe, is that it is often hard to just hack
something together in Lisp. This mostly due to the library issues and a lack
of users creating good documentation and guides.

For example, a few weeks ago I wanted to start writing a program that analyzed
some spreadsheet files, spit back out some relevant information (including
graphs), and then served this information up on some specified port. I
initially wanted to write this program in Lisp so I began to look at available
libraries. For the gui component, my first pick was Qt, for which Lisp
actually has bindings. I spent about a week trying to get all the dependencies
for it installed unsuccessfully. The documentation essentially says, "You need
all these installed," and then gives you a bunch of links to their respective
websites. All of the other details were missing.

Specifically, I could not install the smoke bindings for Qt. I searched for
any guides or documentation and always found a git/svn repository. Once I had
the files, I had no idea what to do with them; where they needed to go or how
to compile them, etc. Raw .cpp and .h files that have dependencies do nothing
in isolation. Furthermore, there was no support forum or any other place to
ask for help.

Finally, I just gave up. It was too much work to just hack together what was
supposed to be a fun weekend project. So I moved onto Python, which just
worked. I'm sure I'm not the only one who has had such frustration.

~~~
gnosis
Did you try using Quicklisp?

Also, I would recommend that when you have problems like these you come ask
about them on #lisp and #quicklisp on freenode.

There are many very helpful and knowledgeable people there. Often, they're the
authors and maintainers of the very tools you're trying to use.

~~~
nocipher
I didn't even know it existed. Thanks for the tip; I'll check it out.

------
S_A_P
OOOH I was so wanting to tell the OP

What is so hard about this??? //assume some sorta IEnumerable derivitive
IEnumerable<foo> bar = new IEnumerable<foo>() { obj1, obj2, obj3, obj4, ...};

var accumulator = bar.TakeWhile(x => x.property == someValue);

but then I saw the .NET 2.0 timeframe.

But even with .NET 2 you had generics which makes things pretty easy. But then
again, he/she is ranting so I should just ignore him/her.

It doesn't matter what language you are using, if you cant write something
that is legible to solve the problem, think about it more.

~~~
InclinedPlane
I suspect they were using .NET 1.x at the time, which would explain a lot.

~~~
S_A_P
I initially thought that as well, but the post did mention generics.

------
robinduckett
Asked me to sign in to Google Groups. Closed tab.

~~~
Helianthus16
I do not understand why giving feedback about the usability of the link
deserves downvotes. I didn't even understand what had happened when I was
suddenly at a google log-in, shrugged, and closed the tab.

~~~
MortenK
Funny thing is, if it were a Facebook login wall, tens of upvotes would have
ensued.

------
drivingmenuts
This is a case where the author put his needs over the needs of the
organization.

------
rorrr
Kudos to his manager for actually looking at the code and recognizing the
problem. Maintainable code is extremely important. Just keep your code simple.
Adding another layer of abstraction instead of writing a simple and readable
loop (if the language doesn't have accumulators) is not a good solution.

I've seen this too many times. Smart developers write complex code, just
because they can (and often it does make it shorter), but then mid- and
junior-level developer struggle with it. So company has to spend more money on
smarter developers.

Here's a relevant post by Linus:

[http://thread.gmane.org/gmane.comp.version-
control.git/57643...](http://thread.gmane.org/gmane.comp.version-
control.git/57643/focus=57918)

~~~
j_baker
> Smart developers write complex code, just because they can (and often it
> does make it shorter), but then mid- and junior-level developer struggle
> with it.

You know, I can't help but be reminded of Harrison Bergeron when I read this.
I'm waiting for the day when someone comes up with a handicap for programmers
so that we can _all_ write code with the same ability as the least intelligent
and least experienced members of our teams.

Did it ever occur to you that there might be a method to smarter developers'
madness? I mean, maybe they write code the way they do because, you know,
they're smart and know something you don't?

~~~
nostrademons
"I'm waiting for the day when someone comes up with a handicap for programmers
so that we can all write code with the same ability as the least intelligent
and least experienced members of our teams."

Java? ;-)

~~~
j_baker
Touché. I must admit that I've never thought of Java as something from Kurt
Vonnegut, but the analogy is apt.

------
mkramlich
link redirects me to a login wall

~~~
gnosis
Try:

[http://groups.google.com.nyud.net/group/comp.lang.lisp/brows...](http://groups.google.com.nyud.net/group/comp.lang.lisp/browse_thread/thread/41c23db25ddcd899)

or type the original link in to the form at:

<http://dongana.com>

------
ddkrone
The same can be said for any statically typed language. Any language that
binds types as late as possible is infinitely more enjoyable to work with than
one that fixes types at compile time. Short of developing missile guidance
systems I don't think static types are warranted for anything.

~~~
DougBTX
For me type inference changes the picture, since it reduces the duplication
you see throughout Java-style statically typed code, but doesn't give up all
the benefits.

~~~
ddkrone
The only benefit I'm aware of is slightly faster code and even then the
dynamic version is almost always more readable and easier to maintain and
refactor. The ideal would be a dynamic language with optional static typing
but I have yet to see a language like that.

~~~
siika2000
> The ideal would be a dynamic language with optional static typing but I have
> yet to see a language like that.

That would be Common Lisp.

~~~
stcredzero
_That would be Common Lisp._

There was such a version of Smalltalk called Strongtalk, but it never got a
community behind it.

~~~
igouy
Actually - "but then the Java phenomenon happened and we eventually had to
switch to Java before ever releasing it".

<http://www.strongtalk.org/history.html>

