
Clojure.rb - swannodette
http://blog.fogus.me/2010/06/09/clojure-rb/
======
phren0logy
I'm coming to Clojure from doing some relatively basic scientific programming
in Ruby and Python. Mostly Python. I don't have a formal background in
programming, and both Ruby and Python made it easy for me to automate portions
of my data analysis tasks. Python's excellent scientific libraries allowed for
even further integration into my data analysis tool chain.

I ran into a few issues that nudged me toward Clojure:

1\. Although Python has a richness of libraries, there were still some niche,
domain-specific libraries available only in Java that look really appealing.

2\. I looked at learning Java a few times, and I had a hard time justifying
spending a lot of time learning it. The gains didn't seem that big for the
tedium I was feeling doing the reading/exercises.

3\. Lisp syntax is quick and easy to learn.

4\. Functional programming makes more sense to me. For example my Python style
involves an unreasonable amount of list comprehensions.

5\. For scientific/numeric computing, baked in parallelism/concurrency is
_extremely appealing._

6\. I was also considering learning R, but when I saw Incanter have been
hoping I could learn Clojure and make use of this excellent library. That way
I con't have to move between a general purpose language and a data analysis
language.

I suspect I'm not alone.

~~~
devonrt
Clojure has (roughly the equivalent) of problem #1. Java has a lot of, err,
great libraries, I guess but many of them are, sadly, hidden behind a Java-
esque API. To use them from Clojure you will need to spend time wrapping up
the Java-esque nature of the API into something more Clojure-like and
unfortunately the answer to the question "How do I do X in Clojure" is often
"Use Java library Y." Thankfully Clojure's Java interop is relatively
painless.

Personally I spent a long time in the Java world and then migrated to Python
and Ruby. I was shocked at how easy to use many libraries are in the Python
world. Libraries like Feedzirra, Mechanize, Python Twitter Tools and so on
don't really have equivalents with respect to ease of use in the Java world.

~~~
swannodette
> Feedzirra, Mechanize, Python Twitter Tools

Except these are exactly the kinds of libraries that are easy to write in
Clojure. Yes, it's important to have these excellent utility libraries, but
having those is just a function of time and the size of the growing community
- nothing inherent to Python itself.

But then you start looking at these really, really powerful mature Java
libraries like Joda, Lucene, Neo4j, Netty, Colt, LWJGL - and you realize that
creating or adopting a simple idiomatic Clojure wrapper for your use case is
going to be downright exciting and fun!

------
kunley
No intention to bash Clojure - it's a wonderful platform & community. But...

I recently switched back to Ruby from Clojure. It was rather pragmatic - i'd
love to experiment more, but I needed to use some libraries I knew very well;
also the peak of productivity which Ruby offers to me was tempting again.

And it happened after a couple of months I had to look to chunks of my Clojure
code to port it to Ruby as it had to be incorporated in a new product. And...

It wasn't so easy to decipher it at a first glance. I also had to jump back
into a state of mind in which I created a bunch of macros to realize wtf were
they doing.

I always was a big fan of macros but this time I realized they like write-only
memory. Hard to share with others without careful documentation. Even hard to
share with future self :)

I just don't have this issue when reading Ruby. In fact, most of Ruby code,
mine or some else's, is instantly comprehensible. There's something in the
brain or what...

~~~
fogus
I doubt anyone reads into what you've written as bashing. There is a definite
complexity cost to using macros, but as you will hear often... avoid using
them unless you absolutely need to... and even then try using a function. A
similar sentiment can be said for monkey patching, metaclasses, and
eigenclasses. They are advanced techniques that introduce complexity and
should be avoided if at all possible. It's the cost of power I suppose.

~~~
kunley
Actually I never took the argument 'avoid macros unless absolutely needed'
seriously. Macros are sexy and fun to code. The ease of writing macros in a
syntax-less Lisp is ubercool. And programming should be fun, right?

