Fork me on GitHub
Jack Arrington00:11:02

Why are you supposed to favor (seq coll) over (not (empty? coll))?


below is the implementation for empty?:

(defn empty?
  "Returns true if coll has no items - same as (not (seq coll)).
  Please use the idiom (seq x) rather than (not (empty? x))"
  {:added "1.0"
   :static true}
  [coll] (not (seq coll)))
so (not (empty? coll)) is actually (not (not (seq coll)))


additionally, there's a few cases where it's useful to know how the seq abstraction operates


also, historically in lisp code an empty list acted as false in conditionals, using seq in clojure allows replicating that idiom with other collection types


though clojure is further away from lisp culturally than it once was


Hey team, am playing with vim-fireplace + luminus, trying to set up a workflow where I can work on both clojure + clojurescript repls. Context Am a noob at all of above (even vim). I have gotten vim-fireplace to work with both clojure + clojurescript, in that: • if reload a cljs file with (js/alert “hi”), it works • if I reload a clj file with (log/infof “hi”), it works Now, I am a bit confused with how to play inside a repl, and send updates to that repl Say I have two active nrepl connections (one for clojure, one for clojurescript) Now, I connected to both: lein repl :connect 7000 # clojure lein repl :connect 7002 # clojurescript If I do something like :%Eval on the file, I see that vim-fireplace does evaluate it, without any complains:

Press ENTER or type command to continue
But, If I check that file in my remote nrepl connection, I don’t see the updated function. I would have guessed that nrepl would have automagically had the latest version — since it is a remote connection to some central place, where both vim-fireplace and my remote repl are sending updates. I do not see this though. Am not quite sure how to debug. Two main questions: 1. If I do :%Eval in vim-fireplace, is it right to expect that my remote nrepl repls should have the latest version of the code? If not, what kind of workflow should I use to play inside a repl? 2. If yes, I am guessing I am making a mistake in vim-fireplace. How would you debug it?


So I have not used vim-fireplace, and thus I may be woefully ignorant of how it actually works. The part of your description that confuses me most is "If I check that file in my remote nrepl connection". Typically you have source files loaded into buffers in your editor, vim in this case. And I would expect that vim, via vim-fireplace, is the process that is making a TCP connection to the JVM process running Clojure, and a separate TCP connection to whatever process is running your ClojureScript runtime.

👍 3

Hey Andy, to clarify my thinking, here’s what I mean: I know that vim-fireplace sends code to two clojure(script) processes: clojure: which has an nrepl connection on 7000 clojurescript: which has an nrepl connection on 7002 Now, I can also open a terminal and connect to those processes:

lein repl :connect 7000 # pane 1
lein repl :connect 7002 # pane 2
When I said “check the file”, I mean: • go to “pane 2" • see my connected repl • write something like (hi-joe), and see if the latest version of the function is there It seems like it is not there, which makes me wonder Because indeed if I do something like :%Eval (hi-joe) in vim, it does seem to have the latest version. So it makes me wonder why doesn’t my “remote nrepl connection” also have the latest version? (I may be misusing terminology / misunderstanding nrepl)


So the JVM is multi-threaded, and I know you can have multiple REPLs connected to the same JVM simultaneously. I do not happen to know whether it is supported to have mutliple REPL connections to the same ClojureScript runtime simultaneously. Perhaps so, but if so, it isn't clear to me how that would work, since ClojureScript runtimes are single-threaded.

👍 3

Perhaps you had two different ClojureScript runtimes going simultaneously, with vim-fireplace connected to one, but lein repl ... connected to a different one?

❤️ 3

Indeed Andy, I think your intuition is on the spot! I had two separate processes. I thought this was necessary, but I realize that indeed jvm is multithreaded, so I could use one process to handle all of this xD. That way vim fireplace only needs to be connected to one process.


Are you also starting a separate TCP connection to your JVM process, outside of vim-fireplace?


