What do beginners struggle with?

@seancorfieldā€™s User Manager example has been very informative for me - I spent some lovely time running it and inserting printlnā€™s to understand ring, next-jdbc, component and other libs. Just look at the comments: https://github.com/seancorfield/usermanager-example/blob/develop/src/usermanager/main.clj

RE the CRUD debate: there are some really nice low-code tools like Hasura and PostgREST that turn a database into an API that can be combined with things like React-Admin that generates an admin UI. Iā€™m not experienced enough to understand their downsides, but if they are integrated into lein or tools.edn they can be used to quickly create a CRUD app that has its business logic and ā€œglueā€ code in Clojure, where presumably the most business value is.

2 Likes

And Cider lets you access them with cider-clojuredocs (or C-c C-d C-c) :slight_smile:
(something I only recently discovered)

1 Like

Alsoā€¦I have a bit of a thing with buying EVERY book but I think new clojure developers should get The Clojure Workshop. This book is over 800 pages and goes through the basics in depth, it goes into working with databases even to the point of going through database pooling, clojurescript, HTTP via Ring. Thereā€™s been a few newer books that never picked up traction that are quite good for newcomers.

3 Likes

because of the current global health crisis schooling has changed considerably in many placesā€¦ alsoā€¦ seams to me, that the covid-situation is acting a bit as a catalyst for certain trends that had already been set into motion well before the outbreak of the diseaseā€¦ i am thinking of MIT open courseware etc. etc.

anywayā€¦ when reading this thread, the fundamental question is really about learningā€¦ about how people are able / can be enabled to acquire new and complex sets of skillsā€¦

okayā€¦ but what is it that students struggle with, when they are supposed to learn how to read and write in elementary school? when they need to digest complicated mathematical ideas at university? when they are tackling lisp / clj for the first time? ā€¦ what can be done / provided to help them succeed? what are the main obstacles holding them back?

soā€¦ as i was pondering these mattersā€¦ why beginners tend to struggle with clj etc. i was reminded of the following:

https://www.feynmanlectures.caltech.edu/I_91.html

enjoy! :smile:

p.s. my 2 centsā€¦ i really like the following quote:

"The power of instruction is seldom of much efficacy except in those happy dispositions where it is almost superfluous.ā€ (Gibbon)

ā€¦and this reminds me a bit of the following anecdote:

It is said that a dispassionate young man approached the Greek philosopher and casually said, ā€œO great Socrates, I come to you for knowledge.ā€

The philosopher took the young man down to the sea, waded in with him, and then dunked him under the water for thirty seconds.

When he let the young man up for air, Socrates asked him to repeat what he wanted. ā€œKnowledge, O great one,ā€ he sputtered.

Socrates put him under the water again, only this time a little longer.

After repeated dunkings and responses, the philosopher asked, ā€œWhat do you want?ā€ The young man finally gasped, ā€œAir. I want air!ā€

ā€œGood,ā€ answered Socrates. "Now, when you want knowledge as much as you wanted air, you shall have it.

my main point being, that what seams to be of the utmost importance is for students to be / become motivated to learn! if they are motivated enoughā€¦ theyā€™ll figure it / something out! :smile:

now, truth be told, i imagine that home-schooling places an enormous burden on parents, because getting kids motivated to do their studying is ( often ) gonna require some real effort!

butā€¦ focusing on clj for a second, when one reads this thread, it is all about some of the language features, the books / learning materials that are availableā€¦ project templatesā€¦ stuff like thatā€¦ but if one thinks about it a bit more from this motivation angle, i guess one could be tempted to argue, that what clj beginners struggle with the most are the relatively poor labor-market-opportunities.

now what makes me say that? well, what is it that motivates someone to study something like physics or computer-science or medicine? lots of reasons of course, but most likely the prospect of landing a decent job will play at least some part in motivating that person enough to buckle down like that.

okay, but now suppose someone starts out learning clj, most likely on their own, investing their precious free time,ā€¦ now, when you start something new it is always fun and exiting, but after a few weeks going to the gym tends to become a chore and so you quit your membership or you simply stop going, because you donā€™t wanna be a quitter. :smile:

long story short, should clj keep becoming ever more popular, more and more jobs will be created as a consequence, perhaps so much so, that schools will decide to teach courses on clj, because they want to enhance the position of their graduates on the labor-market, all of which will help to provide motivation for beginners to stick with clj! :wink:

