6 ms·
For nearly two decades I was a diehard LISP advocate. I even forced all my programers to code three Crash Bandicoot and four Jak & Daxter games in custom LISP d
by agavin 15y ago
For nearly two decades I was a diehard LISP advocate. I even forced all my programers to code three Crash Bandicoot and four Jak & Daxter games in custom LISP dialects that I wrote the compilers for (an article on one here http://all-things-andy-gavin.com/2011/03/12/making-crash-bandicoot-gool-part-9/ http://all-things-andy-gavin.com/2011/03/12/making-crash-ban...).
But by the mid 2000s I started doing the kind of programming I used to do in LISP in Ruby. It's not that Ruby is a better language, but mostly it was the momentum factor and the availability of modern libraries for interfacing with the vast array of services out there. Using the crappy unreliable or outdated LISP libraries -- if they worked at all -- was tedious. Plus the LISP implementations were so outmoded. It was very hard to get other programers (except a couple enthusiasts) to work that way.
Ruby struct a decent compromise. And it's type system and object model are better than CL anyway. The syntax is more inconsistent, and the macro model nowhere near as good. But it turns out. Libraries and implementation matter a lot. Still, you can feel lots and lots of LISP influence in all the new runtime typed languages (Ruby, Python, etc). And 30 years later, listeners still rule!
- minikomi 15y agoIf you have any, I'd be interested in hearing some useful tidbits being a long term lisper now grounded in ruby may have brought forth.
- agavin 15y agoWell it certainly shows you how BAD/OLD the CMCL and ACL Garbage Collection code/algo's were (at least when I last used them in 2006). In ACL you could get these LispMachine-like multi-hour GCs. Now we use tons of GC based systems everyday (like browsers) without having to reboot too frequently.
- brlewis 15y agoIn the 1990s I did mostly C, but in the 2000s I did mostly Kawa Scheme. Java class libraries, especially JDBC, are what led me to choose a Java-based implementation.
- icandoitbetter 15y agoWhat do you think of Clojure? (if you've checked it out)
- cheez 15y agoUm, you're my hero. Not sure if you know that you have admirers out there. After reading about you, I became confident enough to write a Lisp-based DSL for describing and valuing financial derivative contracts. Yes, those. It directly and indirectly made me richer than I've ever been (that's not saying much, though.) In the end, we moved to Python for similar reasons. But you inspired me. Thanks.
- palish 15y agoOh, you can't just leave us hanging like that...! We want to know all about your Lisp experiences; or at least, I would personally love to hear about them.
- cheez 15y agoNot much to know as it was pretty crappy :) Certainly I would not classify it at the same level as GOAL. No debugger, for example. It quickly proved its worth but I wouldn't advocate it to still be used. We found better ways to do the same thing that didn't require as much intellectual masturbation.
- palish 15y agoYou? That... that was you? GOAL? Sir. I have no idea what to say. You were my direct inspiration for a long time. I'm a gamedev (worked at a couple studios now) and I've wanted to integrate Lisp into gameplay for years. I even got a Franz CL evaluation. The discovery of GOAL/Crash Bandicoot further motivated my efforts. Ultimately nothing came out of it; Lua and Python are just so much easier to integrate into a realtime C++ simulation (video game) and are nearly as effective. However, I became a better programmer for life. Discovering GOAL enabled me to think like "if Naughty Dog could do it, then so could I", which sparked me along a path of learning that profoundly impacted my sense of programming aesthetics and quality. Thank you.
- agavin 15y agoThanks for all fan love :-) One of the interesting things about LISP is that it's actually a pretty easy language to parse, interpret, and compile. This isn't actually an accident as the S-expression syntax I'm sure was initially chosen for it's machine regularity (in those early days of underpowered machines). Newer languages are syntactically much more complicated. Ironically most normal programmers, being human, seem to find the more complicated syntax easier and the "simple" S-expression syntax confusing (being backward much of the time to normal human convention). I always found it unambiguous, but go figure. It's also precisely this regularity that makes the awesome macrology of LISP possible. In Ruby you can manually build up strings and feed them into the interpreter, which is equivalent to simple backquote. But you can't do the kind of cool nested constructions that are trivial in LISP.
- kamaal 15y agoIts really not about the syntax. Its about writing in AST. Availability of large set of libraries. And especially I find it very difficult to use it for my day to day uses(Places where I use Awk, sed and Perl) or in other words everyday practical needs. I still don't know How to start learning lisp as a beginner and use it for my day to day needs? I don't think anybody today has the time to study the science behind lisp and then see where its useful to them. We want some thing that we can browse through and straight away go and use now! Is there a recipe book?
- KaeseEs 15y agoI don't know about recipe books, but for a general introduction I've found Conrad Barski's _Land of Lisp_ to be very good and loads of fun, although the commentary gets a little triumphalist at times. You can grab it through NoStarch or Amazon iirc.
- Davertron 15y agoPractical Common Lisp (http://www.gigamonkeys.com/book/ http://www.gigamonkeys.com/book/) by Peter Seibel is an awesome book and free online.
- jules 15y ago
- KaeseEs 15y agoI am curious what you found superior in the Ruby object model compared to CLOS. From those familiar with both Ruby and CLOS (or Moose), I've always heard that the latter is more powerful and more convenient, and (although intermediate at best with all three) found the same myself.
- agavin 15y agoCLOS is perhaps more powerful, but the whole generic function thing is more awkward than object based dispatching. It is perhaps more powerful as it allows arbitrary overloading, but it was a pain. And I wrote a really big CLOS program: The GOAL compiler.
- danssig 15y ago>And it's type system and object model are better than CL anyway. I couldn't disagree with this more. I don't see what is so different about their type system but SBCL is doing more and more type inference for you. As far as object model, generic functions are a superset of message passive. One good way to gauge the power of different languages is to look at the kinds of language-deficiency patterns you have to use. What drew me to Smalltalk was that it needed so few compared to, e.g. Java. What made me leave Smalltalk for Lisp was double-dispatch patterns. Double-dispatch patterns (e.g. Visitor) simply aren't needed in a language with generic functions. >And 30 years later, listeners still rule! With this, do you mean the REPL or something else?
- jules 15y agoCL's generic functions are not a superset of message passing, and neither is message passing a superset of generic functions. Message passing allows an implementation of doesNotUnderstand or noSuchMethod or similar, whereas generic functions don't. Not that I think that is a good trade-off vs all the advantages of generic functions. Besides, the things people accomplish with doesNotUnderstand are much better accomplished with macros anyway.
- danssig 15y ago>CL's generic functions are not a superset of message passing I would say they are. Generic functions can dispatch on a single object if they want to. As far as doesNotUnderstand, most OO languages don't support it anyway. Further, while I can't find it just now, I seem to recall MOP or CLOS itself providing doesNotUnderstand functionality. You could also either provide a doesNotUnderstand specialization on T, or set up a single handler for it. If you insist on similar semantics to Smalltalk/Ruby/JS(?) then it wouldn't be hard to use MOP to create a new kind of method dispatch that simply turned the call for a failed specialization lookup into a does-not-understand call as a last step instead of signaling error.
- jules 15y agoMessage passing OO like in Ruby and Smalltalk means that an object receives messages that it can interpret in any way it wants. For example you can create an object that prints the messages to the console: class Foo def method_missing(meth, *args) puts "#{meth}(#{args.join(',')})" end end f = Foo.new f.foo() # prints foo() f.bar(1,2) # prints bar(1,2) f[2] = "hello" # prints []=("hello") You can't do this with CLOS because methods are lexically scoped. Why is this interesting? For example because with this you can implement transparent remote objects. When you make a call on the object, it makes a network request, on the other computer the call is made and the result is sent back over the network, and finally the original method call returns. So the code would end up looking something like this: # server on ip 1.2.3.4 shared_object = Array.new shared_object[3] = "good morning" serve_object("foo", shared_object) # client remote_object = RemoteObject.new("1.2.3.4", "foo") remote_object.length # makes a network call to 1.2.3.4 and computes the length remote_object[3] # returns "good morning" remote_object[3] = "hello" # sets the index 3 to the string "hello" # code in the server can now access shared_object[3] and it will get "hello" Ruby actually has such a library. It's called Drb. All in all, I think that generic functions are better than message passing, but generic functions are definitely not strictly more powerful.
- nickthedart 15y agoOut of curiosity - what made you go with Ruby rather than Smalltalk?
- jcromartie 15y agoI can't answer for agavin here, but I can tell you one reason why I write more code in Ruby than in Smalltalk: integration. Smalltalk, more than Lisp or Java, is just not suited to little programs that get the job done. It is really great for rapid development of things that live in the Smalltalk image and play with other Smalltalk objects... but stepping outside of those boundaries is often painful and frustrating. Squeak, for example, is plagued by arcane and undocumented classes for socket I/O or HTTP. It just feels like its own isolated world compared to a simple Ruby hashbang script that reads from stdin and writes to stdout.
- nickthedart 15y agoThank you. :) As a fan of PG's articles regarding language power, I've wondered why he didn't make more comparisons of other languages to Smalltalk (whether positive or negative)
- jcromartie 15y agoLibraries and implementation do matter, that's why I've stuck with Clojure. I couldn't imagine starting a project in Common Lisp today. Are you using Ruby in game runtimes, or just tools? How do you feel the use of Racket worked out in the Uncharted games? It seems like an embeddable Lisp (like Racket) might just hit the sweet spot for enabling DSLs and dynamism without bogging you down in an outdated platform like CL. (P.S. big Naughty Dog fan here... I've always wondered about these sorts of details. I think a lot of programmers are very curious about your war stories.)
- agavin 15y agoI compiled some of these posts and some other thoughts on LISP (far far from completely formed, but perhaps amusing) into a blog post: http://all-things-andy-gavin.com/2011/10/25/lispings-ala-john-mccarthy/ http://all-things-andy-gavin.com/2011/10/25/lispings-ala-joh...