(about it may be that asking in #vim will garner better answers @stopachka)

❤️ 3

Thanks @U04V70XH6! Should I a. cross-share there, b. copy-pasta c. delete? (Not quite sure what the etiquette is in clojurians)


Might as well cross-share.

❤️ 3

In general we discourage cross-posting, but if you post in a general channel and folks suggest posting in a more specific channel to get better answers, it's easier to cross-share, and you may still get answers in the general channel (and it seems you figured it out, so thank you for posting a follow-up saying you have it working!).

👍 3

Awesome, thanks Sean. To the adventure! opens vim


Ah! I think I got it: So, what I think happened was this: I was sending my clojure code to my repl that is running clojurescript Looks like even the clojurescript process stores clojure code, so there were no errors when I tried to do that. I guess what I need to do is to have manually run :Connect in vim-fireplace, and scope /clj and /cljs to use different repls (I think) Will report back!


Update: okay, it works! did a bunch of things but I think the gist was that vim-fireplace was not detecting my clojure repl. Will look deeper and move to #vim when time calls for it. Thanks team!

Rafael Gil11:11:23

Hi everyone :) I've managed to finish my first service in Clojure \o/ It's a "REST" api that I use to backup the photos of my iPhone automatically when I put it to charge (if anyone is interested, I can share my Siri shortcut to do that). The service works but only in standalone mode. If I deploy it to a server (wildfly) I can't upload the files (apparently it can't access the local filesystem). Does anybody knows how to solve that? Here is the code: Thank you!

🎉 3

Congrats! I’m curious what the iPhone side of that looks like.

Rafael Gil12:11:21

Thanks @st3fan! It looks like this (screenshots)

Rafael Gil12:11:53

All you have to do is run this script when the iPhone connects to power (in automation tab)

Rafael Gil12:11:53

It is limited to 20 items just for testing, I usually leave it on 500 items (you don't need a limit, but the script can take a long time to run)

Rafael Gil12:11:03

It backups videos too :)


Wow it is crazy that you can actually script this on the device


I had no idea that was possible


Very nice 😺

👍 3
Rafael Gil16:11:11

@st3fan Cool isn’t? And its stock iOS. You can do a lot of things with this (even run javascript using a 3rd party app).


regarding server usage: the correct thing is to use a config with the absolute path to the directory you use for storage, then you need to separately ensure the directory is available to the app based on its user permissions

Rafael Gil08:11:54

@U051SS2EU I did that, but it doesn’t work. I tried to use the (System/getProperty “jboss.server.home”) too, but it shows some weird files (that are not in the defined home folder) and if I concatenate that with any dir name (and create it) it only shows empty. There may be some security config on wildfly that I’m missing.

Jeroen van Wijgerden15:11:27

Although I don’t state the ::id spec should be used, it is actually part of the validation. This surprises me. My understanding of spec was that each time I validate I get to choose by which spec I want to validate a piece of data. This case implies otherwise. What am I missing?

(s/def ::id number?)

 (s/keys :opt [])
 {::id "foo"})

;; #:clojure.spec.alpha{:problems
;;                      ({:path [:jvw/id]
;;                        :pred clojure.core/number?
;;                        :val  "foo"
;;                        :via  [:jvw/id]
;;                        :in   [:jvw/id]})
;;                      :spec ...
;;                      :value #:jvw{:id "foo"}}

Alex Miller (Clojure team)15:11:20

this exact same conversation is happening in #clojure-spec right now if you want to look there

Alex Miller (Clojure team)15:11:44

but in short, s/keys will check all registered keys in the map, whether listed in the spec or not

👌 3

Hmm how do I write a test for a private function?

Alex Miller (Clojure team)15:11:00

use #' when you invoke the function (that is, invoke the var, which invokes the function)


oh so these are still in the namespace .. just not looked up on invocation?

Alex Miller (Clojure team)15:11:03

so if you have (defn- secret [x] x) write (deftest test-secret (is (= 1 (#'secret 1)))))

Alex Miller (Clojure team)15:11:47

"^:private" is just a marker that the var symbol should not be resolved externally, but the var still exists publicly


@st3fan In general, folks don't test private functions, just public functions, so maybe that's a sign that you need to rethink your approach here? (either make the function public -- part of the API -- and supported; or change how you're testing the public function(s) that call that private function) Private functions should be "implementation details".


They are definitely implementation details, but i still want to test them independently of the public api.


Another possibility then is to use with-test to provide tests with the defn of the private function itself. That way the tests "stay private" too, in a way, since they are right there with the "implementation detail".




there is so much in the core 😕