Fork me on GitHub

I'm confused about defmulti


#object[Error Error: No method in multimethod 'cljs.user/query-dispatcher' for dispatch value: ["Select" ["first_name" "like" "Sitges"]]]


I want to match on the "Select" in q but it does not work


I feel like I've followed the examples


If I have a list of things, and want to construct a map where the keys are each thing, and the values are some function applied to each thing, how do I do it? Like this in Python:

{k: f(k) for (k, _) in ['a', 'b', 'c']}


(zipmap things (map f things))


Why am I getting an arity exception when an empty string is passed in as a second argument to a function that takes two arguments? nucleotide-count/count \A, "" throws actual: clojure.lang.ArityException: Wrong number of args (1) passed to: nucleotide-count/count where it's defined as:

(defn count
  "counts instances of base in sq; throws if not a real nucleotide"
  [base sq]
  (count (filter #(
        (assert (contains? bases %))
        (= base %)) sq))


@purohit the problem is that you're shaddowing the clojure.core/count function, but you're still trying to use that core function inside your function. The count which are you trying to invoke in the function body is your count function, not clojure.core/count


So do I need to disambiguate by calling clojure.core/count in my function body?


you should - or rather rename your count function to something else


I'm doing all of the above in proto-repl, and thought I had copied code over directly from a colleague who had made it work in their environment (emacs I think)


@hotbelgo I tried your code and it works for me


oh, so I don't know how to make proto repl work then


Try it in plain clojure repl first. Are you sure you evaluated everything properly?


I've cut and paste the whole thing


I've ctrl+,+b each part


yikes, how do i do that


i'm actually trying to update someone elses code and I'm seeing the same error when I pass data to this multimethod


I don't use protorepl, so I don't know exactly how to eval things there. However, in most editors, you can easily eval the whole file/buffer. That way it should work. Maybe ask in #protorepl if you have specific problems with it. You can also try to select everything and eval it with ctrl-alt-, s (see - Sending a selection).


Also notice, that once you define a multimethod, it's not that easy to redefine it (this is because defmulti uses defonce to define var that holds the multimethod). You can use ns-unmap to remove defmulti definition.


It's possile to reproduce your error with something like this:

;; Notice I incorrectly use sequence
(defmulti query-dispatcher sequence)
(defmethod query-dispatcher "Select" [[_select [lhs op rhs]]]
  (str lhs " " op " " rhs))

(def q  ["Select" [
                   "first_name" "like" "Sitges"]])
