Announcements about events, meetups, conference. Respond in threads please.

Great talk. I was very sad that Clojure Provo couldnโ€™t put the video up but it gave me more of an inventive to ensure that I came to this one ๐Ÿ™‚. I learned a fair bit from this, ironically not just about REPL Driven Development but about all the modern Clojure tools that I still havenโ€™t learned ๐Ÿ˜บ


Hi all, please the recording of "REPL-Driven Development - Clojure's Superpower byย @seancorfield" is available on our YouTube channel:

Chase 2021-01-14T18:46:16.004200Z

@seancorfield Is this where we can ask more questions about the video? I've been trying to explore reveal more too so want to follow along with you.

Chase 2021-01-14T18:47:22.004400Z

I'm looking at your dot-clojure repo. So I think what's happening is that in you called the :reveal and :dev aliases at the command line.

Chase 2021-01-14T18:48:05.004600Z

The :dev alias actually calls out to this dev.clj file which is where all those other reveal options are coming in from. Is that correct?

Chase 2021-01-14T18:48:31.004800Z

So to recreate I would create that dev.clj file and throw it next to my deps.edn file?

seancorfield 2021-01-14T18:48:41.005Z

Probably easier to follow-up either in #tools-deps or via DM but I guess some of this deserves a broader audience...

seancorfield 2021-01-14T18:49:54.005200Z

The dot-clojure repo has a whole bunch of (opinionated) tooling that works together. The dev.clj file lives in that repo -- i.e., it goes into your .clojure folder with the (user) deps.edn which is assumed to contain all the various aliases I regularly use.

seancorfield 2021-01-14T18:51:51.005400Z

:dev (and now, preferred, :dev/repl) is an alias that uses :main-opts to load the dev.clj script. :reveal pulls in Reveal and would run it as well, if it were the last alias on the command-line that contained :main-opts.

seancorfield 2021-01-14T18:53:52.005600Z

To explain that: when you use multiple aliases, their bodies are combined. Mostly they are merged: either a merge of hash maps or a conj of vector contents (`:jvm-opts`) but with :main-opts it is "last one wins" so only one alias's :main-opts end up being used.

seancorfield 2021-01-14T18:55:18.005800Z

clj -M:reveal would start Reveal as the main REPL. clojure -M:rebel would start Rebel Readline as the main REPL. clj -M:reveal:rebel will start Rebel Readline but also make Reveal available as a dependency -- because the :main-opts for :rebel "wins" by being the last alias.

seancorfield 2021-01-14T18:57:09.006Z

clojure -M:reveal:rebel:dev/repl uses the :main-opts from :dev/repl as the last alias to have any main opts, so Reveal and Rebel Readline are on the classpath but their -main functions are not called. The code in dev.clj runs, looks at what is available via the classpath, and decides which REPL to start up and how to combine the various utilities.

seancorfield 2021-01-14T18:57:16.006200Z

Does that help @chase-lambert?

Chase 2021-01-14T19:04:38.006400Z

Mostly! Still wrapping my head around the last alias wins. Is it only in the case of a conflict that it wins because otherwise why use more than one alias.

Chase 2021-01-14T19:05:55.006600Z

Oh wait, so only the :main-opts part pertains to this last one wins.

seancorfield 2021-01-14T19:06:07.006800Z


seancorfield 2021-01-14T19:09:52.007Z

(one important thing to note is that my :dev & :dev/repl aliases will not work on an XDG system because they assume $HOME/.clojure -- on an XDG system that's most likely to be $HOME/config/clojure as I recall)

Chase 2021-01-14T19:10:51.007300Z

Yep, $HOME/.config/clojure

Chase 2021-01-14T19:11:29.007500Z

So your :add-libs alias has a :main-opts section and you still use that even though it's not the last alias you call

seancorfield 2021-01-14T19:13:55.007700Z

Several aliases have :main-opts but those options are not used if a later :main-opts is present. The aliases still bring in the specified dependencies.

Chase 2021-01-14T19:14:29.007900Z

ahh, ok, so you are using everything in the :add-libs alias except for the :main-opts

seancorfield 2021-01-14T19:14:58.008100Z

With :add-libs it's just a bit of "magic" to ensure a DCL (DynamicClassLoader) context for any REPL that is started -- but my dev.clj also contains that code.

Chase 2021-01-14T19:15:50.008300Z

Yeah, I'm trying to parse your dev.clj to see if I can yank it wholesale or if it's going to conflict because I'm using cider nrepl vs your socket approach. hahaha

Chase 2021-01-14T19:17:43.008500Z

So basically whatever alias that will have the call to this dev.clj file has to come last right. My apologies if I'm being super dense about this.

seancorfield 2021-01-14T19:17:49.008700Z

The issue I'm working around with that DCL stuff is that a Socket REPL does not use a DCL context (and neither did Cognitect's REBL). Now that I have dev.clj, any Socket REPL started by it will have a DCL. But I left it in :add-libs (and :rebl) so that I can start a more barebones REPL and still have the DCL context that add-libs (the function) needs.

seancorfield 2021-01-14T19:18:16.008900Z

Yes, clojure -M:lots:of:aliases:and:then:load-dev.clj

Chase 2021-01-14T19:23:01.009500Z

Cool, I will try to pilfer what I can. I use your's and practicalli's. That install-reveal-extras function is a bit intimidating but I think I want it. Haha.

Chase 2021-01-14T19:23:38.009700Z

I kind of wish it was just an option to throw in to the reveal main opts. "corfield-reveal-extras" or whatever

Chase 2021-01-14T19:31:20.009900Z

And so you aren't getting any of the :main-opts from :test either? Hahaha, this seems to be tripping me up. I'm assuming the main opts just aren't that important.

seancorfield 2021-01-14T19:37:58.010100Z

:runner is the alias I use to run tests. :test just brings in some useful stuff.

seancorfield 2021-01-14T19:38:39.010300Z

;; testing and debugging tools (this would normally be overridden
  ;; by a :test alias in the project deps.edn file -- but it's a
  ;; useful default):
  :test {:extra-paths ["test" "src/test/clojure"]
         :extra-deps {org.clojure/test.check {:mvn/version "RELEASE"}}}
:test has no :main-opts

Chase 2021-01-14T19:58:17.010500Z

got it! Awesome. The more I use these tools the more I like them but it definitely takes some tweaking

seancorfield 2021-01-14T19:58:43.010700Z

It's like a set of LEGO bricks!

Chase 2021-01-14T19:59:00.010900Z

Well put.

Chase 2021-01-15T16:57:00.012200Z

@seancorfield I'm back! During your "testing" demo I love that are able to run your tests from your source file and seeing it in Reveal. It was fun seeing @jr0cket's response too.

Chase 2021-01-15T16:57:39.012400Z

It seems you are saying you use - t so it seems to be an editor thing? What exactly does that run? Should I check with my editor tooling or cider tooling (I use a cider nrepl with vim/conjure) to get that setup?

practicalli-john 2021-01-15T17:02:53.012600Z

@dharrigan so called standard definition video for YouTube uploads are available straight away. It take several hours to process full HD video of this length. (This is one reason I stream the Practicalli live broadcasts)

seancorfield 2021-01-15T17:33:03.012900Z

Not sure what you mean about - t ?

Chase 2021-01-15T17:48:30.013100Z

It sounds like you are saying "I hit the hotkey dash test"

Chase 2021-01-15T17:48:50.013300Z

And then you get the results in a Reveal window

Chase 2021-01-15T17:49:11.013500Z

"side-running" Is that what these test runners are?

seancorfield 2021-01-15T17:52:56.013700Z

