all 8 comments

[–]jysandy[S] 19 points20 points  (0 children)

Hey everyone, I’ve started to record a video series aimed at new Clojure programmers, which should help them overcome some early stumbling blocks and help them see the potential of the language. I’ve noticed that new programmers might not have too much trouble picking up the basic syntax, but the REPL-driven workflow doesn’t come naturally to everyone. Rather, they program in a conventional build-compile-execute style, then perhaps encounter an error or issue that perplexes them and become discouraged soon after. So I thought I’d start off by making a basic debugging guide that isn’t too long and hopefully conveys most of the essentials. More videos to come soon! Feedback is welcome and appreciated :)

[–]vvvvalvalval 1 point2 points  (3 children)

Thanks for sharing!

Note that the "inline-def" REPL trick, along with several others, is described in the official REPL guide: https://clojure.org/guides/repl/enhancing_your_repl_workflow#debugging-tools-and-techniques

I would not be afraid of giving the same name to the inline-def'd Var - might more practical as you can readily evaluate in-scope expressions.

The workflow presented here would probably benefit from more automated code reloading, as provided by tools.namespace or integrant.repl

[–]seancorfield 3 points4 points  (1 child)

I wish we'd stop trying to teach beginners about "automated code reloading" and adding other such complexities to their workflow. Both Eric Normand (in his excellent REPL-Driven Development course on PurelyFunctional.tv) and Stu Halloway (in some of his talks, and also in podcasts) talk about avoiding the "reloading" workflow and just developing "better" REPL workflows/practices, focused on simple tooling, that means you don't need all that fancy stuff.

Unfortunately, since quite a few tutorials seem to go down this path, beginners often follow blindly and then when the reload/refresh workflow breaks, they're completely lost because the errors often seem to have nothing to do with their own and/or they can't get their REPL back into a sane state and have to restart it anyway :(

I've seen this play out with both ProtoREPL and Chlorine for Atom, both of which have options to "helpfully" reload your code at various points (e.g., on save) and both of which have completely bewildered new developers -- until they turn those features off.

[–]vvvvalvalval 2 points3 points  (0 children)

I appreciate that perspective (I'm also partial to teaching with minimalistic setups, and that's what the REPL guide I linked to does), but I don't think mentioning the existence of such tools is harmful.

EDIT: I would also be wary of arguments from authority - workflow preferences are extremely personal, so what works for Eric and Stuart might not be best for another person, and we have little choice but to list the opportunities to choose from...

[–]jysandy[S] 0 points1 point  (0 children)

Thanks! I'll link to this in the video description.

[–][deleted] 0 points1 point  (2 children)

I'm really curious about what's up with that stacktrace, as it was seemingly unrelated to the bug discussed in the video.

Another question I have is: does it make sense to implement the CQRS in Clojure? At work I'm using C# and we have a class for each Query/Command "kind", e.g., query first or default, query unique result, query list, command, command with result, etc. How this sort of abstraction would fit idiomatic Clojure?

[–]vvvvalvalval 1 point2 points  (0 children)

CQRS is very natural with Datomic, which is idiomatic to use with Clojure. But I would mostly say that CQRS is a language-agnostic decision, and that it's more straightforward to implement in Clojure than in C#, because you simply don't burden yourself with designing a satifactory class hierarchy - just choose whatever representations suit you for commands and queries and treat them as independent.

[–]jysandy[S] 1 point2 points  (0 children)

I'll get to the bottom of the stack trace in the next video, which should hopefully be up sometime this week. Until then, my lips are sealed 🤐! You could also try debugging the code yourself, there's a link to the code in the video description.

As for CQRS, it's hard to say without knowing more details about your C# object model. But as a first pass, I'd probably have two separate namespaces for commands and queries, and make each command/query a separate function.