Fork me on GitHub

[:app] Configuring build. [:app] Compiling ... To quit, type: :cljs/quit [:selected :app][:app] Build completed. (551 files, 1 compiled, 0 warnings, 6,73s) No application has connected to the REPL server. Make sure your JS environment has loaded your compiled ClojureScript code. Happens right after starting emacs and issuing cider-jack-in on a project that works fine and just fidling around in a .cljs file. So weird.


neither emacs restart or os boot fixes the issue


That’s a cljs repl starting up. It’s basically a jvm program that evaluates your cljs output in a JavaScript engine. It’s saying all is ready but you need to connect to a JavaScript engine. Usually by loading your app in a browser or running node on your generated cljs script

Michael Stokley03:02:23

this is a silly question but back in java-land, i'm used to writing objects with methods that refer to some state that object was originally initialized with. an example might be a client that requires some broad configuration and then exposes a few methods. is there a comparable pattern in clojure?

Alex Miller (Clojure team)04:02:31

you can close over state when you construct a function or reify an interface

Michael Stokley04:02:05

like this?

(defn f1 [a b c d] ...)
(defn f2 [a b c d e] ...)

(defn make-client [a b c]
  {:f1 (partial f1 a b c)
   :f2 (partial f2 a b c)})

Michael Stokley04:02:14

that's just a naive guess - would something like that be idiomatic?


Ok, sorry, said yup and got distracted


A common pattern is to do this:


