Mailing List Archive
tlug.jp Mailing List tlug archive tlug Mailing List Archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]Re: [tlug] recomendations for a functional language
- Date: Tue, 3 Nov 2009 00:06:47 +0900
- From: Curt Sampson <cjs@example.com>
- Subject: Re: [tlug] recomendations for a functional language
- References: <20091102112350.bf06bfd6.attila@example.com> <20091101131525.5f4312bd.attila@example.com> <a63167770911010442pd642beco3268ed5c4a41d02@example.com> <20091102082821.GA28406@example.com> <a63167770911020112q1bd12b27ub5209902a971a6c9@example.com> <87hbtdtfch.fsf@example.com> <20091101131525.5f4312bd.attila@example.com> <a63167770911010442pd642beco3268ed5c4a41d02@example.com> <20091102082821.GA28406@example.com> <a63167770911020112q1bd12b27ub5209902a971a6c9@example.com>
- User-agent: Mutt/1.5.18 (2008-05-17)
On 2009-11-02 18:12 +0900 (Mon), Alan Busby wrote: > On Mon, Nov 2, 2009 at 5:28 PM, Curt Sampson <cjs@example.com>wrote: > > > > Note, however, that Clojure, being a Common Lisp variant, is not really so > > functional as even Scheme, not to mention missing very interesting features > > such as pattern matching and a Hindley-Milner system. > > Although it uses duck typing, and not Hindley-Milner.... Don't underestimate this difference. Moving from duck typing to a good H-M type system is a larger jump than moving from something like Java's "static" type system to Ruby's "dynamic" type system. Duck typing is undoubtedly cool, but proving that your program cannot ever fail in certain ways (bar compiler bugs or hardware failure) is mind-blowing, and will change the way you look at everything. (It gave me some interesting new insights into relational [database] theory, for example.) You haven't really lived until your program has produced the correct result merely due to be compiled, and you realize the program doesn't need to be run. > I can't imagine Clojure not being considered "functional" simply due > to all the things it took from Haskell such as it's use of immutable > data structures, STM, and lack of state. I'll address this in some detail, because this reveals some common misunderstandings about Haskell--ones that took me over a year of full-time programming in Haskell to start to really understand myself. Let's start with the biggest one: "lack of state." Actually, in Haskell you use a lot of state, probably as much as you think you're using in any other programming language. (In other languages, you're actually using quite a lot more.) Haskell is brilliant not because of lack of state, but because of the very strict control of state: you can't use state without explicitly declaring that you're using it and where and how that state may propagate (assuming you understand how monads work and "do"-notation syntactic sugar, of course). The type system is essential to this level of control; I know of no language without a powerful compile-time type system that can force you to be so overt about your use of state. (I am willing to be shown wrong on this point.) This extends into control structures; as it turns out, control structures are all about control of state, and you get some very interesting new ones that, while possible to replicate in other languages (even Java), you're not likely ever to experience in a language where the libraries are not built around them. Once you get into this, it leads you back to the key realization that in typical procedural or OO language, you're using a control structure for every line of code you write: x = x + 1; printf("%d", x"); is actually using a control structure just as much as any code using a while or for loop. And then you realize that you're dealing with handling of state with that "this line executes before that one" control structure. Note well that we do frequently write imperative code in Haskell: that's what the "do"-notation is all about, after all! And it's not just within the IO monad; the ST monad is another example of writing imperative code that executes imperatively; it's the control over where and when this happens, and the ability to contain the side effects, that is the key here. And that, in fact, is the key to STM in Haskell as well. Haskell's STM is nothing special in terms of STM itself; it's just doing what's been available in C and other languages for a longer period of time. It's the type system and its ability to contain and control side effects and state that makes GHC's rather primitive implementation of STM work better than much more sophisticated implementations that have been written for C compilers. As for the immutable data structures: it's a very nice thing that Clojure has decided to go further in that direction in the standard libraries than many other languages have. However, the difference between Clojure with its library and Java with its immutable String class is merely a matter of degree; it's not doing anything that OO programmers haven't been doing for years when they realized at some point in development of some application that a lot of the mutable objects they were using should be value objects instead. That idea wasn't taken from Haskell; value objects and persistent data structures have been around since the dawn of Smalltalk and ML. That Haskell, in general, forces you to use them (unless you want to do a bunch of extra work in your implementation, as we've done with things like the ST monad) is a side-effect of Haskell, but not really actually something I'd tout as one of its great features, except inasmuch as it's part of the "containment of state and side effects" feature (see above). And that this is not really a "Haskell feature" shows: while the Clojure standard library is great, I've heard, not only does Clojure not guarantee the purity of functions (you never know when something you're calling is going to do a setf!), but it cannot without breaking the ability to use other JVM code; you must throw it all out the window when you start to use the Java libraries, which rely heavily on mutable state. Try to use a java.util.Date as a key in a map, and you're toast. And I note that, in all of this, you've entirely left out the other unrelated, yet quite important feature: pattern matching. This is a basic language feature that I believe everybody should be aware of and have used, whether or not they later chose a language that supports it. > I find Clojure a happy middle ground between Haskell, Java, > and Lisp; taking the best of each. While I agree it's a good language, and a happy middle ground, it has not taken the best of Haskell. Haskell's purity, type system, and pervasive use of monads within the libraries are its true strengths, and Clojure has none of these. I do agree, by the way, that the macro facilities provide an extremely powerful tool, but I don't feel that they're different to the degree that something like a Hindley-Milner type system is. In other words: > I'd argue that learning to use macros well, offers more educationally than > the Hindley-Milner type system. Not that static typing isn't useful, but it > doesn't open up new ways of thinking like the way code generation does. Nope. Quite the other way around. But IMHO. I'll admit I don't have a lot of experience writing Lisp macros. (Now, M4 macros, that's another story. :-)) But keep in mind, a reasonably powerful type system *is* a programming language in and of itself. > If you're dismissing Clojure as another Common Lisp variant, I suspect > you're missing the significant difference between the two, and should do a > little more reading into what Clojure is before discussing it. On review, Clojure is certainly further from Common Lisp than I'd thought in my last post (despite being a Lisp-1, and not a Lisp-2), especially in its emphasis on recursion rather than looping (though I've not examined how well it really does when it comes to guaranteeing tail call optimization, which is an important point when using recursion in a language compiled to the JVM). But, while you may well even know Haskell better than I know Clojure, I posit that Haskell is further from the sum of all things you know about languages than Clojure is from the sum of things I know about languages. On 2009-11-02 11:23 +0100 (Mon), Attila Kinali wrote: > You graded Common Lisp, Scheme and Haskell, without giving much > information how you compared them. May i ask what you think the > major differences of these languages are? I think my comments above are applicable to most languages versus Haskell. The big exception would be the ML family (of which Haskell is more or less a member, really, albeit a rather odd cousin), and, somewhat further away, Scala and Erlang. For Common Lisp versus Scheme, I'd summarize the differences as: * the Lisp-1 versus Lisp-2 distinction (which can itself be over-summarized as whether function variables and non-function variables share a namespace, but upon research it turns out to be a lot more subtle than that), * that Lisp tends heavily towards iteration and Scheme towards recursion, * (previously) Lisp has macros, and Scheme doesn't, (now) Lisp has macros but Scheme has hygienic macros, but again, this distinction turns out to have tons of, er, "interesting" ramifications once you get into it, and makes you really think even more about whether you wanted macros or not; * Lisp does a lot, whereas Scheme is missing a lot, from certain very pragmatic points of view. I can't really say you can go wrong learning either Common Lisp or Scheme, quite frankly. They're a lot more different from each other than Python or Ruby, but the greater differences all seem to be in areas that are very troublesome and bear a lot of thinking about. Looking at Clojure, actually, it seems as if it might be one of the best of the Lispy languages to learn, if you're going to go that way. On 2009-11-02 18:12 +0900 (Mon), Alan Busby wrote: > Irregardless of quality, or old/bad design in many cases, it's very useful > not to have to write an entire library by hand simply to deal with paypal, > amazon, or any number of other systems. > Not to mention the additional ease of deployment, like running code on > Hadoop clusters on Amazon EC2. Well, "writing an entire library by hand" is quite often not nearly as hard as you'd think, if you're a half-way competent programmer. (I have proof: I've done this, and I'd say I'm about half-way competent. Hmm. Come to think of it, I may well be better at writing papers than programming. I really should move to academia. :-)) And ease of deployment, well, this is one of the reasons I tend not to use other people's libraries, frameworks, and so on. But I said I wasn't going to get into this. On 2009-11-02 19:01 +0900 (Mon), Stephen J. Turnbull wrote: > Uh, you want to, uh, "clarify" that? I mean, that clearly implies > that you use libraries that deal with *money* "irregardless of > quality, or old/bad design"! That's reasonable. I once started into a ferocious argument about using floating point for representing monetary values. There was, on some forum somewhere, a poor soul with a PHP shopping cart who was worried that it was using floating point to represent dollars, and perhaps things like a 7% discount on the entire order wouldn't work out well. Amid the calls for infinite-precision and clever fixed-point libraries, I suggested that dealing with precision "properly" was going to be pretty expensive, and he simply give, without question, a $10 discount to any customer who complained for any reason about being out by a penny or so. My theory was that this approach would be considerably cheaper than even starting to think about switching from floating point dollars. This was greeted with hoots of derision, and I have now possibly destroyed any future possibility of consulting jobs involving PHP shopping carts. (I may regret this in twenty years or so.) Still, I am not the first. Many decades ago (though he probably is wishing I wouldn't say that), the eminent (he likes it when I say that) Stan Kelly-Bootle attempted to quench an early flame war, and his career hasn't been the same since: Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration. cjs -- Curt Sampson <cjs@example.com> +81 90 7737 2974 Functional programming in all senses of the word: http://www.starling-software.com
- Follow-Ups:
- Re: [tlug] recomendations for a functional language
- From: Stephen J. Turnbull
- Re: [tlug] recomendations for a functional language
- From: Alan Busby
- Re: [tlug] recomendations for a functional language
- From: Attila Kinali
- References:
- Re: [tlug] recomendations for a functional language
- From: Attila Kinali
- [tlug] recomendations for a functional language
- From: Attila Kinali
- Re: [tlug] recomendations for a functional language
- From: Alan Busby
- Re: [tlug] recomendations for a functional language
- From: Curt Sampson
- Re: [tlug] recomendations for a functional language
- From: Alan Busby
- Re: [tlug] recomendations for a functional language
- From: Stephen J. Turnbull
Home | Main Index | Thread Index
- Prev by Date: Re: [tlug] Need advice to choose a router
- Next by Date: Re: [tlug] recomendations for a functional language
- Previous by thread: Re: [tlug] recomendations for a functional language
- Next by thread: Re: [tlug] recomendations for a functional language
- Index(es):
Home Page Mailing List Linux and Japan TLUG Members Links