Hacker News new | comments | show | ask | jobs | submit login
Horses for courses: choosing Scala or Clojure (rrees.me)
35 points by ColinWright 1400 days ago | hide | past | web | 65 comments | favorite



I like compile time / IDE type checking, so I'm a Scala user.

But Rich Hickey is such an amazing guy, steering Clojure, with pragmatic solutions catering to developers while Scala often feels like an exercise in academic language development.


As long as you are hero worshiping, Martin Odersky is an amazing guy also who is quite focused on pragmatic Scala. Ya, scala has lots of features and it does attract more academics, but there is nothing really flimsy ivory tower about it.


After 5yrs of Scala usage, I'm sorry to disagree. Martin might be a very clever guy, but Scala is not catered towards developers but language enthusiasts. From my personal point of view, and everyone else might disagree, it's very slow to compile, has complicated error messages, the API is implemented to be powerful not towards easiness of use etc.


I know Martin, I worked for him 5 years ago. He is like a "hacker's hacker" who deeply understands "programming." Perhaps this doesn't translate very well into "developing," and Scala is a great language for "programmers."

We can argue about the trade offs he made, I think Scala represents a reasonable point in the language design space: its not for everyone, but a lot of people like it a lot; it is probably more popular than Clojure (though LISP'ers tend to be more vocal in general).

It is definitely not a programming language for language enthusiasts, who tend to be more picky than programmers and developers and usually have their personal esoteric favorites.


He might be understanding programming, but from an academic background not from managing large business development projects with issues like compilers, tool chains, on-boarding of new team members, turn over, business pressure to cut corners etc. Scala has very different priorities. The top priority of Scala is "power", language features and the holy grail of marrying FP and OO. The priority of Clojure is solve problems.

Case in point: The lacking Scala API with a high percentage of method calls not described, not explained and rarely any descriptions of classes. Second case in point: In 2013 Scala is still abysmal slow (several seconds for some classes) when compiling (with SBT compile/JRebel reload or with Play compile/reload).

PS: Side note: Not to sound arrogant, but for the perception and spread of the language it is not important what Martin thinks, but in customer development style what my perception as the CTO of a company thinks that might decide between Scala and Clojure.


And you think Eich, Matz, Guido, Gosling, Pike, Ritchie, Wall, Kay, Wadler, Steele, Gabriel, Anders, Syme, Roberto, Stroustrup all understood the role of programming language in business development projects, whereas Martin didn't? All successful programming languages are designed by people passionate about programming, not software development! The people passionate about software development give us crap like UML. Maybe there is something special and different about Rich Hickey's background that he gave you a language that you prefer, but I'm guess its just a different background driving him to make different trade offs that suit you better than other trade offs that could have been made.

Part of the problem you are probably hitting is Scala's attempt to be statically typed while also being flexible, not really its attempt at marrying OO and FP; this tends to require lots of advanced typing concepts that many people are not yet comfortable with, and perhaps they never will be. Dynamic languages save a lot by pooing away the static type system; but of course there is then a lot they can't provide. I am a big critique of this also, we've had our disagreements, but really...at the end of the day it was a design decision made that is no less valid than other design decisions that could have been made.

So don't use Scala if it doesn't suit you, this is reasonable, your criticisms are reasonable, but I don't think it is fair at all to say that the designer was stupid or somehow misguided. There are more CTOs who are misguided than successful language designers.


I see that you have made up your mind, but I'd still be very happy to see an actual code example, as mentioned earlier (or even better, a link to a bug ticket :-D).


I'd love to see a code example!


It's important for a programming language to have a technical person leading it. If the language development is managed by a business person without any academic IT background, you end up with smoke and mirrors.


I think the major error in this piece is assuming that Clojure is really geared towards any one type of problem. Instead, Clojure is designed to give you a set of tools that you can freely combine for the problem at hand. It achieves this by separating concepts that are commingled in other languages, like identity, value, and type.

By splitting out those concepts, you get a very solid foundation on which you can build pretty much any other paradigm.


If you are going to work with concurrency ... I think you definitely want to be using Clojure.

Is it widely accepted that Clojure is better for concurrency? [1] I haven't used Clojure much, so I can't comment on their relative merits. But, I've played with actors in Scala some, and done a bit with STM, and they make concurrency relatively straightforward. It's plausible that Clojure has a better concurrency story (and this blog post has inspired me to try it out) but, concurrency is easy enough in Scala that I don't think of it as a weakness of the language, the way I would with something like C.

[1] This is not a rhetorical question.


Everyone is answering your question mentioning the Clojure STM, but I'd point out the nowadays most concurrency problems in Clojure can be, and are solved without touching the STM. Immutable and persistent collections, atoms, agents and more can all be used outside the STM and produce the right results.


Clojure uses STM and has persistant datastructures by default. This makes it pretty safe when it comes to concurrency. Clojure also has good support for paralellism through pmap and reducers. Making something run in paralell is often just changing the name of a function or importing a diffrent namespace.

I don't know Scala that well, but actors in scala still shares state, and doesn't give the same level of protection when it comes to changing state. Actors also introduce some overhead in case you just want to read a single variable from a datastructure safely. You have to send a command and receive a message, wheras in clojure you just retrieve the value you want. Actors however are, to my knowledge, easier to scale across machines as actors doesn't necessarily have to be in the same process, or even on the same machine.


Scala uses STM and has persistent datastructures by default.

http://doc.akka.io/docs/akka/2.1.4/scala/stm.html


Over the years Scala has adopted some of the concurrency primitives from clojure, now I think if you compare the two there isn't much of a difference between them, however when you start to add in third party libraries I think Scala is actually pulling ahead of clojure. With Akka not only does it do single node concurrency well it also does multinode concurrency with two or three extra lines of code.


Well, when you add in third-party libraries, Clojure can use these too.

I wasn't aware Scala had incorporated Clojuires STM, I thought Scala was married to Actors/Akka?


Akka has implementations of STM, and a few other niceties from Clojure land.

Also your right Clojure can use Akka just like scala so neither is any better for it, but scala can call native clojure code too. What I have found Awesome is that I can work on a scala project or library and hand it off to my co worker who is a clojure guy and he can incorporate it.


Judging from ...

> Actors also introduce some overhead in case you just want to read a single variable from a datastructure safely.

... I think the large part which you are missing is that in Scala, everything is a library, there are no “privileged” operations or data structures:

In Scala, you have a huge set of options available which can be used where appropriate. There was a talk by the creators of Akka recently, and the most important message of their talk was “pick your poison”.

It's not like in Go where people claim that channels and “goroutines” are the solution to every problem or how the Clojure community treats STM/Agents.

In a sense, this also shows the maturity of Scala's developers and ecosystem, because they don't claim that X or Y is the ultimate solution to everything.

- Scala has a full range of immutable & persistent as well as mutable & concurrent data structures available. In general, they are faster and more efficient than the ones in Clojure, due to the heavy tuning they received and the fact that you can pick the implementation which has the best performance characteristics for your use-case.

- The collection library supports data-parallel operations since 2.9, but I think it's great that Clojure tries to catch up!

- Additionally, Scala offers a standardized Future&Promises implementation, as well as support for async blocks (also a libraray feature) in the upcoming version.

- On top of that, you can use java.util.concurrent or any other Java-based concurrency package without any impedance mismatch, like Netty.

- If necessary, you can also drop down to things like Threads, Locks, Queues, synchronization, @volatile variables or sun.mis.Unsafe.

- Actors offer solutions for higher-level concerns of concurrency, like distributed computation, failure tolerance and communication over unreliable networks. (I think the best question whether you need Actors is: “Is there a chance that message X never reaches the receiver?” If the answer is no, there is pretty much no point in using actors.) (There are currently some improvements under-way to make sure that no state can be accidentally captured in Actors, Futures, etc.)

- In addition to that you also have things like the Akka Dataflow libraries, Rx-style approaches or functional reactive programming.

- You can also use the STM library (or agents, ...) if it is the best tool for the job (most concurrency people in Scala say that STM is conceptually a dead-end though).

I hope the explanation helps a bit!


> It's not like in Go where people claim that channels and “goroutines” are the solution to every problem or how the Clojure community treats STM/Agents.

Well... Go offers mutexes (and other synchronizing constructs) becouse Go admits that goroutines and channels, while great for alot of problems, doesn't solve everything. Rich Hickey also just announced a new library bringing "goroutines" and channels to Clojure. Both Go and Clojure communities know that there are certain problems not suitable for their prefered concurrency tools, but that doesn't mean that new functionality can't be added as libraries, as in Scala.

> Scala has a full range of immutable & persistent as well as mutable & concurrent data structures available. In general, they are faster and more efficient than the ones in Clojure, due to the heavy tuning they received and the fact that you can pick the implementation which has the best performance characteristics for your use-case

You can still pick other datastructures specialized for your usecase in Clojure, or create your own persistant or mutable datastructures. All collections from Java, including arrays, are also available, and if these fits better than Clojure's default collections then you are free to use them. The default and easiest option is still to use Clojure's persistant collections as well as atoms, refs and agents for changing state. Since using mutable collections and datastructures requires a little more syntax, most developers will use the persistant collections and the concurrency primitives provided by Clojure. This in turn makes it easier to refactor concurreny into your code, as you normally don't have to change mutable collections to their persistant alternative, and you don't have to check if the procedural code you may have written is thread-safe.

On the flip side, Scala makes it easier to write performant code in a single-threaded setting, mostly becouse working with mutable datastructures and/or procedural code in Clojure isn't really natural, or shall we say "The Clojure Way".

> - The collection library supports data-parallel operations since 2.9, but I think it's great that Clojure tries to catch up!

Well, Clojure has had data-parallel operations bultin long before the new reducers library was available (pmap amongst others).

> - Additionally, Scala offers a standardized Future&Promises implementation, as well as support for async blocks (also a libraray feature) in the upcoming version.

Clojure has had Futures&Promises since the beginning, and asynchrounous code (go-blocks and channels) is available in the upcomming clojure.async library.

> - On top of that, you can use java.util.concurrent or any other Java-based concurrency package without any impedance mismatch, like Netty.

True, using java libraries causes a little impedance mismatch, but is still easy to do. Using stuff from java.util.concurrent is even encouraged when the builtin primitives just won't do.

> - If necessary, you can also drop down to things like Threads, Locks, Queues, synchronization, @volatile variables or sun.mis.Unsafe.

Same in Clojure

> - Actors offer solutions for higher-level concerns of concurrency, like distributed computation, failure tolerance and communication over unreliable networks. (I think the best question whether you need Actors is: “Is there a chance that message X never reaches the receiver?” If the answer is no, there is pretty much no point in using actors.) (There are currently some improvements under-way to make sure that no state can be accidentally captured in Actors, Futures, etc.)

"Pretty much no point in using actors" is IMHO an overstatement, but to each his own. What you say regarding improvements underway to prevent capturing external state is very interesting, and should be a great improvement for safe concurrent operations.


> Is it widely accepted that Clojure is better for concurrency?

I'd argue that Scala supports a far more mature concurrency concept (message passing) as opposed to Clojure's STM. Refactoring Scala's concurrency features to interoperate with plain Java is much easier than refactoring a largish STM transaction.


STM isn't a commonly used feature. (I believe Stuart Halloway said this? http://www.infoq.com/presentations/Concurrency-Clojure)

Rather, I imagine that in such discussions, one should first focus more on immutable values; then the time model of identities and values (which encompasses the ref types, of which STM is just one); then things like pmap, reducers and stuff you get from Java.

[Disclaimer: I know next to nothing about Scala, and would surely enjoy playing with Scala's Akka within Clojure.]


For those of you who don't know of Robert, he works for Guardian, writes a lot of Scala and is one of founders of the London Clojure group. Indeed, he's talking about Riemann on Tuesday @ SkillsMatter.


I didn't find that comparison very useful/accurate (having used clojure heavily for a year or two and scala full-time for the past month). The main differences I find are:

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


After 5yrs of Scala usage, "but on the other hand maintaining scala code across compiler updates is a pain in the ass." this is really a pain, especially if you come from Java where probably 15yrs old code still runs. I would no longer go with Scala for a new project but give Clojure a try.


    Q: What does java.lang.NoSuchMethodError: 
       clojure.lang.RestFn.<init>(I)V mean?
    A: It means you have some code that was AOT
       (ahead-of-time) compiled with a different
       version of Clojure than the one you're
       currently using. If it persists after
       running lein clean then it is a problem
       with your dependencies. Note that for
       your own project that AOT compilation in
       Clojure is much less important than it
       is in other languages. There are a few
       language-level features that must be
       AOT-compiled to work, generally for
       Java interop. If you are not using any
       of these features, you should not
       AOT-compile your project if other
       projects may depend upon it.
https://github.com/technomancy/leiningen/blob/stable/doc/FAQ...


I've never even seen AOT compiled code. If it becomes common (maybe in proprietary projects?) then I would argee that its important to maintain binary compatability.


I just wanted to highlight how bizarre this discussion has become in general (nothing against you, it seems to be a common theme):

    “““
    I'm unhappy with Scala's compatibility guarantees,
    therefore I'll pick a language which

    a) does not provide any binary compatibility guarantees
       at all,
    b) has no tool to figure out whether incompatible 
       changes have actually happened,
    c) lacks any sort of guidance to figure out if library 
       A is compatible with library B short of downloading
       and executing them together,
    d) provides no clean way to cross-compile libraries 
       against multiple versions.

    But hey, let's bash Scala for caring about these issues 
    and deride them for shipping actual, working
    solutions addressing those issues.
    ”””