(defn make-client [option1 opt2 opt3 ...]
  {:option1 option1
   :option2 opt2

(defn get-items [client-map some-other-arg ...]


So say you had the Java class:

public class Client {
  private int x;
  private int y;

  public Client(int x, int y) {
    this.x = x;
    this.y = y;

  public method1() {...}
  public method2() {...}

Michael Stokley04:02:57

the "client" here is just a hash-map that groups the common args, looks like


So the above class would become:

(defn make-client [x y]
  {:x x
   :y y})

(defn method1 [client] ...)
(defn method2 [client] ...)

Michael Stokley04:02:43

that's too simple

Michael Stokley04:02:55

i love it. thank you!


And the difference will be that, the map is immutable. So your defns are not really methods anymore, because methods are assumed to mutate the fields. In our case, if you only need to read from the fields, you just read what you need from the map. But if you need to modify the fields, you would instead return a new map which is the given client map with whatever changes applied to it.

Michael Stokley04:02:32

i feel like another important difference is that we've mostly eliminated the abstraction that is a stateful "client"

Michael Stokley04:02:47

the fact that it's still called a 'client' notwithstanding


Ya, it depends. If the things in your client map allow you to make a remote call to a mutable database, there's still some state in that sense, but it's moved away from your "client" object, and is now where it should be, in your DB for example


And what's nice with this, is you can now call it like so:

(-> (make-client 10 20) (method1) (method2))


Given in this case your methods were to return back a client-map as well.


Which is often the case. Like everything that would be void in java, in Clojure would instead return the client-map


So you get fluent interfaces for free


And if you want to group the client and all its methods into one logical place, then just create a namespace for them and shove it all there 😛

💯 4

This pattern can extend quite far, if you ever need some polymorphism, you can make the map a record, and put the functions inside a protocol. Or keep it a map, but modify some of the methods into multi-methods, etc. Lots of options for handling all possible scenarios


If people find they are confused about what a client contains, you can create a spec for it. And on and on...

Michael Stokley04:02:19

thank you again, this is great


No problem. It can be hard in the beginning to peel the onion. I came from OOP as well, and I think your question is just normal, everyone who does has it, we're almost too used to complexity 😛, that we find it hard to think without it

Michael Stokley04:02:30

really, for me, the worst part is that the concept of a "client", as an object with state and behavior, is accomplishing nothing. the pattern of simply grouping together the data that happens to be shared gets you all the practicality and none of the useless abstraction

👍 8

@U0K064KQV I was going through this thread as I am in general interested in patterns. About treating a namespace as a poor man's class, do you actually use it in production code? I think the aspect of multiple instances of client class with independent states is lost with this approach. All you have is a global shared state.


@UJRDALZA5, if I understand the thread, I think that would be true if there were defs in the namespace containing the state. But I don't think he's suggesting that. Rather a map contains the state and is passed to each fn. So there can be any number of maps (OO instances).

👍 4

You are right! I assumed the all in "shove it all there" included state.


Ya, @UBRMX7MT7 is correct. The pattern here is that "make-client" acts as a constructor for instances of your data.

👍 4

This is really interesting to me. Not really seeing the difference between getting values (“state”) from a function vs. from a variable of some kind. In both cases it’s a symbol that evaluates to values. Help? 😳


But, some use cases in OOP make use of static fields. And in clojure, those would just be global defs


@UCW3QKWKT Hum... imagine you have a Contacts app where the user can create new contacts.


You can't just do:

(def contact
  {:name "Joe" :phone 2223345})


Because, the user will be adding contact dynamically, at runtime. They could add from 0 to n of them, who knows


And you can't predict what name or phone the contacts are going to have. So what you need instead is a way to both parameterize your contact map, but also possibly create many of them, all with different names and phones


You can do that with a function


(defn make-contact [name phone]
  {:name name :phone phone})


So now when the user press "Add contact" and enters a name and phone on the form and clicks submit, you can use make-client to dynamically create a new instance of a contact


Does that make sense?


With a def, you need to know the values ahead of time, and how many unique contact you'll have.


But with a defn, you don't, you can wait till runtime and then use it to create as many of them with whatever values as you want.


But we can have a (def contacts (atom [])) . For any non-trivial apps, I think there will always be a giant state map anchored to some namespace somewhere.


You often don't need one actually


A lot of apps will store the states straight into a DB of some sort. And some others can just carry around state through from start to finish, including long lived apps by using recursion


But yes, some will. But that would be in the containing component.


DB is just an extension of what I said. The data has to be anchored to something. But I am very curious about the other thing you said.


And some others can just carry around state through from start to finish, including long lived apps by using recursion Please expand on it if you have the time.


For example:

(def contacts (atom []))

(defn on-new-contact [name phone]
  (swap! contacts conj (make-contact name phone)))


But a def is still anchored. I thought there's a clever trick here.


Sorry, my example in slack was for: "But yes, some will. But that would be in the containing component."

😀 4

The link to clojureverse shows how to carry over state


Guess I am typing too quickly.


And me too slowly 😋, doing all this from a phone is hard


With the functional approach, there are even some DBs that are implemented like that. If you ever heard of a log store, or an append only store. Basically, you keep carrying last state and making new states out of it, never mutating, and once in a while you just delete the history you no longer need to save on memory/space.


Nice explanation there in the linked article! You can encapsulate even more by passing a make-board fn in there instead of the init-board. But you might already be doing that, since you only shared the loop/recur part.


Yup, definitly. If your initial board needs to be parameterized that be a good idea. Like say on "New Game" you took some options, type of game, size of board, who knows

Michael Stokley05:02:43

is there a naming convention to indicate that a given var might be nil or absent?


A point of terminology, a var is something created by a def, a global definition, those are pretty much never nil


A name bound by let or a function in clojure is called a local, and those are indeed sometimes nil

👍 4
Michael Stokley05:02:37

in scala we're always so explicit about values we expect to always be present and values we might reasonably expect to be missing - does lisp/clojure have a similar approach?


So, the way its done in Clojure, is that absence is represented by the key being missing from the map


You can do that, because of how dynamic the data constructs are


So you have two concepts. First is the data is missing, that would be represented as the key isn't even there. The next one is, the data is there, but its value is nil. That would be represented with the key being there but having a value of nil


So say you had person maps, and sometimes those have a name and an address, sometimes only an address.


You would have:

{:name "Joe" :address "123 bla"}
And if its a person without an address:
{:name "Joe"}
And if its a person where an address was given, but it was garbage, or it was submitted as blank, or the user ticked the box saying "rather not say" you'd have:
{:name "Joe" :address nil}


Oh, and to specify the semantics of a particular map, Spec would be used. You can say which key are mandatory, which are optional, and which are allowed to be nil or not


Though sometimes, simply doc or comments are used, or even its just not specified if its kind of obvious from context


@michael740, I have not seen any such convention in Clojure code.


I have a failing test inside a cljc file, when I run lein test it does not catch the error. But in the console I see that the file was tested. I should do something different in the setup of clojure.test for this situation?


@iagwanderson Not sure I'm following you -- but it seemed to work when I tried it

(! 779)-> lein new app bartuka
Generating a project called bartuka based on the 'app' template.
(! 780)-> cd bartuka/
(! 781)-> mv src/bartuka/core.clj src/bartuka/core.cljc
(! 782)-> mv test/bartuka/core_test.clj test/bartuka/core_test.cljc
(! 783)-> lein test
lein test bartuka.core-test

lein test :only bartuka.core-test/a-test

FAIL in (a-test) (core_test.cljc:7)
FIXME, I fail.
expected: (= 0 1)
  actual: (not (= 0 1))

Ran 1 tests containing 1 assertions.
1 failures, 0 errors.
Tests failed.
(! 784)-> echo $?
(! 785)-> 


that's exactly the problem. But, if yours is working fine, it should be a problem with my current setup


I have added :test-paths ["test/cljc", "test/clj"] to my project.clj and nothing else 😕


how do you know it is failing? Is it possible only a cljs branch fails and you aren't running tests in that environment?


found it! Look at the next example, when I use the use-fixtures it passes with 0 failures.

(ns mamulengo.bartuka
      [(:require [clojure.test :refer [deftest is use-fixtures]])]
      [(:require [cljs.test :refer-macros [deftest is use-fixtures]])]))

  {:before (fn [] "ok")
   :after (fn [] "go")})

(deftest please-work!
  (is (= 0 1)))


the api of use-fixtures is different for both environments. I would expect some error.


actually, it seems like the test was not even recognized, which makes sense because it breaks before. Only hard to catch


Ah, yes, the Clojure code -- run by lein test -- would try to invoke that hash map as a function, passing in the test to be executed.


so it would run ({:before,,,} please-work!) which will "run" but not call please-work!


because that's (get {:before,,,} please-work!) which just returns nil


I'm surprised use-fixtures differs between Clojure and cljs like that...


yes, right? This one was tricky.


thanks for the help!


If you write a function that accepts a test function as an argument (and calls it), that will work for both clj and cljs.


Supporting that :before/`:after` format would be a nice enhancement for clojure.test.

clj 4

I like how readable this approach is


I'll go ahead and implement this in expectations.clojure.test tho'...


also, just minor thing but [clojure.test :refer [deftest is use-fixtures] should work in both environments. don't need to reader conditional that one


I didn't know that. I thought I needed the reader conditional because of the macros.


cool! Thanks!


Hello there, What do you guys use to set up a rest api? I have seen people use Compojure and Ring but would like to know if it is the best option


best options are hard to tell rsrsrs. I like reitit now o/// #reitit


Okay, maybe best options is a little too much to ask, my bad hehe I'll give this one a look, thanks!


I use reitit too


For what it's worth, I've put up a little twitter bot that tweets a random clojure function of the day. You can find it here: It's new, doesn't do anything clever, but it's kinda cute 🙂 Enjoy!

👍 24

That's quite useful actually. Sometimes I forget the less used fns.


I swear I didn't see that thing before I wrote the script 🙂


It was a massive co-incidence!


I saw your posts too and I was like "wow!"


I did see the idea here before:


In the definition for comp there’s a block for composing two functions. I’m wondering why it handles 1, 2, 3, and n arguments differently. Couldn’t it just use apply for any length?


it is a performance optimization


Ah okay.


So apply is slow?


not slow, just slower


@tylertracey09 If you look at the source of several core functions, you'll see a similar "unrolling" of the first few arities -- as a performance optimization.


Good to know.


Can anyone recommend me a clojure book for learning purposes? I do best when I have some exercises to do as well


@tylertracey09 There's Clojure for the Brave and True (available for free online as well), Getting Clojure, Living Clojure -- those are the three that come to mind. Not sure which of those actually have exercises in them.


For exercises, 1) Clojure Koans and Exercism for basic staff, 2) 4clojure for slightly harder puzzles.


Might be just me, but as I know another language already (Java), the 1) Guides and 2) References section on were excellent resources for me. Books were too slow.

