Hacker News new | past | comments | ask | show | jobs | submit login
State of Clojure 2015: Survey Results (cognitect.com)
215 points by jffry on Jan 28, 2016 | hide | past | favorite | 109 comments



My $0.02 on the state of Clojure -

For building stateful UI's Clojurescript + Reagent beats anything else out there.

For data science and algorithms Clojure beats anything else I've used.

For backend web development Rails is still miles ahead of any Clojure workflow.

Datomic is interesting but there's still too much incidental complexity to be super productive with it. It's hard to build a startup on Datomic because of the pricing and productivity hit, but could see it being useful in the enterprise where speed is less important.

I'm very interested in mobile development with Clojurescript on top of React Native, but haven't found a tutorial that wasn't written in hieroglyphics, so assuming that needs some more time to mature.


> For backend web development Rails is still miles ahead of any Clojure workflow.

I feel the same way. And in my opinion, is a symptom of the "library vs framework" culture that is present in the Clojure community. While that is probably a good stance for the first 2 points in your list, in web development there are just so many already-solved-problems that you have to re-work without a framework.

Luminus looked good but seems to be shunned by the community.


>Luminus looked good but seems to be shunned by the community.

Author of Luminus here, and that's news to me. It has over 20k downloads on Clojars and about ~50 downloads a day. https://clojars.org/luminus/lein-template

James Reeves has endorsed it as a good way to start Clojure web development. There's an active Google Groups list https://groups.google.com/forum/#!forum/luminusweb and a Slack channel on Clojurians.

Could you please elaborate on why you believe Luminus to be shunned by the community?


> Luminus looked good but seems to be shunned by the community.

Can I ask what left you with that impression? I've no idea if this is true or not as I don't participate much in the Clojure community, I'm just genuinely curious. I guess a bunch of people just use the lighter weight Compojure/Ring templates that really leave you with an extremely barebones web app to start with?

I used Luminus myself when starting out, but I feel that as you grow more comfortable with Clojure web dev, you'd _typically_ end up putting together your own Leiningen template more tailored to how you like to set things up (as I ended up doing). But even still, I don't think Luminus is by any means bad?


Shunned is a strong word and I don't think it applies. I think Luminis is ok for some things but by and enlarge most people doing webdev in Clojure prefere to go a different way.

Saying it is shunned makes it sound like a whitch-hunt but that not the case. I don't even think the community has an opinion on it. Most just dont use it.


The main goal for Luminus is to address the problems that newcomers would have. It's a batteries included template that sets up some reasonable defaults for your typical web app. That's coupled with a documentation site that explains how to accomplish different tasks using the platform.

Majority of the community are experienced Clojure developers, and have already found their own preferred setup. So, it's not terribly surprising that it's not the target demographic. Once you know the web stack, the libraries that work well, and how to put them together, then it's easy to make an app that's custom tailored to your needs. This is the primary reason for the libraries > frameworks mantra.

However, as the comments in this thread indicate, there's clearly a need for Luminus. Anybody who's new to the language and the ecosystem, needs a decent starting point. Luminus is that.


Yeah exactly, for building UI's less is more and the Clojurescript approach works really well. For building web apps, I really don't care how storing sessions, or configuring your web server or parsing HTTP requests is done, I just want it to work out of the box.


Yeah, it's true. Although I personally learned a lot about HTTP when having to pick and pluck apart at Ring, but an out-of-the-box working stateful server / web backend would be MOST WELCOME in my clojure life.


> For backend web development Rails is still miles ahead of any Clojure workflow.

If by web development you mean building frontends to a relational database. If on the other hand you mean web services, then I think Rails really sucks.


I've also built a Rails like system in Clojure which has easy SQL backend support. I actually find Clojure much EASIER than Rails backend, so I definitely disagree:

https://github.com/zubairq/AppShare

Rails is just such a different thing. Rails IS really is a framework optimised for the days of Page based web applications with small amounts of Ajax requests. Clojure is much more suitable to full web applications (SPAs)


If by web development you mean building frontends to a relational database.