Scala guarantees:

    - Source compatibility between major versions
    - Source and binary compatibility (both backward and 
      forward) for all minor and update releases of that 
      major version
People will have a hard time to find another modern language which gives them these guarantees.

Hypocrisy and cognitive dissonance FTW, I guess.


I was not 'bashing' scala. I discussed the tradeoff between removing old cruft from the language and breaking old crufty code. I was careful throughout that entire comment to only discuss differences between the languages and communites and not make or imply any value judgement. I'm trying to provide useful information for people deciding between scala and clojure, not start a fight.

With regards to binary compatibility, what I think you are missing is that clojure libraries are almost always distributed as source code. The clojure compiler is fast enough to just compile everything at runtime (during development at least) and clojure has not broken source / api compatibility since the first major version. Where AOT compilation is useful is:

a) Improving application startup time

b) Shipping libraries which generate java classes at compile-time (usually to

c) Shipping proprietary libraries without source code

I would definitely like to see the community figure out binary compatibility between libraries to improve cases b and c but it's really not a pressing concern.

EDIT: On AOT compilation http://dev.clojure.org/pages/viewpage.action?pageId=1572898


Fair enough, as mentioned, it was not targeted at you. Sorry if I didn't make that clear enough. I was mainly summarizing my impression of the (sad) current standard of debate in interested circles.