(query-dispatcher q)
IllegalArgumentException No method in multimethod 'query-dispatcher' for dispatch value: ("Select" ["first_name" "like" "Sitges"])  clojure.lang.MultiFn.getFn (

;; Now I want to fix it:
(defmulti query-dispatcher first)
;; But I have to unmap query-dispatcher first
(ns-unmap *ns* 'query-dispatcher)
;; and then re-eval everything.


ah, yes, what you say about renaming rings a bell


and i managed to make it work on a different computer


---- Could not Analyze <cljs form> line:1 column:1 ---- nth not supported on this type: Symbol 1 (ns-unmap ns 'query-dispatcher) ^--- ---- Analysis Error ----


when I was being taught we just renamed stuff


but I changed to query-dispatcher3


did ctrl+, l on each part


and end up with


----  Compiler Warning on   <cljs form>   line:1  column:2  ----

  Use of undeclared Var cljs.user/query-dispatcher3

  1  (query-dispatcher3 q)

----  Compiler Warning  ----
#object[TypeError TypeError: Cannot read property 'call' of undefined]


ok, resarted everytihngf and it works


wow - this is hard


How do I map a function to a collection but also pass another argument? Like I want (map my_fn my_seq extra_arg) because my_fn takes two args


I thought about using partial functions but the argument I'm adding is in the second place instead of the first one


Guess I have to use an anonymous fn


How do I consume two sequences of equal length and run some function on each pair of objects? Like if I have

(def a '(1 2 3))
(def b '(4 5 6))
And I want to run pairs like 1, 4 and 2, 5 [etc] to some function I have


@purohit mapv should do it


Perfect, thanks!


i have these random brainfreezes regarding anything clojure. i want to evaluate/test/try out two sql libs, how should i do it? create a completely empty project for this? seems like a lot of work? using something that's already filled up seems weird


I do all my brainstorm there


@ashnur I usually just have a project for screwing around in, made with lein new, It's the easiest way. There's also and if you use boot it should be easy enought to add deps to the repl.


@ashnur +1 for madstap's approach. I also have a single project ( where I play with random clojure stuff. Usually, I have this project open in Spacemacs with cider-repl running all the time, so I can quickly test anything I want. Using cider + clj-refactor it's very easy to quickly add dependency to the running repl/project: cljr-add-project-dependency.


interesting that lein-try


@ashnur If you're on osx, I think the easiest thing now is to use the new official clj tool. brew install clojure


windows or linux


coming soon to a package manager near you


i am not a rich person 🙂


we're not there quite yet 😃


i just did lein new sandbox for now


{:deps {org.clojure/clojure {:type :mvn :version "1.9.0-beta1"}
        org.bouncycastle/bctsp-jdk14 {:type :mvn :version "1.38"}}}


that's the new deps.edn format for the clj tool


took me a moment to find, but the docs for that tool moved here:

Alex Miller (Clojure team)15:09:06

fyi, a lot of stuff on that page is undergoing big changes atm


@ashnur Might be worth looking at boot since you can first up boot repl and then add new dependencies on the fly and test libraries without needing to restart your REPL (and without needing a project at all).


@seancorfield how do you add dependencies on the fly? set-env! with the new vector of dependencies?


i was afraid of boot because most of the tools i need are explained in terms of lein


What is the meaning of () in the expression (){:x 42} ?


(this was generated by honeysql)


Oh wait, nevermind. Just some repl anomaly


@hmaurer I use merge-env! but, yes, you add new :dependencies to the environment and Boot loads them, then and there.


@ashnur I find boot much simpler to understand than lein, fwiw


@ashnur At work we switched from lein to boot about a year ago. No regrets 🙂


it's less magical


tell me, how much less is that? like, from the normal clojure level of magic, which is OVER9000, how much does it take off? 🙃


haha, it uses that clojure magic to build composable pipelines


lein plugins just use project.clj for every single thing and it makes a mess


Boot is "just functions" (well, "tasks", but you extend Boot and control Boot with plain ol' functions). Leiningen is declarative so you have project.clj and everything else is implicitly executed as plugins etc.


can you do everything with boot that is/was done by lein?


@ashnur I think Boot can do a lot more than Leiningen. Extending Leiningen (with plugins) was always hard so replacing a full Ant-based build script with Leiningen was next to impossible. Replacing it with Boot is a lot more straightforward. We're doing a lot of stuff with Boot now that was extremely hard with Leiningen.


For example, we keep all our dependencies in EDN files and we all "pin" versions of common libraries in a .properties file, then we have functions in our build.boot file that stitch all that together when constructing the final list of :dependencies. That sort of programmatic stuff is ugly/hard/impossible in Leiningen.


this sounds really good, however it's mostly about stuff i am not dealing with now. it's very convenient for me as a beginner that i just have to copy paste into project.clj


also, lot of tutorials and readmes only talk about lein and it's not clear to me how can i take a project.clj for lein and make it into a boot project


yeah that definitely makes sense


I'm writing a blog post aimed at beginners that will address this. It'll show how to use Boot to do simple stuff in a project that assumes Leiningen. Might take me a while to finish it tho'.


i was thinking, "build tool" is kinda misleading isn't it? it builds in the sense of from source to binary, but someone coming from javascript or php will look and say, ok, so i am building projects with this. or is it both?


and usually, the questions that I can't find answers googling are the hardest to get answered on slack too 🙂


still don't know how to import and use it though. it's not explained anywhere


@ashnur Not quite sure what you're asking about -- but Java interop is covered here: -- what questions does that leave unanswered?


that's like the third url today that is called THE docs for java interop 🙂


i got some help on IRC, used a different maven repo, and could import the class


(import 'net.sf.jsqlparser.parser.CCJSqlParserUtil) this was what i was searching


If you were clearer about your problem statement, I could give clearer answers 🙂


if i knew how to be "clearer" i would've said it. i am sorry that i am dumb, but that's kind of the way beginners are 🙂


not sure why you have to say such things though, i didn't blame you for not helping, i am grateful that you try to help. so why you have to attack my inaptitude, i already know i am not clear enough, i will probably never be clear enough in these situations 😞


I wasn't attacking -- I was just teasing that I can't be as helpful as I'd like to be, because I wasn't sure what you were asking. I didn't mean to come across as rude 😞


np then, sorry for being perhaps too sensitive, i am trying to ask clear questions but often trying is not enough


☝️:skin-tone-2: Yes, this.


@seancorfield neat. By the way, I’ve a bit of an unrelated question. I have been told that Spring Boot uses a different technique than standard “uberjars”. Instead of merging all class files into a single jar, they generate a jar containing the librairies jars in a folder, and load them dynamically


is that something doable with boot?


(and yes, I am a beginner and also found boot much simpler to understand after switching to it)


@hmaurer I don't know enough about Spring Boot to understand what you're suggesting.


> Java does not provide any standard way to load nested jar files (i.e. jar files that are themselves contained within a jar). This can be problematic if you are looking to distribute a self-contained application that you can just run from the command line without unpacking. > To solve this problem, many developers use “shaded” jars. A shaded jar simply packages all classes, from all jars, into a single ‘uber jar’. The problem with shaded jars is that it becomes hard to see which libraries you are actually using in your application. It can also be problematic if the same filename is used (but with different content) in multiple jars. Spring Boot takes a different approach and allows you to actually nest jars directly.


shrug No idea... nor do I have any idea why that would matter...

Alex Miller (Clojure team)17:09:47

both approaches have downsides. really, creating uberjars at all is just a bad thing. if only it weren’t so damn convenient.

Alex Miller (Clojure team)17:09:22

the shaded uberjar runs the risk of clobbering, particularly with manifests and other similarly tricky parts of jar files

Alex Miller (Clojure team)17:09:03

using a jar-in-a-jar requires special classloader and url support for the jvm to understand what you’re doing

Alex Miller (Clojure team)17:09:50

I’m not aware whether the latter works in a clean way with Clojure (you’d need something more than just Clojure to make that work)


@alexmiller I see; thanks for the details!


A simple pool, who uses lein and who uses boot?


I started to read about boot now, but for libraries I think lein is better

Alex Miller (Clojure team)18:09:48

we do this poll every year and it’s a good sample size


It'll be interesting to see how much ground Boot has made in the next survey. Leiningen will continue to be the default choice for a lot of people coming into Clojure because it's what (nearly?) all the books recommend right now.


All of our corporate tooling assumes lein, so boot would require a lot of support work for us, and so we’ll probably stay with lein unless there’s a huge advantage. I’m sure a lot of other places are the same.

Jim Rootham19:09:15

I am getting mugged by startup issues. I have a project.clj:

Jim Rootham19:09:19

(defproject voting "0.1.0-SNAPSHOT" :description "Cabal voting back end" :url "" :license {:name "Eclipse Public License" :url ""} :dependencies [[org.clojure/clojure "1.8.0"][http-kit "2.2.0"]] :main ^:skip-aot voting.core :aot [voting.core] :target-path "target/%s" :profiles {:uberjar {:aot :all}})


(you can use triple-backtick to format code when pasting small fragments here @jrootham)

Jim Rootham19:09:13

I ran lein deps after putting in the [http-kit "2.2.0"] and it said it downloaded them

Jim Rootham19:09:34

Although the time it took was a clue that it didn't

Jim Rootham19:09:27

I cannot find http-kit in my project (created with lein app voting)


JAR files are downloaded to your local Maven cache in .m2/repository in your home directory. They are not added to the project itself.

Jim Rootham19:09:10

`(defproject voting "0.1.0-SNAPSHOT" :description "Cabal voting back end" :url "" :license {:name "Eclipse Public License" :url ""} :dependencies [[org.clojure/clojure "1.8.0"][http-kit "2.2.0"]] :main ^:skip-aot voting.core :aot [voting.core] :target-path "target/%s" :profiles {:uberjar {:aot :all}})


@jrootham You'll need to adjust a Slack preference so pressing enter inside backticks does not send the message: (I don't know why this isn't Slack's default -- it's very counter-intuitive)

Alex Miller (Clojure team)19:09:28

I think he just missed the closing triple back tick

Jim Rootham19:09:51

Sorry, not familiar with that idiom


Back to your problem... The JAR files don't get added inside your project tree.


(and the time taken is because a lot of JAR files will be downloaded the first time you reference some new libraries)

Jim Rootham19:09:47

OK, I have found the library, so it did download, I now have the newbie issue of how to use them in my code, in the lein repl should (:require 'http-kit) work, and how do I tell?


When you start a REPL with lein repl inside the voting project directory, it will have the dependencies declared in project.clj and you can (require 'http-kit.whatever) namespace.


(note: no : for the require function -- it has a : inside the ns form in your source code tho')

Jim Rootham19:09:11

(require 'http-kit) gets me a file not found message, your last answer suggests I should be looking for a namespace inside http-kit

Alex Miller (Clojure team)19:09:39

confusingly, the name of the artifact and the names of the namespaces inside an artifact, do not necessarily have any correlation (although usually the artifact name is part of the namespace name)

Alex Miller (Clojure team)19:09:07

in this case, the namespaces of interest are either org.httpkit.server or org.httpkit.client

Jim Rootham20:09:32

Ah, it looks closer, use instead of require. The demo works in the repl. Now for actual code.