In my opinion, yada[1] will change this with its concept of resources (eg it already has File and Directory resources for serving static data, but it wouldn't take much to develop a CRUD/DB resource - in fact, I spoke with Malcolm Sparks (the yada dev) about this).

I personally find the Clojure(Script) development experience, with figwheel, much better than my experience with both Flask and Django (never used Rails).

[1] https://github.com/juxt/yada/


Hm, I guess that's a valid point. I normally think of web apps as a frontend to a database, but could see why that's not the only use case. If you don't have a database associated with the service, can't you just use AWS Lambda or something? Is it necessary to maintain an entire separate project for it?


"For data science and algorithms Clojure beats anything else I've used."

A very strong claim. Julia, R and Rust might have something to say about that.

Fwiw, I think Clojure is awesome. For data science though? (IMO) no(t yet). The Python ML ecosystem is miles ahead of Clojure's.


I mean, I like R, I think R Studio is an incredible IDE, but I would never build anything meaningful in R code. It's messy, slow, and has an antiquated community where people share library documentation in PDF's.

Julia seems promising, I haven't used it on a real project yet though, but I really like how easy it is to do data visualizations in the browser with Clojurescript and don't see Julia really having an answer for that.


What do you use for the browser visualizations? Gorilla repl?


As a scientist, I use a mix of Incanter, Quil, and gg4clj bridge to R's ggplot2 for visualization in clojure (none of these outputs to a browser though).

R's ggplot2 beats Incanter (or anything other charting library) by a large margin in its excellent mix of conciseness and power, but I find Quil pretty nice for animations (superimposing data on geographical maps, for example).

I keep an eye out for new charting libraries coming out for clojure. Last two I spotted were vizard from yieldbot (https://github.com/yieldbot/vizard), and what seems to have only been a small project, xvsy (https://github.com/dvdt/xvsy)


Hadn't seen those libraries before, thanks for the links.

I have to say, Quil is the least Clojurey library I have ever used, and I find it very, very primitive. There's definitely a huge gap for a project built with idiomatic Clojure bindings that can handle both nice graphical stuff but also stodgy charts, with basic stuff like annotation layouts etc. I think something that could work really well if anybody finds the time is a port of G:

http://geosoft.no/graphics/


Late reply, but ran into another plotting library, also from dvdt.

https://github.com/dvdt/gyptis

It is a nice wrapper around vega. Using that now.


Julia will when it can compile to web assembly


I had not realized that Clojure is well regarded in data science. Could you point to some libraries you find especially strong?


I build a lot of stuff with Incanter[1], clj-ml[2] and Quil[3] for building visualisations. None of this is as joined up or as thorough as the equivalent R (or probably Python) bits. Clojure open source libraries are also incredibly prone to being abandoned. Wouldn't trade the language in for anything though, and I've never seen any R code that I would want to maintain myself.

[1]: http://incanter.org/

[2]: https://github.com/joshuaeckroth/clj-ml

[3]: http://quil.info/


I personally use this in place of R, where possible: https://github.com/incanter/incanter


It has a very small portion of the mindshare. Almost everyone uses R, Python, or one of the proprietary things.

I use Clojure for any data science type tasks I have, but that is because I am primarily a Clojure developer.

It is very nice for a lot of basic data analytics -- but I doubt many full time data scientists use Clojure as their primary tool. The number of libraries available for R and Python is pretty amazing.


The number of libraries available for R and Python is pretty amazing.

I wrote some proof-of-concept code for submitting Python Celery tasks from Clojure. I should polish it up, get return values working and publish it... You could then farm out certain tasks to Python when it makes sense (eg because of existing code, libraries or just familiarity of team members). Best of both worlds, kinda ;-)


Check out Beaker Notebook if you haven't http://beakernotebook.com/

It has the ability to autotranslate data between different languages.


Thanks, that looks interesting. I'll take a deeper look over the weekend.


Yeah, the fact is, if an algorithm has a page on Wikipedia, it probably has a package in R.


> For backend web development Rails is still miles ahead of any Clojure workflow.

In what way?


I think most are related to easiness, and so not recognized as an advantage by many Clojure acolytes (see: Rich Hickey's Simple Made Easy talk). Others are a consequence of shared state; also not recognized as a positive in Clojureland (rightfully so in most cases).

Here's my list:

- Database migrations

- Fast TDD (for some sub-Gary Bernhardt definition of fast) with access to the app environment.

- content negotiation

- Authentication with Devise and Omniauth

- Easy built-in support for caching

- Easy built-in support for background queue systems

- Easy support for one-off or occasional scripts with access to the whole app environment (rake tasks)

- Pry (yes, Clojure has awesome REPL powers, but Pry is so easy to use, and you have access to the whole app environment (no loading / switching namespaces or abuse of user.clj))

There's probably some solution to each of these. But all require you to find/know the options, and be able to evaluate which is best for you ("all REAL devs . . ." sure, sure). For Rails, all of these are available to you in the Rails Guides, except for Devise+Omniauth, which has an extensive wiki and tons of StackOverflow answers.


Thanks, that's a good list, and I see the problem.

Out of interest, what makes Pry easier to use? I'm not sure I understand the comment about having access to the whole app environment. In the Clojure REPL you do as well...?


When I reflect on the ease of use question, I realize most of my frustrations with the Clojure REPL have actually been with trying to use it within an editor (Vim, Emacs, and Atom so far). And particularly with getting a ClojureScript REPL through those tools. That's not something I try to do with Pry, being content to use it from the terminal, so maybe not a totally fair comparison.

The app environment thing is mostly about having to switch between a lot of namespaces and/or to make sure they're all loaded upon starting the REPL. With Rails+Pry, you can work with any class in your app immediately. It also lets you put breakpoints in your code, where executing the code in a running process throws you into a REPL at that point, with all the local context up to that point of execution. Also, if you make code changes, you simply type "reload!" in the REPL and everything's up to date. I have a bookmark to read Stuart Sierra's post about his workflow to try to get a grip on how to come close to something like that in Clojure.

And it can do a lot more great stuff, too: https://www.youtube.com/watch?v=4hfMUP5iTq8

Oh and by the way -- thanks for all of your OSS work in the Clojure world! Especially taking the extra step of providing good docs.


Have you tried using Cider under Emacs? Or Cursive? Both of those have debuggers that allow you to add a breakpoint in your code and then evaluate arbitrary expressions. They also allow you to step through each form and see the return value.

There are also a few projects for adding in debug REPLs, but those seem to have fallen by the wayside lately, perhaps supplanted by debuggers.

You might also want to talk a look at Duct (https://github.com/weavejester/duct), which is my ongoing and still early attempt at solving some of the framework problems with Clojure. If you create a template via Duct, like so:

    lein new duct foobar +site +cljs
Then you some of the things you're asking for. The namespaces of your application are loaded when you start `lein repl`. You get a `(reset)` function that reloads your code, restarts your application and pushes those changes dynamically to the browser. You also get a ClojureScript REPL that hooks into the browser.

There are also generators, migrations, database support etc., but currently all inferior to Rails. I'm probably going to be working on the generators next, as they need attention.


Thanks. One thing that looks promising for migrations is the language/ORM-independent tool Switch.


Do you happen to have a link to that? It's not very Google-able!


Ha - especially when I misspell it: https://github.com/theory/sqitch


'Lack' of frameworks. I always think it's kind of funny when starting a new Clojure web project, I have to explicitly insert a middleware for parsing parameter strings into a Clojure data structure, and then another middleware for transforming the string keys in that structure into keywords. There are just a bunch of things that don't magically work for you. That said, I really enjoy Clojure and appreciate/understand the high configurability.


Hi, author of closp (https://github.com/sveri/closp).

TLDR; Yes, clojure is behind in regards of web development, but it is not as bad as you said. There is active work done in this area.

I totally agree with what you said. It is a general understanding in the clojure community that you compose libraries to get things done. However, for web development that still means a lot of repitition, thats why I created the closp template.

It is based on luminus (http://www.luminusweb.net/) which is a lighter "framework" with more options.

My idea was to provide one way with sensible defaults to get started in doing web stuff in clojure.

I still work regularly on it and would be happy about contributions / feature requests. Whereas regularly means in terms of months as I do this all in my spare time.

Also I am quite active in the clojure community and I know that luminus is not shunned, but instead it also receives improvements and releases regularly. Also the author of luminus works professionally with clojure and with luminus.

And I have to admit, that luminus has the far superior documentation, he has done a good job on it I think.


These are precisely the kinds of things that Luminus http://www.luminusweb.net/ addresses. The template generates a project with all these things configured with reasonable defaults for a typical application. Luminus will also setup things like a logging configuration, authentication, databases, Swagger API, etc.

I think the fact that these things aren't magically is a big plus. You can use the defaults, but you can trivially customize the middleware stack for your specific needs.

Another thing to note is that a lot of the stuff that traditional frameworks do is geared towards doing presentation on the server. Modern apps tend to do presentation on the client, and the server primarily provides a set of stateless services for the client to fetch the data that it needs. With this approach, you don't really need a complex server framework in the first place.


Use destructuring to pull the needed values out of the ring request. For example:

(defn login [{{:keys [email password]} :params session :session}] ...)

Also remember as well as the :keys special form you have :strs and :syms.

https://gist.github.com/john2x/e1dca953548bfdfb9844


Oh man, and having to manually configure your server logs just so you can see what requests are being made and where errors are popping up vs. just tailing log/development.txt in Rails...


I only agree about 20% with this assessment of Datomic.

Their "Pro Starter" tier is free. It is plenty to get started with for many use cases.

It doesn't take _that_ long to get up to speed with how it works and how to use it, and if it fits your problem naturally then it can save you so much time and headache.

That being said, I can understand people hesitating to use it.


I don't think Datomic takes that long to wrap your head around, but it does take a long time to actually use. There's no inherent equivalent of Model.all or Model.where(x = y), so chances are that you'll have to write your own DSL for mapping domain objects to datomic queries which is a time consuming non value-adding activity. You'll also likely want to transact through some DSL so that you can do validations, and post-creation lifecycle hooks, where in Rails or something you'd just get that for free. The Devops is pretty frustrating imo, there's no equivalent of the Heroku Postgres or AWS RDBMS one-click deploy for Datomic, so you'll need to set it up and monitor it yourself, which can get tricky when doing things like REPLing into the db from your local Emacs shell can crash a process downstream somewhere because you went over your remote peer limit without realizing it. And there's no view that shows you the IP address of every connected peer, so it's kind of hard to debug what exactly is going on sometimes. I think the query engine is really cool, I just feel like I waste a lot of time using Datomic that I don't with other databases.


Thanks for that; been meaning to try CLJS+Reagent for a side project and the external testimony helps.


Try re-frame, is built on top of Reagent to provide some more magic (and the README is just AWESOME, worth reading it): https://github.com/Day8/re-frame


I love everything about Clojure, except that stats libraries are nowhere comparable to Python sadly.

It's probably still better for building a big ML solution, but sadly for small prototypes it's too much effort.


I have been working in Clojure and Clojurescript full-time for 2 years and feel blessed to have had the experience, and here is what I've taken from it:

1) It changed how I think about programming, big time. I came from Objective-C and pre-2011 C++, and the functional paradigm blew my mind open. It is now the first habit approach I have when working in any language.

2) I really miss types. While I understand the argument about "fighting the type system", I'd still prefer to occasionally tweak my line of code to satisfy an average type system like C++ rather than deal with the lack of safety and clarity that functions with no type specification for input or output provide. I've recently started doing much more in C++, but this time the modern variant (where I'm using lambdas and the algorithm library all over the place, thanks to what Clojure taught me), and it's been a wash of relief to use my brain for things other than remembering what to feed a function I wrote days, weeks, or months ago: just let the compiler tell me, verify that I've done it right. The ability to quickly test an idea in Clojure is great, but I feel like a large dynamically-typed code base is tremendous opportunity for significant run-time problems, since no compiler has verified that a big category of easy-to-make bugs aren't in there. I'm often having to look at the actual implementation of functions that I don't want to study any more, just so I can remember what types to give them, and what to expect back from them. Run-time assertions and :pre/:post are great, but still not the same thing at all -- and verbose, and added runtime overhead. I don't consider Core.Typed to be the solution to this problem; really, this is something that should be at a core language level, and Clojure is dynamically typed, that's its ball-game, and that's fine for many folks. But I'm slowly moving on towards an exploration of static languages like OCaml, Modern C++, and others.

That said, the elegance of Clojure syntax is extraordinary. I don't think it can be beat. It is a joy to use. So all languages have their unique characteristics. I've come to learn what characteristics are important to me, and adjusting my workflow and choices accordingly. But I can't imagine the programming landscape without Clojure.


Clojure was one of the first languages I picked up when I started coding and I really enjoyed using it. The instarepl in Light Table was a huge boon for learning and helped to offset the infamous Clojure stack traces of doom. :) However, I'd be very much interested in hearing more from people who have gone from Java, C#, or another statically typed language to Clojure, particularly in regards to designing, maintaining, and refactoring large codebases.

I don't mean to turn this into yet another static vs dynamic flamewar. I'm just very interested in the patterns that professional Clojure programmers use to help manage this complexity. I know that code in Clojure is normally structured very differently than one would find in a more imperative or OO language, whether dynamic or static. I also realize there are things available, such as Prismatic Schema and Typed Clojure, to assist with these problems.

Really, I'd love to come back to Clojure but the problems I run into in my day job often have me thinking, "types would have made this so much easier." :( As a result, I haven't given Clojure the time to really delve deeply into it. As someone with limited time to try out whole new languages, I'd love to be convinced to go further!


>Really, I'd love to come back to Clojure but the problems I run into in my day job often have me thinking, "types would have made this so much easier."

I've gone back and forth on this one during the course of my career. My first professional language was Borland Delphi (strongly typed), then C (weakly typed), then Perl (dynamic), then Java (mostly strongly typed), Scala (very strongly typed) and now I'm slowly trying to adopt Clojure at my place of work. Out of all those the worst kind of code I've ever come across was in Perl, so for awhile I've blamed the lack of typing as a contributing factor to this. However. Most of the Python code I've seen since around 2001 has been fairly clean looking so that can't just be dynamic typing that was to blame. I suspect Perl's woes had more to do with the "there is more than one way to do it philosophy" as opposed to types. There's just no such thing as idiomatic Perl. In fact I'm seeing some of this in some Scala code. There are nearly-religious level wars around what constitutes idiomatic Scala way of doing things. I've seen completely insane spaghetti-style Scala classes, especially those that dealt with XML code and DSLs. So far, it seems that Clojure in Java ecosystem is more like Python than like Perl. I.e. only one way of doing things that is fairly clear from the onset.


Thanks for your response. Most of my professional work is in Perl, except for frontend stuff in JS, although we are increasingly using Go for more things.

I'm lucky in that our Perl codebase is very well structured and clean, despite having parts up to 20 years old. It relies very little on objects, generally passing around hashes of information. For error handling we even use something akin to the Either type, instead of using exceptions. But yeah, you could go into another Perl codebase and see a completely different story. I guess that I really lucked out!

Anyway, when I walked into this Perl codebase I generally didn't feel too far away from Clojure in terms of its basic setup, creating lots of small functions that accept and produce basic data structures. But where I do feel pain is in safely refactoring that code, getting insight into where things are used, and understanding what might happen to be in this plain old hash being passed around. It's at this point that I miss having good tooling, in the sense of the tooling I've experienced in Go or Scala. The only dynamic language I've used with comparable tooling is Smalltalk, but unfortunately that's not really viable professionally at this time. :(

I've heard good things about Cursive Clojure, so perhaps I should give it a try and see what fancy features it has.


So I worked exclusively in the statically typed (and imperative / OO) world for the first 10 years of my professional career. Several years ago I decided to learn functional programming. I started with Scheme and moved to Clojure. I really enjoy Clojure; it's a real joy coding in it using Emacs with paredit (or smartparens).

I wrote a REST API using Clojure; the code also has to interact with a Postgres database. This is for a side project, but it's not a trivial code base. I definitely miss Java/Eclipse style refactoring (right-click, rename, and EVERYTHING is properly updated). Can't do that in Clojure. Also, I find that I have to write more unit tests with Clojure in order to make up for the fact the compiler can't help me. Not that I wouldn't write tests in Java; but I find I have to write more in Clojure to keep the codebase manageable.

So again, for me, I use unit testing to make up for the fact I don't have the compiler helping me as much.


The Cursive IntelliJ IDE for Clojure does allow you to rename everything in this manner (even keywords used across your codebase). Others may as well, not sure.


clj-refactor is coming along quite nicely...

https://github.com/clojure-emacs/clj-refactor.el/wiki/cljr-r...


Property-based/generative testing should, at least hypothetically, reduce the amount of tests you need to write.


The way I approach it is to make use of the Design By Contract features Clojure took from Eiffel. I almost never want to restrict an input to a function to a specific type or interface. I want it to conform to some kind of contract. So you build the :pre clause to reflect what kind of input you want. Sometimes I add a :post clause to ensure the function has performed correctly.

What does annoy me though (and you can see it clearly reflected in the survey respondents putting such a weight on better error messages) is the way assertions don't give me a traceback (or file name and line number of the assertion).

http://blog.fogus.me/2009/12/21/clojures-pre-and-post/


Runtime assertions (like the :pre clause) are the only way to really do this in a dynamic language, but they are merely a band-aid, and suffer these problems:

1) You have to actually write the assertion/:pre all the time, which is not a trivial step in my opinion. A basic type system just removes this chore altogether. Writing these little assertions really breaks the wonderful flow of elegance.

2) Any errors are only caught with a specific input that would violate the assertion; some inputs might pass, and others not. Therefore, you may not know there is a possible bug that will crash your app or lead to unexpected behavior, even if it runs fine for a long time.

3) You have to keep flipping the assertions switch on and off as you move from testing to deployment, or, just leave them on and suffer the runtime overhead of their checking everything all the time.

4) You will typically write more unit tests to make-up for the tests a type system does for you.


Do you have any books/resources that you recommend to learn Clojure?


I strongly recommend http://www.braveclojure.com/


Second this. Definitely a good beginner's book.


Clojure is amazing. Definitely start lurking in the Clojure IRC channel, I learned a lot just reading other peoples' questions and answers in there.

There is a great book, The Joy of Clojure. Highly recommend it. For specific projects there is also a bigger book, it's more of a reference (like if you wanted to make a website using Ring) called Clojure Programming (it's got a Dodo on the cover and a purple bar).


The Joy of Clojure is the best book on Clojure I have read (and I've read about 5 of the main ones), but its certainly not a beginners book. Read Joy of Clojure when you want to deep dive into the detail and the really powerful aspects of the language. For people who have been using Clojure for a while, I highly recommend reading it.


I think it is a suitable starting resource for any experienced coder. Also, just to add to the thought, if one navigates to infoq one can see Rich Hickey's talks and in it he describes not only a philosophy of an anciently-refreshed-language (lisp a la clojure beauty), but he also talks of some beautiful principles in general. For example, he mentions how when we talk about a River or a Stream, we are not really talking about an object, because there is no section you can block off and say "hey this is the river" due to it changing moment by moment. Yet, for convenience we use the conventional term "river" and it's understood. He also has this one line "the great thing about a hammock is that you can lay in one with your eyes closed and no one will bother you because they think you're sleeping." He totally helped me wake up to the way a coder can really live a fulfilling life, and how the organization/ideation/creation of a digital experience ("application") can happen (and in fact, happens better) away from the computer. Without distraction, with your own balance, it's much easier to focus ones mind. He's truly a great learner and teacher and watching even one talk by him would do anyone interested in Clojure, or the philosophy of coding (if I may call it so) much good.


Programming Clojure, Clojure Programming, or Living Clojure - is a good start. The Joy of Clojure is next step after any of these books.



I wish I had the time to dive deeply into ClojureScript. It's the part of the Clojure ecosystem that interests me the most.

Hope it keeps getting better—a lot of interesting ideas coming from there.


ClojureScript is awesome, and soooo much progress has been made in the past year.

It has made writing browser based UIs so much more fun.

I am really excited about what is in store for it this year -- personally, I am going all-in with ClojureScript.


The first graph I saw was that a poll of Clojure fans shows they like the language features in it. This of course fails to survey the people not using it and why not, and what undesired features prevent them from using it or what lack of features prevent them from using it.


I find getting people's input on things they don't use or participate in to be pretty useless. The people's lack of practical knowledge and prejudice just comes down to perceptions.

So people have a perception about X and don't use it because. A) To difficult B) To different C) doesn't meet a need D) Y is better then X for A B C reasons....


That sounds like a challenging poll to conduct.


That's why it's always worthwhile to do some interviews to get the whys behind the behavior. It's always a risky business to go entirely by quantitative data and then speculate on the underlying motivation.


> What is your company size?

    ~44%    1-10
    ~26%   10-100
    ~17%  101-1000
    ~13% 1000+
Wow, that's stark. Huge tilt towards small businesses / startups. I imagine the chart for Java tilts the other way, but I'm speculating. I guess this goes hand-in-hand with hiring / staffing frustrations.

I'm glad the Cursive / IntelliJ IDE is gaining popularity; I think it's a fantastic option for development. If you are comfortable with IntelliJ.. go download it.


Not surprising really. Big corps always pick safe languages. Primarily because they need a large recruiting base and middle-managers are typically career oriented and therefore risk adverse.


Also, big companies tend to be older and change their tech stack less often.


It wouldn't surprise me to see a large fraction of Java use being at b2b startups/small companies since a lot of those 2bs are large and using enterprise tech can make the acquisition story sweeter...


Never thought of that before. Would be a good reason for a startup to choose Java (I can't think of many others)


Huge workforce to hire from (crucial for start ups), vibrant and huge cosystem, battle tested, can scale to pretty much any size, write once, develop anywhere, ...

I know HN is a bit in a bubble but I've dealt with hundreds of startups over the past ten years and I can tell you that easily 90% of them pick Java from day one.


How much does clojure take advantage of its hosted status? Can anyone who builds clojure software for multiple runtimes comment? It would obviously be extremely nice if you could program libraries once and have them run on the JVM, CLR, and inside the Browser. In practicality how difficult/easy is it to build cross-runtime libraries and how much reuse can you get out of clojure libs b/c of its hosted status?


There's cljc which is a conditional reader that lets you code in clj and cljs in the same file.

It's not that difficult to write a library that runs on both.

But there are differences in the runtimes, of course.

Some examples:

https://github.com/stuartsierra/component https://github.com/plumatic/schema (uses .cljx, the precursor to .cljc)


Nice examples. Am I correct in guessing that this code:

    (ns com.stuartsierra.component
      (:require [com.stuartsierra.dependency :as dep]
            [com.stuartsierra.component.platform :as platform]))

requires the correct platform.clj or platform.cljs depending on the runtime?

And that this:

    #?(:clj
       (defmethod clojure.core/print-method SystemMap
         [system ^java.io.Writer writer]
         (.write writer "#<SystemMap>"))
       :cljs
       (extend-protocol IPrintWithWriter
         SystemMap
         (-pr-writer [this writer opts]
           (-write writer "#<SystemMap>"))))