1. Java. 2. The problem of binary compatibility is two folded: a. What Scala considers major versions (usually minor changes) b. An open source library community that jumps to beta Scala releases for minor updates These two together create a nightmare to upgrade libraries or Scala versions


> 1. Java.

I said "modern language".

> 2.

First, the changes are too large, then the changes are too small? What now?

It's bad if new Scala versions don't ship with full-scale library support, but it's also bad if developers start testing their libraries early?

I guess it is impossible to make you happy.


Sorry to not be able to formulate my concerns in a way you can understand them.


Whilst I understand that you can have good reasons for want to integrate to the libraries he mentions, I can't help feeling that Hibernate is a library that solves a problem caused by the type system, so just using a dynamic language and forgetting Hibernate strikes me as a good approach. Indeed, all the libraries listed look avoidable.


> Indeed, all the libraries listed look avoidable.

Not on an enterprise context, like it or not, most consulting projects on the enterprise world require interaction with them.


Is that the IT equivalent of legally requiring a man with a red flag to run sixty yards ahead of the car?


Right, you should have reason to use all these JPA, Hibernate, EJB in Scala, in most cases you can just go with Scala's modern alternatives (Play, Slick etc.) and build robust apps. Dynamic languages aren't often a pill for everything, especially with larger codebase and when performance is considered.