I code in Ruby using monkeypatches and dirty hacks. I mostly use functional
style with lots of blocks and lambdas and rarely write a proper class. So I'm
a programming language power abuser, and proud of it ;)

But here I'm talking about a cognitive experience of reading code written some
time ago or by someone else. Let's say that with macros/metaclasses/DSLs you
prepare some environment to make your final code more spicey, and then you
write that final code. My conclusion is that for Clojure my reaction on
reading such code was usually "WTF?!?", and for Ruby: "Ahhh that's clear".

Btw I wonder why someone downvoted my original comment..

[edit] One more thing on macros: the On Lisp book which is armed to the teeth
with macros was the cause why I learned Lisps years ago :]

~~~
fogus
Certainly on my own projects any and all dirty hacks are fair game. When I
work with others I try to avoid being cute for cute's sake. I suppose it's no
great revelation that some prefer Ruby syntax to Clojure's. However, I can say
that Clojure works hard to reduce the number of parens that you might find in
similar Lisp or Scheme code. For example, the `let` form in Common Lisp looks
like:

    
    
        (let ((a 10) (b 20)) (* a b))
    

After many years using CL in school I can sympathize with the idea that Lisp
is full of parens. Common Lisp's `let` is nicely delineated and is easy to
reason about... for macro writers. Experienced Lisp users don't blink an eye
at this. However, Clojure takes a different approach:

    
    
        (let [a 10, b 20] (* a b))
    

There are still parens, but they've been reduced leading to (IMO mind you) a
cleaner look. Our opinions clearly differ on aesthetics, but I think it's
worth noting that Clojure libraries will strive for the latter over the
former.

~~~
kunley
It's true that average Clojure code looks cleaner than average CL code. Still
I'm looking for something more cleaner, still being a Lisp. Time for Arc maybe
:]

~~~
fogus
I wish I could speak for Arc, but sadly I can't say that I know more than
superficialities. Hopefully someone else can chime in. Let me say that the
example with `let` is just a small example of an over-arching trend in the way
Clojure code looks vs. CL. I would love to hear more about Arc's approach.

------
st0p
Can anyone point me to some good introductions on programming in a functional
style for people who can already program in OO and imperative languages?

My day job is Java mainly with some javascript mixed in, did a lot of PHP too.
I used to hate JS, untill I learned about closures (and libraries like
mootools and jquery). Having functions as first class citizens is truly nice!

I can see that the concept of immutability has a lot of value in a world where
multicore reigns. And seeing code as data sounds like an awesome feature. But
for me the question remains, how do I use it in practical everyday use? I
mean, after 7 years of developing OO has ingrained to my mind. How do I
transform that OO mindset into a functional one?

Yeah, perhaps I've become lazy, but most tutorials I've found don't tell me
anything usefull. They show me how to print fibonaci numbers. Great, but how
many times have you needed to generate fibonaci numbers? I need to know how to
sort a list, find your next connecting flight or make a transaction to deposit
100 USD on a bank account.

I've build and helped design a couple of systems I'm proud of, even though I
can see big flaws in all of them looking back. I've been most productive in
garbage collected OO languages. I'm not willing to throw all that experience
away but I am willing to accept that there are better ways to solve problems
in code.

I see great potential emerging from both JVM / Closure and .Net / F#. If
anyone can give me pointers to resources which learn me how _not_ to reinvent
the functional wheel, but how to be more productive in my day-to-day job, I'd
be deeply gratefull.

~~~
steveklabnik
I hate to be one of _those people_, but maybe you should check out Real World
Haskell and Learn You A Haskell for Great Good:
<http://book.realworldhaskell.org/> <http://learnyouahaskell.com/>

If you want to learn functional programming, I'm of the opinion that Haskell
is a great language to learn it. Then again, learning by immersion works for
me, and may not for you.

