This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-12-29
Channels
- # aleph (1)
- # announcements (5)
- # beginners (21)
- # cider (4)
- # clojars (1)
- # clojure (39)
- # clojure-europe (5)
- # clojure-norway (133)
- # clojurescript (5)
- # datomic (27)
- # exercism (2)
- # gratitude (4)
- # humbleui (21)
- # hyperfiddle (10)
- # integrant (16)
- # introduce-yourself (1)
- # lsp (17)
- # matrix (1)
- # nbb (10)
- # overtone (5)
- # polylith (21)
- # re-frame (6)
- # squint (3)
- # tools-deps (22)
- # yamlscript (102)
In the https://clojure.org/guides/spec of using Clojure spec, the deck (among other things) is shown as
(s/def :game/deck (s/* :game/card))
Is there a reason why this can't/shouldn't be
(s/def :game/deck (s/coll-of :game/card))
What's the difference and what heuristics would I use to choose one over the other?They are subtly different. * is a regex op and will combine with other regex ops to form a single collection, whereas coll is not
Let me look at the guide to recall the full example here
I wrote this, but I don’t recall why I used * instead of coll here. I think I would probably reach for coll first now. Might be some difference in generated values, but I think should be pretty similar either way.
The guide does call out in the collections section that the 'point' example can be done with s/cat or s/coll-of or s/tuple, but the options conform differently and are differently nestable, and I believe roughly the same idea applies here.
Generally you will want the regex ops when you are describing a collection with internal structure, most commonly syntactic structure for a macro signature
And for “information”/data use cases (like this one), I would probably use coll-of.
Thanks!
If I want to break my specs up in multiple namespaces, is it sensible to just require
the namespaces that have specs the current namespace depends on?
For example, if I have a ns called player
and another called game
:
;; ns player
(s/def :player/name string?)
(s/def :player/score int?)
(s/def :player/player (s/keys :req [:player/name :player/score]))
;; ns game
(s/def :game/player (s/coll-of :player/player))
Do I just (require [player])
in game even if I don't have any functions in that ns to call?
Is it preferable to dump all the specs in the same namespace? It "feels" more right to separate them by domain concept, but then of course there will be interconnections.
Does spec choke on cycles in general? What about when multiple namespaces are involved?I have found generally it’s better to put the “domain” specs in their own package. In most cases, specs can refer to other specs by name without worrying about loading order (as long as they are all loaded before use). You can use :require with :as-alias to get name aliasing without loading if needed
What is the Clojure's equivalent to Python's subprocess package? In a POSIX system I want to invoke, from a Clojure script, a binary, feed data into its stdin, and retrieve its outputs from stdout and stderr. I want also to get the status of its running. Such a subprocess equivalent would enable me to do all the above.
clojure.java.shell is probably the closest in 1.11.1. Clojure 1.12 will have a new clojure.java.process namespace that’s updated a bit
There are some external libs as well, notably https://github.com/babashka/process
The new c.j.process has a lot of overlap with that
I tried to :require clojure.java.shell and got Syntax error (ClassNotFoundException) Was I supposed to capitalize anything or do some other magic?
user=> (require '[clojure.java.shell :as shell])
nil
user=> (dir shell)
*sh-dir*
*sh-env*
sh
with-sh-dir
with-sh-env
nil
or if you're in the ns
form, you'd use (:require [clojure.java.shell :as shell])
some examples at https://clojuredocs.org/clojure.java.shell/sh too
Thanks, I see I had to quote the vector given to require (I know what quoting a list means, but what does quoting a vector mean?). And (println (shell/sh "ls" "-al" "nonexistent")) demonstrated to me that I get also stderr and status code.
Quoting (in all cases) means “read but don’t evaluate”. Vectors evaluate their elements, and symbols are resolved to the value they refer to. In this case quoting is used to treat the symbols as symbols, without resolving them