Hibernate is limited by the language it finds itself in. Enhance it with a few macros and you get something truly wonderful - type-safe handling of data from outside your application.

(as for spring, I'm working on a type-level alternative as we speak)


what is meant by "multi-core concurrency"? Isn't that just paralellism?


Yes. I guess he was distinguishing from multi-machine concurrency i.e. distributed systems, which are a different matter and one which both languages have tools for, but the author chose not to address.


Paralellism is about using multiple cores to speed up a certain operation. Cuncurrency is about doing many things at once.

Multi-core concurrency means that your concurrent operations can happen at the same time and thus corrupt shared state.


I think the notion of operation serializability is important in this context. From what I understand, in the broadest possible strokes, "concurrency" means "it doesn't matter in what order the sequence of operations happens and how their execution is reshuffled as long as the dependency invariants are maintained".


When it comes to more or less large and real world systems - I really can't imagine how one can work with dynamically typed languages.


A dynamically-typed OO language like Python is very different from a dynamically-typed functional language like Clojure. [1]

In a functional language you are mostly passing around fairly pure concepts of data as lists and maps, and transforming and combining data between functions. This data is standalone, and serialisable, and so easy to understand; a REPL-oriented environment means that code gets implemented incrementally, building from some inputs to the required result interactively, so everything gets some testing as it is developed.

The static types of this pure data probably wouldn't be very interesting.

Compare with SQL - SQL lets you join and transform arbitrary tables using queries. SQL doesn't require you to create up-front static types to accommodate the shapes of the resultsets of queries that are include joins. The Clojure Way has a lot in common with SQL, I find.

[1] of course there are plenty of large real world systems written in Python etc.


> SQL doesn't require you to create up-front static types

You realize that DML/DQL is only one part of SQL? It also includes a DDL. All the types are right in there.


Try to finish the sentence before deciding it is inaccurate.

> resultsets of queries that are include joins.

I have never had to use DDL to declare the types of the results of a join. What database do you use where you do?


This is because the types can be derived from the ones declared, not because joins are suddenly “dynamically” typed.

Static types != manifest types.


DDL is boring. DML/DQL are the power of SQL and the relational model. They are what enables ad-hoc querying that the schema designer had never considered. As soon as you do anything other than select * the composite types defined in DDL aren't as important.

I was suggesting that the immutable part of FP (which is most of it) has a lot of similarity with relational querying, which is very successful in the real world.


I used to think that, too, but Clojure is not dynamically typed in the same way Ruby, Python, Javascript or Groovy are. The most important difference, from a maintainability point of view, is dynamic dispatch. All those other languages can call any method on any object. If the object has that method - it runs; if not - something else happens. But other than comparing method names, you have no way of knowing whether method foo in object A is indeed an override of method foo in object B, or whether it does something else altogether.

Clojure is entirely different. When you write (f x) you know exactly how f is going to dispatch by looking what f is in f's namespace: either it is a simple function, a protocol method implemented by x (just like interfaces in Java) with the protocol defined in f's namespace, or a multimethod in f's namespace.

So in Clojure, you don't have dynamic dispatch at all other than Java-like polymorphism or multimethods whose implementations are confined to a single namespace.


Why? Static languages ensure type safety (which are uncovered in unit tests anyway) and to ensure this type safety, they need more information from you, the developer. Clojure allows you to write less code which, depending on who you talk to, equals faster development time.

Static languages are also usually faster, so I guess the tradeoff stands between raw performance and code size.

There are numerous succesfull projects using dynamic languages. Github, as far as I know, uses Ruby.


Yes, but when it comes to reading/understanding and refactoring/modifying code - this is where things get complicated.


Never really had any problems reading/understanding dynamic code, actually I (and this is highly subjective) think it's easier to read dynamic code because you don't need to read a lot of extra code written to satisfy a compiler.

I agree completely when it comes to refactoring/modifying code though. This can become cumbersome, especially if you don't have unit tests.


Well, what you call an extra code to help to satisfy a compile, I call a part of a documentation which helps understanding the code, in addition with some static integrity checking :)