is how you perform different operations in a single file based on runtime?


The first part requires platform on both platforms. You are correct about the latter.


> In practicality how difficult/easy is it to build cross-runtime libraries and how much reuse can you get out of clojure libs b/c of its hosted status?

It depends on what you're trying to do, and whether the platforms help.

Doing something 'pure' like math or datastructures: trivial. Writing a common interface to two different host libraries (e.g. DateTime in JVM & Browser): manageable. Doing something 'host-y', like graphics, with no host libraries in common: very hard.

Basically, Clojure doesn't get in the way of cross-platform concerns, but it might still be a difficult problem.


To add, it's not great at the moment and will be more confusing until Clojure/ClojureScript 1.7.x is the minimum supported due to the introduction of reader conditionals (cljc), as they're not backwards compatible. Cljx is the old method that cljc should obviate, but there'll be a transition period.

I work for a SaaS/PaaS company using Clojure internally for 2 years and was looking into making a universal client (jvm, clr, js, ios, android)... I'd surely have used a Cljx core with Lein profiles for each platform prior but now it's up in the air, may still have to go that way if we're supporting older Clojure. Each approach on its own is easy, but now there are two and the unofficial one (cljx) is more widely supported than the official one (cljc).


I can't speak to running Clojure outside the JVM, but on the JVM there's good interop with native Java, which allows using Java-based tools and libraries.

