This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-06-16
Channels
- # announcements (33)
- # atom-editor (1)
- # aws (21)
- # babashka (174)
- # babashka-sci-dev (2)
- # beginners (59)
- # calva (4)
- # chlorine-clover (9)
- # clj-kondo (51)
- # clojars (7)
- # clojure (86)
- # clojure-czech (4)
- # clojure-europe (21)
- # clojure-france (6)
- # clojure-nl (1)
- # clojure-uk (2)
- # conjure (7)
- # core-async (3)
- # core-logic (3)
- # cursive (10)
- # data-science (8)
- # datalevin (14)
- # datomic (12)
- # events (1)
- # fulcro (5)
- # graalvm (10)
- # gratitude (3)
- # honeysql (3)
- # hyperfiddle (3)
- # introduce-yourself (4)
- # joyride (3)
- # leiningen (3)
- # malli (13)
- # minecraft (15)
- # music (1)
- # off-topic (40)
- # pathom (16)
- # polylith (28)
- # portal (25)
- # rdf (15)
- # remote-jobs (3)
- # shadow-cljs (23)
- # specter (1)
- # sql (5)
- # tools-deps (25)
- # xtdb (31)
org.clojure/clojure
itself is not a Git library, so you can't use find-verisons
for it.
Seems like this commit: https://github.com/clojure/tools.deps.alpha/commit/a4ad9c23250270a173101aee6bb2eceeaee53d92
Created https://ask.clojure.org/index.php/11974/regression-tools-deps-alpha-cant-find-versions-coordinates
(And add a test!)
Does anyone know of a legitimate way to programatically differentiate between the entries in an instance of a defrecord that are declared as fields in the defrecord
form and those entries that may have been assoc
'd on after the fact?
Great question! I was idly thinking about writing some helper code that could distinguish between declared dependencies in a com.stuartsierra.component
component and ad-hoc fields that were added as internal implementation details.
So I suppose you want to do this in a general case and don't have these "empty" record instances around.
You could try to access them as fields or even use __extmap
directly: https://github.com/jumarko/clojure-experiments/blob/master/src/clojure_experiments/records.clj#L20-L21
@UK0810AQ2 by some people, yes. Others consider the fields in the defrecord
form to be the declaration of what is required. Arguably they declare different dependency sets though. The defrecord
tells you all the dependencies you might need for full functionality as defined by the code of the record itself, whereas the component/using
form tells you what you are providing in a specific system map. You might for example use the same component type in more than one context. In particular, if you manually assoc some things onto a component and component/start
it at the REPL then you might not have the metadata.
@U0FR9C8RZ does the solution I suggested work for you?
It certainly works. Tbh I'm not that keen on it though because "extmap" looks a lot like the kind of internal implementation detail I wouldn't want to build on. Thank you for your gist, though.
This was more a curiosity thing than something I need to build.
I also considered looking at the result of .getDeclaredFields
, de-munging them and comparing them to the names of the map keys. It's using slightly more "public" data, but it still feels like a questionable hack.
I think it's perfectly fine for the kind of question you are trying to answer. If you are looking at building a tool for public use then maybe not but I wouldn't be afraid of that approach if you decide to actually build it.
(cmd)user=> (defrecord Foo [bar baz])
user.Foo
(cmd)user=> (Foo/getBasis)
[bar baz]
this may help?Ah, interesting!
I'm still trying to figure out how to actually use that if all you have is an instance of Foo - my interop is rusty
you can narrow things down using reflection too
(ins)user=> (-> (reflect/reflect (map->Foo {:a 0})) :members (->> (filter #(= (:type %) 'java.lang.Object))) pprint)
({:name __extmap,
:type java.lang.Object,
:declaring-class user.Foo,
:flags #{:public :final}}
{:name baz,
:type java.lang.Object,
:declaring-class user.Foo,
:flags #{:public :final}}
{:name __meta,
:type java.lang.Object,
:declaring-class user.Foo,
:flags #{:public :final}}
{:name bar,
:type java.lang.Object,
:declaring-class user.Foo,
:flags #{:public :final}})
nil
user=>
I used clojure.reflect/reflect (comes with core) to find getBasis
if it's something done once on startup, the cost of reflection might be outweighed by the clarity it provides
(-> (reflect/reflect (map->Foo {:a 0})) :members pprint)
shows all the methods, but fair warning many are stubs / error when called (map methods that java expects that make no sense on an immutable object)
it's too bad that getDeclaredConstructors
for defrecord doesn't return a zero arg constructor
hmm... then all the code would have to worry about the "uninitialized" state as well as the "initialized" state...
While using clojure.tools.namespace.repl/refresh
blows stack with an #error containing the key {:cause "Invalid token: ::any-namespaced/keyword"}
. It does this even when the namespaced keyword is inside of a comment block. Or commented out via #_ inside of a comment block. Is this expected behavior? Is there a way around it? It's certainly starting to get inconvenient. Any ideas appreciated.
Since comment
is a macro, its contents still need to be read, which is when namespace-aliased keys are resolved. You can use the fully qualified namespace :my.entire.namespace/keyword
to avoid the issue, or comment it out using ;;
which is ignored by the reader.
Appreciate the knowledge. Thanks for the prompt delivery.
Hi everyone, I need to scan my CLJ and CLJS dependencies for vulnerabilities and license compliance (something like https://docs.snyk.io/products/snyk-open-source, but for Clojure). Any advice would be much appreciated!
Is it a one-off task? Can't speak about CLJS, but for CLJ, I run lein pom
in all our projects and then used Whitesource to run the audit. Most tools like that work just fine if they assume they're dealing with Java/Maven
if you're getting audited or if this is for a tech due diligence, most likely you'll still spend hours explaining what's going on :-)
(the toughest thing to explain was that you can't really do static code analysis on Clojure, beyond clj-kondo/other linters, people just assume that Java's solutions are standard - stuff like Sonar Qube etc)
There are sonar integrations with support for things like kondo and nvd checking btw
I used it during SOC2 audits and when selling my biz, def worked as far as the technical part was concerned
yeah was going to add I did actually use it for getting through security review a couple times, but when I compare it to codeql + typescript definitions from GitHub for example, it's extremely light. It was accepted as sufficient evidence, but I personally wouldn't mind a bit more comprehensive suite
There's https://github.com/rm-hull/nvd-clojure which is based off of the Java DependencyCheck library
I use https://docs.snyk.io/, its exactly like https://docs.snyk.io/ π although I havent checked how comprehensive the reports are (but then I havent had to do an audit) I suspect it covers a similar amount to nvd-clojure
within a cljc ns can you require-macros the same ns? e.g (ns foo #?(:cljs (:require-macros [foo :refer [bar])))
I'm running this in shadow and it's telling me it can't find foo. The project is older so maybe this was valid at some point and isn't now? or it was built differently...
The answer appears to be yes, though there is also refer-macros which might be more concise (according to the docs).
Clojurians, I'm finding this one interesting.
(seq? [:vector :aint :iSeq]) => false
(sequential? [:but :is :sequential]) => true
So what gives? Is there a reason why vectors don't implement ISeq? I'm sure there's a well thought out one, but I don't get it.
lists happen to also be seqs, because the methods for using a seq (first, rest, car, cdr, whatever) are the same for seqs and lists
(you can kind of kludge one using subvec, but that retains references to the original vector in a way that rest on a seq doesn't)
If it helps, I don't think it's that obvious. Someone recently posted an old article that talked about some of the underlying ideas, https://insideclojure.org/2015/01/02/sequences/
Yup, definitely worth a read. I think the portion about laziness might get me over some confusion as well.
I was also surprised, at first, that vectors don't implement ISeq (it's not to say that there aren't very good reasons. there are).
there's also some background here, https://clojure.org/reference/lazy
I lost you at first and started to get it at vectors not having rest operation.
Can't say I know any language very well outside of Clojure. Up until recently I just wrote code for fun.
so java has iterators for traversing collections, like if you have a set in java, and you wanted to process each element in it, you could do it like
... it = theset.iterator();
while(it.hasNext()) {
whatever(it.next());
}
you can uses iterators in clojure like
(let [it (.iterator theset)]
(while (.hashNext it)
(whatever (.next it))))
or in in a way that consumes stack space, but will make the pattern clearer
((fn thisfn [it] (when (.hasNext it) (whatever (.next it)) (thisfn it)) (.iteator theset))
or with a seq instead of an iterator
((fn thisfn [s] (when (seq s) (whatever (first s)) (thisfn (rest s))) (seq theset))
OK, now I'm showing some lack of understanding. What is the relationship between calling .hasNext .Next, loop/recur and peek/pop? I struggle at times with doing things like that and often write code, change, write more, until I accidentally get things working.
a java iterator is a mutable cursor, hasNext asks if there are more items, next returns the next item and moves the cursor forward one
those things don't relate to loop/recur (looping) in any particular way, except that usually when you use an iterator you are looping over calling those methods
To make it practical, a good pattern to practice would be loop/recur with peek and pop which will cover me for my sequential needs?
peek and pop work on stacks (lists or vectors), so they will cover you for stacks, but it is much more common to be using seqs, which is done with first and rest
double damn
ok, first and rest I use quite frequently.
I'm following this code until I get to theset.
((fn thisfn [s] (when (seq s) (whatever (first s)) (thisfn (rest s))) (seq theset))
You've been a big help. Right now I'm writing a function to store vectors and lists in Datomic. I've been naming my attributes and functions as seq, :seq-index :seq-value :seq-type. What would you name it in place of seq to be more accurate?
How are you storing a vector in datomic?
Everything is a string, with the type annotated, maps are stored with a ref-many attribute of entries containing keys and vals annotated with a type attribute, vectors/lists are stored with ref-many items annotated with an index attribute. Nesting is done by making additional passes to replace the string collection value with a ref. Largely because I couldn't figure out how to postwalk or do anything clever. It's all fairly simple, no magic.