I understand the argument. In my experience though, documentation and/or tests usually always makes type info redundant. But I'm well aware that people have different views on this. Each to his own.


> Static languages ensure type safety (which are uncovered in unit tests anyway)

Wrong.

> ... and to ensure this type safety, they need more information from you, the developer.

Wrong.

Anyway, correlation != causation. If I would claim that there are some projects which are successful, despite being untyped, I could pretty much use the same data points to make my claim.


> Wrong.

What? Static languages doesn't ensure type safety? Or errors due to wrong use of types doesn't get uncovered in unit tests? Unit tests runs the code, so when it runs code where wrong types or names are a problem, the code will fail, thus uncovered... Doesn't help for code you don't have tests for though, which instead require manual testing.

The type system does need more information from the user to allow the same kind of flexibility in a type safe environment. Polymorphism either through interfaces or class inheritance is basically a way to tell the compiler that "Hey, i know these objects look different, but they do support the function/method I'm calling, so relax ok?".

When someone says they don't understand the use of dynamically typed languages in a real world setting, it makes sense to mention that a company like GitHub mainly uses a dynamically typed language in their product. Heck, even Facebook uses a dynamically typed language quite extensively in PHP. Yes, you could make the argument that alot of successfull projects use statically typed languages, and naturally they do. The point is that dynamically typed languages work just fine in a real world setting.