This instantly gives you access to a whole ecosystem of stuff written for Java. It's very easy to use the Java AWS SDK directly from Clojure code, for example.


I was working on a clojure/clojurescript app a while ago. I was hoping to share code between the two. This was pre-clj 1.7 with reader conditionals, so I did some manual footwork to try and resolve the small differences. However the biggest issue I repeatedly ran into was libraries. One of clj's biggest strengths (and why it has an awesome library ecosystem) is that you can just nab a battle tested java lib and write a tiny clj wrapper around it. Those libraries are, obviously, not going to run in js land. As clj matures and we see more pure clj libraries the situation will hopefully improve, but I felt somewhat thwarted by my attempt.


Wasn't there a question regarding React Clojurescript usage? I don't see the results for that.


There was just the question about whether you use a React binding and that's in the post.


80% of people said they use it


Link current shows a 404. Correct link is http://blog.cognitect.com/blog/2016/1/28/state-of-clojure-20...


Whoops, paste fail. Good catch.

It looks like somebody at Cognitect has also added a redirect now. Sorry about that!



Quick note to HN readers: if you Ctrl+A / Command+A (Select ALl) you can actually read the article.


I respect it's usefulness, but the LISP syntax just never worked for me. (((())))))()()))(()))())) is not something I want to read and write all day.


