337 karma · joined April 10, 2015
This choice is what makes it an interesting and pleasant language to work with. I've often dealt with Scala code that is much simpler to understand than comparable Java code, but still more often than not, Scala code is made needlessly complicated.
That choice implies a certain kind of respect for the programmer: here's a very, very powerful tool, and use it wisely.
Go is the antithesis of this, and I get its point, it's the opposite philosophical direction. I think it's a direction that will not move the industry forward, it's a direction that will undoubtedly help us produce value---software, reliably---instead of doing something amazing.
When it comes to pure old MVC, I feel that it is a bit like Greenspun's tenth rule:
> Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.
So any UI environment will eventually contain an architecture that more or less embodies the spirit of MVC.
And I think MVC is fine within a single environment. That means, the information travelling from the models to the controllers to the views does not contain intermediary where mediums are crossed. A traditional Rails application crosses from databases to a Ruby program to a web browser, and each bit of logic is dependent of the others.
What makes the backend/frontend separation such a good model is that a front running on a REST API is not inherently dependent on a protocol or a server implementation, and the same applies to the backend. This will work in the post-HTTP world, whenever that comes.
Traditional Rails apps assume they are talking to a web browser. This is assumption is no longer tenable.
Therefore, in your question, you could substitute Clojure with functional programming, and the examples in which FP allows you to express thoughts you wouldn't know how to express in for, while and so on -- are plentiful.
I may not be answering your question, but there's a reason for that: the functional programming aspect isn't Clojure's main selling point. It's the other ideas. Software transactional memory, immutability, its emphasis on state and identity, the protocol system, transients, concurrency, transducers, the list goes on.
Scheme is more functional programming oriented, Common Lisp is less so. Scheme is very minimalist, it's most recent standard contains only about 20 syntax definitions! Unfortunately this transformed Scheme into a concept from an implementation. Compare this to CL, which has just about everything and the kitchen sink, and is more of a "concrete" language.
To choose a Lisp is to choose an implementation. I'd recommend playing with all of them. Common Lisp, a Scheme (CHICKEN or Guile), or the "recent" ones like Clojure and Racket. Racket is very much a Scheme - it used to be called PLT Scheme - and has a bunch of PLT superstars building really cool stuff with it.
Clojure, the JVM-based Lisp, has more in common with Common Lisp than any other, but embodies a strong philosophy about identity and value. It has a lot of common with Haskell in that regard, supporting immutable data structures and STM right out of the box. It also has really cool ideas like transients [1], transducers [2] and protocols [3], features which have since crept into other languages.
Clojure is probably the most popular right now, and its ecosystem is growing every day, and can be used for building serious stuff. This doesn't mean you can't build cool stuff with other Lisps! CHICKEN Scheme has a great package ecosystem, so does Racket, Guile lags behind, and for Common Lisp there's a recent "State of the Ecosystem" article[4] that summarizes its ecosystem.
"Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot."
-- Eric S. Raymond
[1] http://clojure.org/transients
[2] http://clojure.org/transducers
* merlin-mode, for autocompletion
* ocp-indent, for external code formating... think running gofmt on every enter press (surprisingly, it's fast enough unless your file is 2k lines long)
* tuareg-mode (everything else, REPL etc.)
* flycheck-ocaml for syntax checking
The "real" IDE plugins aren't even close and that's saying a lot since the hodge-podge of addons I just listed isn't
The default Emacs user experience is awful so if you're a Vim user, just install the "evil" package and enable it inside Emacs by doing M-x evil-mode, then you have Vim inside Emacs. Or use Vim, but the experience isn't as complete w.r.t. tooling[3]. There's always Spacemacs as well[1].
[1] https://github.com/syl20bnr/spacemacs
[2] https://github.com/the-lambda-church/merlin/wiki/emacs-from-...
[3] https://github.com/the-lambda-church/merlin/wiki/vim-from-sc...
There is a general attitude in the Go community eschewing all sorts of complexity be it in the language itself or tooling and this attitude is toxic and stupid. It will prevent Go from becoming a serious language unless this nonsense about "simplicity" is left to perpetuate. There is nothing wrong with keeping a language elegant--cue a brouhaha about generics in 1... 2... 3...---but forcing this attitude to tooling is not a wise thing to do. A significant majority of professional devs do not write their code in vim without syntax highlighting, which is what some eminent members of the Go community seem to be in favour of. They need auto-completion, refactoring (which search and replace isn't), automated deployment and testing, debugging and project support.
The CLR supports user-defined value types whereas the JVM doesn't, it relies on a classical uniform data representation. Because value types are stack allocated, in C#, you will have less stress on the GC (because you can define stack-allocated value types), on the other hand, the JVM GC will be doing a lot more work. This is why you see "the JVM is heavily optimized" statements.
Another downside of the JVM is that it has no native support for tail call optimization, this is not that major, but it is a bit silly for functional languages running on the JVM (Clojure). The Scala compiler is intelligent enough to do this by itself, but there's no native support on the VM itself, unlike on the CLR.
Another point is that the CLR was designed as a true language-agnostic virtual machine, so developing new languages on it is easy. It is not hard to do that on the JVM, but more so than on the CLR.
A pure function always returns the same result because it only depends on its input parameters. An impure IO function does not.
You can always omit them, if you're prepared to deal with code duplication, but I think you're downplaying its significance: it is not just "maybe some" code duplication, nor is it a "a few casts". It's sometimes a deep, murky swamp you're forced to trudge in, and it's not pleasant.