In any case, Real World Haskell does a good job of explaining, well, real
world examples. And "Learn You" is a nice intro to the language itself.

~~~
masterj
I'd played around a bit with Clojure, but in the end it kinda left me
scratching my head, unsure of how to go about doing anything useful in it. Not
to mention that it's a pain to get it installed and set up properly.

I've been reading learnyou over the past few days, and I can definitely feel
the wheels starting to turn. I'm really looking forward to finishing it and
diving into Real World Haskell.

Though I'll definitely give Clojure another try once I have a better grasp on
the mindset with which to approach it.

~~~
Scriptor
A good trick with lyah is to try to write the code for a function _before_ you
see the actual example code. It'll get you in the functional mindset much
faster.

------
mcav
Clojure feels like a true "next step" after Python, for me. Before Clojure, I
casually observed Lisp and thought, "That's nice, but I'd lose the benefits I
currently get from Python's standard library." But with Clojure, taking
advantage of Java's libraries is almost as good. The power of lisp with a vast
library of existing libraries.

Is it a good idea to base a language off of another, in the way that Clojure
runs on the JVM and relies on Java libraries for the places where there isn't
a pure-clojure alternative? I go back and forth, because I don't want to see
Clojure take a hit if Java starts plunging. But when I look at it from a more
practical perspective, the interop gives Clojure an essential ingredient --
without it, I doubt Clojure would thrive.

~~~
byw
I wonder if Rick Hickey would've used Parrot VM if he started Clojure today.

Some of the limitations of Clojure like the lack of TCO and continuation were
due to the JVM. Parrot VM has these features. You also get to access libraries
implemented in other languages, though I'm not sure how much libraries are in
reality.

------
nkh
For Rubyist's unfamiliar with Clojure, here is a link to a welcoming talk by
Stuart Halloway at RubyConf 2009:

[http://rubyconf2009.confreaks.com/21-nov-2009-10-25-clojure-...](http://rubyconf2009.confreaks.com/21-nov-2009-10-25-clojure-
for-ruby-programmers-stuart-halloway.html)

------
fogus
Of course this begs for a series of posts: clojure.py, clojure.js, clojure.pl,
and clojure.arc. ;-)

~~~
steveklabnik
Without dragging out the whole "Ruby is an acceptable Lisp" thing, I feel that
your choice of Ruby was appropriate, though. With the obvious exception of
Arc, I feel that Ruby is far closer to Lisp than any of those other languages.

Then again, maybe it's just because I'm reading Metaprogramming Ruby right
now.

~~~
angelbob
Python offers most of the same abilities, though Pythonista culture seems to
emphasize them less.

~~~
steveklabnik
Absolutely. The Python culture is explicitly anti-functional programming, even
though the language doesn't have to be.

------
plinkplonk
"Call me crazy, but it seems that there is a large influx of Ruby programmers
exploring the Clojure programming language."

This is true in my experience. And this is the reason I stay away from
Clojure, although I have great respect for Rich Hickey and admire many of the
decisions he made in its design. The migrants _seem_ (completely subjective
perception) to be less the thoughtful ultra competent core Ruby devs,(who seem
to have largely stayed on in RubyLand) and more ... vocal .... folks from the
Ruby on Rails wing of the Ruby community. DHH is strident _and_ competent. A
lot of his followers/emulators picked up just the stridency.

------
mark_l_watson
Michael's article makes sense to me. BTW, I am trying to do all of my work in
just Clojure and Ruby - a nice choice, but some Java and Common Lisp work
keeps coming up that prevents a clean break.

------
sigzero
I hope they didn't bring their attitudes. ha!

~~~
francoisdevlin
You can't survive more than 15 seconds in the Clojure world if you bring an
attitude. Learning the language is a humbling experience. As such, the
community is in 2 distinct groups right now.

1\. Those that are going through some serious growing pains.

2\. Those that recently went through the same growing pains, and have much
sympathy for group 1.