Have you actually tried it for a significant period of time?

Most (but not all) people who have used lisp for significant projects find that they either like the parens or are simply neutral about them.

There are very few people I have heard from that have stuck through a significant project in lisp and came out hating the parens still.


Exactly this. I've actually never met a person who has used a lisp to build software and complained about parens. I have the feeling parens are like functional language syntax, just something foreign which seems annoying or pointless until you actually start using the tools for a significant time and learn the benefits that arise from what initially seemed strange and alien.


> Most (but not all) people who have used lisp for significant projects find that they either like the parens or are simply neutral about them.

There's a substantial selection bias there in that people who have strongly negative feelings about parens have plenty of opportunities in the field to work with languages without them, so the only people likely to put up with them on significant projects are ones who feel positively, neutrally, or perhaps only weakly negatively about the feature from the start.

That said, I do think the complaints about that particular feature are overblown, much the way those about Python's particular whitespace handling are.


I think this is related to the fact that our own internal parsers that have been trained upon c-style code falls about when trying to read list code. So the dislike is not due to the number of parenthesis, but rather our own internal discord when trying to apply our existing mental parsers.

The only way to get around this is to spend enough time using the language so that you can build a new mental parser.


I did quite a bit of Common Lisp coding back in the day and I never grew to like the syntax. I felt it was the price I had to pay for macros, but otherwise found it awkward.