> What?

I disagree with your notion of equating types with tests. They are fundamentally different. Types provide substantially stronger guarantees without having to execute any code.

> The type system does need more information from the user to allow the same kind of flexibility in a type safe environment.

Did you have a look at Haskell? Or any other language with type inference? The connection you are trying to establish between "untyped == no need to specify types explicitly" and "typed == necessary to specify types explicitly" is patently wrong.

Having a helpful compiler doesn't mean that the language has to suck. I don't want to offend you, but your comments create the impression that you are lacking experience with a modern, statically typed language.


> I disagree with your notion of equating types with tests. They are fundamentally different. Types provide substantially stronger guarantees without having to execute any code.

I'm not equating types with tests. I'm saying that type errors comes to light when a unit test for a given code is run, because you will get unexpected results and/or an exception is thrown.

> Did you have a look at Haskell? Or any other language with type inference? The connection you are trying to establish between "untyped == no need to specify types explicitly" and "typed == necessary to specify types explicitly" is patently wrong.

I started learning Haskell but stopped when I came to monads. I've also experience with other languages that provide type inference like Go and F#. Go requires you to define interfaces (something you don't need in a dynamic language like, say, javascript). Haskell also has features that require the developer declare something upfront (types and type derivation), as do F# (discriminated unions and/or types).

My actual example was regarding class inheritance and implementing interfaces. Polymorphisism through inheritance or interfaces is great in a statically typed language, but not required or even possible in certain dynamic languages.

> Having a helpful compiler doesn't mean that the language has to suck. I don't want to offend you, but your comments create the impression that you are lacking experience with a modern, statically typed language.

I never said statically typed languages suck. I've developed an app in C# which was a great experience, and at my day job I work in C++ (which IMHO is a sucky language, but not due to being statically typed). Haskell is also a great language, as is Go and C#.

What I did say is that statically typed languages often require more code, which (depending on who you talk to) slows down development compared to a dynamically typed language. Statically typed languages does however usually entail better performance and (sometimes) smaller memory footprint than dynamically typed languages. There is a tradeoff, but that doesn't make one more suited for real world applications than the other, which there exists numerous examples of.


> Haskell also has features that require the developer declare something upfront (types and type derivation)

Generally not. Type inference does that for you.


You can't use custom types without defining them first. Sure, you don't have to decleare where you use them usually, due to type inference, but for type inference to work you actually need to define a type.


Both have their place - as evident from their continued coexistence.

I don't see why there are static vs dynamic flamewars. From my experience, dynamic languages are good at doing more with less code, and getting somewhere faster. Stuff written in static languages tends to be more efficient and reliable. I'm happily using both.

And the line between static and dynamic languages is a bit blurry anyway.


Scroll near the bottom of this page, and you'll see types used for safety — not just performance — and there's contracts too: (http://adambard.com/blog/clojure-batteries-included/)

[Disclaimer: I have never used core.typed.]


Hint: lack of imagination is seldom considered a positive trait in creative fields.


Engineering requires creativity within constraints. If you're not comfortable with this, you should change a profession.


That's a tautology (and therefore a waste of words) and you know it.


I'm no Clojure expert, but listening to the Scala parts was like “Ok, I might disagree, but one can claim that ... WOW, that's factually wrong ... nod ... this is pretty misleading the way it is described ... ok, this sounds reasonable ... no, that's just wrong”.

Can a Clojure expert comment on whether the Clojure part is as wrong/inaccurate as the Scala part?




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: