Fork me on GitHub
#clojure
<
2022-11-04
>
Casey10:11:13

I want to have a function in my user ns that calls the function (dev/repl-reset) but I don't want to load the devns in the top level of userns, because I want to be able to open a repl even if the rest of the code doesn't compile. I just figured out that I can't do something like this (defn reset [] (require [dev :as dev]) (dev/repl-reset)) Is there someway to achieve this?

p-himik10:11:37

requiring-resolve.

❤️ 1
jkxyz10:11:11

Or something like

(require 'dev)
(eval '(dev/repl-reset))
The compiler expects to be able to resolve the dev/repl-reset var when it compiles the function, so if you delay the var resolution then it works

Casey10:11:46

these are great, thanks!

dpsutton14:11:51

at metabase we do something similar: • our user.clj has a function to load a dev namespace: https://github.com/metabase/metabase/blob/master/dev/src/user.clj • the dev namespace loads lots of stuff but not automatically at startup: https://github.com/metabase/metabase/blob/master/dev/src/dev.clj

Casey15:11:43

Yea that's exactly what I have now! It's a nice pattern. However I wanted to bind an emacs key to a function in user that would call a function in the dev namespace. But I work on different projects and the dev ns itself is named different things. So my plan was to put a function in user (which is common across all) that I could bind my emacs key too, then each project's user ns would be able to dispatch it to the right dev ns.

Casey15:11:08

But of course I don't want the user ns to load the whole world

Casey15:11:19

requiring-resolve looks like it'll do

dpsutton15:11:20

You can just use a fully qualified name to dev. (dev/load-stuff) and as long as you’ve loaded dev once it will be fine

Drew Verlee18:11:13

Why doesn't

(.-secretKey
   (.getCredentials (DefaultAWSCredentialsProviderChain.)))
return the field "secretKey" I can get the key using the method .getAWSAcessKeyId or by using the "bean" function. But i would have expected .-<field> to work to. What i'm i missing?

hiredman18:11:42

java has this thing called beans, which is basically an object with a bunch of getters like getSecretKey

hiredman18:11:51

the getters all start with "get"

hiredman18:11:35

clojure.core/bean turns an object into map by calling all the methods that start with "get" where the key is based on the method name with the get prefix removed

hiredman18:11:12

you can see from the java doc here https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/AWSCredentials.html that there are methods for the interface

Drew Verlee18:11:26

that makes sense. Thanks! yeah, i thought the information from cider-inspect and reflect was telling me it was a field, but i guess it never actually says "field" anywhere.

hiredman18:11:50

it isn't a field

isak19:11:06

Can someone help me understand this?

user=> (cond-> -50 seq? first)
Execution error (IllegalArgumentException) at user/eval159 (REPL:1).
Don't know how to create ISeq from: java.lang.Long
user=> (seq? -50)
false
I expected to get -50 as a result from the first form, since (seq? -50) is false, and first should not be called on -50. Here is the macroexpansion, which also isn't what I expected:
(clojure.core/let
  [G__165 -50] 
  (if clojure.core/seq? 
    (clojure.core/-> G__165 clojure.core/first)
    G__165))

phronmophobic19:11:40

> Note that, unlike cond branching, cond-> threading does > not short circuit after the first true test expression. edit: just realized this isn't relevant here

hiredman19:11:43

cond-> also doesn't thread through the predicates

hiredman19:11:36

So you are looking at the truth value of whatever the name seq? is bound to

isak19:11:25

Why does this return -49? (cond-> -50 odd? inc)

isak19:11:57

Oh, something strange there too, hmm

isak19:11:28

Oh I get it I think

isak19:11:27

Yea that explains it, thanks

skylize22:11:51

If it helps, this macro (a rewrite from condp) should actually do what you are trying to use cond-> for.

(defmacro cond-of
  [expr & clauses]
  (let [gexpr (gensym "expr__")
        emit (fn emit [expr args]
               (let [[[a b :as clause] more] (split-at 2 args)
                     n (count clause)]
                 (cond
                   (= 0 n) `(throw (IllegalArgumentException.
                                    (str "No matching clause: " ~expr)))
                   (= 1 n) (list a expr)
                   :else `(if (~a ~expr)
                            (~b ~expr)
                            ~(emit expr more)))))]
    `(let [~gexpr ~expr]
       ~(emit gexpr clauses))))
(cond-of val-to-test-then-transform
         pred1? handle1
         pred2? handle2
         handle-else)

skylize22:11:42

Actually, I think that's not exactly what you wanted? I guess you probably want to thread through multiple pred functions and transform on each match. Sorry. This macro doesn't do that.

isak22:11:30

No worries, I was just confused about what parts got threaded, but I can live with the existing cond->. I was kind of wondering if what I expected existed, but it isn't important for what I'm doing.

Lone Ranger00:11:31

(cond-> -50 (seq? -50) first)

Lone Ranger00:11:53

I think is what would provide the expected behavior