
Tim Daly on Lisp in Industry - fogus
http://article.gmane.org/gmane.comp.java.clojure.user/34269
======
dkarl
_So, yes, lisp does not HAVE a lot of libraries. But what people miss is that
lisp doesn't NEED libraries. Why have a graph library when you can just embed
the graph naturally in the data? When I wear my Java hat I search for
libraries to do what I want. When I wear my lisp hat I simply do what I need.
I can't remember when I needed a "library". So, to a lisper, libraries have
the flavor of crutches. Having a large set of libraries (crutches) is not a
feature._

I suppose this makes sense for a guy with his resume: lots of AI and
mathematical programming. However, this attitude makes no sense when you're
trying to write a rich application with iteration after iteration of adding
trivial but laborious features. When you want to add user preferences to a GUI
app, you need a dialog box, a backing store, plus all kinds of bells and
whistles like an easy way to add validation and tooltips to the preference
values, some kind of encryption for passwords, etc. Of course the ideal case
is for all this stuff to be written in Lisp and for your application to be
written in Lisp, but if the Lisp ethic continues to be "we don't need no
stinking libraries," then frameworks written in brain-dead languages like Java
will continue to predominate, and we will just have to be happy if there's a
Lispy language that integrates well enough to use the framework. (In
particular, in Java that means being able to create classes that implement
interfaces, and making sure those classes get loaded through the right
classloader.)

~~~
akshayubhat
Even with Graph Mining, I have rarely seen anyone using lisp or FP language.
Most of the practitioners and researchers use C++ , Java or Python with
specific libraries such as Jung, Netowrkx, SNAP.

~~~
dman
I am assuming you havent heard of Allegrograph.

------
ezy
This is typical Lisper fare. Steve Yegge is right.

Open source math packages and academic software isn't "industry". Sorry.

And the bit about not needing libraries is just insane. It doesn't make any
real sense unless you're interested in reinventing the wheel, over and over
and over. Again, it makes sense in an academic context, because most likely,
he's usually inventing something totally new and the user interface to the
code is pretty mundane.

As for embedding the data in the code; Well, lispers love to talk about this,
but realistically, people have been doing this in other languages for years.
See lex/yacc as a somewhat recursive example of a domain specific language to
generate data to parse other domain specific languages that might generate
data :-). Just because your "domain specific language" is forced to be sexps,
certainly doesn't make it superior, IMO.

Honestly, the idea that _everything_ must be done with the same tool is a
crazy idea -- and emacs adoption of that lispish philosophy (which is
unsurprising given its origins) is what makes it such a turd.

~~~
msg
Oh no you di'int.

Some of us just like to have infinite scrollback buffer, rectangle select,
bookmarks, regular expression replace, in our remote shells. And all our other
customizations.

Emacs isn't the be-all end-all tool (it doesn't run on the JVM for starters).
But it is one _interface_ to rule them all, and the interface is extensible at
runtime. You can install a few packages and have a Java IDE running inside the
interface. Or a version control system.

It's not that you have to... but you invested enough effort in making your
interface powerful. You want to do more inside of it.

~~~
ezy
Oh yes I did. :-P

I don't actually feel as strongly as this comment might sound -- use what you
want to use -- but I wanted to get a dig in :-)

When I used emacs extensively (in viper mode, before Vim really was popular
and good vi alternatives with filename completion existed), it really blew as
a text editor without viper, and all the customizations never really worked
well with one another. (Viper didn't work with anything else, typically).

In particular, the shell mode you refer to was just awful. Most of the time it
would get confused by what came out of the pty -- lord help you if you
happened to echo the wrong thing (e.g. binary data) by accident to the
terminal.

Meanwhile, scrollback/rect select are basic features of any terminal emulator
(or gnu screen), and re-replace/bookmarks in the history is a basic feature of
modern shells.

~~~
pvg
_When I used emacs extensively (in viper mode_

That's like saying 'when I used a 747 to drive to the corner store...'

~~~
ezy
Yes, that's right.

~~~
kunley
Gentlemen, I think the whole emacs-is-too-big point is totally obsolete in
this century.

Vim eats 8-10M of my memory. Emacs with many different modes running eats
15-20M. It mattered back in 1996 when I've had 24M of RAM, heck I remember
programming in emacs + X11 having as low as 16M and I survived ;)

But to the point. The difference between 10 and 20M _doesn't matter anymore_.

What matters is that Eclipse eats 500M of memory, is sluggish and I doubt it
offers better programming experience; still so many people don't want to
listen that there are alternatives to it.

I think that's the area we should debate & educate people. Both vi/emacs are
brilliantly light these days.

------
felideon
My favorite parts:

    
    
      I am currently working in Java to re-implement an algorithm I
      prototyped in lisp. If I replace all of the required curly-braces
      and semicolons in Java with parens it turns out that the Java
      program has more parens than the lisp program. The lisp program
      is 20 lines, the Java program has crossed 100 lines and is still
      growing.
    
      In Java I need "factory objects", "visitors", and other such pieces
      of "design patterns". In lisp, I have never needed to write a "factory".
      The whole "visitor" pattern becomes a 1-line (map...) call. To a lisper
      "design patterns" are like dress patterns in sewing. If you can't sew
      (program) you can still make something to use by copying a pattern.
      But you can hardly consider yourself a Taylor (programmer).

~~~
kunley
I find Ruby really close to CL/Clojure with regard to happily _not using_
design patterns. I usually write pure code and use long method chains -- it
mimics the Unix paradigm with small tools connected with pipes. I rarely write
proper classes actually and I'm happy with it.

If anobody is interested, I described this style of coding here
<http://inthephase.org/partial-function-application-in-ruby>

I also think that the oo-like call chain:

data.transform1.transform2...transformN

is better readable than:

transformN ...(transform2(transform1(data)))

because the order is transformations is not reversed, so one sees what's going
on with the data in the first pass as he reads, there's no need to mentally
reverse the chain. The expressiveness is the same, but the readability of the
former wins IMO.

~~~
prospero
In Clojure you can rewrite the second example as (-> data transform1
transform2 ... transformN). Macros are a hell of a thing.

~~~
kunley
Yeah that's true and my Clojure code contained a hell lot of -> and ->>
constructs. They're very useful.

------
hga
See also this about OODA loops:
<http://article.gmane.org/gmane.comp.java.clojure.user/34272>

~~~
kunley
This is interesting and has funny yet valuable military metaphore.

------
ww520
Another language religious war. What the heck. I got some time, I'll jump in.

With all due respect, he's wrong on the library issue. Lisp lacks good
libraries, period. Couple years ago I have a project in mind and tried to
develop it in Lisp. I couldn't find good libraries on database binding,
SMTP/POP3/MIME, threading, Unicode, etc. Most were abandon-wares or not
complete. Sure I could have written them in Lisp, but then I would be
developing Lisp libraries instead of my app.

The JGraphT example he picked was a bad one since Lisp supports the graph-like
data structure happily. It's like saying you don't need a hashtable library
since it's already supported natively in the language.

Edit: I don't mean to bash Lisp (I like it a lot and had done a Lisp
implementation in C) but the standard Lisp library issue is a real one. It
should not be just swept under the rug.

~~~
lispm
Interesting, the Lisp image on my Laptop has ALL of that preloaded, and quite
a bit more.

~~~
ww520
May be you can share what Lisp image you use? I'm always open to Lisp
development and see what's possible.

I went through CLisp and SBCL for Windows, but decided against SBCL due to its
large runtime image.

~~~
lispm
I have the LispWorks 64bit Enterprise Edition. It does provide Unicode,
concurrent threads, database access, networking, GUI lib, ... Some of the
other stuff I have loaded as libraries. My base image with software loaded is
probably larger than SBCL's but it also contains more stuff.

LispWorks runs also nicely under Windows.

Possible drawback: it is commercial and not open source.

~~~
ww520
_Possible drawback: it is commercial and not open source._

I think that's the main reason. $5000 does buy a lot of libraries.

~~~
lispm
Not only that. It buys you one of the fastest Lisp implementations, which runs
nicely on Windows, Linux and Mac - everywhere with native GUI. Windows isn't
that well supported by open source Lisps. The commercial ones are much better
in that respect. Though, for me the Mac OS X support is more important, since
I'm also not a regular Windows user.

~~~
lelele
Yes. Money buys you time.

------
nadam
I don't understand this:

"Why have a graph library when you can just embed the graph naturally in the
data?"

Why do you need a graph library in Java? Why cannot you embed the graph into
the data in Java?

class Node { List<Node> pointsTo; }

Java is a bit verbose, but it is not something from the devil. Also some of
this verbosity is because of strong typing, which is self documentation,
provides for nice tool support and for compile-time detected errors.

