by Michael Fogus
Best known as the inventor of Clojure, a Lisp that runs on the Java Virtual Machine and the first new member of the Lisp family to attract any widespread interest since Scheme and Common Lisp, Rich Hickey has been a software developer and consultant for two decades.
Rich Hickeyã¯20幎æ¥ã®ãœãããŠã§ã¢æè¡è ããã³ã³ã³ãµã«ã¿ã³ãã§ãClojureã®åµå§è ãšããŠããç¥ããããClojureã¯Javaä»®æ³ãã·ã³äžã§åäœããLispã§ãLispæã®äžã§ã¯SchemeãCommon Lisp以æ¥ã¯ãããŠå¹ åºã人ã®èå³ãåŒããæ°ããèšèªã ã
Prior to starting work on Clojure, he made four attempts to combine Lisp with either Java or Microsoftâs Common Language Runtime: jfli, Foil, Lisplets, and DotLisp but Clojure was the first to draw significant attention. To date there have been four books published on Clojure, including The Joy of Clojure by interviewer Michael Fogus. The first Clojure conference, ClojureConj held in 2010, drew over two hundred attendees. And the Clojure Google group has, as of this writing, 4,880 members who have posted over 46,000 messages since it was started in 2007.
Clojureã«åãçµãåã圌ã¯LispãJavaãMicrosoftã®Common Language Runtimeãšçµã³ã€ãã4ã€ã®è©ŠäœãããŠãããjfliãFoilãLispletsããããŠDotLispã ãããããå€ãã®äººã®æ³šç®ãéããããã®ã¯Clojureãã¯ãããŠã ã£ããä»æ¥ãŸã§ã«ãã€ã³ã¿ãã¥ãŒã¯ã§ããMichael Fogusã®ãThe Joy of Clojureããå«ãã4åã®Clojureã«é¢ããæ¬ãåºçãããã2010幎ã«ã¯Clojureã®æåã®ã«ã³ãã¡ã¬ã³ã¹ Clojure/conjãéå¬ããã200äººè¶ ã®èŽè¡ãåå¡ããããããŠãClojureã®Googleã°ã«ãŒãã¯ãéå§ããå·çæç¹ãŸã§ã§4,880人ã®ã¡ã³ããŒãç»é²ãã46,000ãã®ã¡ãã»ãŒãžãæçš¿ãããŠããã
In past lives Hickey has been a music composition major, a guitarist, and a serious C++ programmer, even teaching an Advanced C++ course at New York University. In this interview, Michael Fogus talks with Hickey about complexity, abstraction, and the past, present, and future of Clojure.
圌ã¯éå»ã«ã¯äœæ²å°æ»ããã®ã¿ãªã¹ãã§ããã£ãããŸããä»äºãšããŠC++ããã°ã©ããããŠããããšãããã¥ãŒãšãŒã¯å€§åŠã§C++ã®çºå±çãªå 容ã«ã€ããŠè¬çŸ©ããŠããããšãããã£ãããã®ã€ã³ã¿ãã¥ãŒã§ã¯ãMichael Fogusãè€éããæœè±¡ããããŠClojureã®éå»ãçŸåšãæªæ¥ã«ã€ããŠRichãšå¯Ÿè«ããã
Fogus: What drew you to programming?
Fogus: ããã°ã©ãã³ã°ãã¯ããããã£ããã¯ïŒ
Hickey: I was running a recording studio and got a computer for it. I was intrigued by what it could doâthis was in the relatively early days of MIDIâand filled with the possibilities of what it might do. So I taught myself C and assembly language and started writing music software. I was immediately hooked.
Hickey: æã¬ã³ãŒãã£ã³ã°ã¹ã¿ãžãªããã£ãŠãŠããã®ããã«ã³ã³ãã¥ãŒã¿ãè²·ã£ããã§ããããã§ãã³ã³ãã¥ãŒã¿ã§ã§ããããšã«èå³ããããããŠââåœæã¯MIDIãåºå§ããŠããé ã ã£ãããââã³ã³ãã¥ãŒã¿ã§ããããããããªãããšã§é ããã£ã±ãã«ãªããŸãããã
Fogus: You play guitar, correct?
Fogus: ã®ã¿ãŒãã匟ãã«ãªããã§ãããïŒ
Hickey: Yes, I was a music composition major in college.
Hickey: ããã倧åŠã§ã¯äœæ²ãå°æ»ããŠãŸããã
Fogus: Iâve often found that great programmers are skilled musicians. Do you think that musical art is related to the art of programming?
Fogus: ãããããã°ã©ãã¯é³æ¥œã®è ãããããšãå€ãã§ããããé³æ¥œã®ã³ãã¯ããã°ã©ãã³ã°ã®ã³ããšé¢ä¿ããããšæããŸããïŒ
Hickey: I think the skills useful for one are often useful for the other. Coding and music performance are fairly different, other than being disciplines that reward practice, but software design and composition have a lot of similarities. Both involve manipulating and coordinating abstractions, and envisioning their realization, in the case of programs that are processes, in and over time. Iâve certainly found software design satisfies the creative urge I intended to pursue in composition, and has completely displaced it.
Hickey: äžæ¹ã§äœ¿ããã¹ãã«ãããäžæ¹ã§äœ¿ãããšããã®ã¯ãããããšæããŸããã³ãŒãã£ã³ã°ãšæŒå¥ã¯ãäž¡æ¹ãšãç·Žç¿ãå¿ èŠãªåéã ã£ãŠããšä»¥å€ã¯ããªãéããã©ããœãããŠã§ã¢ãã¶ã€ã³ãšäœæ²ã¯äŒŒãŠããšãããå€ãã§ãããäž¡æ¹ãšãæœè±¡ãæäœããããé£æºããããããã®æœè±¡ãã©ãå®çŸãããããèããããšã«é¢ä¿ããããããŠããœãããŠã§ã¢ãã¶ã€ã³ã¯åãäœæ²ã§è¿œãæ±ããã¯ãã ã£ãã¯ãªãšã€ãã£ããªè¡åãæºãããŠãããããšã«æ°ã¥ãããã§ãã
Fogus: What was the first interesting program that you wrote?
Fogus: æåã«æžãããããããããã°ã©ã ã¯äœã§ããïŒ
Hickey: An early program I wrote that got me excited about the possibilities of computing was a simple evolution program. Bugs moved around on the screen looking for food, with random movement to start. I would start it before bed, with the bugs shaking around, and awake to find they had evolved these fluid, efficient movement strategies. It was then that I realized that simulations and generative programs would allow us to see and discover things that analysis and calculation couldnât.
Hickey: æåã®é ã«æžããããã°ã©ã ã§ãã³ã³ãã¥ãŒã¿ã«äœããããããšãžã®å¯èœæ§ã«è奮ããã®ã¯ç°¡åãªé²åããã°ã©ã ã§ããããè«ãé£ã¹ç©ãæ¢ããŠã©ã³ãã ã«ã¹ã¯ãªãŒã³äžãåãåããã§ããå¯ãåã«èµ·åããŠããã¡ãã¡ã§ããã¡ãªãåããŠãè«ããèµ·ããŠã¿ããšæ»ããã§å¹ççãªåããããããã«é²åããŠããã§ãããåæãèšç®ã§ã¯ã§ããªãããšãã·ãã¥ã¬ãŒã·ã§ã³ãšçæçããã°ã©ã ã§ã§ãããã ãšæ°ã¥ããã®ã¯ãã®æã§ãããã
Fogus: What do you do to improve your skills as a programmer? Do you have certain exercises or pet projects that you use?
Fogus: ããã°ã©ããšããŠã®è ã磚ãããã«ããŠããããšã¯äœã§ããïŒãã£ãŠããèšç·Žãšããæ°ã«å ¥ãã®ãããžã§ã¯ãã¯ãããŸããïŒ(FIXME)
Hickey: I read relentlessly. I donât do any programming not directed at making the computer do something useful, so I donât do any exercises. I try to spend more time thinking about the problem than I do typing it in.
Hickey: ã²ãããèªæžãããŠããŸããã³ã³ãã¥ãŒã¿ã«äœã䟿å©ãªããšãããããããšæã£ãŠããã°ã©ãã³ã°ãããŠãªãã®ã§ãèšç·Žã¯ããŠãŸãããã¿ã€ãã³ã°ãããããåé¡ã«ã€ããŠèããæéãå€ããšãããã«ããŠãŸãã
Fogus: Speaking of reading, you once created a Clojure Bookshelf list on Amazon that was very popular. Of those books listed, are there any you think every programmer should read?
Fogus: èªæžã«ã€ããŠè©±ãåºãŸããããåã«Amazonã§Clojureæ¬æ£ãªã¹ããäœã£ãŠäººæ°ã«ãªã£ãããšããããŸããããããã®ãªã¹ãã®äžã®æ¬ã§ãããã°ã©ããªãå šå¡èªãã¹ãã ãšæããã®ã¯ãããŸããïŒ
Hickey: I couldnât highlight just a few. Each illuminates some things and ignores others. Iâm not really comfortable advocating what others ought to do. Personally, I try to read, on an ongoing basis, books such as those on the list and papers from academia, many of which are available online. And I like to see a commitment to learning on the part of people with whom I work.
Hickey: ããã€ãã ãåãäžããã®ã¯ç¡çã§ãããããããã®æ¬ãç¹å®ã®ããšã«ã€ããŠã¯è©³ãã説æããŠããã©ããã以å€ã®ããšã«ã€ããŠã¯ç¡èŠããŠããããã«ãä»ã®äººã«å¯ŸããŠäœãããã¹ãã ãšããã®ã¯ããŸãæ°æã¡ã®ããããšã§ã¯ãªãã§ããå人çã«ã¯ããªã¹ãã«èŒã£ãŠããããªæ¬ãåŠè¡æ¹é¢ã®è«æãèªãããã«ããŠããŸããã ããããããäžã§èªããŸãã(FIXME)
Fogus: Letâs talk about some of your choices for the Clojure Bookshelf list. For example, on the surface Clojure seems to be very different from Ruby, yet you list Programming Ruby 1.9 by Thomas, Fowler, and Hunt. How did that book, and Ruby in general, influence the design of Clojure?
Fogus: Clojureæ¬æ£ãªã¹ãã®æ¬ã®ãã§ã€ã¹ã«ã€ããŠè©±ããŸããããããšãã°ãClojureã¯èŠãç®ãšããŠã¯Rubyãšå šç¶éããŸãããThomasãšFowlerãHuntã®æžãããProgramming Ruby 1.9ãããªã¹ãã«å ¥ã£ãŠãŸãããããã®æ¬ãRubyå šè¬ã¯ãClojureã®èšèšã«ã©ããã圱é¿ãäžãããã§ããïŒ
Hickey: Well, influences can be positive or negative. Looking at Python and Ruby left me resolute that I didnât want to create yet another syntax and yet another object system. On the other hand, they set a high bar for concision.
Hickey: ãŸããè¯å®çãªåœ±é¿ãããã°åŠå®çãªåœ±é¿ããããŸãããPythonãšRubyãèŠãŠãããã«å¥ã®æ§æãšå¥ã®ãªããžã§ã¯ãã·ã¹ãã ãäœãã®ã¯ãããããšæ±ºå¿ããŸãããäžæ¹ã§ããããã®èšèªã¯ç°¡æœãã«ã€ããŠã®é«ãããŒãã«ã«ãªããŸããã
Fogus: Do you think Ruby or Python has taken the ALGOL-derived syntax to the limit of its concision?
Fogus: RubyãPythonã¯ALGOLãã掟çããæ§æãšããŠãç°¡æœãã®äžéã«ãããšæããŸããïŒ
Hickey: I donât know. Iâm more interested in reducing complexity than I am in concision.
Hickey: åãããªãã§ãããåã¯ãç°¡æœããããè€éããæžããããšã®æ¹ã«èå³ããããŸãã
Fogus: Letâs explore that a little. There are the complexities of the problem, which are mostly language independent, and then there are incidental complexities imposed by the language itself. How does Clojure alleviate the last of theseâthe incidental complexities?
Fogus: ããã«ã€ããŠããã¡ãã£ãšè¿œç©¶ããŠãããŸããããåé¡ã®è€éããšãããã®ããããŸãããå€ãã¯èšèªã«äŸåããªããã®ã§ãããããããèšèªèªèº«ã«ãã£ãŠæã¡èŸŒãŸããå¶çºçè€éãããããŸããClojureã¯åŸè ã®ãã€ãŸãå¶çºçè€éããã©ããã£ãŠåããããã§ãããïŒ
Hickey: Reducing incidental complexity is a primary focus of Clojure, and you could dig into how it does that in every area. For example, mutable state is an incidental complexity. The mechanics of it seem simple, or at least familiar, but the reality is quite complex. In my opinion, it is clearly the number one problem in systems. So, Clojure makes immutable data the default.
Since we were talking about syntax, letâs look at classic Lisp. It seems to be the simplest of syntax, everything is a parenthesized list of symbols, numbers, and a few other things. What could be simpler? But in reality, it is not the simplest, since to achieve that uniformity, there has to be substantial overloading of the meaning of lists. They might be function calls, grouping constructs, or data literals, etc. And determining which requires using context, increasing the cognitive load when scanning code to assess its meaning. Clojure adds a couple more composite data literals to lists, and uses them for syntax. In doing so, it means that lists are almost always call-like things, and vectors are used for grouping, and maps have their own literals. Moving from one data structure to three reduces the cognitive load substantially.
As programmers weâve become quite familiar with many incidental complexities, but that doesnât make them less complex, it just makes us more adept at overcoming them. But shouldnât we be doing something more useful?
Hickey: å¶çºçè€éããæžããããšã¯Clojureã®æ倧ã®é¢å¿äºã§ããClojureããããã©ããã£ãŠãããã¯ãããããšããã§æãäžããããŸããããšãã°ããã¥ãŒã¿ãã«ãªç¶æ ã¯å¶çºçè€éãã§ããä»çµã¿ã¯ã·ã³ãã«ã«èŠããããå°ãªããšããªãã¿ããããã®ã ãšæããŸãããå®éã¯ããªãé£ãããåã®æèŠãšããŠã¯ãããã¯ã·ã¹ãã ã®ãã³ããŒ1ã®åé¡ã§ããã ãããClojureã¯ã€ãã¥ãŒã¿ãã«ãªããŒã¿ãããã©ã«ãã«ãããã§ãã
æ§æã®è©±ãããŠããã®ã§ãäŒçµ±çãªLispã«ç®ãåããŠã¿ãŸãããããã¹ãŠãæ¬åŒ§ã§ãããããã·ã³ãã«ãæ°å€ããã®ä»ã®ãªã¹ããããªãããã®äžãªãã·ã³ãã«ãªæ§æã®ããã«èŠããŸãããããã以äžã·ã³ãã«ãªãã®ããããŸããïŒã ãã©ãå®éã«ã¯ãã®çµ±äžæ§ãæãç«ãããããã«ããªã¹ãã®æå³ãããªããªãŒããŒããŒãããŠããŸããé¢æ°åŒã³åºãã ã£ãããæ§æèŠçŽ ã®ã°ã«ãŒãã³ã°ã ã£ãããããŒã¿ãªãã©ã«ã ã£ãããã©ã®æå³ãªã®ãã¯ã³ã³ããã¹ããåãããªããšæ±ºããããªããŠãæå³ãç¥ãããã«ã³ãŒãã«ç®ãéããšãã®èªç¥çè² æ ãå¢ããŸããClojureã¯ãªã¹ãã®ä»ã«ãããã€ãã®ã³ã¬ã¯ã·ã§ã³ãªãã©ã«ãè¿œå ããŠããããæ§æã«ã䜿ãããã«ãããã§ããããããããšã§ããªã¹ãã¯ã»ãŒåžžã«åŒã³åºãã®ãããªãã®ãæå³ããããã«ãªã£ãŠããã¯ã¿ã¯ã°ã«ãŒãã³ã°ã«ããããŠããããåºæã®ãªãã©ã«ããã€ããã«ãªããŸããã1ã€ã®ããŒã¿æ§é ã3ã€ã«ãªã£ãããšã§èªç¥çè² æ ã¯ããªãæžããŸããã
åãã¡ã¯ããã°ã©ããšããŠãããããã®å¶çºçè€éãã«ãã£ããæ £ããããŠããŸããŸããããã ãããšãã£ãŠå¶çºçè€éããè€éãããªããªã£ãããã§ã¯ãªããã§ããå¶çºçè€éããå æããã®ãããŸããªã£ãã ããªãã§ããã§ããåãã¡ã¯ãã£ãšæçšãªããšãããã¹ããããªãã§ããïŒ
Fogus: So once incidental complexities have been reduced, how can Clojure help solve the problem at hand? For example, the idealized object-oriented paradigm is meant to foster reuse, but Clojure is not classically object-orientedâhow can we structure our code for reuse?
Fogus: å¶çºçè€éããåæžãããåŸãç®ã®åã®åé¡ãClojureã§ã©ã解決ã§ãããã§ããããïŒããšãã°ãçæ³ã®ãªããžã§ã¯ãæåãã©ãã€ã ã¯åå©çšãä¿ããŸãããClojureã¯æãªããã®ãªããžã§ã¯ãæåã§ã¯ãªãã§ããããåå©çšã®ããã«ã¯ã©ããã£ãŠã³ãŒããçµã¿ç«ãŠãã°ãããã§ããããïŒ
Hickey: I would argue about OO and reuse, but certainly, being able to reuse things makes the problem at hand simpler, as you are not reinventing wheels instead of building cars. And Clojure being on the JVM makes a lot of wheelsâlibrariesâavailable. What makes a library reusable? It should do one or a few things well, be relatively self-sufficient, and make few demands on client code. None of that falls out of OO, and not all Java libraries meet this criteria, but many do.
When we drop down to the algorithm level, I think OO can seriously thwart reuse. In particular, the use of objects to represent simple informational data is almost criminal in its generation of per-piece-of-information micro-languages, i.e. the class methods, versus far more powerful, declarative, and generic methods like relational algebra. Inventing a class with its own interface to hold a piece of information is like inventing a new language to write every short story. This is anti-reuse, and, I think, results in an explosion of code in typical OO applications. Clojure eschews this and instead advocates a simple associative model for information. With it, one can write algorithms that can be reused across information types.
This associative model is but one of several abstractions supplied with Clojure, and these are the true underpinnings of its approach to reuse: functions on abstractions. Having an open, and large, set of functions operate upon an open, and small, set of extensible abstractions is the key to algorithmic reuse and library interoperability. The vast majority of Clojure functions are defined in terms of these abstractions, and library authors design their input and output formats in terms of them as well, realizing tremendous interoperability between independently developed libraries. This is in stark contrast to the DOMs and other such things you see in OO. Of course, you can do similar abstraction in OO with interfaces, for instance, the java.util collections, but you can just as easily not, as in java.io.
Hickey: ãªããžã§ã¯ãæåãšåå©çšã«ã€ããŠè°è«ããããã§ããããããã«ã(FIXME)è»ãäœã代ããã«è»èŒªã®åçºæãããŠãããã§ãªããã°ãåå©çšã§ããããšã¯ç®ã®åã®åé¡ãã·ã³ãã«ã«ããŸãããClojureãJVMäžã§åäœããããšã§ããããã®è»èŒªãã€ãŸãã©ã€ãã©ãªã䜿ãããšãã§ããŸããã©ãããã°ã©ã€ãã©ãªã¯åå©çšãããããªããã§ãããïŒã©ã€ãã©ãªã¯1ã€ã2ã€ãããã®å°æ°ã®ããšãããŸãã§ããããã«ãªã£ãŠããã¹ãã ããèªå·±å®çµçã§ããã¹ãã ãããããã䜿ãåŽã®ã³ãŒãã«ããããèŠæ±ããªãããã«ããã¹ãã§ããããã¯ãªããžã§ã¯ãæåã«ããããªããšããããšã¯ãªããããã¹ãŠã®Javaã©ã€ãã©ãªããã®åºæºãæºãããŠãããããããªãã§ãããã ãããã®ã©ã€ãã©ãªã¯æºãããŠããŸãã
ã¢ã«ãŽãªãºã ã¬ãã«ãŸã§äžããŠãããšãããªããžã§ã¯ãæåã¯èããåå©çšã®éªéãããŠãããšåã¯æããŸããç¹ã«ãã·ã³ãã«ãªæ å ±çããŒã¿ããªããžã§ã¯ãã䜿ã£ãŠè¡šãããšã¯ã1ã€ã®æ å ±ããšã«ã¯ã©ã¹ã¡ãœãããšãããã€ã¯ãèšèªãäœãåºããšããæå³ã§ã»ãšãã©ç¯çœªçã§ãã(FIXME)ããã«å¯ŸããŠãé¢ä¿ä»£æ°ã®ããã«ãã¯ããã«åŒ·åã§ã宣èšçã§ãç·ç§°çãªã¡ãœãããèããããŸãã1ã€ã®æ å ±ãä¿æããã®ã«ç¬èªã®ã€ã³ã¿ãã§ãŒã¹ãæã£ãã¯ã©ã¹ãçºæããããšã¯ãçç·šå°èª¬ãæžãããšã«æ°ããèšèªãçºæãããããªãã®ã§ããããã¯ååå©çšã§ããã®çµæãšããŠå žåçãªãªããžã§ã¯ãæåã¢ããªã±ãŒã·ã§ã³ã§ã¯ã³ãŒãççºãèµ·ãããã ãšæããŸããClojureã¯ãããé¿ãã代ããã«æ å ±ã®ã·ã³ãã«ãªé£æ³ã¢ãã«ãæšå¥šããŠããŸããããã«ãã£ãŠãæ å ±ã®åããŸããã§åå©çšã§ããã¢ã«ãŽãªãºã ãæžãããšãã§ããŸãã
ãã®é£æ³ã¢ãã«ã¯ClojureãæäŸããããã€ãããæœè±¡ã®ãã¡ã®ã²ãšã€ã§ããããããæœè±¡ã«å¯Ÿããé¢æ°ããšããåå©çšã«åããã¢ãããŒãã®çã®åºç€ã«ãªã£ãŠããŸãããªãŒãã³ãªå°æ°ã®æ¡åŒµå¯èœãªæœè±¡ã«å¯ŸããããªãŒãã³ãªå€æ°ã®é¢æ°ããã€ããšããã¢ã«ãŽãªãºã ã®åå©çšãšã©ã€ãã©ãªã®çžäºéçšã«ãããéµã«ãªããŸããClojureã®å€§éšåã®é¢æ°ããã®æœè±¡ã䜿ã£ãŠå®çŸ©ãããŠããŠãã©ã€ãã©ãªäœè ããããã䜿ã£ãŠå ¥åãšåºåã®åœ¢åŒãèšèšããããšã§ãç¬ç«ããŠéçºãããã©ã€ãã©ãªéã§ã®é©ç°çãªãŸã§ã®çžäºéçšæ§ãå®çŸããŠããŸããããã¯ãDOMããªããžã§ã¯ãæåã§èŠããããã®ä»ã®äŒŒããããªãã®ãšã®èããéãã§ãããã¡ãããªããžã§ã¯ãæåã§ããããšãã°java.utilã®ã³ã¬ã¯ã·ã§ã³ã®ããã«ãã€ã³ã¿ãã§ãŒã¹ã䜿ã£ãŠåæ§ã®æœè±¡ãããããšãã§ããŸãããjava.ioã®ããã«ãç°¡åã«ã¯ãããªãå ŽåããããŸã(FIXME)ã
Fogus: Can you expand on what you mean by âsimple associative model for informationâ?
Fogus: ãæ å ±ã®ã·ã³ãã«ãªé£æ³ã¢ãã«ããšèšã£ãŠãããã®ã«ã€ããŠè©±ããŠããããŸããïŒ
Hickey: Most classes used to represent information are just bespoke associative maps of named properties/attributes to values. But in the customization process we usually lose the ability to treat them like generic maps. This then precludes the writing of generic information manipulation code, since such code requires the capability to generically access/modify/add properties by name/key, enumerate properties, etc. An associative information model retains and emphasizes those capabilities.
Hickey: æ å ±ãè¡šãããã«äœ¿ãããã»ãšãã©ã®ã¯ã©ã¹ã¯ãå€ã«å¯Ÿããååã€ãã®ããããã£/å±æ§ãããªããããã ãã®ããã«äœããããã ã®é£æ³ãããã§ããã ãã©ãã«ã¹ã¿ãã€ãºãããéçšã§æ®éã¯ããããäžè¬çãªããããšããŠæ±ãèœåã¯å€±ãããŠãããŸãããããããšãäžè¬çã«æ å ±ãæäœããã³ãŒãã¯æžããªããªããŸãããªãããšããã°ããããã£ãã³ãŒããæžãã«ã¯äžè¬çã«ååãããŒã«ãã£ãŠããããã£ã«ã¢ã¯ã»ã¹ããããä¿®æ£ããããã€ãå ããããããããã£ãåæãããããèœåãå¿ èŠã§ãããããé£æ³æ å ±ã¢ãã«ã§ã¯ãããããèœåãæ®ããŠåŒ·ãæã¡åºããŠããŸãã
Fogus: Are there any domains where this abstraction-oriented approach isnât suitable?
Fogus: ãã®æœè±¡æåã®ã¢ãããŒããé©ããŠããªããã¡ã€ã³ã¯ãããŸããïŒ
Hickey: I think the approach in general has universal appeal. The pressure on abstractions, and on dynamic languages like Clojure, comes from the quest for performance. People seeking the utmost performance might not find Clojure suitable. They might not even find Java suitable, with its lack of composite value types both on the stack and in arrays.
That said, this is an area of ongoing improvement in Clojure, which is already pretty fast, as dynamic languages go. With optional type hints, Clojure can already generate local code as fast as Java, and new work on primitive arguments and returns is enabling that speed across larger scopes. Whether that can be carried to the highest levels of the abstraction stack, without incurring the rigidity and complexity of a full-on type system, is an open question I intend to pursue.
Hickey: åã¯ãã®ã¢ãããŒãå šè¬ã¯æ®éçãªãã®ã ãšæã£ãŠãŸããClojureã®ãããªåçèšèªã«ãããæœè±¡ã«å¯Ÿããå§åã¯ããã©ãŒãã³ã¹ã®æ¢æ±ããæ¥ãŠããŸããæ倧éã®ããã©ãŒãã³ã¹ãæ±ãã人ã«ãšã£ãŠã¯Clojureã¯é©ããèšèªã«ã¯æããªããããããŸãããã¹ã¿ãã¯ã«èŒããããé åã«å ¥ãããã§ããåæåããªããšããçç±ã§ãJavaã§ãããã®äººã®èŠæãæºãããªããããããŸããã
ããã¯ãã£ãŠããããã¯Clojureã§ãŸã æ¹åéäžã®é åã§ããããŸããåçèšèªãšããŠã¯ãã§ã«ååéãã¬ãã«ã§ããã©ããªãã·ã§ãã«ã«ã€ããããåãã³ãã䜿ãã°ãClojureã¯ãã§ã«Javaãšåããããéãã³ãŒããçæã§ããŸãããããŠãåŒæ°ãæ»ãå€ã«å¯ŸããŠããªããã£ãåããšããããã«ããæ°ããåãçµã¿ã«ãã£ãŠããåºç¯å²ã§ãã®é床ãåºããããã«ãªããŸããèéãå©ããªããŠé£ãããã«æ©èœã®åã·ã¹ãã ãªãã§ãæœè±¡åéå±€ã®äžçªäžã®ã¬ãã«ãŸã§ãã©ãçããã®ãããšããã®ãåãè¿œãæ±ããŠããæªè§£æ±ºã®åé¡ã§ãã
Fogus: In an old paper of yours, âCallbacks in C++ Using Template Functorsâ, you write favorably about C++, OOP, and static typing. Why did you change your mind?
Fogus: ããªãã®ããã³ãã¬ãŒããã¡ã³ã¯ã¿ã䜿ã£ãC++ã§ã®ã³ãŒã«ããã¯ããšããæã®è«æã§ã¯ã奜ãã§C++ããªããžã§ã¯ãæåããã°ã©ãã³ã°ãéçåã«ã€ããŠæžããŠãŸããããã©ãããŠå¿å€ãããããã§ããïŒ
Hickey: Iâm not sure I did. I said C++ was flexibleâit isâand that, when implementing a callback system for C++, one should remain aligned with its object orientation and static typing. More interesting to me, in rereading it, is that I am still now making the same arguments I made then, fifteen years ago, against mixins and derivation as extension mechanisms.
That said, I certainly was a fan of C++ in the day, and five more years of it cured me of that. The complexity is stunning. It failed as the library language it purported to be, due to lack of GC, in my opinion, and static typing failed to keep large OO systems from becoming wretched balls of mud. Large mutable object graphs are the sore point, and const is inadequate to address it. Once C++âs performance advantage eroded or became less important, you had to wonderâwhy bother? I canât imagine working in a language without GC today, except in very special circumstances.
Along the way, I discovered Common Lisp, which was much more flexible, dynamic, simpler, and fast enough, and decided that was how I wanted to program. Finally, with Clojure, that is becoming possible, and practical, for me.
Hickey: å¿å€ããããã®ãã¯åãããªãã§ãããåãèšã£ãã®ã¯ãC++ã¯æè»ã ã£ãââä»ãããã§ããã©ââã®ã§ãC++ã®ã³ãŒã«ããã¯ã·ã¹ãã ãå®è£ ãããšãã«ã¯ãC++ã®ãªããžã§ã¯ãæåãšéçåã«ãããã£ãæ¹ãããããšããããšã§ãããããèªã¿çŽããŠãŠãã£ãšãããããã£ãã®ã¯ãæ¡åŒµã®ä»çµã¿ãšããŠã®ããã¯ã¹ã€ã³ãšæŽŸçã«ã€ããŠãåã¯15幎åãšåãããšããŸã èšã£ãŠããã£ãŠããšã§ããã
ãšã¯ããã(FIXME)åãC++ãã¡ã³ã ã£ãã®ãéå»ã®è©±ã§ããããã5幎ã§åã®C++奜ããæ²»ããŸãããC++ã®è€éãã¯è¡æçã§ããåã®æèŠã§ã¯ãGCããªãããã§ãC++ã¯èªãã称ããã©ã€ãã©ãªèšèªã«ãªããããŠããŸããããéçåã¯ãªããžã§ã¯ãæåã§æžããã倧èŠæš¡ãªã·ã¹ãã ãæ±ãæ³¥å£åã«ãªãã®ãé²ãã§ããããŸããã巚倧ãªãã¥ãŒã¿ãã«ãªããžã§ã¯ãã®ã°ã©ãã¯äžæºã®çš®ã§ãããã解決ããã®ã«constã¯åäžè¶³ã§ããäžæŠC++ã®ããã©ãŒãã³ã¹äžã®å©ç¹ãå°ãããªã£ãããããã»ã©éèŠã§ãªããªã£ãããããªãã§ãããªããšããªãããããªããã ïŒããšæ©ãããšã«ãªãã§ããããä»ã§ã¯ãéåžžã«ç¹æ®ãªç°å¢ã§ããªãéããGCãªãã®èšèªã§ããã°ã©ãã³ã°ãããªããŠæ³åã§ããŸãããã
ãã®éäžã§ããã£ãšæè»ã§ãåçã§ãã·ã³ãã«ã§ãååé«éãªCommon LispãèŠã€ããŠãããã§ããã°ã©ã ãæžãããšæã£ããã§ããæçµçã«ã¯ã(FIXME)Clojureãæã«å ¥ããåã«ãšã£ãŠã®å®çšçãªæ段ã«ãªããŸããã
Fogus: In an email exchange, you mentioned that during the process of learning Lisp, you experienced joyâa motivation for the title of my book, by the way. Can you elaborate on that feeling and why it seems that Lisp fosters such a feeling?
Fogus: Lispã®åŠç¿éçšã§åã³ãå³ãã£ãããšã¡ãŒã«ã®ãããšãã®äžã§èšã£ãŠãŸãããããããã¯ç§ã®æ¬ã®ã¿ã€ãã«ãã€ãããã£ããã«ããªã£ããã§ããããã®ææ ã«ã€ããŠãšããªãLispãããããææ ãè²ãã®ãã«ã€ããŠè©³ããæããŠãããŸãããïŒ
Hickey: You can reach a point with Lisp where, between the conceptual simplicity, the large libraries, and the customization of macros, you are able to write only code that matters. And, once there, you are able to achieve a very high degree of focus, such as you would when playing Go, or playing a musical instrument, or meditating. And then, as with those activities, there can be a feeling of elation that accompanies that mental state of focus.
Hickey:
Fogus: What programming languages have you used professionally?
Hickey: Mainly C, C++, Java, C#, Common Lisp, and Clojure.
Fogus: What is your second favorite programming language?
Hickey: If I had been more satisfied with any of those, I wouldnât have written Clojure. If I had to be stranded with something other than Clojure, Iâd be happiest with a good Common Lisp and its source code. If I had more free time, Iâd spend it with Haskell.
Fogus: I have a theory that the excitement surrounding Clojure is in part due to a general open-mindedness fostered by Paul Grahamâs original Lisp essays and the popularity of Python and Ruby. What do you attribute to Clojureâs success thus far?
Hickey: I agree with your theory. I think Paul Grahamâs essays were hugely influential, and got people interested in Lisp, a Lisp-like way of thinking about programming, and the importance of rejecting conventional wisdom. And Python and Rubyâand PHP and Javascriptâhave helped herald a renaissance of language diversity, as people were obviously succeeding with languages other than Java/C#/C++. All of this paved the way for Clojure.
Itâs interesting, because Clojure provides almost nothing you canât find somewhere else. But I do think it occupies an otherwise empty spot in the multidimensional space of language features and capabilities. If it hadnât, I wouldnât have written it. Thatâs the spot I wanted to work in, and enough other people must want to be there too.
Fogus: Youâve personally done a lot to set the tone in the Clojure community. How much does a languageâs community contribute to its success?
Hickey: I think it is a huge component. I am so happy with, and proud of, the Clojure community. People are helpful, and respectful, and positive. I think the key point is that the community values itself, such that people will decide it is more important to preserve the quality of the community than to vent their emotions or prove themselves right.
Fogus: Can you talk briefly about the Lisp-related projects leading up to the creation of Clojure? Specifically, what were the goals of dotLisp, Foil, and Lisplets?
Hickey: dotLisp was the inevitable rite of passage write-a-Lisp-interpreter thing. The only thing interesting about it was that, like Clojure, it was designed to be hosted and provide convenient access to the host, the CLR in this case.
Jfli was next, an attempt to provide access to Java by embedding a JVM inside a Common Lisp process. This worked okay, but still had a dissatisfying us-and-them feel.
Foil was essentially the same concept, but out of process. It used the same sexpr wire protocol to support both Java and CLR interop. Still us-and-them, and slower than same process, but theoretically less intrusive.
Lisplets was even more decoupled, merely translating Java servlet requests and responses to sexprs so you could write your servlets in Lisp.
In the end, none of these really let you sneak Lisp into a more traditional shop, nor did they provide satisfyingly fast access to the abundant Java libs from Lisp.
Fogus: What lessons did you take away from those experiments when creating Clojure?
Hickey: That it was possible to create a satisfying Lispy syntax for accessing traditional OO stuff. That you really want to be on the same side of the fence, sharing GC, etc. with the host. The âforeignâ part of FFI has to go.
Fogus: Clojure was once in parallel development on both the JVM and the CLR, why did you eventually decide to focus in on the former?
Hickey: I got tired of doing everything twice, and wanted instead to do twice as much.
Fogus: Referring back to your previous comment regarding the negative aspect of influences, Iâm led to wonder if the inclusion of Prolog Programming for Artificial Intelligence by Ivan Bratko to your Bookshelf was of this variety. Youâve mentioned elsewhere that the common view of Prolog as declarative is overblownâcan I assume that Prolog negatively influenced Clojure?
Hickey: I didnât say overblown. I said it is less declarative than it might be, what with cut/fail and clause order dependence. On the other hand, it is much more declarative than what most of us are doing all the time, and serves as inspiration towards a more declarative approach. During the early development of Clojure, I built a prototype predicate dispatch system for it using a Lisp-based Prolog. It never became part of Clojure, but I am still interested in predicate dispatch, as well as using logic systems in place of a type system for Clojure. Definitely a positive influence, if somewhat under-delivered upon, as of yet.
Fogus: I have studied the Clojure Datalog implementation and am saddened that it does not get a lot of exposure. Do you think that there is a place for it, or some derivative, as the basis for that âlogic systemâ?
Hickey: Yes, definitely. I like Datalog a lot.
Fogus: To what extent should a programming language be designed to prevent programmers from making mistakes or writing bad code?
Hickey: Iâm reluctant to say âshouldâ, as different languages can rightly take different approaches to this. I know my personal focus is on enabling people to do the right thing rather than preventing them from doing the wrong thing. In the end, there is nothing that will prevent people from making mistakes or writing bad code.
Fogus: Following that ideaâsome people are surprised by the fact that Clojure does not engage in data-hiding encapsulation on its types. Why did you decide to forgo data-hiding?
Hickey: Letâs be clear that Clojure strongly emphasizes programming to abstractions. At some point though, someone is going to need to have access to the data. And if you have a notion of âprivateâ, you need corresponding notions of privilege and trust. And that adds a whole ton of complexity and little value, creates rigidity in a system, and often forces things to live in places they shouldnât. This is in addition to the other losing that occurs when simple information is put into classes. To the extent the data is immutable, there is little harm that can come of providing access, other than that someone could come to depend upon something that might change. Well, okay, people do that all the time in real life, and when things change, they adapt. And if they are rational, they know when they make a decision based upon something that can change that they might in the future need to adapt. So, itâs a risk management decision, one I think programmers should be free to make.
If people donât have the sensibilities to desire to program to abstractions and to be wary of marrying implementation details, then they are never going to be good programmers.
Fogus: Where can we draw the line between sensibilities and language philosophy? That is, could the same be said for immutability in that we could simply say that programmers should follow a convention of immutability instead of it being enforced by the language?
Hickey: Thereâs no such thing as a convention of immutability, as anyone who has tried to enforce one can attest. If a data structure offers only an immutable API, that is whatâs most important. If it offers a mixed API, itâs simply not immutable.
Enforcement is orthogonal. Thatâs not to say there isnât value in enforcement, as many optimizations can come into play. But thereâs no free lunchâtype systems that can enforce purity are complex.
Fogus: What would you say to people who claim that Clojure is not a âreal Lispâ?
Hickey: Life is too short to spend time on such people. Plenty of Lisp experts have recognized Clojure as a Lisp. I donât expect everyone to prefer Clojure over their favorite Lisp. If it wasnât different in some ways, thereâd be little reason for it to exist.
Fogus: Aside from an obvious language choice like Lisp-1 vs. Lisp-2, how does Clojure differ from and hope to improve on Common Lisp and Scheme?
Hickey: The two most significant changes are: the core library is implemented in terms of abstractions, not concrete data types, e.g. sequence and associative abstractions rather than cons cells, and the core data structures are immutable and persistent.
Fogus: Referring back to your previous statement about Clojure allowing Lisp to be sneaked into traditional shopsâhow does Clojure differ in this respect from other JVM-based Lisps?
Hickey: Not much. You can sneak in almost any JVM language similarly.
Fogus: Youâve said youâve been surprised by how popular Clojure has become, but on the other hand didnât you bet a couple years of your life with little or no other income to produce the first version?
Hickey: I started it while on a sabbatical I had given myself. Not a break from work, but a break to work, as a completely free person. I gave myself leave to do whatever I thought was right, with no regard for what others might think, nor any motivation to profit. In releasing it, I had the normal expectations for a new languageâthat ten to a hundred people might use it. Maybe I would get some help or code contributions.
It has taken off, and subsequently demanded far more time than the sabbatical I planned. So, Iâm trying to recoup some of the investment Iâve made. Had it been a financially motivated undertaking, Iâm sure Clojure would not exist, but I donât regret having invested in it.
Fogus: You released a series of videos introducing Clojure that generated serious buzz around the language. In my opinion they are a brilliant marketing strategy, especially for a young language. Were you intentionally creating those videos as marketing material, or was that simply a side effect of a purely informational pursuit?
Hickey: Iâve never intentionally marketed Clojure, other than the first email announcing its existence to the very few members of the jfli and Foil mailing lists.
Iâve given many invited talks, and the videos are recordings of some of those talks. It just seemed like a sensible way to leverage the effort that went into doing the talks. I was quite surprised by the audience they received, but it proves that videos like that are much more efficient than talking to fifty to a hundred people at a time.
Fogus: As someone who only knows Haskell enough to read the papers, Clojure appears to be influenced by it substantially. From the names and operation of core functionsâtake, drop, iterate, repeat, etc.âto its protocols facility, there is a lot in Clojure that a Haskell programmer would recognize. Can you elaborate on Haskellâs influences on Clojure both positive and negative?
Hickey: I think Haskell is a fantastic, awe-inspiring piece of work. I havenât used it in anger, but it certainly was a positive influence. Haskell obviously goes much further than Clojure in pursuing the ideals of functional programing. In particular they differ in the approach to using types to enforce things.
In some ways, Clojure is an experiment to see how many of the benefits of functional programming can be delivered without static enforcement. Certainly Clojure shows that you can get many benefits of using immutable data and pure functions merely by supplying them as defaults and choosing to use them, much in the same way you can get the benefits of walking on the sidewalk without there being guard rails forcing you to stay on the sidewalk.
I think the great challenge for type systems in practical use is getting them to be more expressive without a correspondingâor worseâincrease in complexity. I have yet to see that, so they are not aligned with my desire to reduce complexity in programing. As far as protocols go, they are as much akin to Common Lispâs generic functions as to Haskellâs type classes, both of which demonstrate it is more flexible and extensible to keep functions and data separate, than to combine them as in typical OO.
Fogus: Itâs clear that protocols are influenced by CLOS. However, while CLOS allows you to build complex class hierarchies, Clojureâs types and protocols do not. Can you comment on the problems associated with class hierarchies and how protocols address them?
Hickey: One way to think about inheritance and hierarchy is as a form of logical implicationâif X is a Y, then all the things that are true of Yâs are true of Xâs. The problems come about when you attach something to the hierarchy. If Y is just an interface, then itâs relatively easy to make X satisfy it without conflict or contradiction. If Y is behavior and/or data, then things get dangerous quickly. Thereâs more potential for conflict and contradiction, and, usually, thereâs also a method for partial overriding of the inheritance and thus, qualification of the isa implication. The implication is broken and your ability to reason about things turns to mud. And then of course there are the type-intrusion problems of inheritance-based designs.
Protocols and datatypes generally eschew implementation inheritance, and support interface inheritance for interop only. Protocols support direct connections of datatypes to protocols, without any inheritance. And protocols support direct implementation composition, which, in my opinion, is far preferable to inheritance for that purpose. You can still get implementation inheritance by extending protocols to interfaces, but that is a necessary compromise/evil for interop purposes, and should be used with care.
Fogus: Protocols and datatypes provide the basis for a bootstrapped Clojureâhow important is it to implement Clojure in Clojure?
Hickey: It is important to be able to implement Clojure in Clojure, in order to make sure it has sufficient facilities to implement its data structures and algorithms. We are implementing any new data structures this way, and it is working out well. As far as going back and redoing things, I think the most important bit is the Clojure compiler. It currently is a lot of Java, and no fun to maintain. In addition, there are several things Iâd like to do differently with it in order to provide better support for tools. Next most important would be to move the abstractions from interfaces to protocols. Finally, a full bootstrap would make ports easier.
Fogus: Different target hosts would naturally support different subsets of Clojureâs functionality. How do you plan to unify the ports?
Hickey: I donât. It has not been, and will not be, the objective of Clojure to allow porting of large programs from one host to another. That is simply a waste of time, and needed by almost no one. Currently, you often have to change languages when you change hostsâfrom Java to C# or Javascript. This is better than that, while short of some full portability layer. The idea is to be able to take oneâs knowledge of Clojure and its core libraries, and of the host du jour, and get something done. Certainly, non-IO libraries, like Clojureâs core, can move between hosts. The JVM and CLR have rough capability parity. Weâll have to see how restrictive a Javascript host might be.
Fogus: Will you formally define a âClojure Kernelâ as part of the Clojure-in-Clojure process?
Hickey: I doubt it. Perhaps after a few ports exist we can put a label on the commonality, but trying to do such formalization prior to getting a few hosts under your belt seems folly.
Fogus: Favorite tools? Editor? Version control? Debugger? Drawing tool? IDE?
Hickey: Circus Ponies NoteBook, OmniGraffle, hammock.1
Fogus: You have been known to speak out against test-driven development. Do you mind elaborating on your position?
Hickey: I never spoke out âagainstâ TDD. What I have said is, life is short and there are only a finite number of hours in a day. So, we have to make choices about how we spend our time. If we spend it writing tests, that is time we are not spending doing something else. Each of us needs to assess how best to spend our time in order to maximize our results, both in quantity and quality. If people think that spending fifty percent of their time writing tests maximizes their resultsâokay for them. Iâm sure thatâs not true for meâIâd rather spend that time thinking about my problem. Iâm certain that, for me, this produces better solutions, with fewer defects, than any other use of my time. A bad design with a complete test suite is still a bad design.
Fogus: Clojure provides function constraints via pre- and post-condition checks that provide a subset of Eiffelâs contracts programming. Do constraints eliminate the need for, or complement unit testing?
Hickey: They complement unit tests. They have a number of nice propertiesâthey document the intent of the code at the point it is written, and can optionally run in the context of the program.
Fogus: It seems that your decision to include features in Clojure is orthogonal to their implementation and inherent complexities. For example, it seemed that streams were right on the cusp of being integrated but were discarded outright. Likewise, scopes are relatively simple to comprehend and implement, but likewise seem to have been dropped, or at least delayed greatly. What are the reasons that you stepped away from these two in particular, and in general, what is your ultimate criteria for adding new features to Clojure?
Hickey: The default position is to not add features. Complexity does matter.
Streams, in particular, exposed some difficult things in the API with which I wasnât comfortable. Now some of the motivating ideas have moved into pods, where they make more holistic sense. Various features interact, e.g. pods, transients, and references, so you canât look at any one in isolation. Scopes may seem easy to implement, but only in ways that suffer the same limitations as vars and binding vis-Ã -vis thread-pool threads. I have ideas about how to do that and binding better, and that work may have to precede delivering scopes. Scopes are still on the table.
Iâd like for any new features to be actually needed and have designs I feel good about. It is a process that requires exploratory work, and time to think. I reserve the right to come up with a better idea, and sometimes I am just allocating time to do that by waiting. I like to think I donât primarily work on featuresâI work on problems that features help solve. Scopes are a feature but resource management is a problem; streams and pods are features but process is a problem. As you work on problems, you developâand sometimes abandonâideas for features.
Fogus: Iâve spoken with a few of your former co-workers, and they described you as a trouble-shooting and debugging master. How do you debug?
Hickey: I guess I use the scientific method. Analyze the situation given the available information, possibly gathering more facts. Formulate a hypothesis about what is wrong that fits the known facts. Find the smallest possible thing that could test the hypothesis. Try that. Often this will involve constructing an isolated reproducing case, if possible. If and only if the hypothesis is confirmed by the small test, look for that problem in the bigger application. If not, get more or better facts and come up with a different idea. I try to avoid attempting to solve the problem in the larger context, running in the debugger, just changing things to see effects, etc. Ideally, you know you have solved the problem before you touch the computer, because you have a hypothesis that uniquely fits the facts.
Fogus: Is there a fundamental difference between debugging imperative/OO code versus Clojure code?
Hickey: There is no fundamental difference, but debugging functional code is much easier because of the better locality.
Fogus: Clojureâs threaded concurrency story is very solid with numerous flavors of reference types providing different usage scenarios. Do you feel satisfied with Clojureâs current concurrency offerings, or do you have plans to expand on the current reference model, or perhaps venture into distributed concurrency?
Hickey: Over time Iâve come to see this as more of a state/identity/value/time/process thing rather than concurrency in and of itself. Obviously it matters greatly for concurrent programs. I think there is room for at least one more reference type. To the extent one value is produced from another via a transient process, you could have a construct that allowed that process to have extent and/or multiple participants. This is the kind of thing people do on an ad hoc basis with locks, and could be wrapped in a reference-like construct, pods, that would, like the others, automate it, and make it explicit and safe.
I donât see distributed concurrency as a language thing. In addition, I donât think most applications are well served with directly connected distributed objects, but would be better off with some sort of message queues instead.
Fogus: While there are also primitives supporting parallelism, Clojureâs story here has a lot of room for expansion. Do you plan to include higher-level parallel libraries such as those for fork-join or dataflow?
Hickey: Yes, there are plans, and some implementation work, to support fork-joinâbased parallel map/reduce/filter etc. on the existing data structures.
Fogus: Are high-level languages harder to optimize?
Hickey: I have no idea. What I do know is that, as we get to more virtualization, adaptive runtimes, dynamic compilation, etc., it is becoming more difficult to obtain a deterministic performance model for all languages on such runtimes. This is presumably a trade-off to get better performance than we could obtain through manual optimization.
Fogus: Youâve cited the philosophy of Alfred North Whiteheadâin particular his works Process and Reality and Science and the Modern Worldâin explaining Clojureâs notion of state, time, and identity. What can we, as programmers, learn from Whitehead specifically and philosophy in general? Is there a place for philosophy in the education of software developers?
Hickey: I am not a proponent of the philosophy or metaphysics of Whitehead, and could hardly claim to understand it all. I was putting together a keynote for the JVM language summit and striving to find language-independent core ideas in the Clojure work. I was reminded of some Whitehead I had studied in college, so opened up a few of his books. Sure enough, he was all over some of the themes of my talkâtime, process, immutability, etc. He is quite quotable, so I made him the âheroâ of the talk. But Whitehead was not an inspiration for Clojureâany connections were a serendipitous discovery after the fact. That said, the number of connections was startling.
To the extent we create simplified models of the world, like object systems, as programming constructs, yes, I guess any broader understanding of the world could benefit programmers.
1 Hickey has dubbed his previously mentioned tendency to spend more time thinking about problems than typing in code âHammock-Driven Developmentâ.