I think Fulcro RAD
has a really good story here for showing and editing data. Its guiding design principle is extensibility and itā€™s good at it. It can do a lot for you out of the box and makes it easy / possible to take over to any desirable extent.

But it is intended for solving complicated needs and thus has a steep learning curve. For me it is absolutely worth paying the learning price once and then benefit from it for years but it is not suitable for one off use. I would not recommend it as a beginner ClojureScript framework.

Its key concept is ā€œattributeā€. Ex: (defattribute :person/fname :string {}) where the final map can contain any plugin/user data such as :sql/schema, formatters, validators,ā€¦ Those are then used when generating code to read/write/display/edit them. And you can always write your own code for any of that. Works great for me.

1 Like

eureka!!!

today i read the following and i feel like all of a sudden a few ( obvious? ) things are finally starting to click / falling into place for me! :slight_smile: here it is:

Arthur Rubinstein: ā€žIf I were to begin my career anew it would be on this keyboardā€œ

WOW!!! i mean, isnā€™t this very similar to what we have with emacs / lisp / clojure?

what do i mean:

  • clj is for experts
  • average work experience of clj programmers is very high

but what is the eureka you ask? well, take a look at this:

basically i was thinking, people really should learn to program in lisp, and if they later get a job using some other programming language, nop. whatā€™s more, i always felt like people should WANT to learn how to program in lisp, becauseā€¦ that is what i would have wanted! :slight_smile:

but let us look at some of the things that have happened in this respect:

  • MIT: long moved away from lisp
  • HTDP: in the process of moving away from lisp?
  • university in tĆ¼bingen: moved away from lisp?
  • ā€¦

hmmā€¦ soā€¦ i supposeā€¦ here is the deal: if someone wants to become a ( professional ) piano-player, they are very likely to wanna start out using the mainstream keyboard layout, and piano-schools and teachers are very likely to wanna teach using the mainstream keyboard layout, and only after you have mastered the commonplace instrument are you gonna start looking for possible improvements / more exotic alternatives.

alright, but coming back then to the thing i have said about motivation, mentioning Feynmanā€™s somewhat unorthodox lectures on physics; what i have just realized today, is that things just do not work like that! :slight_smile: in other words, when thinking about an emacs / lisp beginner, to think of a university student is probably very much misleading. the person taking an interest in learning clj is very likely to be a seasoned programming veteran who is not worried about learning to program or finding a job at all!

bottom line, what i argued before may make perfect sense in theory ( why not start on the janko keyboard?! ) but in practice the argument does not seam to be sustainable under the weight of the contradictory evidence. :frowning:

1 Like

I find that the single biggest flaw in Clojure is the ridiculously opaque compiler messages. I donā€™t know how people who have no Java experience can deal with it. And the problem is rarely described on the command line. Instead, we must examine an output file from the compiler that (usually) lists a Java stacktrace in which we may or may not be able to discern the syntactical error.

1 Like

These are the things that I struggled with as a beginner, and to an extent still have some problems with today.

a) Error messages. The error messages are much improved since I started with Clojure, but they are still not very informative. So the classic beginner error of (1 2 3) is rewarded with ā€œExecution error (ClassCastException) at user/eval2005 (REPL:1).
class java.lang.Long cannot be cast to class clojure.lang.IFn (java.lang.Long is in module java.base of loader ā€˜bootstrapā€™; clojure.lang.IFn is in unnamed module of loader ā€˜appā€™)ā€ rather than ā€œError: the first item in list (1 2 3) isnā€™t a function.ā€ I also had problems with the usual beginner mistakes, such as using def rather than let.
b) Program structure. Most texts concentrate on the syntax (such as it is), often at a very low level, such things as cons, conj, etc., but saying very little on how to write Clojure code. Iā€™ve worked though multiple books on Clojure, yet I am still struggling somewhat in managing dependencies in Clojure. I made some progress when I set Clojure aside for a while, and learnt how to code in Haskell, which has a more opinionated style of coding. Then, returning to Clojure, I made a lot more progress. My coding continues to improve.
c) Poor documentation. I had problems with using JACOB (Java COM Bridge). As I wasnā€™t coming from a Java background, I didnā€™t really understand the CLASSPATH and LOADPATH. I think Iā€™ve got JACOB straight in my mind, but havenā€™t made much progress with connecting to databases. The documentation isnā€™t very good - can I volunteer to help out?

5 Likes