Of course you might need a graph library to use pre-packaged notrivial graph
algorithms, but it is independent of the language used.

~~~
jpr
In Common Lisp you can embed arbitrary data structures in to your code because
the reader can build them at read-time, and it can also evaluate arbitrary
code at read time (you can turn this feature off for safety). So "embedding a
graph" means something totally different in CL. The CL reader can also
basically read both persistent pointers (symbols) and ephemeral pointers (the
#N= #N# notation with which you can even read self-recursive structures).

Contrast this to Java, where there are no literal datastructures, no reader,
and all your data structures must be explicitly built from constructor up.

I _really_ wish these things would be something that people would be thaught
at universities, but thanks to Java-schools, they aren't.

~~~
ww520
That's a good feature in Lisp. How would that negate the need of a graph
library? I once needed to do topological sort on a graph. Sure I can code it
myself but I ended up calling the Boost library for it.

~~~
rikthevik
I think he's referring to defining existing graphs in the code. Because of the
relationship between code and data in lisp, you don't need to define graph
objects and connect them all at run-time, which you'd have to in Java.

It's like who in Python you could say

mydict = { "a":1, "b":2 }

as opposed to

HashMap d = new HashMap(); d.put("a", 1); d.put("b", 2);

~~~
ww520
If that's the case, why does one need to use a graph library to construct
simple graph data structure? It looks like JGraphIt is used as a strawman
argument to exaggerate the difference.

BTW, Java does support some notion of literal construction using array.

    
    
      e.g. new Object[] {"abc", "xyz", 1, 2, 3, new Integer[] {4, 5, 6}, new Node(2)};

------
unwind
What does "about 1 million things of code" mean? Typo? If it's a million
programs/libraries/packages/other actual artifacts, then that's almost crazily
large.

~~~
lispm
Axiom is a very very complex piece of software. It has code in several
languages, implements languages, uses literate programming, it contains a very
large library of mathematical concepts, documentation for those, tests, ...

So, it is not lines, but really a million things, functions, documentation
snippets, tests, ...

That's also in line with my thinking. I'm not thinking in code lines, but live
domain level objects.

------
jrockway
Ouch. This was painful to read. Map is not a visitor. (setcdr foo foo) is not
the same as the 10,000 line graph library.

This is truly the lisp attitude that is preventing it from becoming a success,
"some other language does that, therefore we don't really need that".

Wrong. You do need that. And, you can learn from the other language's
implementation and get it right.

~~~
lispm
Visitor pattern intents:

* Represents an operation to be performed on the elements of an object structure

* Visitor lets you define a new operation without changing the classes of the elements on which it operates

To me that sounds awful like MAPPING/FOLDING.

~~~
jrockway
Yes, but Lisp has nothing built in that does this. Unless all your data
structures are lists of non-lists.

~~~
lispm
Okay, now that we have established that the Visitor pattern is actually about
mapping, as Tim said, we can give an example:

Given nodes of a tree, with data and children.

(defstruct node d c)

We can define a map function:

(defun mapt (n f s k) (when n (funcall f (funcall k n)) (mapc (lambda (n)
(mapt n f s k)) (funcall s n))))

The mapt function takes a start node, a function to apply on each node's data,
the successor function and a key function that extracts the data from the
node.

Then we can call it, printing all node contents:

(mapt #S(NODE :D 1 :C (#S(NODE :D 2 :C NIL) #S(NODE :D 3 :C NIL))) #'print
#'node-c #'node-d))

With generic functions we can provide content specific behavior. Here
eventually PRINT-OBJECT will do the right thing.

Usually Lisp provides these mapping functions. For example in LispWorks
CAPI:MAP-PANE-CHILDREN walks over the sub panes of a pane.

That's what he was talking about, there is no special Visitor pattern
implementation, just mapping over the object structure. The mapping function
depends on what it is, a tree, a cyclic graph, ...

I found Tim's post not really that painful...

~~~
jrockway
So, writing functions to visit your data structures is not "the Visitor
pattern"? That's exactly the point of my original post; Lisp thinks they
invented everything and do everything in their own amazing way, when in
reality, they solve the same problems the same way as everyone else.

~~~
lispm
The Java Implementation of the visitor pattern involves interfaces and classes
plus double dispatch.

All that has been replaced with one mapping.

Which was Tim's point.