Behrokh Farzad20:02:32

has anyone had a problem with downloading tools.deps in IntelliJ IDEA settings? I keep getting the following error Cannot execute, please download tools.deps in Settings: Cannot execute, please download tools.deps in Settings


Hi Behrokh, not sure if you already solved the issue, but it's a problem with Cursive and it's fixed in EAP only. If you don't want to download that, you can fix like this: Go to Build Tools -> Clojure Deps: Use private repo: ID: Central / URL: Then refresh and download.

👍 8

thanks @U7JCZJR0W I was suffering the same.

Behrokh Farzad19:02:27

thanks @U7JCZJR0W it’s working now.

Guillermo Ithier20:02:11

Hello Clojurians, I'm having a problems getting access to a zero-token through a POST so that I can use it in my buffer to perform an authentication request. Now the URL here's the link ; following along a video 'Microservices with CLojure'.  I'm lost on how to use this site to create a way to well, access to a zero-token through a POST so that I can use it in my buffer to perform an authentication request. Here is the relevant functions that calls the outdated api: (defn auth0-token []
  (let [ret
        (client/post ""
                     {:debug false
                      :content-type :json
                      :form-params {:client_id (System/getenv "AUTH0_CLIENT_ID")
                                    :client_secret (System/getenv "AUTH0_SECRET")
                                    :grant_type "client_credentials"}})]
                                  (json/parse-string (ret :body))))

