9 ms·
Tim Daly on Lisp in Industry
- felideon 16y agoMy 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).
- dan00 16y ago"The whole "visitor" pattern becomes a 1-line (map...) call." That doesn't make sense. It's 'visitor pattern' -> defmethod.
- LaPingvino 16y agoclosures in datastructures ;)
- lispm 16y agoYou may want to reread the Visitor Pattern.
- dkarl 16y agoIf he has to rewrite the algorithm in Java, instead of a better JVM language, it's because somebody in management has dreams of doing all subsequent work with cheap interchangeable Java programmers, probably contractors. Odds are the algorithm won't work anymore the first time they touch it. But that's a separate issue. I studied math before getting into programming seriously. When you have the solution to a problem in your head and go to write out a proof, sometimes it goes smoothly, and sometimes you discover complications that you hadn't taken into account. It's either easy or educational. Lisp seems to be the same way. When a Lisp program turns out to be harder than I expected, it's because I didn't completely understand the problem. Java programs always turn out to be much more complicated than the solution in my head. Even if I nailed it. And Java programmers assume I'm just inexperienced and woefully naive to think that programming could be so simple.
- nadam 16y agoInteresting, but it is very different in my case. Sometimes I think days on a complicated algorithm, if it is a really hard problem. Once I know the algorithm in my head, is is totally trivial to code it in Java (or any other language I know). For me 'hardness' is not on the language level, so it almost does not matter in which language I code in provided that I know the language and preferebly it is higher level than Assembly and preferably has garbage collection.
- felideon 16y agoIt's not as much as the language makes it "hard" as much as it is that it makes it tedious. The language can get in your way as far as wanting to express your thoughts or algorithm. It's the same in natural languages. In English we have the word love, in Greek you have: agápe, éros, philía, and storgē. One could thus argue that Greek is more expressive than English, as Lisp is more expressive than Java, for example.
- nadam 16y agoYes, Lisp is a more expressive language than Java. But when I have to find out a nontrivial algorithm it does not help if I use a very expressive language. For example let's have this old interview question: find a loop in a linked list with O(1) memory. Here the used language does not matter. I feel the same with almost all algorithms. I know that using a less expressive language can get in your way. I programmed a lot in ASM, and later in C. They got in my way sometimes. Java is a far more expressive language than Asm and C. So it is already luxury for me in a sense (although really not as expressive as Lisp)
- numeromancer 16y ago"For example let's have this old interview question: find a loop in a linked list with O(1) memory. Here the used language does not matter. I feel the same with almost all algorithms." Sure, it doesn't matter, as long as you don't actually write the code. When you write the code, the language then matters a great deal. I conjecture that the signal/noise ratio for such an algorithm would be much lower in Java than in Lisp.
- nadam 16y ago"I am currently working in Java to re-implement an algorithm I prototyped in lisp." Maybe this is the problem. If I develop in Java, I think in Java. I don't prototype in other languages. I don't use 'factory objects' and 'visitors' and all such things. The syntax of JAva is a bit verbose, but I just cannot imagine that if you write something in 20 lines in any language I cannot write that in 40 lines in Java. Maybe a concrete example would be nice. Otherwise for me performnce is very important. One of the reasons that I use Java is that it is very fast (and I know how to write fast code in it.)
- dpritchett 16y agoPeople do this a good bit for algorithm programming contests. Use dynamic languages to prototype out all of the good ideas you can think of, then rewrite the most promising ones in C for maximum performance.
- coliveira 16y agoYou're probably not very creative about the language... Have you ever tried J? There are a lot of 1 line programs in J that require 100 lines of Java.
- nadam 16y agoThe most concise language I know is Joy. http://en.wikipedia.org/wiki/Joy_(programming_language) http://en.wikipedia.org/wiki/Joy_(programming_language) The 100 factor must be an exaggeration for most problems. In 100 lines I can put lots of information or quite complex algorithm even in Java. Some things are quite concise even in Java. See the greatest common denominator code: int gcd(int a, int b) { return a==b ? a : gcd(Math.abs(a-b), Math.min(a,b)); }
- sanderjd 16y agoYeah but gcd is very simple (and also your version of it stack overflows around 7 digits, depending on how quickly a gcd is found, so it isn't really "correct") - most simple tasks will have similarly sized simple representations in nearly any language. The argument levied against Java is that it's code size does not scale linearly in relation to other languages as the complexity of the problem increases.
- kunley 16y agoI 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 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.
- jpr 16y agoI think the oo-like call chain is nicer when you don't have any arguments and stuff doesn't nest. The difference of static vs. instance methods also makes it slighly more complicated to comprehend. I think overall the simplicity of Lisp-style nesting wins when the expressions get more complicated.
- kunley 16y agoGood point -- instance methods make it all a bit dirty. I usually use some meta trickery to turn toplevel methods, which can be mentally eq to defuns, into oo-chainable stuff. Well I suppose I just should clean this code and put an example on a blog.
- prospero 16y agoIn Clojure you can rewrite the second example as (-> data transform1 transform2 ... transformN). Macros are a hell of a thing.
- kunley 16y agoYeah that's true and my Clojure code contained a hell lot of -> and ->> constructs. They're very useful.
- akkartik 16y agoThat first paragraph resonated with me as well. I've been using lisp for just a few months, so I'm hardly the grizzled lisp veteran of stereotype. And yet when I bring up lisp and you-the-person-across-from-me-who-seemed-so-smart-until-now say parentheses are hard to read, I find it's easy to sympathize with lispers. The language has lots wrong with it, no question. But if you're pretending to be knowledgeable about the subject and your critique of lisp includes 'parentheses', you're a moron. (Exhibit A: Quora founder Charlie Cheever http://www.quora.com/Is-Arc-a-useful-language-for-web-programming http://www.quora.com/Is-Arc-a-useful-language-for-web-progra...)
- hga 16y agoSee also this about OODA loops: http://article.gmane.org/gmane.comp.java.clojure.user/34272 http://article.gmane.org/gmane.comp.java.clojure.user/34272
- kunley 16y agoThis is interesting and has funny yet valuable military metaphore.
- unwind 16y agoWhat 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.
- statictype 16y agoPresumably he meant 'lines' of code but in lisp the concept of a single line of code is a little vague so he modified it to 'things'
- strait 16y agoQuite probably he meant S-expressions, but said 'things' to avoid scaring away those unfamiliar.
- lispm 16y agoAxiom 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.
- dkarl 16y agoSo, 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 16y agoEven 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 16y agoI am assuming you havent heard of Allegrograph.
- deleted 16y ago[deleted]
- 16y ago
- nadam 16y agoI 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 16y agoIn 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 16y agoThat'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 16y agoI 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);
- ezy 16y agoThis 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.
- lispm 16y agoThe software was written originally at IBM. Axiom was sold commercially, before it was open sourced. Axiom is also not written in one language. It is really the opposite. Lisp is basically the runtime for a complex domain specific language for mathematics. It is in some ways similar to Haskell. The language allows, how can I say it, a structuring of the mathematical domains with a typed language. Probably one of the most advanced pieces of software in that area. The capabilities of Axiom are really amazing.
- ezy 16y agoI have nothing to say about Axiom in particular, not my domain -- I'm glad it's a cool piece of software. But I feel my comment still holds; Axiom is obviously a piece of research software with a research interface (e.g. a programming language as an interface) that was developed to help people do research. It is not a typical example of software in "industry" where "industry" is implied by the OP to be software in a general sense over many domains. But perhaps the argument is weaker than that... Anyway, I don't have enough of a stake in this to argue. But I do think the characterization of lisp as something that is suitable for "industry-blub" is inaccurate. I don't subscribe to the view that there's this strict hierarchy from lisp down to blub. Rather, Lisp is a prototyping and template language, and in products, shows up in areas where the product itself is continually a prototype. Research software fits this bill, as does the scripting interface to a larger product. pg thinks rapidly changing web apps fit the bill -- I think that might actually be true in the early stages, and less so later on. That seems to be where the evidence points, at least.
- ww520 16y agoAnother 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 16y agoInteresting, the Lisp image on my Laptop has ALL of that preloaded, and quite a bit more.
- ww520 16y agoMay 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 16y agoI 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 16y agoPossible drawback: it is commercial and not open source. I think that's the main reason. $5000 does buy a lot of libraries.
- jrockway 16y agoOuch. 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 16y agoVisitor 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 16y agoYes, but Lisp has nothing built in that does this. Unless all your data structures are lists of non-lists.
- lispm 16y agoOkay, 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...