Did you ever learn Paredit? Once I did, editing any other type of code became awkward in comparison.


Admittedly, I've not used it for any significant period of time. But I do base a lot of language learning on the ease of use of its syntax for newcomers. Having to force my way through a significant project with it, just to potentially enjoy it, keeps it at the bottom of the interest list.


> But I do base a lot of language learning on the ease of use of its syntax for newcomers.

From what I've observed of learners, people without lots of programming background seem to have no more problem with parens in lisps (in the broad sense -- mostly, I've seen this with Scheme and Racket) than with syntax features of various Algol-family (C, etc.) languages.

People with extensive experience in programming that is mostly restricted to Algol-family languages seem to be the people who are most put-off by lisps and their parens.

Which is to say, there are different kinds of newcomers.


I was referring to "newcomers", as just people new to LISP, and not complete newcomers to programming languages. So more the latter of what you wrote.


> I was referring to "newcomers", as just people new to LISP, and not complete newcomers to programming languages.

Sure, but not all newcomers to lisp that are familiar with programming are people that whose programming experience is tightly tied to Algol-family languages. For me, Lisp wasn't any more unwelcoming than any other new languages when I encountered it well into my experience with programming, but a number of languages I encountered much earlier in my programming life (BASIC, Forth, Logo, x86 ASM, among others) weren't Algol-family languages.


The fact is that there aren't actually more parens than most languages. Take a look at any JavaScript code base and you'll see far more parens there.

One benefit of Lisp syntax is that it provides you visual information about relationships in the code, since it's structured as tree. The nesting tells you how functions relate to each other at a glance. It makes the code easily scannable, once you're used to reading it.

Another big advantage is that you can use a structural editor with Lisp. You don't actually manage parens by hand, the editor does it for you. You can see it in action here. https://cursive-ide.com/userguide/paredit.html

The syntax is actually one of the easiest ones to learn, because there is very little of it and it's very consistent. Just because it's not familiar, doesn't mean it's hard to learn.

I use Clojure at work and I regularly train co-op students. I haven't had a student who took longer than a couple of weeks to become productive with the language, or didn't love using it. However, most had a negative reaction to the syntax initially.


When i was testing out clojure a few months back, it took me around 4 to 6 hours to get used to them. After that, my eyes where just ignoring them and the code looks very much like a C type syntax.


Really though, it's better to think that Lisp has no syntax, and that really you're writing your code directly in the parse tree that other languages compile-to. The parens are simply to define the boundaries of the trees.

And besides, with proper indentation, it becomes easy to read and easier on the eyes.



Idiomatic Clojure tends to have fewer parenthesis than Java.


I also find that it tends to be more concise which lends to denser code. The density can be a bit off putting until you become accustom to reading it. The other part that is weird is having all of the closing parenthesis on a the last line. Consider the idiomatic way:

  (defn do_stuff
    [coll]
    (filter #(> % 10) (map Math/sqrt coll)))
Vs

  (defn do_stuff
    [coll]
    (filter #(> % 10) 
            (map Math/sqrt coll)
    )
  )
Even though this is the same code, if you are coming from a c-style background the latter is probably easier to read.


Lisp syntax is awesome. It is unfortunate that some people have trouble getting used to it. I wish we could all live in parentheses paradise.


It may be a hindrance for new-comers who use notepad(or some other editor that has no knowledge of LISP).

For everyone else, what parenthesis are you talking about? I don't even see them.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: