Fork me on GitHub
#clojure
<
2022-08-16
>
Sameer Thajudin00:08:39

What is the best way to implement user authentication and authorization for a Clojure Luminus application that has a front end developed using Reagent? Can the Spring security filter chain be used?

Adam Helins09:08:44

Do you have a one-liner for listing all namespaces available on the classpath? :thinking_face: Not just those that have been required.

jumar10:08:12

You wanna do that from the REPL? I think you need something that can have a look at specified source directories and find all the namespaces defined there. Something like #clj-kondo

Adam Helins10:08:15

I eventually followed this and it seems to play nicely: https://clojure.github.io/tools.namespace/index.html#clojure.tools.namespace/find-namespaces-on-classpath @U05224H0W Not exactly a one-liner but almost

๐Ÿ’ฏ 1
jpmonettas11:08:07

this if far from a one liner but you can index a entire code base (with all its dependencies) into a datascript db with one line and then query things like namespaces and much more https://github.com/jpmonettas/clindex

jpmonettas11:08:15

like :

(clindex/index-project! "./my-project" {:platforms #{:clj}})

(d/q '[:find ?nsname
       :in $ 
       :where
       [?nid :namespace/file ?fid]
       [?nid :namespace/name ?nsname]]
     (clindex/db :clj))

๐Ÿ’ฏ 1
thheller09:08:44

that is not a one-liner ๐Ÿ˜‰

pieterbreed13:08:03

If one wanted to delay require-ing a namespace and using fn's from that namespace, guarded by an if, how would one go about it? My own experiments have shown that just having require inline does not work, as I'm getting ClassNotFoundExceptions around fn's in the namespace I'm delaying loading. I've found https://github.com/clojure-goes-fast/lazy-require which seems to fit my need. Is there a better way to achieve this?

p-himik13:08:29

I'd use requiring-resolve. Not sure why plain require leads to an exception in your case though.

pieterbreed13:08:18

I'm not quite sure. My code looked like this:

(if something (do non-dev...) 
  (do (require '[ns] '[ns2]) 
      (ns1/fn (ns2/something ...) ...)))
The ns1 and ns2 are deps in a :dev alias, which is why I can't have it in my ns declaration's require. If I eval the require with the repl first, this code works, it's the delay-loading that does not work.

p-himik13:08:14

Ah, well, you still need resolve. And requiring-resolve does two things in a single call - that's why I suggested it.

1
pieterbreed13:08:38

Thank you, this worked.

๐Ÿ‘ 1
Jeongsoo Lee19:08:37

TIL: class and type are two different functions:

Jeongsoo Lee19:08:01

(defrecord Hihi [x y z])
(class hihi)
;; => clojure.lang.PersistentArrayMap
(type Hihi)
;; => java.lang.Class

Alex Miller (Clojure team)19:08:40

I don't think that's showing you what you think it is

Jeongsoo Lee19:08:49

However, it sometimes yield the same results:

(def hihihi {:x 1 :y 2})
(class hihihi)
;; => clojure.lang.PersistentArrayMap
(type hihihi);; => clojure.lang.PersistentArrayMap

Alex Miller (Clojure team)19:08:33

in most cases, class and type will give you the same answer - class is just the Java class and type is that but it can be overridden with a metadata tag

๐Ÿ˜ฎ 1
Alex Miller (Clojure team)19:08:48

user=> (type ^{:type 123} [])
123
user=> (class ^{:type 123} [])
clojure.lang.PersistentVector

Jeongsoo Lee19:08:58

Yeah, the documentation of type says: โ€œReturns the :type metadata of x, or its Class if noneโ€. Then it follows that if I supply the record Hihi with a type metadata, type will pick it up.

Alex Miller (Clojure team)19:08:44

in your first example above, you capitilized Hihi which is a class name, which resolves to the Java class representing the record (not the hihi record instance)

Jeongsoo Lee19:08:30

Oops, I just tried my hypothesis out and it confirmed your explanation.

Noah Bogart20:08:54

I'm playing around with Eastwood, I have (def min-part-byte-size (* 1024 1024 5)) and then I use it with (> (.size output-stream) min-part-byte-size) (and I have output-stream defined as ByteArrayOutputStream). eastwood yells about this: boxed-math: public static boolean (long,java.lang.Object). I'm surprised that the def isn't smart enough to know it's a long. can I type-hint the def or do I have to type hint it everywhere it's used?

Alex Miller (Clojure team)20:08:29

vars can't point to primitive values so it's being boxed into a Long

Alex Miller (Clojure team)20:08:09

you can type hint the def though

๐Ÿ‘ 1
Alex Miller (Clojure team)20:08:05

although I'm not sure that will help you enough here. this is also the rare case where using :const actually makes sense (assuming you're not altering that var)

