Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am primarily a Python, Java, C++ programmer, and I've gained a recent interest in functional language. I'm thinking of picking up a LISP dialect: Clojure. Now, I've been working through tutorials and whatnot, but I've noticed that beyond syntax differences, I don't feel that I am learning any fundamentally different way of solving problems.

So, are there any advantages of learning Clojure after Python in the way I can write programs?

share|improve this question

migrated from stackoverflow.com Mar 14 '11 at 8:54

This question came from our site for professional and enthusiast programmers.

12  
I think this question is quite valid. All over SO people say "learn a functional language, it'll change the way you approach problems". So what, then, is wrong with asking how it is supposed to change your approach? Perhaps an edit to the question would be in order. What features of Clojure will help in understanding functional programming? –  Josh Smeaton Mar 14 '11 at 2:41
1  
I think the problem is that there's already many variants of this question for Lisp ("I've tried Lisps, but I don't get it", "Is Learning LISP useful?", etc.). Just how many "Why Lisp?" questions do we need? –  Ken Mar 14 '11 at 5:46
1  
Have not you noticed macros? It is a fundamentally new concept for a Python programmer, you can't have anything comparable in neither of the languages you're using (even C++ templates are too far from that). But, it have nothing to do with a functional programming too. –  SK-logic Mar 14 '11 at 10:02

6 Answers 6

I think the biggest advantage of learning Lisp, ML or Haskell for a Python programmer is the appreciation of thinking recursively for algorithmic problems, separation of mutable and immutable states, the importance of deterministic output types, the problems of type coercion, and a familiarity of basic functional programming building blocks such as lambda, accumulate, zip, map, reduce, filter, currying, higher-order functions, partial functions, streaming, eager and lazy evaluation and so on. They are immensely useful for writing concise code snippets. They may not be the ideal modeling blocks for every programming problems, but for data processing, they are far better substitutes for pure procedural code. If you pick a statically typed functional language like SML or Haskell, you'll learn all the elaborate ways to assemble a program from a bunch of functions with the right types, and the magic behind type inference.

Functional programming is a kind of enlightenment. Learning functional programming not only makes you a better Python programmer, but also a better programmer in general. As a final bonus, learning a functional language will make you understand why the BDFL made the choices he made in Python. Granted, GvR denied that he cares about FP in Python, but undoubtedly he knows enough of it that a lot of its concepts have seeped in. List-comprehension is a great example of it.

share|improve this answer
    
Well-put answer! –  Jasie Mar 14 '11 at 4:17

So, are there any advantages of learning Clojure after Python in the way I can write programs?

Compared to Python, Clojure focuses on a more functional approach. It is not as rigidly as Haskell enforcing referential integrity, but strongly encourages functional programming, and thus is a good choice for introducing you to a generally more functional style. Unlike Haskell, it is not a pure functional language in the strict sense, as there are means of altering mutable state, and you are not forced to separate side effecting from pure code, although this is widely considered good style. Clojure provides efficient persistent lazy datastructures supporting this.

My impression is, that Guido is not really a friend of functional programming, and that he and the Python community simply made other design choices. That does not make Python a lesser language, but a rather different, more "conventional" one. So you will discover other and very powerful means of abstraction and composition, as well as other algorithmic approaches in languages like Clojure or Haskell -- a different view on programming. (For example a shift of focus to transformations of data using different higher order functions, function composition and so on. This is also possible in Python, being a modern language that incorporates some of these features, but functional languages take it to another level.)

As far as other Lisps are concerned: Clojure is more oriented towards functional programming than most Lisps in use today. Although they are among the oldest functional programming languages, it is not true that Lisps in general discourage imperative programming. CL for example is a very eclectic language, which will allow you to program in a variety of paradigms -- It has a very elaborated OOP-System (CLOS), to mention just one.

Apart from the functional programming aspect, you will also learn about the benefits of homoiconic languages and a fully featured Lisp macro system. There are very few languages which treat code as data and allow, to this extent, forging the language (thus DSLs) at your hearts content. The point here is not only that this is possible, but that it is made as easy as possible. So, even if Haskell might be the better choice for learning about functional programming (of course this also depends on taste), Clojure has the additional benefit of being in the Lisp family of programmable programming languages.

Those are the two major points you are going to learn about, coming from Python to Clojure.

Clojure also heavily focuses on parallel/concurrent programming. On one hand, this is a feature shared by functional languages in general, because eschewing mutable state means avoiding one big source of bugs in such programs. On the other hand, Clojure was specifically designed to make concurrent programming easy.

Another important difference between Clojure and Haskell is Clojure's -- not only as far as typing is concerned -- more dynamic approach to programming. (That is true for all Lisp dialects I know.) At the moment, I am more fond of Haskell, and really appreciating its impressive type system, but I would say that you could really benefit from Clojure as a means to widen your horizon. There are different approaches to programming, and learning about them will definitely make you a more rounded programmer.

share|improve this answer

James Gosling put it very well in http://nighthacks.com/roller/jag/entry/equations_and_methods in talking about optimization.

