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
:thumbsup:
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:
nil#'virtual-library.core/hi-joenil#'virtual-library.core/cli-options#'virtual-library.core/http-server#'virtual-library.core/repl-server#'virtual-library.core/stop-app#'virtual-library.core/start-app#'virtua
l-library.core/-main
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.
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)
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)Thanks @seancorfield! Should I a. cross-share there, b. copy-pasta c. delete? (Not quite sure what the etiquette is in clojurians)
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!
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.
Perhaps you had two different ClojureScript runtimes going simultaneously, with vim-fireplace connected to one, but lein repl ...
connected to a different one?
Might as well cross-share.
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!).
Awesome, thanks Sean. To the adventure! opens vim
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.
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: https://gist.github.com/rafagil/8bf03c4de4ef19dae728b61542f26861 Thank you!
@noisesmith 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.
Congrats! I’m curious what the iPhone side of that looks like.
Thanks @st3fan! It looks like this (screenshots)
This is the iCloud link: https://www.icloud.com/shortcuts/cab3a34ba0be48fdbf0a5796460ee59d
All you have to do is run this script when the iPhone connects to power (in automation tab)
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)
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 😺
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/explain-data
(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"}}
this exact same conversation is happening in #clojure-spec right now if you want to look there
but in short, s/keys will check all registered keys in the map, whether listed in the spec or not
Hmm how do I write a test for a private function?
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?
so if you have (defn- secret [x] x)
write (deftest test-secret (is (= 1 (#'secret 1)))))
great!
"^:private" is just a marker that the var symbol should not be resolved externally, but the var still exists publicly
Wonderful
@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).
@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".
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