clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
Black 2021-02-03T13:47:36.148200Z

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.

alexmiller 2021-02-03T13:57:08.148600Z

It’s not supported

alexmiller 2021-02-03T13:57:39.149500Z

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

Black 2021-02-03T14:22:01.149800Z

Thanks!🙏

mbjarland 2021-02-03T14:41:21.154600Z

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.

alexmiller 2021-02-03T14:45:42.156300Z

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

alexmiller 2021-02-03T14:49:16.159600Z

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

mbjarland 2021-02-03T14:50:14.160800Z

@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.

alexmiller 2021-02-03T14:51:43.162300Z

(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})

mbjarland 2021-02-03T14:51:48.162500Z

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

mbjarland 2021-02-03T14:52:58.163200Z

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

alexmiller 2021-02-03T14:55:03.163800Z

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

mbjarland 2021-02-03T14:55:37.164Z

yeah, there is that

alexmiller 2021-02-03T14:56:38.164900Z

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

mbjarland 2021-02-03T14:57:05.165500Z

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

alexmiller 2021-02-03T14:59:54.166600Z

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.

mbjarland 2021-02-03T15:01:10.167700Z

@alexmiller ok thanks again, that helps.

alexmiller 2021-02-03T15:03:51.168100Z

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

mbjarland 2021-02-03T15:04:03.168300Z

ok will do

vanjakom 2021-02-03T16:18:11.169400Z

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

vanjakom 2021-02-03T16:18:14.169600Z

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

vanjakom 2021-02-03T16:18:15.169800Z

vs

vanjakom 2021-02-03T16:18:26.170100Z

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

alexmiller 2021-02-03T16:20:24.170500Z

I presume inferred type

alexmiller 2021-02-03T16:21:12.171200Z

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

dpsutton 2021-02-03T16:21:42.171900Z

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

vanjakom 2021-02-03T16:21:46.172Z

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

alexmiller 2021-02-03T16:22:08.172400Z

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

alexmiller 2021-02-03T16:22:23.172600Z

so somewhat arbitrary

vanjakom 2021-02-03T16:23:11.173100Z

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

vanjakom 2021-02-03T16:23:12.173300Z

?

alexmiller 2021-02-03T16:23:27.173600Z

(first nil) is a function that returns an Object

alexmiller 2021-02-03T16:23:41.173900Z

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

alexmiller 2021-02-03T16:23:57.174200Z

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

Søren Sjørup 2021-02-03T16:25:42.175200Z

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

alexmiller 2021-02-03T16:25:48.175400Z

yeah

👍 1
alexmiller 2021-02-03T16:25:57.175700Z

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

vanjakom 2021-02-03T16:47:32.176700Z

strange even java is doing same

vanjakom 2021-02-03T16:47:36.176900Z

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));
    }
}

vanjakom 2021-02-03T16:48:35.177800Z

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

2021-02-03T19:18:59.179200Z

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