Fork me on GitHub

I gotta go to bed, its 2am and I gotta run to work tomorrow! Hopefully I can figure it out tomorrow. Thanks everyone for your help, and good night 🙂


Got the REPL server running and connected. how to run the main.clj file ?


there are some keybindings listed in its package documentation here:


load file and evaluate top block stand out as what you may want


Is this where we register keybindings ?


Vim mode would be used if I were using vim as my editor. since I'm using Atom, I need non vim bindings .


I would imagine the keybindings are already hooked up. And vim refers to vim emulation in atom not vim the program


If the bindings are already hooked up, how to load and eval the file ?


I think Chlorine doesn't hook up any key bindings by default


Have you tried just calling the commands from the command palette?




Calling commands that Chlorine hasn't registered ?


Ran the Chlorine command "chlorine:load-file" manually.


It looks like you just have a folder with a single clj file in it?


Clojure isn't a scripting language, you do have to have a project folder set up


eg. by using lein new app <project-name>


It is a project folder. look in the top left corner of atom


that's an Atom "project" which is a different thing, I'm not sure what the proper term is in Clojure


basically it expects a certain directory structure to be set up, with e.g. a src/ folder and a project.clj file to declare your dependencies


if you just want to get up and running with the language without dealing with these things, I can recommend


I guess it would be just 'Clojure project'

Edward Hughes02:06:57

@paulgureghian Did you install a build tool like Leiningen or Boot? It'll make setting up your project a lot easier. The Clojure tooling really does help with bootstrapping yourself.


Gonna try it with clj first.


Technically, Clojure can be used as a scripting language if you want.


Just not so many people want to for very short-running programs with Clojure/Java. I think a few more might do so with ClojureScript and/or joker.


Am I getting closer to making this all work ?


What does it say when you click on “view issue”?


OK, I looked at the source code of Atom... @paulgureghian Where is your cursor / which panel has focus when you try to load file? The Clojure source file must be the active panel with your cursor in it. Otherwise Atom has no "current editor" and Chlorine can't load file -- because your cursor isn't in a file.


In our long DM exchange, I specifically mentioned that you needed to have the cursor in the source file editor, not the REPL panel or elsewhere.


Hi guys quick question:

 (reflect java.lang.Object)
 (filter map?))
I want to use the reflection API to get all the functions of a Java class, but I saw something werid: Not sure what the hashtag means in this senario. In the code above, I even tried filtering out only map objects, but the hashtag thing still remained
Is there a name for these #something.something.something, and why do they behave as if they are maps? Thanks!


;; The full answer I got was
 {:declaring-class java.lang.Object,
  :exception-types [],
  :flags #{:final :native :public},
  :name getClass,
  :parameter-types [],
  :return-type java.lang.Class}
 {:declaring-class java.lang.Object,
  :exception-types [java.lang.InterruptedException],
  :flags #{:final :public},
  :name wait,
  :parameter-types [],
  :return-type void}


Those are Clojure records, defined with defrecord. They were designed to behave very similarly to maps.

👍 4

OHHHHHHHH Isee, i didnt even think that they were records


They return true when you pass them to map?, but they are not clojure.core/= to regular maps. They have their own distinct types, and are immutable, and because they have a distinct type they can be used with Clojure protocols.


thank you so much andy


I will go read up on records


Hi, I have the following in my project.clj :resource-paths ["resources/" "resources/symspell-1.0-SNAPSHOT.jar"] it allows me to access the symspell library locally and works fine as long as I do lein run or lein test. But once I build the uberjar, it tells me that it can't find the classfile, how can I solve this?


not sure how exactly it relates to uberjar but if you want to use local jar you should install it into the local maven repo via lein install


then the uberjar should work fine. Adding the jar on the resource path is weird


just add it to :dependencies


oh ok thank you


the jar comes from a java project thought, not a clojure one, so I imagine I shouldn't install it with lein but with maven?


Works, thank you !


I was just trying to write a spec for my re-frame app-state and wanted to spec a Date. I found some code where someone used inst? for that, but I don't quite understand it. Doc says it validates if x satisfies Inst and Inst has just no documentation. I figure it means something like "Instant", i.e. "can be expressed as a timestamp" since Inst defines inst-ms* - is that correct?