Jimmy Miller20:02:00

People might be able to help more if you describe what is and isn't working. When you run your code what does it do that you didn't expect? What do you want it to do?

Guillermo Ithier20:02:43

Can someone help me with this? Thank you in advance 🙂


I imaging (:headers ret) will have some info there


Is emacs the go to for clojure?


if you already know emacs yes. if you're just learning clojure you probably don't want to start learning both emacs and clojure. in which case I personally recommend Cursive for IntelliJ. Some others like VSCode with Calva and Atom


@tylertracey09 If the editor/IDE you are already using supports Clojure, I'd stick with that while you are learning Clojure. What are you using now?


I use VSCode


Really all I want is to be able to evaluate an expression in line


I guess that’s what folks use the REPL for, but I saw a screencast where the guy was using emacs and he had a command that would evaluate the expression under the cursor or something


calva with VSCode can do that


Oh neat I will check into it, thanks


I think I’m using a different plugin atm. I will try Calva instead


Out of curiosity if you use emacs were you using it before clojure? I remember reading something about how emacs was implemented with a LISP and so you can write extensions using LISP as well. Is that what got you folks into it or did you migrate because of clojure tooling at the time?


I used Emacs decades ago, back in the 17.x/18.x days. I moved away from it round about 19.x I think. I started using C++ IDEs then Java IDEs. Eventually, after a bunch of languages, I ended up in Clojure and went back to Emacs because it was the "best" / "most popular" -- and was shocked that it hadn't changed much in... twenty years?


I went back and forth between Emacs and other editors for a while, when learning Clojure, then settled on Emacs... until I saw Atom/ProtoREPL at Conj one year! I switched to Atom and never looked back. ProtoREPL is no longer maintained (and I think it's actually broken in recent Atom releases?) but I switched to Chlorine over a year ago and I love that combination (Atom/Chlorine, plus Cognitect's REBL data browser, with a simple Socket REPL -- no nREPL etc).


curious, why not the socket prepl?


@U4R5K5M0A I think Chlorine starts a prepl once it has a plain socket connection.


The socket REPL is nice because you can a) telnet/netcat to it from your phone b) connect to it via unrepl/unravel c) connect from Chlorine ...


it is a time machine


I'm honestly not sure how much knowing clojure would help you writing Emacs Lisp. they're dramatically different


visiting an alternate future branched off from this world in the 70s


I wrote a heartfelt cover letter to David Nolen and the other folks over at Vouch. Here’s hoping I get the chance to learn from some experienced clojure developers