Ah, right. I have three hot keys bound to running tests: * ctrl-; t -- runs just the test under the cursor (i.e., you have your cursor on the name of a test in a test namespace) * ctrl-; x -- runs all tests in the current namespace (so you're editing a test namespace) * ctrl-; X -- runs all tests in the associated test namespace

seancorfield 2021-01-15T17:53:06.013900Z

I think the latter is what you're referring to?

Chase 2021-01-15T17:53:59.014300Z


Chase 2021-01-15T17:54:23.014500Z

So when I go back to my own editor tooling I should be looking for whatever command calls the "associated test namespace"?

seancorfield 2021-01-15T17:54:35.014700Z

The code behind that looks at the current ns, say, and then tries to require (and if that fails, it tries, which is a convention for Expectations users like me), and if the require succeeds, it then runs all the tests in that associated namespace.

seancorfield 2021-01-15T17:55:05.014900Z

I don't know how (or even if) CIDER supports that out of the box -- check its (copious) docs and/or ask in #cider

seancorfield 2021-01-15T17:55:53.015100Z

I would be surprised if CIDER did not support that -- and I would expect Cursive would also support this -- but I don't use CIDER or Cursive.

Chase 2021-01-15T17:56:07.015300Z

Will do. Thanks Sean

seancorfield 2021-01-15T17:57:07.015500Z says it will do that association.

seancorfield 2021-01-15T17:57:28.015700Z

If youโ€™re in an implementation namespace (e.g. some.ns), CIDER will try to find a matching test namespace (by default some.ns-test) and run the tests there.

If youโ€™re in something that already looks like a test namespace (e.g. some.ns-test), CIDER will simply run the tests in that namespace.

Chase 2021-01-15T17:57:29.015900Z

Ahh, you don't have to look that stuff up for me. ty!

seancorfield 2021-01-15T17:57:59.016100Z

Your question made me curious. Now I know the answer and can respond to others who ask that question ๐Ÿ™‚

Chase 2021-01-15T18:03:19.016300Z

Looks like my editor tooling does have it built already as well!

Chase 2021-01-15T19:10:59.016500Z

So I'm trying to pilfer your reveal extras. I cut your dev.clj file down to just the install-reveal-extras function and edited my deps.edn reveal alias to this:

Chase 2021-01-15T19:11:11.016700Z

:reveal {:extra-deps {vlaaad/reveal {:mvn/version "1.1.171"} nrepl/nrepl {:mvn/version "0.8.3"} cider/cider-nrepl {:mvn/version "0.25.5"} com.bhauman/rebel-readline {:mvn/version "0.1.4"}} :jvm-opts ["-Dvlaaad.reveal.prefs={:font-size,20}"] :main-opts ["-m" "nrepl.cmdline" "--middleware" "[vlaaad.reveal.nrepl/middleware,cider.nrepl/cider-middleware]" "-i" "-f" "rebel-readline.main/-main" "-e" "(load-file,(str,(System/getProperty,\"user.home\"),\"/.config/clojure/dev.clj\"))"]}

Chase 2021-01-15T19:11:42.016900Z

I hope that is readable. But I don't seem to be getting any of those extras that you show in your video.

Chase 2021-01-15T19:14:00.017100Z

So I suspect something is being pulled in or added in your start-repl function for reveal huh?

Chase 2021-01-15T19:25:02.017400Z

Ahh yep, "If Reveal is picked, add some custom code to automatically display tap>'d values with metadata and in table view." I will see what I can do to pull that out of there. I'll leave you alone now. Haha. Great video btw!

clyfe 2021-01-13T11:22:37.366Z

Is it just me or that's 360p for everyone? Can hardly see the code.

dharrigan 2021-01-13T11:27:12.366700Z

It's only showing 360p, quite fuzzy

yogidevbear 2021-01-13T12:15:46.367500Z

Shows 1080 for me now. Might just have been YT processing the video after initial upload.

yogidevbear 2021-01-13T12:16:35.367700Z

Thanks @seancorfield for doing the talk and thanks @bruno.bonacci for hosting, recording and sharing ๐Ÿ˜„ ๐Ÿ’ฏ


@dharrigan It takes a few minutes after a new upload of a video for YouTube to postprocess the HD video. It should be there now


It takes a few minutes after a new upload of a video for YouTube to postprocess the HD video. It should be there now

dharrigan 2021-01-13T13:23:09.368500Z

ah, perfecto! ๐Ÿ™‚

johanmynhardt 2021-01-13T16:07:49.369Z

๐Ÿ˜Ž Thanks for last night's talk. I had a :poop: connection and couldn't watch all of it, so I'll go through the video once I get a chance. I've found a new tool for my toolbox that's a no-compromise now ๐Ÿ˜‹


Intrested in Kafka, Clojure and Distributed Systems?? Sign up for this talk