So what is Newton's Method? It's kind of like a function that takes two functions as parameters (f(x) and f'(x)). But the second parameter is should really be derived from the first. f'(x) can be approximated by a little numerical trickery, but it's a numerically dicey thing to do. One of the big drawbacks with closures and function pointers is that you just get to execute the function. You can't do any introspection. This is one of those times where I miss Lisp macros: the ability to rip open a function and do wild things like symbolic differentiation was wonderful. My PhD thesis project was filled with such hackery.

The problem is that you need both the function and the first derivative. In most languages you can only execute the code, but in Lisp you can treat the code as data, and find out what it does, and do the symbolic differentiation yourself.

See the difference?

share|improve this answer
    
+1 just because it demonstrates an interesting reason to look at Lisp and not just at functional programming in general. –  CodexArcanum Mar 14 '11 at 19:44
    
Does anyone have more information on what Gosling is talking about here? I've got a basic understanding of Common Lisp style macros from books like Practical Common Lisp and Land of Lisp, but I can't imagine this: "rip open a function and do wild things like symbolic differentiation was wonderful". That sounds like using some kind of introspection to get the source of the body of a function; is that possible in any Lisp? Alternatively, does anyone know where I could get a copy of Gosling's thesis? I couldn't find anything when I searched... –  spacemanaki Mar 15 '11 at 15:00
    
@spacemanaki, to my understanding you can ask the Lisp system for the token tree corresponding to a given function. You can then analyze this tree as you would any other tree - like the DOM tree in XML - and symbolic differentiation is not that difficult. A *-node becomes a +-node with each argument recursively differentiated too, etc. –  user1249 Mar 19 '11 at 22:56
    
@Thorbjørn Ravn Andersen Can you provide some citation for that? Which Lisp systems, Scheme or Common Lisp? I understand how it would work, but what I was saying was that I don't think that's true for general functions. Someone in #lisp claimed that it's not possible, and that makes sense to me. Some Scheme/Lisp systems are compiled, and by the time the function object evaluated the source is not available. The only way to do this, and possibly how Gosling did in his dissertation, would be to wrap every function definition in a macro. That being said, I don't know for sure. –  spacemanaki Mar 20 '11 at 1:12
1  
Over a month later, someone asked about this on SO, and the answer turned up function-lambda-expression which does exactly what Gosling described, returning the source code of the function. Implementations are not required by the spec to support this though (SBCL doesn't seem to, but CLisp does). You could definitely implement a symbolic differentiation package this way. –  spacemanaki May 1 '11 at 20:35

Some ideas:

  • Master concurrency using Clojure's persistent data structures and STM-managed references. See this video by Rich Hickey. In my view, this is possibly the most exciting feature of Clojure as it offers a credible route to building highly concurrent applications for multi-core machines that are free from locking issues.

  • Exploit the fact that Clojure is a homoiconic language (as are all Lisps) and you can therefore treat code-as-data. To see the power of this, try writing some macros that generate Clojure code at compile-time..... you can use this to generate your own syntax and language constructs which is much more powerful than most other languages. Try implementing a proper short-circuiting "and" operation as a function call, for example - in most languages you can't because the arguments will both get evaluated before the call to "and". But with macros this is easy.

  • Write some non-trivial code in a functional programming style. Coming from any imperative or OOP background this should be a good experience. e.g. use Ring to write a web server as a single function..... see this great video for inspiration.

  • Read SICP and do the exercises in Clojure (it's not particularly hard and a good mental exercise to translate the examples from Scheme to Clojure). This book is a masterpiece of MIT computer science education and will certainly broaden your mind if you haven't explored these kinds of concepts before. There is also a "SICP in Clojure" project that you can google although I'm not sure how complete that is so far.

  • Have fun with lazy evaluation. Write some algorithms using infinitely large data structures. Project Euler has quite a few challenges that are quite amenable to this kind of approach (e.g. creating a lazy list of all prime numbers.....)

share|improve this answer
    
+1, also for stressing lazy evaluation and infinite data structures (streams). I have been exploring this lately and once you have understood the ideas you can use them in other languages too. I have first explored streams in Scheme and Scala and now I am rewriting some ugly Java code based on iterators to much cleaner code using immutable streams and lists (using lazy evaluation and memoization). I think this concept should be used more often because it is really elegant and powerful. –  Giorgio Apr 8 '13 at 9:19
    
So, I think learning streams in a more functional language like Scheme (or Clojure, Haskell, Scala, etc) can really help to better understand this concept and make it easier to use it in a non-functional language like Python. –  Giorgio Apr 8 '13 at 9:21

its a zen thing...

see that code is data, and data can be code even when you may not want it to ;) see that code can create data can create code, and learn to type in abstract-syntax-trees :)

share|improve this answer
1  
Zen? Or would it potentially be a hypervisory issue? –  Vatine Mar 14 '11 at 16:04
1  
hehe, work with VMs long enough and you start to get 'side effects' like this... edit –  Arthur Ulfeldt Mar 14 '11 at 18:54

If you want a different style, try something that promotes/restricts you to using functional constructs, rather than something that just supports those constructs.

share|improve this answer
2  
What is "straight Lisp"? Common Lisp? Scheme? Emacs Lisp? ;-) –  Chris Jester-Young Mar 14 '11 at 2:47
1  
What do you mean by straight lisp? Do you mean this? www-formal.stanford.edu/jmc/recursive.html . You might want to be more specific. For functional programming, it seems that scheme would promote functional thinking more than common lisp. –  Jack Kelly Mar 14 '11 at 2:48
1  
C-Lisp and Scheme are just fine. Mainly some language that promotes/restrict you to functional constructs rather than just supporting them. –  Mike Lewis Mar 14 '11 at 2:51
1  
@Mike: Careful, don't call Common Lisp "C-Lisp"; either call it Common Lisp or CL. "C-Lisp" is too easy to confuse with CLISP, an open-source Common Lisp implementation. (Other popular implementations include, e.g., SBCL.) –  Chris Jester-Young Mar 14 '11 at 2:56
3  
@Mike: Also, neither CL nor Scheme particularly enforce functional programming, nor (in CL's case) particularly encourage it. –  Chris Jester-Young Mar 14 '11 at 2:58

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.