I’m taking a quick look at the source code (, and it looks like the Inst protocol is extended to at least java.util.Date, and also possibly to java.sql.Timestamp and java.time.Instant, so if you have any of those three it should satisfy inst?.


Yes, best to read the source I think. Other libs may extend Inst too:


That was very helpful indeed, I just never thought of grepping over core to answer such questions


That was very helpful indeed, I just never thought of grepping over core to answer such questions


you don't have to grep - just use your editor to navigate to function definition


Slack is having the hiccups today, my work Slack was double-posting things people typed too. Haven’t had any more instances since I restarted Slack at least 🤞


Annd of course Slack tries to double-post that one too, so I guess it must not be a client-side issue.


when creating protocols, do you find yourself using maps often? or do you try to be more specific?


I mean if I have a contract which has the parameters url and id would you send in a map instead? to make it more "Future proof"?



(defprotocol AmountCommand
  (get-amounts [context])
  (set-amounts [context]))


I don’t create protocols often, but that definitely looks like a good/idiomatic usage to me.


hi all, I have question about associative destructuring. I would like to pass the keys which I need to destructur as an input user vector.


basically, this works

(defn filter-event [{:keys [id type]}]  (println (str "---" id "--"  type )))


but what if I want to make the id type configurable


like one could select their own keyword for the data. It might be that destructing isn't the way to go there

😁 4

destructuring is probably not what you are after. Think of each printed param as some function of the passed in collection. You could use a higher order function

(defn make-event-logger [id-fn type-fn]
    (fn [c] (println (str "---" (id-fn c) "--" (type-fn c)))))
(def filter-event (make-event-logger :id :type))

clj 4

here is how is solved :


defn apply-filters [user-f event])
(doall (map #((keyword %) event)  user-f )) 
                                                                                            (defn gh-filter-events [events-json]
  (doall (map #(apply-filters user-filters %)  events-json )))


I think however the first doall is redundant


Hi! I am somewhat confused with async. I've got this re-frame handler (re-frame/register-handler :request-it (fn [db _] (go (let [response (<! (request-all-from-db))] (prn (:status response) ) (prn (:body response)))))) that prints 200 and the expected map to console. However when I run (go (let [response (<! (request-all-from-db))] (:status response))) the return-value is the actual channel. How is that?


The return value of a go block is always a channel.


If you want to do stuff with the response, it needs to be inside of that go block (or another one)


Ah yes, that sounds familiar ...


So I would assoc that into app-db inside the go then I guess


Well you're no longer inside the context of the original function. You'll need to dispatch another event with the response i believe. Let me try to find an example, I haven't done re-frame in a while


Eeh ... I am no longer within the context of the original function, because actually the go-block transforms into a callback chain?


yep! i believe that doc outlines how to use re-frame with async requests


It kind of does. I tried this but the error Error: No protocol method IAssociative.-assoc defined for type cljs.core.async.impl.channels/ManyToManyChannel: [object Object] seems to indicate that I am still dealing with a channel where I would expect to be dealing with the taken value: `(re-frame/register-handler :request (fn [db _] (go (let [response (<! (request-all-from-db))] (re-frame/dispatch [:process-response (:body response)])))))` `(re-frame/register-handler :process-response (fn [db [_ response]] (assoc db :data response)))`


Jesus, I really don't get slack-formatting either


Well one problem is that your request returns the go instead of db


Well I see how that might be a problem.


In the example, they return (assoc db :loading true)


Yup. I guess I was too preoccupied with being afraid of async to think clearly for a minute there. Thanks for bearing with me.


sure thing! good luck 🙂

Felix Linker16:06:07

I have the feeling that clojure lacks a couple of functions that I'd like to see in the core library which have been left out to keep the core small as far as I understand. But I don't want to repeat myself over and over and I also don't want to create my own little personal dependency. What do you personally do about this?


how about a thrid party dependency?

Felix Linker16:06:31

I never stumbled upon one when I was searching for those functions of which I was sure they must exist.

Felix Linker16:06:41

For example map-update which maps update 😄

Felix Linker17:06:34

In general, I feel like I'm having problems working with maps. I often have the feeling to repeat the same code patterns over and over for general map transformations and generating maps also isn't fun.

Felix Linker17:06:40

What exactly are you referring to?


I tend to miss dissoc-in occasionally

Felix Linker17:06:35

Yeah, stuff like that. Is there any library you could recommend?


medley has a few things: but not a lot.

👍 4
Felix Linker17:06:30

That looks like a good start! Thanks


There's also 'useful' and also some lib from Metosin I think


the older I get the less I like deps like that. I normally copy it out of my last project, or write it fresh. :man-shrugging:


nice and coupled


I was forgetting a couple of other similar libraries, but then found that they are linked from the beginning of medley's README.


@linkerfelix I think once you've really internalized how Clojure works, you'll stop wanting map-<something> and just treat map as something you use to apply arbitrary transformation functions -- and you'll focus on those instead.

Felix Linker17:06:37

Yes, I also was asking because I had the feeling that I might be missing something about clojure.


The main options are: repeating yourself over and over, creating your own little personal dependency, using someone else's dependency, or petitioning to have them added to Clojure. The last one is the least likely to happen, so I hesitate to even mention it. The Clojure maintainers are very conservative about adding such things.


oh, and Sean's suggestion: get comfortable with small compositions of existing things, without having to give them names.


The threading macros can help you here aswell


-> and ->>

Felix Linker17:06:03

Yes! I'd be down for that. But for something like map-update, I currently don't have such nice small compositions


What does map-update even do tho'?

Felix Linker17:06:35

The thing I struggle the most with is transforming maps and creating new ones dynamically


Transforming hash maps -- reduce-kv is often what I reach for.

Felix Linker17:06:36

(defn map-update
  [m f]
  (reduce (fn [m2 [k v]] (assoc m2 k (f v))) m m)

Ahmed Hassan18:06:50

Won't reduce have first m as {} i.e. empty map?

Ahmed Hassan18:06:51

Something like this: (defn map-update [m f] (reduce (fn [m2 [k v]] (assoc m2 k (f v))) {} m)

Felix Linker10:06:23

Your option certainly is a bit cleaner but the semantics don't change. The result will be the same.

Felix Linker17:06:54

Call update for all keys


think about threading the collection through successive assoc/assoc-in/update/update-in etc. for example

#(-> % 
     (assoc :foo "bar"
                :bing "bam")
     (assoc-in [:path :to :deeper] "baz")
     (update :counter inc))

Felix Linker17:06:23

@crispin That's a good illustration for -> but I don't struggle with such use cases.


(reduce-kv (fn [m k v] (update m k f)) m m) -- but I don't find myself doing that very often so I'm curious as to why it seems like a "core" operation to you?

Felix Linker17:06:29

Well... because I do 😄 I often have maps with uniform data-types and I want to transform those step-wise.

Felix Linker17:06:09

Often, I first create a map from a list of keys where k should be mapped to some (f k). That's not nice for me currently as well although zipmap seems to be promising.


Interesting. Nearly all my hash maps are heterogeneous, rather than homogeneous. What is the domain you're working in?


I believe that map-update above is often called map-vals, and is in the medley library, and many others.


f is the "map" from k to (f k)

Felix Linker17:06:53


Felix Linker17:06:59

Can you use functions like maps?

Edward Hughes12:06:51

I mean, if we wanted to be pedantic about it, one would say that maps are a generalisation of the concept of a function.

Felix Linker17:06:40

It's crazy to me that you can add gists as dependencies 😄 Thanks!


Something truly beautiful that tools.deps allows us to do (I didn't realize you could have multi-file gists until I saw someone do that last year!).


these proposed answers are updating the val not the key clearly I misunderstood something


(we don't use those, I just knocked that up a year ago because someone was asking about map-vals and map-keys)

😉 4

I dont get why you would create a map with values that are all some function of the key


just use the function


that's not what's being done


update takes a key to know where to run the function


the function runs on the val


"Often, I first create a map from a list of keys where k should be mapped to some (f k)"


oh - then all the answers proposed are wrong

Felix Linker17:06:21

What @crispin sounds very appealing. I will think about whether I can update my code to make use of this because in the end he is very much right

Felix Linker17:06:51

That sounds like the best answer to me because all the time I had the feeling that I was doing something wrong.


also hash-maps are functions. that look up the first passed arg in them.


its a blury line sometimes

Felix Linker17:06:09

Yeah, I knew that. But I will spend some time working more on functions than on maps. Thanks for the rubberducking (at)everyone 🙂


like sometimes I might have (def other-color {:red :blue :blue :red}) and use it like a function


(other-color :red)


thats the other way round


I really like how all the collections are also functions. One that feels most elegant to me sometimes is using sets as functions


Quick dumb questions about Figwheel and repls. I use Atom text editor and have proto-repl up and running well. Getting into cljs and figwheel. Do I need two repls, one for figwheel and one for clj?


there's probably a way to avoid that, but it wouldn't make things better


two separate repls is the thing that makes the most sense


How do you go about sending code to the right repl?


I'm not sure how any of that works in atom


Look like Luminus thinks of that with some sidecar stuff making the switch back and forth pretty easy.


Though I'm having some cider/piggieback errors.


guys, I'm looking for a cheap/minimalistic way for passing encoded-data(json) to a shprocess which I lunch via clojure/sh.


are you asking how to generate json?


I have been thinking on following options: 1) env variable. 2) pass it as argument to shell of clojure ( I think that :in do it)


@noisesmith nope I have already json byte which i decode.


Imho, the 2nd option might be the best. But I was just asking in case...


option 2 is the only one likely to break things in weird ways


because there's no quoting layer issues with env or files, there is with command arguments


there's also stdin (unless the process also has to read other input)


yep, I think it could read aother input.. 😞 by env. variable I was thinking if it might a problem if I pass to much data on it?


oh wait, do you mean ?


if so, there's no quoting issues, just make it an arg


there's also a clojure command you can run in shell scripts, I probably got it mixed up


ah ok.. thx/

noisesmith19:06:24 doesn't run sh - it directly does a process invocation without using a shell


(confusing name)


so it doesn't do globbing / interpolation as a shell would, which means no escaping needed for args

clj 4

There are length limitations on the command line, and probably for env variables, that are higher if you use a tmp file instead, but maybe the size limits on command line args is high enough for your use cases.

clj 4

Thx. I think I will be usz a tmp file


I hacked a little with stdin and sh but it has some limitations. In theory I want to give the possibility to user to create their own clients with some data .


Looks like the Slack servers are up again.


Is this primed correctly for running / evaluating the code ?


@paulgureghian Yup, the load file operation completed -- the REPL shows the result of the last form evaluate, in this case the defn of -main (whose result is the Var name). Yay!


Now you can type code into your main core.clj file and evaluate each form into the REPL!


How to eval and output the "I dont do a whole lot ... yet" ?


I thought it was supposed to also output to the terminal ?


I am not sure this would work, but if you typed in a form (-main) and evaluated it, I think it should cause the function -main to be called. Where the standard output goes to in the Atom environment, I do not know.


Note that typing such a (-main) form into your core.clj file and leaving it that way is probably a bad idea, because then loading the file itself would cause the function to be called. Often people will have a block of text at the end of a Clojure source file like this:


;; forms here that I sometimes like to evaluate during interactive
;; development, but do not want to be evaluated when I load this file.




Does the spoken text part get eval'd and outputted ?


If you mean the lines that begin with ;;, all text after ; up to the end of the line are comments in Clojure.


No, not the comments. the stuff between " "


If you cause the function -main to be called, it should execute the println calls, which should cause output to appear wherever standard output is configured to go in your setup. I don't know where that is in your Atom environment, as I haven't used Atom.


What do you use ?


I thought since I have the REPL server in the terminal, it would output println there.


I am a becoming-a-greybeard who uses Emacs and vim (and vi before vim existed), and have such muscle memory for them that it will take some odd occurrence to make me seriously consider switching, but that doesn't mean I would recommend it for someone learning Clojure.


Did you try typing in (-main) and then put the cursor just after the ) in that, and then I assume there is some menu item for your Atom setup that "sends this form to the REPL and evaluate it" (or some similar words)?


Change the cursor position in the "chlorine REPL tab or the core.clj tab ?


Sorry, AFK for a while there. Maybe even more directly, if you click in the REPL tab and type (-main) and enter that, it should call the function, and maybe you see the standard output in that window.


That should hopefully answer the question of where standard output goes in your setup.


But for long term development, it is highly recommended that you type forms into a file, like the (comment ...) part of the file core.clj that I mentioned earlier, for long term saving of things that work, and because often when trying things out interactively you find you want to make a small addition or modification to something you evaluated earlier.


I thought that just by having the repl server it would show there as well.


I can't tell you where it will go, as I do not know. Have you tried it and seen what happened?


Your computer won't break.


@andy.fingerhut No, Chlorine's REPL panel is readonly -- you do not type into it.


Ah, my bad. Sorry for being misleading there. I should listen when it comes to Atom, rather than suggest 🙂


If your cursor is just next to either parenthesis in (-main) in the source code editor then "evaluate block" will run that function (using ctl-, b if you followed my advice to set up the keymap bindings).


But you type expressions into your source code -- and Andy's recommendation to put exploratory code inside a (comment ...) form is a good one.


Are those key-map bindings part of the deps-edn or the files and folders in your repo ?


The keymap bindings from the Chlorine package page, that you can install in Atom. I explained how to do that yesterday.


Specifically I said to use the second set of key bindings shown (i.e., not the vim ones, which are listed first).


If you bring up the Atom command palette and type keymap, you'll see Application: Open Your Keymap


You should be able to copy'n'paste the Chlorine key bindings from the Chlorine package web page (on into that file at the end, then save it -- and they should take effect immediately.


ok. ill do that. im using the load command and its working, but its outputting to the editor and console. i thought it was also going to show in the terminal as well ?


No, the Terminal REPL is just to get the Clojure process started for Chlorine (although you can play with code in the Terminal REPL outside Atom/Chlorine if you really want).


ok. things are starting to come together now.


I just gotta find clojure stuff to put in core.clj and eval it ?


the bindings from the atom io page has a duplicate and its faulting on the copy paste. can i use a different key-value pair ?


Just remove the duplicate and save the keymap. ctl-, c -- I'll let Mauricio know.


I submitted a pull request, to change source-for-var to be bound to ctl-, S instead. Thanks for catching that!


I kept both, but changed the letter


I have already caught two issues in atom - chlorine


Beginners try stuff that more experienced folks know not to do 🙂


When can I refer to myself as a Clojurian ?


😆 Whenever you feel like it -- you've become a familiar character on this Slack already!


Some good peeps here


Clojure folks are enthusiastic and like to help more folks become Clojure folks.


I am already a Ruster, Gopher, Pythonista, Javer, and now a Clojurian


Just hit the 'ctrl' key then the 'f' key to load file ? doesn't seem to work


All of those key bindings are control-comma then the letter: two separate key presses -- first control + comma together, then release, and then press whatever character is next. That's what ctl-, f ctl-, b mean.


OK, I should be listening not typing right now, but for most IDEs at least the definitions of which keys do what in the IDE are in an IDE-specific file, in this case an Atom-specific file. Unless your IDE was actually implemented in the Clojure programming language, they wouldn't be inside of a deps.edn or Clojure source file.


Yeah. I gotta get my hands dirty with the keybindings


Would VSC also need keybindings or can I use its run button ?


I don't know VSC. Does your Atom setup have any menu item anywhere with a description similar to "evaluate block"?


When your cursor is in the source code editor.


I am betting there are a bunch of menu items, but perhaps the ones specific to Clojure are grouped together somewhere.


Nothing. I need to do the binding stuff. or use that Clojure specific IDE


You are right. I found the Chlorine commands.


If one has a name similar to "evaluate block", then if you move the cursor in the source code editor panel to just after a form like (-main), or any other expression you want to try to evaluate, and then select that menu item, it might work. The part that I do not know is whether it is important for the cursor to be just after the code you want to evaluate, or somewhere inside of it. Just after is a guess on my part.

Drew Verlee22:06:30 When it says "without source" can someone elaborate on what that means? Source files? Wouldn't those be a jar/.class files?


right, if you want to deliver an application without source, you need to aot compile and ship the resulting class files


Or a .clj file


the clj file is the source


and yeah, usually you'd put the class files in a jar, but you don't technically need to


@paulgureghian I mentioned a day or three ago that Clojure compiles each expression just before executing it, and normally the compiled result goes in the running JVM process's memory only, not written to the file system. drewverlee is asking about the capabilities that Clojure has, not needed by everyone, to actually write JVM byte code files to the file system.


It is possible to use Clojure in a deployed application without ever using this capability, if you deploy Clojure source code instead, and have it compiled shortly after the JVM process begins.


Also you don't need class files to make a jar file


So packaging as a jar file or not is on a separate axis from producing class files or not


@paulgureghian I was wrong on another of my guesses about Atom earlier. The Chlorine package does not create any Clojure-specific items in the menu. Creating the key bindings is recommended. If you haven't done that, I now know the steps for how to do it.


I think I'm good on that front. lets see ...