Thinking in Clojure for Java Programmers
blog.factual.com
blog.factual.com
You've done an excellent job of showing Clojure's benefits to a much, much wider audience - programmers not familiar with functional programming. Also it's compelling to hear that you're successfully using Clojure to efficiently "script" larger Java codebases.
Kudos for writing such a hype-less, non-condescending, and educational tutorial for Java/imperative programmers!
* easier to write
* perform just as well
* be concurrency safe
Clojure isn't there yet, but it's well on its way I think.Which is probably a side effect of having been created when 64kB was a decent memory size.
This is far preferable to typing e.g. "public static void ..." all the time
I have a hard time believing that the best choice of name for all of these operators just so happens to always be some 3 or 4 character string that's almost but not quite a word and seems to have dropped some vowels.
As for "public static void ...", that's a disease of another sort, equally as bad.
`car', and `cdr' and replaced in clojure with `first' and `rest'.
Once you've spent ten minutes with the language, these names aren't going to trip you up.
Do you think that every index variable in a loop should be called "index"?
user=> (macroexpand '(defn f [x] x))
(def f (.withMeta (clojure.core/fn f ([x] x)) (.meta (var f))))
[edit: clarified an ambiguous initial statement]Mathematics and natural languages take the same approach, assigning the most commonly used bits of the language the smallest words/symbols. It makes the document easier to parse, when done within reason.
You don't need any of that to program with Lisp (although Emacs and SLIME can help)
Autocomplete:
http://stackoverflow.com/questions/4289480/how-to-do-automat...
Debugging:
http://clojure.org/getting_started
Plugins:
https://github.com/swannodette/textmate-clojure
http://code.google.com/p/counterclockwise/
http://plugins.intellij.net/plugin/?id=4050
Options:
[emacs is too hard on windows] http://clojure.bighugh.com/
[but I use a mac] http://aquamacs.org/
[but I write ###.NET] https://github.com/richhickey/clojure-clr https://github.com/jmis/vsClojure
I wish monitor real estate progressed at the rate of Moore's law, but I suppose we'd need bigger rooms to put them in before too long.
a * b
would be replaced by: multiply(a, b)
which is much more self-documenting :-)At the most simplistic semantic level a binary addition operator is a simple mapping of what the machine wants to do (take 2 registers and put their sum in an accumulator register).
Lets expand that simple piece of code. Now you have more than 2 numbers to sum:
2 + 3 + 40
you have been forced to encode both stages of summing the first pair of numbers and then the result and the third value. Contrast this with a lisp (+ 2 3 40)
Lisp has takes care of all of the details for me; i merely need to supply the operands and the language worries about mapping it to the underlying operations as needed.Clearly, here is a situation where lisp notation elevates me from having to think about the machine.
Touche, indeed.
Obviously neither one is more "human"; humans don't know the first thing about math until they're educated. This has everything to do with what's familiar and nothing to do with what's "natural" to the human mind.
My reading of your posts is that you advocate ignoring any R' that has an impedance greater than zero. Surely it would be wiser to evaluate the switch to R' if the value of R' less the impedance of R' is positive?
Is this a fair representation of your position?
"One day I asked him, 'Roger [Hui], do you do math in English or Cantonese?' He smiled at me and said, 'I do it in Cantonese because it's faster and it's completely regular.'" - "A Conversation with Arthur Whitney"
Also, math notation is pretty much the only bad syntax example when comparing with other programming languages. It becomes literally the only example when you leave hard asceticism and take the approach that Clojure does of providing literals for vectors, maps, and sets.
So, yeah, maybe dig a little deeper next time instead of dismissing tools out of hand? Many programs never directly perform arithmetic, are Lisp dialects unsuitable for those as well?
edit: I love Clojure's literals but I still think even with editor help, nested parens are a less readable form of structure than c-style blocks. I understand why it's done that way (uniformity for macros), but that doesn't mean I have to like it in and of itself.
I don't feel strong one way or another on this issue, though I do program in Clojure. If you want infix math in clojure: http://data-sorcery.org/2010/05/14/infix-math/
(infix [1 + 2] * 3)
;=> 9 ( (1 + 2)/(3 + 4) )**2
vs. , . 2
/ 1 + 2 \
| ------------- |
\ 3 + 4 /
The difference may seem subtle, but it's shockingly important. A better example may be ,-, b
\
\ x + 1 dx
\
'--' a
instead of something like trapz(a, b, @(x) x+1);
The truly human way of writing down math requires much more flexibility than a typical text editor can really afford. This isn't to say that some sort of pseudo-visual programming is Teh Futar though.(I do think a LaTeX --> solved expression tool would be awexome though.)
When precedence is to be overridden, the infix form can be easily understood by anyone with basic knowledge of arithmetic. Prefix on the other hand can be confusing. This makes BigDecimal arithmetic in Java cumbersome compared to languages which allow operator overloading.
;)
(* (+ 1 2) (/ (+ 3 6) (+ 1 2)))
I was also skeptical regarding the readability of prefix notation vs. postfix for large problems. However, when I tried it, I actually found it easier to handle. For example, here's a very obnoxious heat transfer correlation that I typed in common lisp: ( * 4.364
(expt (1+ (expt (/ Gz 29.6) 2)) 1/6)
(expt
(1+ (expt (/ (/ Gz 19.04)
(* (expt (1+ (expt (/ *Pr* 0.0207) 2/3)) 1/2)
(expt (1+ (expt (/ Gz 29.6) 2)) 1/3)))
3/2)) 1/3 ))
Versus, in infix it's more like: 4.364 * (1. + (Gz/29.6)**2)**(1/6)
* (1 + ( Gz/19.4/(
(1 + (Pr/0.0207)**(2/3) )**(1/2)
* (1 + (Gz/29.6)**2 )**(1/3)
))**(2/3) )**(1/3)
Now, I admit that my sense of whitespace is pretty inconsistent, but still: Here is a real case of a very annoyingly nested expression in both infix and prefix notation. While I think it would take quite a while for anyone to sort out what the Hell is going on for either of these regardless of experience (versus, say, rendered LaTeX), I would put forth the suggestion that the common lisp is actually easier to understand.