Alex Miller (Clojure team)20:08:19

user=> (set! *unchecked-math* :warn-on-boxed)
:warn-on-boxed
user=> (def ^:const ^{:tag 'long} min-part-byte-size (* 1024 1024 5))
#'user/min-part-byte-size
user=> (> (.length "abc") min-part-byte-size)
false

jumar04:08:19

Isn't just :const enough? This doesn't produce any warnings for me:

(def ^:const min-part-byte-size (* 1024 1024 5))
(> (.length "abc") min-part-byte-size)
Also, is the above definition using ^{:tag 'long} basically the same as this?
(def ^:const ^long min-part-byte-size (* 1024 1024 5))

Alex Miller (Clojure team)04:08:38

I think :const is enough, I said that later on. And no, that tag is not the same - var meta is resolved so that resolves to the long function object, which is not a valid type hint

Alex Miller (Clojure team)20:08:16

even just ^:const might be enough there

Noah Bogart20:08:46

thank you for double checking, i appreciate it

Colin P. Hill20:08:14

Anyone know offhand of a JSON serializer that can, e.g., write :foo/bar as "foo/bar"? clojure.data.json/write[-str] discards namespaces on any instance of clojure.lang.Named, and doesn't appear to have an option to change that behavior.

Colin P. Hill20:08:13

The value I'm working with isn't in a key position, unfortunately.

Alex Miller (Clojure team)20:08:39

this is lower-level, but you can also extend JSONWriter protocol on clojure.lang.Named

Colin P. Hill20:08:49

(json/write-str {:foo/bar :baz/bork}
                :key-fn str
                :val-fn str)
;; => "{\":foo\\/bar\":\"bork\"}"

Colin P. Hill20:08:29

Yeah, I thought about doing that, but wouldn't that change its behavior globally?

Colin P. Hill20:08:18

Probably won't be an issue in my case, but I'd like to avoid monkeypatching if I can. Never know who might step on that rake later.

Alex Miller (Clojure team)20:08:20

maybe val-fn is applied too late there to catch it

Alex Miller (Clojure team)20:08:51

in any case, seems like a good issue to file on https://ask.clojure.org if you like

Colin P. Hill20:08:00

Sure, I can do that

Alex Miller (Clojure team)20:08:17

seems like a reasonable thing to want

Colin P. Hill21:08:57

:face_palm: I used :val-fn. The correct argument is :value-fn.

Colin P. Hill21:08:53

(json/write-str {:foo/bar :baz/bork}
                  :key-fn str
                  :value-fn (fn [_ v] (str v)))
=> "{\":foo\\/bar\":\":baz\\/bork\"}"
Works fine.

Colin P. Hill21:08:43

Ah, still runs into trouble when the instance of Named isn't the value of a map, though โ€“ e.g., a member of a vector. I'll file an issue with an example of that.

Stel Abrego21:08:26

I vaguely recall seeing a naming convention from the Malli source where some binding names have a question mark prefix like ?foo. I assumed that means that there's some nil punning involved and the value might be nil. Seems like a shorthand maybe-foo. Is that a thing people do? I like it but I might have just made it up in my head ๐Ÿ˜„ I'm thinking about naming a function time-str->?inst and I'm wondering if that is readable enough.

Colin P. Hill21:08:18

Doesn't answer the general question, but just to confirm your assumption in the case of Malli: https://clojurians.slack.com/archives/CLDK6MFMK/p1659726501229449?thread_ts=1659724001.224529&amp;cid=CLDK6MFMK

๐Ÿ‘ 1
Colin P. Hill21:08:55

But to answer the readability question: as you see there, I personally couldn't intuit what it meant, and had to ask

Stel Abrego21:08:23

@U029J729MUP I guess the fact that I'm also asking kind of answers my own question ๐Ÿ˜‹

hiredman21:08:01

I tend to assume ?foo is a logic/pattern variable https://github.com/clojure/core.unify/

๐Ÿ‘ 3
seancorfield22:08:10

And for anyone using HoneySQL, ?foo would mean a named parameter in a SQL statement, rather than anything optional.

๐Ÿ‘ 1
seancorfield22:08:27

(so, more like logic/pattern variable stuff)

wevrem00:08:58

Does anyone ever name these types of functions in reverse, so res<-in? I like the way it looks at the call site: (let [res (res<-in in)] โ€ฆ)

1
Stel Abrego04:08:55

@UTFAPNRPT I've never done that but I see what you mean!