I started my first (and only, still working on it) Clojure project based on a Luminus template. At the beginning, I did not understand most of the code that tied the whole project together. Reading a lot of Clojure books did not help me with that either. Instead, I just deleted/changed code and saw what happened. So now i feel more comfortable, but even though my code has been in production for a few years now, I still have a sense that I donā€™t know what I am doing.

2 Likes

A word about me. A seizure has forced me to use a phone as my left hand is useless. Serious frustration with files using Android 10, no root authority. Want to write simple prog to find strings in local files. Two problems, donā€™t have r/w access to a file I created. And for the life of me I canā€™t find doc to open, read and write files.

Regarding the first, I plugged ā€œfile:///storage/emulated/0/a.htmlā€ into Chrome and got:
ERR_ACCESS_DENIED. Also tried ā€œhttp://127.0.0.1:27524/storage/emulated/0/a.htmlā€ and got:
This site canā€™t be reached127.0.0.1

refused to connect.
Try:

Checking the connection
ERR_CONNECTION_REFUSED

I donā€™t know how I found ā€œhttp://127.0.0.1:27524ā€ and since I failed to copy it, I got to waste hours looking for it. Am seriously disappointed with my 2 apps, especially the pro version of one. All they give is (slurp ā€œa.txtā€) and (spit str ā€œa.txtā€). Seriously.

clojure/clojurescript.org donā€™t give simple examples either. What additional software do I need? Not looking forward to installing JDK and a ton of additional software given my limitations. Just really like what I see of Clojure and would like to learn as much as I can.

TIA

The good news is that we now have auto complete thanks to clojure-lsp
Here is a short talk about it from @borkdude :

Hey, thatā€™s true, we do have a few options for static auto-complete, Cursive has also been doing it for a few years now, and more recently with clj-kondo you have clojure-lsp and anakondo doing it as well. We also had auto-complete with a connected REPL for a while thanks to complement.

That said, we do not have auto-complete that shows only operations available to the type. And thatā€™s the bit I was referring too. People used to Java for example with IntelliJ, they often donā€™t learn to know what types things are and what operations the types have, they simply rely on their IDE for it. Itā€™s a little how you forget even simple multiplication like 9*4 once you start using a calculator.

1 Like

People used to Java for example with IntelliJ, they often donā€™t learn to know what types things are and what operations the types have, they simply rely on their IDE for it.

I find it the opposite. Auto-complete accompanied by documentation and navigation features helps me get a better overview of the libraries Iā€™m using.

1 Like

Me. All the time! :smiley:

2 Likes

I donā€™t think Iā€™m a beginner, Iā€™ve been playing with Clojure on and off for about 8 years, but Iā€™ve started a new project recently with clojure cli / deps.edn. The biggest problems Iā€™ve had are:

  • Identifying Clojure application architecture best practices
  • Tooling ergonomics
  • Library discovery and selection

For application architecture, Eric Normandā€™s question ā€œOrganizing Clojure code - A real problem?ā€ has been a great help. Turns out I was bringing some C# habits to Clojure.

For deps.edn, examples have been really useful, if a little overwhelming:

I find deps.edn to be a pretty nice way to encode build related stuff as data, and I find it easier to understand than Leiningen, but the ergonomics are just ghastly. I know we should favour simple over easy, but I donā€™t think itā€™s unreasonable to want to have both. Tools like Git or Homebrew have a relatively friendly and discoverable interface that helps you learn more about how to use the tooling. I understand that clojure cli is supposed to be simple, and that these kinds of ergonomics arenā€™t part of what it does. Unfortunately, as a byproduct, I spend far too long trawling through examples and guides to try and curate my own set of aliases.

I found the post ā€œ[Idea] A tool for helping developers get started using Clojure CLI tools and deps.edn - Community Center / Community Building - ClojureVerseā€ which led to the creation of ā€œlilactown/plumā€, but at a glance that doesnā€™t seem to have gone anywhere.

I found an example of a makefile wrapping deps.edn in antq and ended up learning how to debug make so that I could have one too. A couple of days later borkdude announced Babashka task runner, which is rather nice, and I converted my project to using that.

My project is a small thing, and itā€™s an attempt to port an overly complicated project that I built with Leiningen over to deps.edn. Part of that complexity was too much state in too many places so I decided to find some libraries to handle sql queries, connections, and migrations. There are quite a lot of libraries out there, many of them abandoned (though that doesnā€™t always matter). Finding them and choosing between them is a time consuming nightmare. Not to mention library gotchas like logging and handling of date and times.

