The big lie wrt lines of code vs bugs is the kind if bugs.
What good is a single line of clojure vs 25 of golang if it takes 45 minutes to get that line of clojure working. I might have more bugs in my golang but the are trivial.
I've busted my ass on clojure for two years with various projects (systemverilog parser/manipulator, CPAP data decoder interpreter visualizer). I want to use clojure but I find myself dealing with awful error messages, constantly breaking tooling (cider), and dealing with asinine constructions all in the name of functional and programming directly in an AST.
I tried. I've read the awe inspiring posts about lisp from Graham and Fogus and Raymond and of course R Hickey and Granger and Hagelberg and Stokke . I think all these people are amazing!
After two years I have not gotten there. I can write reasonably sophisticated applications, but the productivity is so low I feel like in programming in Russian.
I got fed up with tree traversal the other day and said screw it. I turned around and rewrote versions of my CPAP app in golang, and then CPP in d a day. It took me weeks to get this done in clojure.
I couldn't get a binary parser framework to work except for the most trivial case, so I wrote my own generic binary parser. I couldn't tell if seesaw made swing better or worse. Actually I decides worse because at aleast with Java interop I can tell what the hell is going on.
In CPP writing a binary parser was nearly as simple as defining a struct and memcpy. God I live memcpy. You know how many years it's been since I wrote CPP? Never. I've never written a line of CPP before and the rewrite was almost pain free. The Makefile and understanding data alignment in struct a was the hard part.
I know your feeling, I've programming in Clojure for one year now (although I don't have time to program with it full time). I think your kind of problems are more related on "how" you use Clojure rather than Clojure itself. Errors are obscure only if you try to do too much things in one function. Try to keep functions as simple as possible and to do one task per function, no more. Then message errors are not that hard to figure out, although yes, I agree that for example in Java errors are easier to figure out (but definitely not fixing them...). And anyway using the REPL you can test one function at a time, given it's a pure function, which is also a new state of mind: eliminate all possible mutable state.
I've found that when using Clojure you have to think in a different way about the problems to be able to "see" how your problem can be resolved in Clojure in a more elegant and concise way. This is hardest task I've found when moving to Clojure from Java: change your mind. With the right mindset, everything (in my case at least) seems like pretty trivial in Clojure, and definitely much faster to code and test than Java.
I can so related to this. Thank you for articulating the problem (I thought I was just doing it wrong). To elaborate on what you're saying in pseudo code, imagine writing this in algorithm in clojure:
take a collection -> split by is-even? -> for each collection, sort ascending -> take the first of each collection
This is the level of abstraction I want to think about. But, when one of these functions takes or returns something you don't expect, debugging the problem usually took me 30 minutes. The error messages were very opaque to me.
I could never figure out a good work flow to debug these problems. I still feel like there's something I'm doing wrong. People on IRC tell me you eventually understand the errors better, they're just confusing at first. I never got to that point though.
To address one of your points, I've found it much easier to get a complex line of clojure code working since I started using the InstaREPL in LightTable.
It shows the REPL output of each line of code as you write it, which is spectacularly handy.
I feel like the "Why Use Clojure?" essay is a bit flawed. I feel like it focuses too much on details so minor that I would regard them as trivial. I would suggest that a much better answer to the question "Why use Clojure?" could be found by reading Colin Steele's essays. When he became CTO at Hotelicopter/RoomKey he was inheriting a vast system of PHP and Ruby. When they re-wrote the system in Clojure, he had a very small team: only 4 programmers. That they were able to accomplish so much in a short amount of time says a lot about the power of Clojure. These are 2 essays he wrote:
It's hard to write any kind of essays that try to show that X is better than Y in the realm of Programming Language + Platform (yes, Programming Languages these days don't buy much if the Platform is under-supported even though the majority won't admit it).
If you wrote too high-level without enough details, people would call you out for "supporting your argument without any merit".
If you wrote too technical/low-level, it looks like a script kiddie toy and not "for production ready system with complex requirements and multiple stakeholders with evolving needs".
I gave up convincing people a while ago and just focus on get things done. Java, as verbose as it is, still productive enough for me thanks to the ecosystem + tools + libraries + etc.
Those posts don't tell me much about Clojure, except that Ruby wasn't fast enough and Java wasn't fun enough, and that the CTO digs Lisp. Doesn't give me concrete reasons why I couldn't do the same with Java + Netty.
The introduction has a reasonable premise, but I thought Business Case No. 1 doesn't do much to further the point. In fact, it reinforces the academic/industry divide that is belabored in the intro.
Ask people who are working on "commercial" development how often they have to implement a Fibonacci sequence or something similar. The example comes across more like a neat party trick then something that would make itself useful on a daily basis.
Not very convincing when the very first example is apples vs. oranges: the java fib() code includes a main() driver with command line parsing and printing of the result to stdout, which I don't see in the clojure version.
Clojure, being a Lisp, uses the tradition of a REPL (Read-Eval-Print-Loop). The REPL handles all of the command line parsing and printing for you. All you do is load up your program and start calling functions with it. It makes for a great interactive development tool, as it can be used within most editors/IDEs which tend to have commands for automatically reloading all your code in the REPL.
Not to mention you could easily rewrite the Java version in one line with a conditional, if you wanted. Whitespace in your code isn't always a bad thing IMHO.
You focus on one example to say "not very convincing"? Please elaborate more on why Clojure features are "not very convincing", I would like to hear your opinion.
Good question. Unlike most languages with which I am not yet familiar, Clojure looks like Greek. Most languages are at least somewhat readable. Perhaps I need to know Lisp to appreciate Clojure. Coming from a Java/Scala/Ruby/Python/Haskell/Pascal/C# background. I can't make head or tail of Clojure examples. It might as well be encrypted. To those who are using Clojure, which previous languages enabled you to make sense of Clojure more easily? Or was it something you learned from scratch?
If you're really coming from a Haskell background I very much doubt that you "can't make head or tail of Clojure examples. It might as well be encrypted.".
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 don't know a Clojure. Why should knowing understanding one language imply that you automagically know another? If you know Spanish, Portuguese May look familiar but it won't be exactly the same. Does that mean you should understand Korean or Japanese?
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.
The thing that helped me most when I started learning clojure is to mentally move the parenthesis over to the other side, so
(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.
If you already have a background in each of Ruby ,Python, Haskell and Haskell you probably can learn a good chunk of Clojure in a weekend, as it shares many features with these languages. The main difference, of course, is the prominence of lispy prefix function calls delimited by parens. Well, and macros, but Ruby does some of this.
Unless you're a native Greek speaker. My point being that prefix notation is not something common in programming languages, but that doesn't mean it doesn't work or it's obscure: it's obscure to you because you're not used to read it, that's all. And yes, maybe the example is not best example.
What would objectively define "readability"? I hear this word thrown around a lot without much thought given to what it means. As far as I can tell whether a person considers a language "readable" is really only correlated with whether they were first taught a language with similar lexical syntax. People who were taught Scheme consider sexp based languages more readable, and people who were taught C/Java prefer semicolon delimited block-like languages.
One of the reasons I think people may find clojure hard to read is that there isn't much vertical spacing. Do you find this translation of js to clojure any easier?
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.
I don't find the example Clojure in the original article terribly readable, speaking as someone who writes a decent amount of Common Lisp.
My 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.
Take a gander at the javascript/clojurescript synonyms cheatsheet, it's a lightweight way of seeing the mental transformations you need to do to get from a curly brace language to a s-expression based language: http://kanaka.github.io/clojurescript/web/synonym.html
I'm not a Clojure programmer, but I have an interest in things that run on the JVM. I went through this semi-quick guide to get an overview of how the language and syntax works:
You don't need to "know Lisp" in the sense of being proficient, but you need to be familiar with s-expressions. Once you grok s-expressions, the rest is "just" grokking a bunch of functional idioms not specific to Clojure.
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.
C code can be unreadable and sometime pure poetry. Lisps are the same. One difference though, s-exps are the most editable thing in the universe, paredit-like interaction makes you forget the superficial lack of readability.
I think the answer is interesting because it's not purely mine, but instead summarizes a poll of ~5 strong engineers at my previous company. Two years later, I still think most of these bullet points hold, though I could also add a few more advantages and a few disadvantages of using Clojure.
Could substitute Clojure for Scala and the arguments made in the post would be at least equally valid.
2014 is going to be a big year for the JVM as the Java 8 gorilla cometh. Will be interesting to see what impact that event has on Scala/Clojure/Ceylon, etc. alternate JVM language adoption.
For languages that were designed to be "better than Java", then Java 8 represents a threat, however Clojure and Scala have very active and thriving communities and contain concepts and ideas that go beyond "Java with Closures".
I use Scala in production, have done so for the last 2 years, have been learning a lot about FP and loved every minute of it. It's rather interesting, because before Scala I basically wanted C# on top of the JVM. And now C# is looking bland, bureaucratic, unproductive and I don't want it anymore.
Of course, many people hoped that some language will end up replacing Java as THE language for the JVM. That never had any chance of happening, even if closures would've never make it in Java. The people that wanted more capable languages already moved on and the shops and software developers that continue using Java will not change languages, because if Java worked well for them, it will continue to work well in the future and everybody had plenty of opportunity for change already. Java will still be the main language used in the enterprise, simply because enterprise software development tends to favor cheaper, easier to replace developers. Of course, this is one reason for why startups tackling the enterprise space are thriving, but that's another discussion.
Back to the point - we tend to think of languages and their evolution as some kind of football tournament. For me it's rather uninteresting what language will "win". I don't really care. All I care about is for a language to have a sustainable and active community that churns out useful libraries. And some people fear that they won't find jobs with language X. Personally I found the contrary to be true - finding well paying jobs for working on interesting projects in languages that are not Java, C#, C++ or PHP is much, much easier. Things are easier also from the employer side, because you've got less noise to deal with and usage of a certain language becomes one of the main attractions for that job. In my experience, it's a win-win combination, which is why I fear the thought of my favorite languages becoming too mainstream. But then again, I don't really care about languages that much. All I care about is for me to not suffer while trying to express what I want in code, which is why I stay away from Java.
Anyway, I'm on my Christmas Holiday, so back to reading "Functional Programming in Scala". It's a pretty cool book btw.
I agree Java 8 will be big. I have started experimenting with Java 8 language features. I use Clojure a lot, and I occasionally use Scala. Java 8 features might get be using Java again for new projects.
Fewer lines of code doesn't necessarily mean obfuscation, this is a language feature. If Clojure is obsfuscated, then what is Perl, encrypted? On the other hand, fewer lines of code definitely mean less bug probability.
I wish this didn't use the 590 core functions vs 30 Java keywords argument. Clojure only has a handful of "special forms", whereas Java has dozens. A better count would be all the methods in String, Int, List, Array, etc.
> With a total of around 590 unique functions7 in the Clojure core library alone that can be quite daunting when compared to C or Java which only range from around 30 to 50 keywords.
I count 19 special forms, 71 macros [1], 444 functions, and 29 variables in clojure.core. I don't think we should count functions or variables because these are like library functions and members (methods and fields) in other languages. But both special forms and macros are special in that they can't be passed around in the executing code. There's 90 of those, which is comparable to Java's 50-something keywords, or C#'s 70-something.
[1] excluding the 4 special forms `let`, `fn`, `letfn`, and `loop` which are also macros
Can your validation example handle checking at the map level (i.e. the case where a required field is missing)? It seems like this is something you would want to do.
So if thats the best list I am happy I went with Scala. Especially the Leiningen example. Is that seriously what needs to be written for a project to build ? Its as bad as maven.
Functional languages, as personal experience above leads me to believe, are inherently more difficult to comprehend
I don't agree with this. They seem "weirder" and harder, but they're not intrinsically difficult. They're just less familiar.
Also, there are a huge number of people out there who think they "know Java" but really don't. If you don't know what volatile and synchronized are and how they work, for one example, you don't really know Java. I would say that, unless everything in Java Concurrency in Practice is familiar to you, you don't really know Java.
Java and C++ are actually complex, difficult languages. The difference is that, with "design patterns" and explicit managerial attention to differences in ability (i.e. don't give mediocre programmers hard problems) it's more possible to half-ass that knowledge.
The weirdness is such that I understand, actually I felt it was, more difficult to comprehend. It's a complete point of view reversal. It ends up a simpler model with lots of quality, but sometimes something different and too simple is the hardest to understand.
[+] [-] DigitalJack|12 years ago|reply
What good is a single line of clojure vs 25 of golang if it takes 45 minutes to get that line of clojure working. I might have more bugs in my golang but the are trivial.
I've busted my ass on clojure for two years with various projects (systemverilog parser/manipulator, CPAP data decoder interpreter visualizer). I want to use clojure but I find myself dealing with awful error messages, constantly breaking tooling (cider), and dealing with asinine constructions all in the name of functional and programming directly in an AST.
I tried. I've read the awe inspiring posts about lisp from Graham and Fogus and Raymond and of course R Hickey and Granger and Hagelberg and Stokke . I think all these people are amazing!
After two years I have not gotten there. I can write reasonably sophisticated applications, but the productivity is so low I feel like in programming in Russian.
I got fed up with tree traversal the other day and said screw it. I turned around and rewrote versions of my CPAP app in golang, and then CPP in d a day. It took me weeks to get this done in clojure.
I couldn't get a binary parser framework to work except for the most trivial case, so I wrote my own generic binary parser. I couldn't tell if seesaw made swing better or worse. Actually I decides worse because at aleast with Java interop I can tell what the hell is going on.
In CPP writing a binary parser was nearly as simple as defining a struct and memcpy. God I live memcpy. You know how many years it's been since I wrote CPP? Never. I've never written a line of CPP before and the rewrite was almost pain free. The Makefile and understanding data alignment in struct a was the hard part.
[+] [-] m0skit0|12 years ago|reply
I've found that when using Clojure you have to think in a different way about the problems to be able to "see" how your problem can be resolved in Clojure in a more elegant and concise way. This is hardest task I've found when moving to Clojure from Java: change your mind. With the right mindset, everything (in my case at least) seems like pretty trivial in Clojure, and definitely much faster to code and test than Java.
[+] [-] tieTYT|12 years ago|reply
I could never figure out a good work flow to debug these problems. I still feel like there's something I'm doing wrong. People on IRC tell me you eventually understand the errors better, they're just confusing at first. I never got to that point though.
[+] [-] phren0logy|12 years ago|reply
It shows the REPL output of each line of code as you write it, which is spectacularly handy.
[+] [-] Sssnake|12 years ago|reply
[+] [-] lkrubner|12 years ago|reply
60,000% growth in 7 months using Clojure and AWS
http://www.colinsteele.org/post/27929539434/60-000-growth-in...
Against the Grain: How We Built the Next Generation Online Travel Agency using Amazon, Clojure, and a Comically Small Team
http://www.colinsteele.org/post/23103789647/against-the-grai...
At this point RoomKey is a lot bigger than Hipmunk.
[+] [-] edwinnathaniel|12 years ago|reply
If you wrote too high-level without enough details, people would call you out for "supporting your argument without any merit".
If you wrote too technical/low-level, it looks like a script kiddie toy and not "for production ready system with complex requirements and multiple stakeholders with evolving needs".
I gave up convincing people a while ago and just focus on get things done. Java, as verbose as it is, still productive enough for me thanks to the ecosystem + tools + libraries + etc.
[+] [-] sehugg|12 years ago|reply
[+] [-] kohanz|12 years ago|reply
Ask people who are working on "commercial" development how often they have to implement a Fibonacci sequence or something similar. The example comes across more like a neat party trick then something that would make itself useful on a daily basis.
[+] [-] mpweiher|12 years ago|reply
[+] [-] chongli|12 years ago|reply
[+] [-] GhotiFish|12 years ago|reply
fib-seq is not a defined token. wtf is going on here?
[+] [-] sehugg|12 years ago|reply
[+] [-] m0skit0|12 years ago|reply
[+] [-] unknown|12 years ago|reply
[deleted]
[+] [-] kvtrew76557|12 years ago|reply
[+] [-] coldtea|12 years ago|reply
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.
[+] [-] hippee-lee|12 years ago|reply
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.
[+] [-] ispolin|12 years ago|reply
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.
[+] [-] gajomi|12 years ago|reply
Some links: http://blog.fogus.me/2010/06/09/clojure-rb/ http://stackoverflow.com/questions/4509782/simple-explanatio... http://jkkramer.com/sudoku.html
[+] [-] m0skit0|12 years ago|reply
[+] [-] freyrs3|12 years ago|reply
[+] [-] n72|12 years ago|reply
function doThis(arg1, arg2){
}(defn do-this [arg1, arg2]
)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.
[+] [-] pnathan|12 years ago|reply
My 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.
[+] [-] r4vik|12 years ago|reply
[+] [-] taude|12 years ago|reply
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...
[+] [-] wonderzombie|12 years ago|reply
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.
[+] [-] agumonkey|12 years ago|reply
[+] [-] vezzy-fnord|12 years ago|reply
[+] [-] ytdtty|12 years ago|reply
[+] [-] lpolovets|12 years ago|reply
I think the answer is interesting because it's not purely mine, but instead summarizes a poll of ~5 strong engineers at my previous company. Two years later, I still think most of these bullet points hold, though I could also add a few more advantages and a few disadvantages of using Clojure.
[+] [-] virtualwhys|12 years ago|reply
2014 is going to be a big year for the JVM as the Java 8 gorilla cometh. Will be interesting to see what impact that event has on Scala/Clojure/Ceylon, etc. alternate JVM language adoption.
[+] [-] bad_user|12 years ago|reply
I use Scala in production, have done so for the last 2 years, have been learning a lot about FP and loved every minute of it. It's rather interesting, because before Scala I basically wanted C# on top of the JVM. And now C# is looking bland, bureaucratic, unproductive and I don't want it anymore.
Of course, many people hoped that some language will end up replacing Java as THE language for the JVM. That never had any chance of happening, even if closures would've never make it in Java. The people that wanted more capable languages already moved on and the shops and software developers that continue using Java will not change languages, because if Java worked well for them, it will continue to work well in the future and everybody had plenty of opportunity for change already. Java will still be the main language used in the enterprise, simply because enterprise software development tends to favor cheaper, easier to replace developers. Of course, this is one reason for why startups tackling the enterprise space are thriving, but that's another discussion.
Back to the point - we tend to think of languages and their evolution as some kind of football tournament. For me it's rather uninteresting what language will "win". I don't really care. All I care about is for a language to have a sustainable and active community that churns out useful libraries. And some people fear that they won't find jobs with language X. Personally I found the contrary to be true - finding well paying jobs for working on interesting projects in languages that are not Java, C#, C++ or PHP is much, much easier. Things are easier also from the employer side, because you've got less noise to deal with and usage of a certain language becomes one of the main attractions for that job. In my experience, it's a win-win combination, which is why I fear the thought of my favorite languages becoming too mainstream. But then again, I don't really care about languages that much. All I care about is for me to not suffer while trying to express what I want in code, which is why I stay away from Java.
Anyway, I'm on my Christmas Holiday, so back to reading "Functional Programming in Scala". It's a pretty cool book btw.
[+] [-] mark_l_watson|12 years ago|reply
[+] [-] m0skit0|12 years ago|reply
[+] [-] elwell|12 years ago|reply
"perseption" => "perception"
"Fewer lines of code is a great thing" => [the opposite argument could easily be made as well; more lines of code (within reason) = less obfuscation]
[+] [-] m0skit0|12 years ago|reply
[+] [-] zhodge|12 years ago|reply
[+] [-] unknown|12 years ago|reply
[deleted]
[+] [-] ChristianMarks|12 years ago|reply
[+] [-] unknown|12 years ago|reply
[deleted]
[+] [-] JackMorgan|12 years ago|reply
[+] [-] vorg|12 years ago|reply
I count 19 special forms, 71 macros [1], 444 functions, and 29 variables in clojure.core. I don't think we should count functions or variables because these are like library functions and members (methods and fields) in other languages. But both special forms and macros are special in that they can't be passed around in the executing code. There's 90 of those, which is comparable to Java's 50-something keywords, or C#'s 70-something.
[1] excluding the 4 special forms `let`, `fn`, `letfn`, and `loop` which are also macros
[+] [-] creese|12 years ago|reply
[+] [-] m0skit0|12 years ago|reply
[+] [-] robin2|12 years ago|reply
[+] [-] bonemachine|12 years ago|reply
Comparing any functional language to Java is just silly. As illustrated by the Fibanocci example.
[+] [-] dkhenry|12 years ago|reply
[+] [-] michaelochurch|12 years ago|reply
I don't agree with this. They seem "weirder" and harder, but they're not intrinsically difficult. They're just less familiar.
Also, there are a huge number of people out there who think they "know Java" but really don't. If you don't know what volatile and synchronized are and how they work, for one example, you don't really know Java. I would say that, unless everything in Java Concurrency in Practice is familiar to you, you don't really know Java.
Java and C++ are actually complex, difficult languages. The difference is that, with "design patterns" and explicit managerial attention to differences in ability (i.e. don't give mediocre programmers hard problems) it's more possible to half-ass that knowledge.
[+] [-] agumonkey|12 years ago|reply