What do beginners struggle with?

The top 4 “entry” languages for Clojure have been Java (~30%), JavaScript, Ruby, and Python (10-15% each) for many years. This year’s survey results were same.

2 Likes

Clearly elucidating an issue can help. Today I looked at Luminous in depth, one more time, and decided to do something I hadn’t considered before. Just start with hiccup. Start building the application I have in mind with hiccup. Ah ha! Maybe this is my way in. Bottom up, from a single library, rather than top down, trying to sort out which libraries I need to start with without starting.

Do do anything useful, I’ll need dependency management, so deps … I want to start as simple as possible rather than get into the weeds with lein or boot. A routing library … I like what I’ve heard about bidi. I feel like I can start to be productive working from the bottom up like this.

That may be dead obvious to anyone with Clojure experience. Let’s see how it works out taking this path …

This is why I tend to recommend new Clojure developers avoid Luminus and all of the ClojureScript stuff and just start with a very simple Ring app, then add Hiccup for HTML generation (or Selmer, my preference), then add Compojure or Bidi for routing, then maybe add next.jdbc to work with a database. Take things one step at a time, understanding each step as you go.

Once you’ve built a basic SSR (server-side rendered) HTML app and understand how that sort of thing works, then you can do the same thing with a pure front end app, following just the basic ClojureScript tutorials, then do it again following a (simple) Reagent tutorial. Again, making sure you understand each new piece of tech as you adopt it.

Once you’re fairly comfortable with an isolated front end app, start wiring it up to your back end app. At this point you’re just focusing on communicating between the front end and back end, probably passing EDN back and forth (or JSON) and doing simple HTTP calls against a simple REST-like back end.

At that point, start a fresh project with a Luminus template and all the bits and pieces you think you need, and then recreate the app you’ve built up piece by piece inside the context of a Luminus / Reagent / whatever “framework”.

That approach means you’re not trying to learn “too much at once”.

I think there’s far too much “stuff” in even a basic Luminus template project for a beginner to be comfortable with if something breaks – and it will! Om and Fulcro suffer from the same “too much” aspect (in my opinion) so they’re things to come back to, once you understand how to build the basic stuff.

8 Likes

Sean, I’ve found your https://github.com/seancorfield/usermanager-example, I’ve cloned it, got it running in a browser, studied the code, ( the structure looks familar :slight_smile: ) the documentation for several libs you’ve used, got Chlorine set up using your video and a new series from ( Thomas ) https://www.youtube.com/channel/UCfBUN43AQoyGiQxmCIDZe2w and I’m well on my way.

Thanks for putting that example together! Your advice above is excellent, and not apparent. In other languages, it is very likely a good thing for a beginner to start with a framework. So I’ve been looking for the right framework to guide me into Clojure, which has not been the right way in for me. Your example app is the perfect starting point. Something works in the browser, just a few libs to deal with, enough meat to really build a functioning app without getting lost in too many details to absorb at once.

1 Like

Hi!

Sorry for the “stream of thought” style of this post…

I’ve been learning Clojure on and off, but the last two weeks I decided to experiment with “fullstack” clojure: write a simple backend and client app.

I just finished setting up the environment after about two weeks of struggling. In a nutshell, I decided to go in an epic yak shaving journey to learn just enough emacs (cold turkey… although I finally gave up to evil-mode :slight_smile: ) and ended up spending two weeks just trying to get a setup involving two nREPL clients (for clj and cljs respectively) to work.

I posted a bug on cider’s tracker with some details of what I learned in the process and some suggestions to add a “fullstack” section on cider’s excellent cljs docs.

Before attempting to learn CLJS I was mostly ok playing with cursive and Clojure (I even got a license for the awesome Cursive IDE!). I still don’t have a lot of clarity about the parallel/concurrent aspects of Clojure, and I feel like core/async is under documented, but all in all I’ve been slowly feeling more at home with the language.

Once you add CLJS into the picture though… oh boy. It becomes so complicated that I almost quit a few times in frustration. I decided to switch to emacs for this since Cider looked like the most popular option for fullstack dev environments. Cider and Figwheel docs are great though and the plethora of other info elsewhere (nrepl site and dirac repo where useful) helped a lot, but it is A LOT TO READ AND ABSORB!. I think this is interesting because to a lot of people, including myself, cljs is a selling point for clojure itself. But the difficulty of setting up CLJS may be a reason for taking people away from both!

Is not just about making it work… also about understanding what’s going on behind the covers! Just look at these diagrams… haha not your grand parents’ REPL :stuck_out_tongue:

Final thing: as a beginner I walk through the fragmentation of the Clojure ecosystem and it hurts a bit… when I finally think I kinda have a mental image of the Clojure REPL ecosystem I find out about SocketRepls, pRepls, unravel… Also, I still haven’t looked into shadow-cljs.

My next steps: learning a bit more about ring (hopefully my experience with ruby/rack will help here), and choosing a router. Uffff, forgot to mention, took a long detour to understand why we need things like component, integrant, etc… It is the paradox of choice at play. I think I’ll try to do things manually for a while…

ADDENDUM: to limit my scope I’ve been mostly following the “tools.deps” section of the projects I’m learning (like figwheel), since it is the latest and shiniest way :slight_smile: In general this has worked fine, the CLI and configuration seems to be quite usable and flexible. The only caveat is that some projects only show examples of how to setup things with lein or boot, but not with tools.deps, so I need to figure that out myself.

I think often very new beginners are not even aware of what functions in clojure.core, clojure.string, etc. are available to them. When all you know is that everything is an expression and a few primitive types and collections, it’s still hard to know how to get from a to b if you don’t know what’s possible. Once you understand all (or at least some of) the tools you are given to manipulate the data then you can start really solving problems in Clojure.

1 Like

I found this DEV blog very useful for getting set up as a beginner on Windows. True you can use Linux on Windows now but it’s still different.

1 Like

Newbie here. I’m currently learning Clojure, mainly through Exercism. The following might be a bit unstructured, but hopefully it will provide some value.

In the beginning, trying to solve problems there, I assumed I should write all my code within the function templates given. On harder, more complex problems, this caused me to trying to write a solution in one go, instead of more systematically dividing the problem into subproblems and solving
them first.

I’ve read about programming to abstractions in “Clojure for the Brave and True”. I understood it while reading, but it seems like it will take me longer to fully grasp, as I’m a little confused about which data structures are sequences, which are collections.

Regarding leveraging the platform and its native possibilities, I’ve assumed that doing that was undesirable; that a real Clojurian would limit himself almost exclusively to Clojure itself. (I have no idea where this comes from, but I personally regard programming in Java with disdain.) I’d now like to
use Java methods etc. more often, but as I know almost no Java, I will find it hard to do so.

I guess I have a tendency to write low-level code. That would be because of me not knowing the more high-level way of doing things, and I seem to have the assumption that to learn Clojure (or anything, for that matter) well, one should first “master” the low-level stuff.

Until I was told about The Clojure Style Guide, I would sometimes feel a little paralyzed when pondering how I should do something. I like following conventions, so now I will often look up things in this guide.

It would have been awesome if Exercism included even more basic problems, the easiest ones being about just teaching what different core expressions do, and a clearer ordering of problems, such that by following it, one would incrementally build up one’s knowledge (kind of like what Khan Academy are doing with math skills). Among the basic problems would be problems teaching one when to use Java related ways of things.

You might want to give 4Clojure a look for these kinds of exercises. There are a lot of exercises that allow you to explore the core library, and looking at other contributor’s solutions to problems can be eye-opening. I had much fun code golfing some of the problems when the site was released, but it seems to be a little forgotten these days.

Ah, thank you for your recommendation!

That’s very interesting… Clojure was designed as a hosted language and there’s a fundamental assumption that you’ll use Java interop for things. That said, Clojure wrapper libraries can sometimes make that easier (some Java class hierarchies assume mutability, builder patterns, and easy access to variadic functions). At one time, quite a few string operations required Java interop but with the goal of portability between Clojure and ClojureScript, those have now been filled in (in clojure.string) so you can avoid those particular String method calls.

Writing a Clojure library from scratch to “replace” a Java library is rarely worthwhile but there are some cases out there where the Java library is so hard to use that even a sophisticated wrapper can’t entirely protect you from sharp edges.

One of the design decisions I made with next.jdbc was to leverage the native Java SQL types a lot more than I had done in clojure.java.jdbc – and that has allowed next.jdbc to be quite a bit faster than c.j.j. in several situations, as well as making it easier for users to drop down into the nuts and bolts of JDBC if they need to tweak things that aren’t directly exposed in the wrapper.

embracing my role as gadfly, i’d have to say the overall quality of the ( attitude towards ) documentation.

https://ask.clojure.org/index.php/8400/doc-perhaps-not-precise-enough?show=8400#q8400

Thank you for mentioning my video! I’ve started publishing a new series. Here’s a link to the fist part.

1 Like