Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I don't get it. Scala has all the features, it's fast AND it's easier to read (no matter how much the presentation tries to play down the () issue, it's there.)

Why not use Scala insead?



no matter how much the presentation tries to play down the () issue, it's there.

I'm getting tired of statements like this. I've been using Clojure for a couple of years now. I got over the () "issue" after a couple of weeks, once I discovered Counterclockwise for Eclipse (and, eventually, Emacs paredit or smartparens). You just don't notice them after a short period.

In general, editors that "understand" Lisp-like syntax are more powerful than other code editors. Being able to select forms - anything enclosed in a (), {} or [] - with a key combination and move them easily around the hierarchy (also see barfage & slurpage in the paredit cheatsheet: http://www.emacswiki.org/emacs/PareditCheatsheet) makes editing code faster than other languages.

As for the "easy to read" argument, I now find Clojure easier to read than, say, Java because there's generally less of it.


Agreed. I remember hearing the exact same about significant whitespace in Python. Its just one of those things that, after a little bit of use, simply fades away into the background and stops being an issue. Many people even grow to like significant whitespace in Python and parens in Lisps.


Clojure is dynamically typed, homoiconic, and places a lot of emphasis on immutability and managing state. Scala has different design goals. Idiomatic Clojure code is quite different, structurally, from idiomatic Scala. You should try it, and believe it when everyone says that the parentheses fade after about a week.


Well I just might, for now Scala seems to be doing a pretty good job though :P

Is learning clojure enough if I would like to write lisp in future?


> Is learning clojure enough if I would like to write lisp in future?

Since clojure is lisp (although not common lisp or any other non-clojure variation like Scheme), I would have to answer yes.


There are great reasons to use Scala (specifically Akka, static typing), but syntax is a bullshit reason. A decent programmer can adapt to normal languages like ruby, scala or lisp in about a week of use. Wacky languages like perl or k might take a bit longer.

Also, syntactically Scala is a lot more complicated than lisp. It's a bit closer to Java, but that doesn't make it simpler. Just more familiar.


frankly, in the world, people are using scala instead.

however, i have to differ with you completely regarding scala being easier to read. as someone who regularly works with scala code i find it incredibly difficult to read in comparison to clojure. Lisp syntax is different from what most people are used to but is very simple; scala looks more like the syntax that people are used to, but is deceptively quite different, and is quite complex.


Can't agree with this more. All the plus pointed touts for FP are available in Scala without the necessary mental context-switch that is required to grok the parenthesis extravaganza. Why Clojure instead of Scala?


The 'easier to read' part is valid maybe for the first week of working with a Lisp (commenting as a part of a team which switched from mostly-Java to only-Clojure several months ago).

Pros for Clojure:

* Faster code -> result cycle. No need for compilation (except for AOT-compiling releases).

* Absence of static typing helps in some of the domains, e.g. web applications. We have successfully used Prismatic's Schema[1] in places where a stable data interchange format was needed.

* Binary compatibility. No need to recompile libraries for different Clojure versions.

* Community oriented towards simplification. People mostly try to mimic Rich Hickey and Clojure.core development approach.

* Orientation towards small libraries. I haven't yet had a need to use a framework written in Clojure (although Pedestal[2] seems interesting).

[1] https://github.com/Prismatic/schema [2] http://pedestal.io/


How complete is core.typed? Does it have a good story for scala type features I've come to depend on (covariance, some kind of typeclass-like functionality, higher kinds)?


Core.typed appears to have some higher kind and variance support (as seen in the user guide - https://github.com/clojure/core.typed/wiki/User-Guide).

Type classes can be mimicked via multimethods or protocols.


Well, first of all Clojure is a substantially simpler language than Scala, which counts for something. Secondly, I believe that Clojure does a better job of presenting the developer with a new way of thinking about problems, which (as alluded to further up the thread) can be a big source of productivity gain and inspiration.


Not really. There may be some larger idioms and concepts that are more expressive than scala, but simpler language? A case in point:

scala

   if (x > 0) ...
clojure

   if (> x 0) ...
The clojure syntax here is a bit absurd, IMHO.


It's only "absurd" if you're quite new to programming and math.

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'm not sure the precedence of syntax makes it simpler, though. In the end, it's just syntax, but the primary posit that's been put forth is that Clojure is simpler to use than languages such as Scala. And Polish notation, while existent, is not the common form of expression in mathematics.

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.


And hence the productivity self-selection bias...

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".


All this from an assertion about the simplicity of Clojure syntax?

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.


The fact that <, >, +, - and other operators are just functions brings alot of benefits.

- 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?


It's only absurd since we're so used to assuming that (some) math functions are special and deserve special notation. The notation for almost every other function you're going to use is f(x,0), why should the function '>' get a different notation?

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.


> why should the function '>' get a different notation?

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.


I think consistency with math doesn't make "if x > 0" simpler than "> x 0". Makes it easier, as it's already ingrained in the memory, yes.

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.


Yes, agreed. Although, what's the point of simplicity if things aren't any easier?


They actually are easier once you learn the (simple) novelties. Simplicity makes the learning process shorter.


>It's only consistent in terms of how clojure presents it, but it's inconsistent with treatment elsewhere.

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...


check: (> x y z 0) vs: if( x > y && y > z && z > 0)

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)


But then, Clojure can also do this for an arbitrary number of operands

    (< 1 2 3 4 5 6)
    ;; true
Any function can also take arguments from a list,

    (apply < (range 1000))
    ;; true
Prefix notation really comes into it's own when you start looking at multiple arity functions. Please don't confuse unfamiliarity with absurdity.


Those are great examples, and I agree -- the compactness far exceeds something like Scala.

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.


And yet nobody has issues with foo(a, b)

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.


Forgive my terrible macroing but, if your really must, you can:

    (defmacro ord-compare [a ord b]
      `(if (or (= > ~ord) (= < ~ord)) (~ord ~a ~b) "Use > or < to compare."))
  
    (ord-compare 3 > 2)
Edit: there's also incanter.inflix, which will translate inflix notation into clojure like notation.

https://github.com/liebke/incanter/blob/e1235cf9ffa2e528823e...

Check out the tests for how to use it:

https://github.com/liebke/incanter/blob/aa71f1135c3beb7bf7a4...

A good example:

    ; $= translates inflix to prefix notation. 
    ($= 3 <= (5 * 2/7))  ;will give you false.


I'm just going to copy-and-paste this old comment:

When evaluating language tradeoffs the scala community values power more and the clojure community values simplicity more.

Scala wants to provide you with the most powerful language possible. Clojure wants to make it easy for you to mold your own language.

Scala language tooling works at compile-time and analyses the language statically. Clojure language tooling connects to a running environment and uses introspection. Scala has much better static checking and clojure has much better introspection. While both languages have a repl, the clojure community puts much more emphasis on live, interactive programming.

Clojures syntactic extension mechanisms are much simpler, being based on sexps. Scalas are powerful (eg can access the lexical environment) but much more heavy-weight.

Clojure has run-time eval. This makes it possible to do eg domain-specific jit (eg compiling DSLs -> clojure code -> java bytecode on the fly). Scala has a run-time interpreter which I haven't used but is reputed to be slow.

I haven't yet explored non-jvm backends for scala but I suspect that clojure will eventually dominate on that front for two reasons: 1) when clojure-in-clojure is finished porting clojure to a new platform will be far easier than scala and 2) clojure was designed from the beginning to be a parasitic language and delegates many features to the underlying platform.

Scala breaks backwards compatibility much more often than clojure. Whether this is a pro or con is up for debate. There are lots of small niggling things in clojure I would like to change but on the other hand maintaining scala code across compiler updates is a pain in the ass.

Personally, I believe that the number one problem a language needs to address is managing complexity. The clojure community largely seems to get that and is driving for simple, orthogonal language features and libraries to an extent that I've not seen in any other community (eg http://blog.getprismatic.com/blog/2012/10/1/prismatics-graph...). In addition, the most exciting research I've seen on that front (eg http://www.vpri.org/pdf/tr2011004_steps11.pdf http://boom.cs.berkeley.edu/ ) and most of my favorite tools rely on powerful introspection and runtime code generation. I think Yegge describes this better than I can - http://steve-yegge.blogspot.co.uk/2007/01/pinocchio-problem....


I got really into Scala a couple of years ago, and then worked on a big Scala project. One of the problems is that if you throw average Java developers into it, and don't give them the time to learn the language properly-- these were smart engineers, it was a lack-of-time problem rather than an ability issue-- you get a lot of Scala-in-Java. The code is just as unreadable, "enterprisey", and unattractive as it would be in Java.

I would use Scala for a personal project where I felt I needed compiler-time typing: I was writing something for the ages, or where bugs might be truly intolerable (say, high-frequency trading) but code would remain small. I wouldn't recommend it for a huge project, though. (Then again, I generally wouldn't recommend huge projects.)

Scala tends to fall down on large projects, especially if the developers aren't skilled. Cyclical dependencies (yes, I know they shouldn't exist, but they will if you have a team of 25+ engineers and a wide skill spectrum) defeat incremental compilation, which matters when your compile speed is ~500LoC/second (Scala's compiler is very powerful). Also, SBT is a nightmare. I haven't used Scala's macro system but I can't imagine it being as clean as Clojure's.

I like Scala on its terms alone, even if I've seen it go wrong on large codebases. (Java has the same issues, but it has tools that rescue you. It's an ugly hackish thing, to rely on tools to deal with code messes; but they're there.) I like static typing (at least, the theory that comes from it.) However, I tend to think that what most programmers really want when they say they want "static typing" is something more like Prismatic's Schema: runtime checks that can be turned on or off (performance) as needed.

I think Clojure's easier to read and to write. It just looks harder, because people exaggerate the parentheses problem, which is not much of one at all. If anything, the only thing that's somewhat hard to explain to newcomers is quoting (e.g. why '(1 2 3) returns (1 2 3) at REPL but (1 2 3) is an error). The quotes were the hardest thing for me to get right when I started in Lisp.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: