Fork me on GitHub
#clojure
<
2021-02-03
>
Black13:02:36

Hi, can I use fdef for spec on defmulti ? I am using it in clojurescript and after hotreload in figwheel I got this message:

Uncaught Error: No protocol method IMultiFn.-add-method defined for type function
is it a bug or I am using spec wrong?
(defmulti ->api-event
          "Map form outputs into api event."
          {:arglists '([form-id form-values])}
          (fn [form-id _form-values]
            form-id))

(s/fdef ->api-event
        :args (s/cat :form-id keyword?
                     :form-values (s/map-of keyword? any?))
        :ret (s/nilable ::types/api-resource))
When I remove fdef part, error will not throw.

Alex Miller (Clojure team)13:02:39

You can spec the dispatch function itself, or you can wrap it in a function to spec it

Black14:02:01

Thanks!🙏

mbjarland14:02:21

Hi, I would like to resolve the dependency graph of a set of maven root dependencies. The things I've found in clojureland for this are tools.deps.alpha and pomegranate. I would however only like to resolve the graph (i.e. load the pom:s), but not download it (i.e. the jars) and also I would like for the process to be multi-threaded as large dependency graphs otherwise get time consuming. From my understanding tools.deps.alpha does multithreading but not the "lazy loading" and pomegranate is the other way around (i.e. can skip downloading but not multi threaded). Any pointers to libs or perhaps to how I should use the existing ones to accomplish this much appreciated. Started doing the multi threading part myself but implementing all the nuances of pom parsing (parents, variables, etc) is some work. End result should be a tree of [group artifact-name version] tuples in some suitable format.

Alex Miller (Clojure team)14:02:42

it is possible to tactically use parts of tools.deps to just traverse the pom / dependency structure, but the parallel download is buried in the dep expansion so you'd need to build that yourself

Alex Miller (Clojure team)14:02:16

in particular, the individual node step in the middle can be done with something like

mbjarland14:02:14

@alexmiller ok that makes sense. I'll take a look at the source. The problem I am trying to solve is that we run into these massive dependency graphs for large projects and they often have either internal version collisions or when they don't, they make it impossible to upgrade anything in a controlled manner because it's hard to find a non-colliding upgrade path. I'm looking to build a tool to programmatically explore the version trees. Surprised something like this does not already exist since semantic versioning is what it is.

Alex Miller (Clojure team)14:02:43

(clojure.tools.deps.alpha.extensions/coord-deps 'org.clojure/clojure {:mvn/version "1.10.2"} :mvn {:mvn/repos clojure.tools.deps.alpha.util.maven/standard-repos})

mbjarland14:02:48

and this is not clojure specific, just the state of the java eco system I think

mbjarland14:02:58

@alexmiller thank you, that looks promising, just ran it in a repl.

Alex Miller (Clojure team)14:02:03

it's on you to avoid cycles, ignore exclusions, etc etc of course :)

mbjarland14:02:37

yeah, there is that

Alex Miller (Clojure team)14:02:38

there are facilities for comparing versions and things like that - some of that is exposed ctdae/compare-versions etc

mbjarland14:02:05

@alexmiller but the above handles things like boms, parents, pom variable expansion etc?

Alex Miller (Clojure team)14:02:54

handles must cases properly understanding things like parents, pom variables, etc (uses the appropriate maven apis). I think we've had issues with boms in the past, so I'm not positive about that part.

mbjarland15:02:10

@alexmiller ok thanks again, that helps.

Alex Miller (Clojure team)15:02:51

if you have followups, #tools-deps is a thing

vanjakom16:02:11

Hi guys, I'm trying to understand how this two calls to String/valueOf are producing different behavior

vanjakom16:02:14

(String/valueOf (first nil)) "null"

vanjakom16:02:26

(String/valueOf nil) Execution error (NullPointerException) at java.lang.String/<init> (String.java:166).

Alex Miller (Clojure team)16:02:24

I presume inferred type

Alex Miller (Clojure team)16:02:12

first one is probably String.valueOf(Object), second one maybe String.valueOf(char[]) ?

dpsutton16:02:42

> if the argument is null, then a string equal to "null"; otherwise, the value of obj.toString() is returned. for the Object overload

vanjakom16:02:46

yup, I understand that, but I'm having trouble to understand why nil is assumed to be char[] instead of Object

Alex Miller (Clojure team)16:02:08

I don't think it's assumed, you're just getting first match from the reflector

vanjakom16:02:11

but why then takes another match when given (first nil)

Alex Miller (Clojure team)16:02:27

(first nil) is a function that returns an Object

Alex Miller (Clojure team)16:02:41

and there is a valueOf(Object), so that's a match

Alex Miller (Clojure team)16:02:57

in the latter case, null means no type information so anything could match

Søren Sjørup16:02:42

and then it defaults to the first match based on arity?

Alex Miller (Clojure team)16:02:57

user=> (defn value-of [^Object o] (String/valueOf o))
#'user/value-of
user=> (value-of nil)
"null"

vanjakom16:02:32

strange even java is doing same

vanjakom16:02:36

public class Test {
    public String foo(Object o) {
        return System.currentTimeMillis() + "as Object";
    }

    public String foo(char[] c) {
        return System.currentTimeMillis() + "as char[]";
    }

    public static void main(String[] args) {
        Test test = new Test();

        System.out.println(test.foo(null));
    }
}

vanjakom16:02:35

thanks for feedback, I'm still a bit confused but will try to understand

skykanin19:02:59

Is there a reason why the edn spec hasn't been updated with the ##NaN ##Inf and ##-Inf tagged literals introduced in clojure even though Rich Hickey was in favour of doing so back in 2014? Relavant thread https://github.com/edn-format/edn/issues/2