if (x > 0) ...
if (> x 0) ...
In fact, it has been with us in programming for over 6 decades, and is a classic mathematical syntax called Polish Notation ( http://en.wikipedia.org/wiki/Polish_notation ).
For one, it makes all method invocations the same: the method name followed by the arguments. Here the method is operator plus (addition).
I find it "absurd" in that it requires adaptation to a form of syntax that's more niche than anything. I don't see that adding to the argument of simplicity in this particular scenario.
I'd guess that, for you, Clojure _wouldn't_ have the same kind of efficiency that some others see. Lisp, in general, appeals to people who think "A is really the same thing as B. Cool!" They see treating all functions the same as a really worthwhile thing, in and of itself. Others, such as yourself, aren't really excited by that. It's a style thing.
Fanatical generalization can be a really effective trait in some circumstances. A small team of generalizers working on a reasonably-defined problem (such as a re-implementation) can turn out amazingly simple and compact code, since they tend to factor out common things.
On the other hand, a generalizer might not be as tactically-focused as someone else. A tactical person might be more inclined to make a surgical change, whereas a generalizer might wind up with a "toolbox enhancement".
A tactical person is going to get more mileage out of tools that already take care of a lot of common cases, and do them in common ways. A generalizer will do better with tools that are more "meta".
Because this is just syntax, "A 'looks' the same as B. Cool!" is a more definitive statement. After all, it's just getting compiled/translated to JVM byte code anyway.
Efficiency is an entirely different conversation and tangential to the one we've been having regarding syntax and simplicity. Nobody has asked to this point, but I have no problem with Clojure's syntax structure. I find it very compact, I like the explicitness of parentheses, and like that it works in the JVM. (Disclaimer: I've not deployed any Clojure-based code in a production environment, so my own experience is limited.)
I also find that it's syntax has its own quirks, much like every other language. And while some things 'look' the same in Clojure, other things don't -- and that's perfectly ok. It's relatively consistent enough that the syntax logically points to its idioms.
But I stand by my original comment: it's only as simple as the observer makes it out to be. I don't find the syntax of Clojure more or less simple than many other languages.
- They are variadic functions, they work on a range of inputs.
- Their names are valid identifiers, which allows for function names like list->vector
- Precense is fairly self-evident. 2 * 2 / 5 - 1 vs (- (* 2 (/ 2 5)) 1). You could add parenthesees to the first, and most would, Lisp just forces you to.
- They are consistent, a function is the first element of a list, no matter what
- Closely related to the above point, they make writing macroes easier. Imagine if macroes had to take infix operators into account. Certain macroes would have to scan the syntax they receive for the presense of operators, or you would have to create special macroes for operators...
- You would need special syntax for passing operators as values to other functions. ((dummy) < 5) ;; What should happen here if dummy returns another function instead of something orderable?
I agree that it is uncommon and take getting used to, but it does have the advantage of being consistent, and consistency and lack of special cases is a part of simplicity.
I think that the concept of standards is worthy of consideration. While '>' is an operator in scala and other languages, it's also an operator in basic mathematics. And in basic math, we're taught "if x is greater than zero" using the notation of "if x > 0" (parentheses notwithstanding.)
It's only consistent in terms of how clojure presents it, but it's inconsistent with treatment elsewhere. Consistency does go to simplicity, but if it takes some "getting used to", it can't be all that simple.
For example, how would you express the "between?" in infix notation? In Clojure we can use the same function - "(> 1 x 0)".
I do agree that Clojure way takes some getting used to.
Well, engineers using scientific calculators handled polish notation (and reverse polish notation, like 3 4 + for 3 + 4) just fine for half a century or so...
Now the next question is: where do I need that for? Just let it soak in for a while: it is surprising how your solutions change if your tool works differently.
I've been busy with Scala for some time now, but the OO aspect also dominates the FP part. And that OO part is huge: traditional classes, case classes, traits (which are occasionally used standalone) static functionality not in the class but factored out in an object, structural typing just to name some.
There are many aspects I like of Scala, but simplicity is not among them. In teams you will have to have strong communication if you do not want to limit yourself to a subset of the language ("no fp" for instance)
(< 1 2 3 4 5 6)
(apply < (range 1000))
Although I think I could create a function in Scala that permits the same thing, yes? Mostly the arbitrary operands or range reference imply recursion & iteration, which I believe I could implement easily. (Check me if I'm wrong here, I might be missing something.)
I wouldn't have suggested that, except that Clojure (as I understand it) also encourages that one can "expand" the language. I would see adding this capability as a Scala function in the same light.
Which is basically the same as (foo a b) except the ( if one identifier later.
I've often seen stuff like this in languages without operator overloading: a.add(b.multiply(c) d.subtract(5)) and nobody complains about that, but a lot of people are hung up about (add a (multiply b c) (subtract d 5)) which is almost the exact same thing. Of course, in Lisp-like languages, you would be able to redefine functions, s it would actually look like this: (+ a (* b c) (- d 5))
I don't get why people have such big complaints about syntax. Whatever you are used to is easier to read. Obviously! But its not hard and does not take long to get used to this.
So once you are used to it, Lisp is simpler because it has one single rule that is followed by every language construct: (function params) - in other languages you have all kinds of flow control statements with different rules (if, else if, while, for, switch.. all have different rules). Then theres function calls and method calls. Precedence. That's a lot to have to remember.
(defmacro ord-compare [a ord b]
`(if (or (= > ~ord) (= < ~ord)) (~ord ~a ~b) "Use > or < to compare."))
(ord-compare 3 > 2)
Check out the tests for how to use it:
A good example:
; $= translates inflix to prefix notation.
($= 3 <= (5 * 2/7)) ;will give you false.