> What matters to me in a language is whether I can use it without thinking about it.
I love this statement. It reminds me of the what it feels to be good at mathematics (not my words): "Your intuitive thinking about a problem is productive and usefully structured, wasting little time on being aimlessly puzzled." from http://www.quora.com/Mathematics/What-is-it-like-to-understa...
The author also says more about mathematics:
> To make an analogy with math, it's nicer to have a general formula that you can derive others from than having to memorize a whole bunch of formulas for specific problems.
> This is where Clojure comes in. With it I can always easily derive a solution to a particular problem from a small set of general patterns. The number of things I have to keep in my head is not overbearing.
Any language that lets you spend your brainpower on the essence of the problem is a tremendous advantage and joy. This unlocks creativity and productivity.
"By relieving the brain of all unnecessary work, a good notation sets it free to concentrate on more advanced problems, and in effect increases the mental power of the race.
"Probably nothing in the modern world would have more astonished a Greek mathematician than to learn that...the whole population of Western Europe...could perform the operation of division for the largest numbers....
"It is a profoundly erroneous truism...that we should cultivate the habit of thinking what we are doing. The precise opposite is the case. Civilization advances by extending the number of important operations which we can perform without thinking about them. Operations of thought are like cavalry charges in a battle---they are strictly limited in number, they require fresh horses, and must only be made at decisive moments."
That being said, the proper notation is very problem-dependent.
> Any language that lets you spend your brainpower on the essence of the problem is a tremendous advantage and joy. This unlocks creativity and productivity.
For some reason the only language that let me reach this level is Python. I tried Clojure and Common Lisp, but for some reason I could never be as efficient as I wanted with them, which I think is a shame because in some ways I think the Lisps are superior to Python (due to the "code is data and data is code" of Lisp).
I really like Python, and use it on a daily basis but I found that after enough experience in Clojure, I prefer it when I have the choice and there isn't a compelling reason to use Python instead.
This isn't a criticism by the way, I do understand that people have different preferences of language idioms, and I do occasionally find myself scratching my head about the idiomatic Clojure way to solve a problem that wouldn't have been so hard for me in Python.
While I don't think Python is a bad language at all, it has some limitation that I am becoming more and more being aware of them - lack of static typing, limitation of lambdas, speed is an issue sometimes, but on the other hand it's very easy for me to be productive in it.
I am pretty sure that its lack of features is making Python easier to "master" (I don't claim to master it, just that I am more productive with it), but this lack can be limiting sometimes, so I am trying to find a solution to have both power and proficiency.
I use Clojure a lot, and did more Python in the past. Whenever I come back to Python, I am frustrated by being unable to remember what's a plain old function and what's a method, and the differences defining functions vs classes and methods etc..
In Clojure I know it's always (except for interop) just functions on values. Some functions dispatch to an implementation based on the type of the value, as is the case with multimethods and protocols, but it's still always just function calls from my point of view while writing the code.
Objects in Python little more than glorified namespaces. I always think of methods as a function that gets the namespace where it was declared as the first argument. Yes, there is the inheritance thing, but in Python it is just a mechanism to organize code.
Lua does not do the currying bit, but it does a lot less OOP and a lot more "dictionaries with stuff that can do something like prototype OOP if you squint hard enough". Java and whatnot just don't let you really use methods as first class citizens, so it doesn't matter.
I was big on Python side back in the early 2000's, on the Perl vs Python for system administration tasks.
Maybe because of the experience in using scripting languages on the server side for a late 90's .COM startup in terms of performance, I never could convince myself to use Python other than for shell scripting on steroids.
I always looked for other languages in terms of tooling support, IDE support and support for native compilation on their toolchains (JIT or AOT).
It's nothing I miss, it's just that I couldn't keep in my head all the standard way to do things in Clojure/CL. I kept wondering "oh, how do I check if an element is a member of a list in Clojure, again?", or "ok, so I need to put this Sexpr out of this parenthesis, so with paredit I need to do C-right or C-left?", etc.
I plan to give Clojure and CL another shot in the future, but for now I am just lack of proficiency with them (I think I wrote about 1k loc in those language, including 4Clojure and project Euler, and some mock projects I tried to do but gave up).
To be a language means to be a way of defining thoughts in order to have them delivered to another.
With no constraints you could just write random rubbish (a bit like this). With the constraints of Java or C# you write code which does it's job, however a lot of work is in fitting your thoughts within the extensive syntax of the languages' constraints.
Clojure, or any other Lisp, helps in that the initial constraints it imposes are simple ().
Once you get a feel for the simplicity you get the feel for the power it brings.
It's a bit like wingtsun kung fu. Your brain is no way fast enough to react to your opponent fast enough to decide for example is this a hard punch or a soft punch. By that point the punch would have been received, restricting your thinking further. However if your body knows the language of wingtsun there is no thinking involved. Period.
Your body knows the language of interacting with another body so leaving your mind the time to make decisions. Your body has embraced the language and can rely on it to keep you alive whilst giving your mind the freedom (time) to make decisions or ultimate kill moves or be creative.
Another word for decisions is creativity. The cost of creativity is time. So embrace your language and be creative with your thoughts given the time your language allows. If you feel your language is asking for help unrelated to your problem then either you don't understand your language or the language is not a language at all and maybe another is better for the current context.
> Any language that lets you spend your brainpower on the essence of the problem is a tremendous advantage and joy. This unlocks creativity and productivity.
Isn't that the huge advantage of having a compiler? I can let it worry about whether I connected function input/output correctly and only care about what the function itself is doing.
I recently migrated to clojure from the php world. I have to say that although I am still learning the language, its actually fun compared to php, which would sometimes feel like pulling teeth to get some basic functionality. Way less boilerplate, and as can be said of anything good, it just works.
Also, the idea of thinking in the problem domain versus the subset of problems that arise in languages like php is an acute difference. Just being able to focus on the product as your programming keeps you on task and thinking about new ways to implement features, etc. -- big difference.
I made a career move from dentistry to programming. And I would say that anything I've used pre-clojure is a good approximation of pulling teeth. But even pulling teeth has the benefits of knowing when you're finished and the direct customer feedback is usually good.
I'd been programming since a child and I think in all honesty I was pushed into dentistry by the people that love me and wanted me to make money.
However dentistry in London is medicine in two years then three years specialising in the head and neck. Then two years dentistry training.
I found it a LOT of learning facts. I know that knowledge-based systems are better than humans for that application.
I had the pleasure of learning human anatomy for two years with Prof Harrold Ellis. Which is what I really took away with me. The guy was a genius. And the other was "If you are not certain then say I don't know, never guess, always seek truth" not that many people appreciate that knowledge in my experience. Robotic surgery yes, lying about the safety of amalgamate fillings no and telling mums of the effects of sugar and carbonic acid drinks was not enough scientific exploration for me.
I think I was too young, always the youngest in my year, to really know and show what I wanted to do. I should have studied Physics but was told at the time "I'd end up a Physics teacher" as if this was a bad thing...
Pre-uni I wanted to build quantum computers but my Physics teacher at St John Ruskin College school didn't know what direction I should head in (the school at the time was also being ripped off by the head mistress, look it up, bad).
After that I got a scholarship to a private school to do A levels which was absolutely brilliant. Dulwich College an excellent school where I was treated like an adult and learnt maths, physics and chemistry. Two of the best years of my life.
Nobody noticed really that I wasn't just lazy and so it was very tempting to my parents to be told I could go to the best medical school etc when I pissed the exams.
So I went to the best medical school in the UK, Europe not really sure why.
After two years depression forced me to take some action and I quit and got a job in a bank as a COBOL programmer. I learnt that COBOL doesn't cure depression but can even make it worse. However I learnt from two old ladies who were probably employed AS computers in their prime. And they were the awesome COBOL dinosaurs.
From there on its always been a bit of struggle not having a degree. Although what I've taught myself, and continue to do so, is worth several degrees at least. Probably a PhD or two.
I now know a lot of programming languages and have lots of experience in them. Clojure took me to the next level with regards to meta-programming and language design. I still have hopes for genetic programming.
My interests now are really into augmented reality and basically augmentation of human perception, memory and "brain power" both in the progression of our species and knowledge itself.
That's another issue too. If it's not a public website that you're building it's quite hard to show off your work!
One of my favourites was a forward-chaining rules inference engine written in T-SQL on MS SQL Server for a sixth-form college. The Management Information System (MIS) was called unit-e built by Capita PLC and probably cost a LOT of money.
It was quite a good system, the query builder for advanced users was excellent (every MIS should have one), but it had a fair amount of data duplication - names, addresses, previous address etc. And the admin staff had lots of name changes and spelling corrections to make. Also you had the data entry dudes who'd write a lazy name like fiesta try basharat instead of Fiesta Try Basharat.
So I built the rules-engine as a stored procedure (SPROC) called by triggers on tables. The rules themselves were just simple SPROCs and some not so simple but the rule interface was simple and so the system was robust. All of a sudden every letter sent by the school was formatted properly and went to the correct address! The admin team even gave me and my junior a present! And the 'junior' became an expert in SQL and learnt a secret ninja weapon (rules, inference engines and conflict resolution).
How many good things were created? How do you demo the transition of knowledge? How do you monetize the time saved? How do you portfolio the potential for benefit of new rules that haven't been thought of yet?
Expansion of knowledge, the beginnings of infinities, there's so much out there I love it!
I'm in the process of making the move from PHP to Clojure as well. FYI, deploying to Amazon Elastic Beanstalk with the beanstalk leiningen plugin is a breeze.
My biggest problem with Clojure (specifically ClojureScript) is that it's too workflow opinionated. Nearly all Clojure devs use 1 of 2 text editors. Nearly everyone uses Leiningen. Nearly everyone uses some sort of auto-builder. Nearly everyone uses hot-swapping.
Clojure wasn't even optimized for this workflow, it's just the only one that works. So as much as I love the language I keep going away from it because I prefer the freedom of my own workflow.
Well, people do use these tools, but honestly, do you really want a language with multiple build tools / package managers? The java world is a mess here. Leiningen is pretty great, no need to fragment the community.
As far as editors go, I'm perplexed. You can use nearly any editor, why do you perceive the need to use one of these 2?
Completely agree with leiningen, it's not an opinionated choice, just what I've seen with maven seems a huge hassle.
In terms of editors I've hit this a bit, attempting to follow tutorials or the like is frequently met with 'step n: install the clojure plugin for Emacs', then 'eval with <Emacs keybinding>' forever after. The Om tutorials iirc are written as tutorials through Light Table (which seems like a great editor). Having to separate learning about the language and how the editor does things just increases the barrier to entry.
> Well, people do use these tools, but honestly, do you really want a language with multiple build tools / package managers?
I want multiple workflows. A single build tool can accommodate that, but Leiningen can't/doesn't.
For example, let's say I have a compiler called mycc. I can build something like this:
mycc main.c -o main
I might then combine it with an file watcher utility like entr
find . -name '*.c' | entr mycc main.c -o main
With Leiningen it has to do that all. AND you pretty much have to use the auto rebuilder capability (which means your workflow starts with turning the auto rebuilder on).
> As far as editors go, I'm perplexed. You can use nearly any editor, why do you perceive the need to use one of these 2?
Then why do nearly all (probably 95%) Clojure devs use either Emacs or LightTable?
Right now I'm using a combination of leiningen, guard, livereload, compass and a shell script to handle my specific build workflow.
I'm confused as to why you think leiningen has to do it all.
I'm also not sure what you mean by auto rebuilder (for clojurescript I use the auto feature of cljsbuild ...). My workflow starts with starting a REPL.
Also, I use vim very happily, many people use Cursive happily. But the reason there seem to be fewer editors in use is that REPL integration is so useful that only those editors with good REPL features end up being used. Clojure's ecosystem isn't stopping anyone from using other editors, those editors just haven't implemented a specific feature that is extraordinarily useful when writing Clojure.
I may have misunderstood you but it seems like you are seeing problems that don't exist because the solutions look different than what you expect.
I think you are misunderstanding. People have shown in this thread that they have a slightly different workflow from each other, but my point was that Clojure(Script) points you towards a particular type of workflow, one that I do not like. What I essentially want is 1 of three things:
1) Fast builds so I can set up an auto-build script.
2) A Leinengen daemon so I don't have to worry about building at all.
3) ClojureScript so I can just refresh the browser.
As far as I can tell none of these are possible. If I am wrong please correct me.
You can certainly get all of that stuff (except fast builds in some particular circumstances).
My project I described before is a web app, and my workflow involves my editor, a browser, a clojure repl, a clojurescript browser repl that runs code in the browser and a shell script that runs the various watchers I described before.
If I change any clojure file the browser refreshes automatically (and my tests run automatically).
If I change any clojurescript file it gets rebuilt automatically and the js file is reloaded in the browser (just the js, not a full page refresh)
If I change any sass file, it gets rebuild and the css in the browser refreshes (just the css)
If I change any html template then, depending on the template, either the page is refreshed or my clojurescript is rebuilt and the js refreshed.
So all those things are possible (I saw a cool post the other day of some ring middleware to handle using clojurescript inside <script> tags transparently).
The non-clojure stuff is handled completely outside of the clojure ecosystem, I was using LiveReload and Guard when doing python dev to get that partial refresh on file save functionality and it was pretty simple to hook clojure into that same workflow.
I will say that if you are doing a lot of compile time template processing in your clojurescript like I am (using Kioo/Om/React.js) then the compile time for the clojurescript can be a little long, but since I have a browser REPL I do my experimental stuff in there instead of hitting that recompile cycle frequently so it's only a minor imperfection in practice.
So I definitely don't worry about building at all, and I don't even have to refresh my browser thanks to LiveReload - I just have to hit save in my editor.
There unfortunately aren't a lot of tutorials for setting this kind of thing up. I've got a start on writing up my setup and will put the project skeleton on github soon-ish ... I have this damn real work that keeps getting in the way.
I'm not sure how many serious devs use LightTable (although I'd be interested to know!). I keep it handy for writing little scripts (in Clojure, Python or Javascript) that benefit from the interactive style, but I do most of my actual development in Vim. I tried emacs, but I just couldn't stick with it, and the fireplace vim plugin is really great.
Leiningen, in my experience, is nicely extensible for what I've needed to do. I've got a project that has to pre-compile Protocol Buffer files. To do that, I use Leiningen profiles.
You can't wrap it with your own scripting because compiling is too slow. That's the essential problem, Leiningen has to be the center of your workflow. There's no other (meaningfully productive) way.
What I dislike is the need to run a background task per-project, every time I work on the project. What I would like is either:
1) Faster (sub 500ms) compile times so that I can flexibly use a workflow I prefer.
2) A "Leiningen daemon" that runs when I start my computer and automatically compiles any project.clj files that exist.
3) ClojureScript to build in the browser, so that my workflow can be any text editor + refresh the browser.
Leiningen plugins cannot give me any of those things, correct?
Fast JVM startup is possible with a preloader like Nailgun. A Leiningen daemon is very easy to create. lein-cljsbuild automatically generates ClojureScript so you can use any editor and refresh your browser.
The JVM way of doing things is different but not inferior. You extend Leiningen with Leiningen plugins written in JVM languages, not with external tools. Yes, you can do everything you would ever want to do.
> Fast JVM startup is possible with a preloader like Nailgun.
This has never worked for me with Clojure. I'd enjoy a more specific example.
> A Leiningen daemon is very easy to create.
Could you explain more? I specifically want 1 Lein daemon for all projects, not 1 per project. I want to be able to create new projects on the fly. I only want this feature because the ClojureScript build process is too slow to do on demand.
> Then why do nearly all (probably 95%) Clojure devs use either Emacs or LightTable?
Why should it even be a question?!
Seeing it this way is a mistake. Most developers use tools they are comfortable with, and beginners use what they see in tutorials.
Now about why this repartition, well: Clojure allows you to work with a REPL. Therefore, it's no surprise that developers stick to the "few" editors that allow this style of development. You can see this going with Scala, too.
This said, nothing I know of in Clojure forces you to stick to those editors. Most Java developers use Eclipse or Netbeans, yet, nothing prevents you to use IntelliJ.
I think you'll find considerable diversity in Clojure. You've got a confluence of people coming from Java, Ruby, Lisp, and other languages. You've got enterprises and start-ups using it. This diversity is certainly one reason that Clojure is so popular and useful to so many people.
Java has Maven, Scala has SBT, Clojure has Leiningen. That's not so bad. I use all three languages, and the appropriate tool for the language. I don't use hot-swapping for anything.
For IDEs, in Clojure, you have the choice of Vim, Emacs, Cursive (for IntelliJ), Light Table, and Counterclockwise (for Eclipse), and more. All of them are good, pick your favorite.
Java and Scala are both pretty usable with Maven or SBT (my own Java projects use SBT now). Clojure is pretty much limited to Leiningen. (And, personally, I find working with Leiningen to be a huge drag.)
Personally I find leiningen a breath of fresh air after working with Maven (and Ivy, then ant before it). But you can certainly use Maven with Clojure if you'd prefer.
I'm curious what language and workflow you prefer? In my opinion, there are plenty of other technologies (quite popular ones at that) that have a specific workflow considered "best practice", arguably because "it's just the only one that works".
I prefer any language that requires nothing more than a text editor (any) and possibly a compiler. Where you can use any build system you want and be pretty much just as productive.
I agree that there are other languages that suffer the same problem, the .NET languages for example (except kinda F#), but there are plenty that do not (C, JavaScript, etc).
Well, sure you can use whatever tools you want for C, JS, etc., but then when you contribute to a project in which somebody else made the decisions (either on the job or an open source side project), then you have to learn a whole different set of workflow tools, including all of their quirks and bugs. To me, it's a breath of fresh air to be able to look at a Clojure project and immediately know where to go to find out what dependencies are pulled in, know how to run the project, etc., instead of having to dig through somebody's mad collection of Bash scripts that invoke some weird build tool that I haven't been exposed to.
Clojure (and ClojureScript) have stand alone compilers and ship very nice APIs to compile code (if you want to write your own compiler). People use lein (and its plugins) because mucking around with a compiler and then managing dependencies, setting up your classpath manually, and writing a test runner is a waste of time.
As far as text editors go, you're not forced into using an nrepl-enhanced client. I got by fine on tmux+vim with no editor support for clojure other than syntax highlighting and rainbow parens for a long time. That said, having paredit, nrepl (for code completion, dynamic eval in the correct context, documentation lookup, misc other plugins), and a test runner with easy macros in my "ide" makes my experience better. There's absolutely no reason why one couldn't just use a notepad and the clojure compiler plus whatever random build system strikes their fancy.
C brings in its own problems. Compiler (in)compatibilities, the need to install libraries on a machine to be able to compile and run programs. And besides, in C you still have a build system problem - Make is fine, but it is definitely opinionated about how things happen, and you potentially have to write a lot more boilerplate to get a complex project built with Make than you do for Leiningen, Maven, SBT, etc.
I personally find that to be a horrible experience. Nothing worse than having to install a bunch of tools that you'll never use again, to compile someone else's project. For example, if you use CMake, tough, project A uses autotools. You use bjam? Project B uses QtCreator/QMake. You use Waf? Project C uses SCons.
No thanks, just give me a standard build tool like leiningen and be done with it.
(Ok, so its not "usually" that drastic, because there are only a handful of winners, but its happened a few times now that I've had to install Ruby - a language I don't use myself - just to run Rake to build some non-ruby software I've wanted...)
If I'm a developer, I've got the problem I mentioned. If I'm a user, I only have the problem if I build from source.
Either way, with a standardised build tool like leiningen, I don't have the problem because, as a developer, I only need leiningen. As a user building from source, I only need leiningen. Both use cases are much simpler.
However, having said that, I was only referring to the developer experience in my comment. I'm not really too sure what you read it as, but like I say above, I don't think it really matters: its a problem either way and both go away with a standard build tool.
Lein evolved to be the winner because afaik it was simply the best at it. If another tool out did it, that would be fine with people I think, but most of what you need (and THEN some) is available as lein plugins, so there's no need to dethrone it.
When you're buying into a languague, you're also buying into the ecosystem, and if the ecosystem elected it's tools, and it's optimizing it's workflow towards those, then that's what it is. You either buy the whole package (leiningen specifically, I'm not sure what's the editor problem you mention), or you don't.
I'd put it this way, when you try a language, you are testing to see if the ecosystem works for you. Many, if not most, ecosystems have some kind of sweet spot where you find more support.
You don't have to buy the whole ecosystem, but the more you stray the less community overlap you'll find.
REPL-driven development is wonderful. I'm not a Clojure user (yet), but I write a lot of Scheme. My programs are living creatures that adapt and evolve as they are running. It's refreshing to see that Clojure is seeing real use in the industry. Gives me hope that I can get paid to work with a language I really enjoy some day.
I'm a bit curious about your comment. Do you mean during development you run your code on a REPL and change portions of it , or do you mean you run code in Production in a REPL and change portions of it as it's running?
I'm interested to know your setup in either of those cases. The one inconvenience I have about REPL based development is that I need to copy over an expression from my editor into the REPL and if I make any changes in the REPL, like fix a typo, I need to make sure to copy it back to my editor.I guess this may be because I don't use Emacs and have an editor and REPL in one.
REPL Driven development as it's called is really yes having your whole system running at your thingertips (even production for the adventurous). You can execute arbitrary code and get results or see what state has changed. You can also redefine anything (in Clojure at least) that is referred to, such as functions and variables (I use these terms loosely here).
Normally you have your IDE configured so that anything executed is executed in the context of the running REPL session. So there should be no need to copy/paste.
When done properly with tests running on every change you really can't, as a developer, get any quicker feedback. It's brilliant and empowering!
Your issue could be emacs but, for Clojure at least, there is the Cursive Intellij plugin which is now definitely usable. Also there are the brand new IDEs like LightTable.
LightTable.com started out with some very different ideas with regards to code organisation and there is still a lot of potential work there. But lighttable instead became open source and a core for plugins. The plugins now range from rainbow parentheses to 'pick your language' evaluation.
If you want to discuss any of these ideas or others please do or PM me. I'm always willing to discuss as my girlfriend is hopeless. But then for everything not programming she keeps me sane.
My setup involves GNU Guile Scheme, Emacs, and the geiser extension for Emacs. I boot up my Guile application and it spawns a REPL server. In Emacs, I run M-x connect-to-guile to connect to that server. From there, I edit my source code files as normal. However, once I've made an edit, I press C-x C-e next to the region of code that I want Emacs to send to the Guile REPL and view the results. The edit/apply process repeats until I'm done working and kill the application.
It's a really great way to work. I've spent a good amount of time making this workflow work well for applications that run an event loop, such as a game or web server, by writing a "cooperative" REPL server for Guile [0].
I'm a strong static-typing advocate, and for years this has put me off learning Clojure. (In fact, my very first HN submission, back in 2010, was about Clojure: https://news.ycombinator.com/item?id=1453259). I've been coding exclusively in Clojure for the last month however, and I found it extremely enjoyable to use. Much easier to learn than Haskell, for example, because Clojure isn't purely functional.
The key of Clojure is that it's pragmatic, as opposed to dogmatic. It's a language designed to solve real-world problems in production environments (hence the focus on concurrency, for example).
Also, being a lisp, it's a "programmable programming language", and once you realize the power that that gives you, it's hard not to fall in love with it.
I learned Clojure from the book Clojure Programming (http://smile.amazon.com/Clojure-Programming-Chas-Emerick/dp/...). Once the book gets past the basics, it starts giving lots of concrete examples for how to solve real problems idiomatically in Clojure.
Well, p in pmap does stand for parallel. :) The two are obviously linked, Storm does both parallel and concurrent processing on the data. Another example is PigPen (http://techblog.netflix.com/2014/01/introducing-pigpen-map-r...) from Netflix. As far as pure concurrency goes, I'm not sure any companies have articles discussing that.
Ok thank you. Implementing map reduce style parallzation doesn't need any language level support. I don't see how clojure is any better at this than say java ( hadoop is java after all).
I am looking for 'pure concurrency' in a app like videos games exctracting last ounce of processing power from a multicore machine. This what the original comment stated was the core competence of Clojure.
>I am looking for 'pure concurrency' in a app like videos games exctracting last ounce of processing power from a multicore machine. This what the original comment stated was the core competence of Clojure.
That's not actually what the parent comment stated though. It says that Clojure is designed to solve real-world problems in production environments.
In many cases this doesn't mean squeezing out the last ounce of processing power, but being able to reason about concurrent code safely. You pay an overhead of using immutability in order to facilitate higher correctness.
When your system grows it becomes important to be able to reason about parts of it in isolation. This is particularly important when you're running in a multithreaded environment.
That's what people generally mean when they say that Clojure has focus on concurrency. Since the data is immutable you can make assumptions about what the code is doing that you wouldn't be able to make otherwise.
I have a friend who is deeply into modern static-typed languages (Haskell and OCaml), but has worked professionally for a couple of years in Clojure. His big gripe with Clojure is that it's still dynamically typed, and thus vulnerable to type-based uncertainties. In languages like OCaml, lots of bugs are actually syntax errors and will be caught at compile time.
On the other hand, Clojure is at least a functional language. You get the benefits of immutability, no side effects, higher order functions, etc, in a neat and understandable package. And it runs in the JVM and thus has access to the bazillion or so libraries written in Java, thus getting around the interop problems that other modern languages (and some older ones) have.
Has your friend used core.typed[0]? I haven't really, but I've wondered if it might be the perfect balance for people who really miss their type system.
On the contrary, I came from Haskell-land and was impressed by Typed Clojure, at least in that it is capable of representing some things that are not easily represented in Haskell types. For example, union and intersection types can be pretty powerful. They can have easy variadic functions, and the occurrence typing is sweet -- after a runtime null check, it will remove the `Nil` type from a type union within the if-branch, or a runtime collection-empty check will modify the type in the subsequent branch to no longer include a case for a possibly-empty sequence.
On the other hand, Typed Clojure does not offer nearly the cohesive experience one gets from Haskell, nor do the types guide optimizations etc. Type checking is really a lint step rather than a build step. And almost all existing Clojure code is still dynamically typed, so you can't usually infer how to use a lib based on its type signatures (since it doesn't have them), which I love being able to do in hs.
I'm a huge static typing fan though outside of Java I'm really only currently into Scala. The issue comes up once in a while, mostly when I miss my tooling, but for a lot of cases, a library like Schema by Prismatic meets what you would want a type system for.
Back to tooling, usually you're into a mess of apis because you are forced to use or choose a type, which then enters a whole world of semantics architects love arguing about. For Clojure, a lot of functionality can be clear and concisely done in maps and lists and the handful of functions which operate on them.
I love this statement. It reminds me of the what it feels to be good at mathematics (not my words): "Your intuitive thinking about a problem is productive and usefully structured, wasting little time on being aimlessly puzzled." from http://www.quora.com/Mathematics/What-is-it-like-to-understa...
The author also says more about mathematics:
> To make an analogy with math, it's nicer to have a general formula that you can derive others from than having to memorize a whole bunch of formulas for specific problems.
> This is where Clojure comes in. With it I can always easily derive a solution to a particular problem from a small set of general patterns. The number of things I have to keep in my head is not overbearing.
Any language that lets you spend your brainpower on the essence of the problem is a tremendous advantage and joy. This unlocks creativity and productivity.