Except if you mean that you dabbled in Haskell, but are a Java/Scala/Ruby/Python/Pascal/C# guy.
In any case, it takes no more than 1-2 days (from scratch) to get to understand functional code. Remember that you weren't born able to understand imperative code either. Just learn the (very basic) syntax rules, and the rest is easy.
I recall interviewing a potential hire who lauded his appreciation and understanding of functional programming - and he really believed it. So I asked him to explain to me what a closure was, and give me some examples of ways you can exploit them in your code, practically. Pretty straightforward question for someone who claims to understand the concepts of functional programming.
Of course, I wouldn't be bringing this up if he was even remotely successful, but I don't think this was a result of his presenting himself in a dishonest manner. I think closures are subtle ideas; much like function application, composition, and other ideas that seem familiar and easy to understand until you are asked to apply them practically. That's when the gap between what you think you know and what you actually know is borne for the world to see.
From the little bits of dabbling with various lisps in have done a functional language is different enough from my bill paying regular languages (JS, php, Java) that without a focused study on a project that hits several layers of a typical stack, I fully expect the language to be foreign to me. Until I know the 350 core language operations by heart I'll not be able to play with them. If I cannot play I'll never be able explore the language and use and misuse it until I can make it do what I want it to do.
So the fact that it looks encrypted to you is a good thing. It's a code waiting for you to break it. It's a problem waiting. A small group of extremely intelligent people are responsible for the family of lisps. That tells me that if/when I do dedicate the time and effort to understanding the lisp tools it will be worth the effort.
(println (max 34 64 15))
becomes println(max(34,64,15));
and vice-versa.Another thing that helped is realizing that almost all things that require special syntax in other languages look like function calls in clojure. So, for example, to create a new function, you call the defn "function" and pass it parameters for the name of your new function, the expected arguments, and the body of the function.
The last thing is remembering that in clojure, the last statement in the body of the function is automatically the return value of the function, so I just imagined that the last statement had a "return" call in front of it.
With these 3 rules I could mentally translate 95% of clojure* to c-style code and back.
*The other 5% is mostly about macros, which are what give clojure (and other lisps) the power to add new features to the language via libraries, among other cool things. They they're powerful and used sparingly though, so you won't bump into them too much, and when you do, most will be documented as to how to use them properly.
I would say that most syntax in other languages is there precisely so that not everything looks like a function call.
In fact I think that only 13 "functions" are "magic" in clojure (as in written in java), and the whole rest of the language is written using those 13 functions[1]. That would be like, for example, adding golang's channels to ruby syntax by writing ruby code, without having to drop down to C, which i think is pretty cool.
I also found it very useful in real-life, mostly through having clojure libraries that can do things more seamlessly than similar libraries in other languages. For my last project, I needed to use maybe monad functionality quite often, and having it be as easy to use as the core language in my code was a huge win for my sanity.
[1]: I think some of the data structures are written in java as well, but only for performance reasons.
Some links: http://blog.fogus.me/2010/06/09/clojure-rb/ http://stackoverflow.com/questions/4509782/simple-explanatio... http://jkkramer.com/sudoku.html
function doThis(arg1, arg2){
var m = arg1 + 3;
var n = modifyArg(arg2);
if (m > 3){
System.out.println("bigger!");
}
return m + n;
}(defn do-this [arg1, arg2]
(let
[m (+ arg1 3)
n (modifyArg arg2)]
(if (> m 3)
(println "bigger!")
)
(+ m n)
)
)I'm not suggesting this is good clojure, but it's closer to the way imperative languages are written.
One thing which still causes me to expend a few extra brain cycles for me is the [] in the let clause. The fact that the locally scoped vars m and n are contained within a syntactic block, as it were, makes me feel that they're within an inner scope and not available to the code below. It's really trivial and absolutely a feel thing, but it does have small effect on the ease of readability.
proc doThis(arg1, arg2: int): int =
let m = arg1 + 3
let n = modifyArg(arg2)
if m > 3:
echo("bigger!")
return m+n
With the added bonus that you get compile-time type checking (as well as a fair bit of type inference - notice I didn't have to specify any types other than the function signature), and the code itself compiles down to highly efficient C (https://gist.github.com/tylereaves/8116774 if you're really curious, do remember that code isn't intended to be human readable/modifiable). proc foo(x: int): int =
let z = x * 2
#z visible
block:
let y = z * 4 #z & y visible
let foo = 3 #z and foo visible, y out of scopeMy real entry into the Lisp world was via Perl and the higher order functions that I used there. That enabled me to grasp the overall semantic of Lisp; lots of time in the code did the rest.
EDIT: actually this was the link I meant to post. It was on HN a couple weeks ago: https://docs.google.com/presentation/d/15-7qFy6URdE7Owi2Litk...
EDIT: Not this link, though it looks interesting: http://www.innoq.com/blog/st/presentations/2010/2010-05-20-C...
Actually if you're familiar with Haskell then Clojure idioms should be more familiar to you. Clojure's datatypes are (almost all) immutable, driving it towards a lot of functional idioms you see in such as Haskell or maybe Scala.
On the other hand, I would be genuinely surprised if someone familiar with Haskell were unable to pick up ML, or vice versa.
I really like Clojure, and it's what I started with in terms of Lisps. When I wanted to explore more "traditional" Lisp, I looked into Common Lisp, and it didn't thrill me. It felt old to the point of decrepit.
Racket feels very modern, and very polished. I'm trying to groom it as my go-to scripting language.