Iā€™m now at the point where Iā€™ve got a bug relating to how migrations are running, which is fine, and I thought Iā€™ve quickly whip up test project so I can try an isolate the problem. I couldnā€™t remember the semantics for calling seancorfield/clj-new, so had to open up my .clojure/deps.edn to check. I thought about wrapping my global deps.edn in Babashka tasks to try and provide some executable documentation, but it feels like Iā€™m just pushing deps up hill at this point.

So, here I am, frustrated, having poured time into a hobby project where the only real headway Iā€™ve made is setting up tooling, and Iā€™m still haunted by the thought that the next time I set up a project itā€™s not going to be much easier.

I donā€™t think the clojure community is deliberately making things hard for beginners, but it is hard. Simple is wonderful, I love simple, but I donā€™t think itā€™s unreasonable to want to have at least some of that simple within reach, for it to be easy.

If Iā€™d done this project at work, in C#, Iā€™d already be done. Thatā€™s because itā€™s my day job, but thatā€™s also because all the pieces I need to make it work are within easy reach.

Donā€™t get me wrong, when Iā€™m dealing with the internals of the application, when all the libraries are in place and I donā€™t have to think about how to get a repl running, Clojure is wonderful, and I often solve C# problems first in Clojure and try and convert the solution. But getting to that point seems a lot more painful than it has to be.

4 Likes

tools.deps is NOT a build tool. It is not meant to encode build related stuff as data, but only launching apps with appropriate dependencies pulled in and made available. It is a dependency manager and application launcher for Clojure.

With this in mind, it makes sense that it doesnā€™t offer the ergonomics youā€™d want of a build tool. The fact itā€™s so simple has enabled others to very easily and quickly (I kid not, like in one day you can build one), create full build tools and build pipelines around it.

So whatā€™s happening now is there is no ā€œwinningā€ build tool in the community yet. Leiningen used to be it, but since tools.deps has made it so easy for everyone to write their own build tool, it created a state where each project has their own build machinery leveraging tools.deps.

So if you followed, youā€™d now understand this is totally fine, you do need to add some build tooling to your project, because tools.deps does not provide any build facilities of its own. So wrapping/extending it with something else to allow for defining build tasks and build task pipelines is necessary.

Alright, now, the core team is currently working on a tools.build to complement tools.deps as the official build tool, but not much is known of it yet. In the meantime I think babashka task is a great start putting together your own build tooling.

1 Like

I hadnā€™t heard about tools.build, thatā€™s something to look forward to. Thanks.

Hey there, Iā€™m a beginner, and hereā€™s what Iā€™ve found difficult so far:

  1. Refactoring. When I need to change things Iā€™m a lot slower. I love emacs, but the ramp up time to get anywhere near as quick as an Intellij product is still large ahead of me. When I want to move things and extract things it just takes a bit of time (in emacs-for me-as a beginner). Also, I wish there was auto-importing/requiring when I specify a fully qualified variable (is there?).

  2. Working with async data (network resposnes). When I fetch some data asynchronously, how can I use that data throughout my application without a network call each time I need that piece of data? ie. auth token.

  3. Sometimes I wish the documentation was better. For instance when I first started splitting out my functions from a single file, I was trying to learn how use namespaces so I read Clojure - Namespaces and thereā€™s no examplesā€¦ just a programmatic explanation of what it is. I learned how to use namespaces and how/when to use :require and :use by googling clojure projects github and looking through other peoplesā€™ source code.

So far, other than that, I love everything about Clojure though and itā€™s what I want to make my main language (I use Kotlin and JS at work).

Iā€™m currently using it to build a Postman-like helper tool for myself to generate and move data for me in the services Iā€™m working on across their many different environments and for this I absolutely love the repl. I can build functions in clojure around servicesā€™ apis and create complex automation tasks that a typical rest-client canā€™t do and I can run those functions while simultaneously building them, itā€™s absolutely insane I love it. I want to do something, I write the function, I evoke it. Love.

Please upvote this issue: Namespace introduction/guide is needed Ā· Issue #419 Ā· clojure/clojure-site (github.com)!

2 Likes

Is there any reason you donā€™t just stick with Intellij and Cursive?

Iā€™ve been using Clojure professionally for 3 years and I still donā€™t quite get the hype for emacs when it comes to Clojure development. I mean, I get the whole philosophy behind emacs and the synergy of the Lisp heritage, but from what Iā€™ve seen of various Clojure emacs setups they rarely beat the functionality of (a barely configured) Cursive. Iā€™m sure some 10xers with finetuned setups will disagree with me, but most people donā€™t operate at that level.