Fork me on GitHub

just a heads up... is has a coupon code order66 that will get you 30% off on any ebook, audio book or screencast!


I just got Clojure Applied ($25.00) and Web Development with Clojure ($24.00) for a total of $34.30. Pretty good deal if you ask me 🙂

bananadance 8
👍 4
🙏 4

Thanks @UAW40E21F... just got myself 3 books for < $55! Worth the investment!

👍 4

what did you get?


Thanks a lot! I was just planning to buy some books from there 😂


Programming Clojure, Web Development with Clojure & Clojure Applied @UAW40E21F


ah cool! We have the same Clojure library now haha


Just a week back I had already purchased Getting Clojure by Russ Olsen


I thought about getting that one.. but am still on the fence about it. I'm afraid it will be too much like Brave and True level... I get bored reading pretty easily... so I needed project based books to keep my mind engaged and see how it all goes together from a bigger picture....


Getting Clojure seemed like it was based on "why" not "how".. I also figured that after Programming Clojure I wasn't sure how much more (or different) it could offer


@UAW40E21F I guess we all have our own ways to learn ... myself I like example based books ... and we need to read books which panders to our learning style 🙂


oh for sure... everyone learns differently! 🙂

☝️ 4

The question now is .. which one should I read first? I've read Programming Clojure and got tired of reading and moved on to doing Codewars and actually writing code... which one is a good follow up?


4clojure is a nice set of exercises


Right, so I have a “running with scissors” kind of question


Given a simplified example wherein: 1) I have a type X defined with deftype 2) with a :volatile-mutable field next which will only ever contain type X itself (or nil) 3) and a protocol function implementation that walks down the chain of Xes via said next field and loop-recur …is there any way I can set! the value of next field on an object down the chain that is not “self”, but I know that it is going to be of type X? (Still in that protocol function, inline implementation)


user=> (defprotocol p (f [_ _]))
user=> (deftype t [^:volatile-mutable a] p (f [_ x] (set! (.-a ^t x) a)))
user=> (let [t1 (t. 1) t2 (t. 2)] (f t1 t2))


@gadfly361: Working with sodium and implemented the rating component. How do I get it's value? (-> % .-target .-value) returns nil (


When I want to have primitive with metadata should I just use ^:my-meta [a] and use it like 1-ary tuple?


@mhsmit This is for using soda-ash (instead of sodium, CC @deg)

    {:max-rating 5
     :on-rate    (fn [_ rating-map]
                   (let [{:keys [maxRating
                                 rating]} (js->clj rating-map
                                                   :keywordize-keys true)]
                     (js/console.log "The maxRating is" maxRating)
                     (js/console.log "The currrent rating is" rating)


@mhsmit Take a look at Sodium's value->event-fn and value->atom-fn, both in core.cljs. They exist to sugar around the need to grab the second value from a Semantic-UI component.


FWIW, I hate those two function names, and would consider renaming if I get any better suggestions.


@gadfly361 thanks... 😄 .. I did this (get (-> %2 js->clj) "rating")


hi! I'm a little familiar with the language already. I want to know now how to structure a project in terms of business logic. How do you map the entities (if there is such a thing?). I mean what is the parallel of object oriented mapping of classes in Clojure?


and if there is any material that I can study about that

Alex Miller (Clojure team)14:06:03

I wrote a lot about domain modeling in the first chapter of Clojure Applied if that’s of interest (some of that I would love to revisit now in light of spec’s release)


How the modeling works in Clojure then?

Christian Johansen14:06:41

Maps with specs 👌


@aj07mm Consider, here's a model for a customer contact: {:first-name "Somebody" :last-name "Something" :email ""}


A vendor contact: {:first-name "Somebody" :last-name "Something" :email ""}


A sales lead: {:first-name "Somebody" :last-name "Something" :email ""}


Now if you have a full-name function, it just works with Customer Contact, Vendor Contact, Sales Lead, etc.


(defn full-name [data] (str (:first-name data) " " (:last-name data))


do you usually define it as a template somewhere in the project, more like a class?


It's possible, but often that's a premature optimization, at least in the early stages of development


The trick is to try and move your point of view from "I need to define all the nouns" to "I need to define all the verbs."


The OOP perspective sees everything in terms of defining a bunch of nouns with built-in behaviors, but that's inherently unnecessarily complex.


The FP perspective is to define the verbs, i.e. how does your data need to be transformed to accomplish your objectives.


I recommend namespacing your keys also. So instead of :first-name, maybe :user/first-name or :your-product-name.user/first-name if it's the first name of a user in your system. Another example would be instead of :id, which could be anything, make it specific like: (if that's what it's referencing).


@manutter51 that was clarifying!

🙂 4

I've found that a lot of your modeling actually happens outside of your code, such as in your database. Defining your tables (if you're using SQL) tends to define, or at least strongly guide, your data model in the code.


how do you usually represent the relationships?


It depends, but you can do things like nested data structures (line items on an order, for example).


I mean, that is not a good question


what is the default database for a clojure project?


a relational one? or there is some other model that suits the FP way of thinking?


Whatever you choose, you can use SQL, NoSQL, flat CSV text file, whatever


Datomic is pretty interesting, but I wouldn't start with that if I were just learning Clojure. SQL works just fine, or Mongo, or whatever you're already familiar with.


I'm questioning because of the talks of Rich on Datomic


try Datomic if you really want to go whole hog


Definitely worth playing with Datomic.


thanks everyone for the anwsers!


datomic is really nice with clojure, but quite expensive if you're using it for a commercial project


Personally I'm using Postgres but that's because I'm also using PostGIS which I can't really do through Datomic.


@jgh it’s free now actually


unless you want support


I thought it was like $5000/yr after 1 year if you want updates


“support” 😄


ah well updates are important for databases heh


yes and no


although i guess datomic isn't really the database


for Datomic, there’s not a lot of major bugfixes anymore, it’s more around bringing in new stuff


and yes, the actual data layer is something else


When developing an SPA with Clojurescript and Reagent, what is common practice for getting the initial state of the app from the server? Do you do an ajax request back to the server on page load or is there a way to have the initial state preloaded in the atom when the user first requests the page?


I've used a combination of rendering script tags setting values you can access into the template for config, and Ajax or websockets for runtime data


So rendering the data in an html tag then populating the state atom with that?


Could I create a <data> tag that contains an edn string then just read that into the state atom?


why not just make an ajax call on load? seems much simpler and gives you a lot of control over how and when data gets loaded


@U8ES68TGX that's most likely what I am going to do. I just didn't know if making a request for the page then making another request for the data was considered inefficient because it is making 2 requests


@UB16T3Z6F if you are worried about that kind of optimization you’re going to have to get really sophisticated because you’re talking about optimizations on the order of dozens of milliseconds. that’s a whole new world of hurt.


just keep it boring. you’ll be much happier.


oooh ok. thank you @U8ES68TGX


I'm all for keeping it simple but I don't want to put what might be considered bad practice into the code of a project


no its totally normal to make an ajax call to get user data once the SPA is loaded


but it sounds like it's perfectly fine


specifically I use a script tag for special tokens that should be known on load - just a few magic strings


everything else is just ajax / websocket


just chiming in because why not - when dealing with data already stored in a session (such as a returning user) i feed that right into the constructor of the app. for example


@U051SS2EU out of curiosity, what's your go-to web socket library (if any)?


in the past I used sente


i've been having major issues with sente, mainly a 5 second timeout after a first reconnect (aka user has authenticated). have you come across that?


but I no longer work on a webapp and haven't used the latest sente


hmm, okay. i must have wired something backwards. thanks. 🙂


is there a way to look at the resource paths when lein run is invoked? I'm having trouble loading my log4j.xml in the resources directory


The resources are just entries in the classpath

Alex Miller (Clojure team)15:06:27

(System/getProperty "java.class.path")


If you are running from a jar, make sure you are using io/resource and not io/file


(if accessing it directly)

Karol Wójcik19:06:29

Hi Clojurians! I am trying to develop simple command line. I am receiving following error:

Compiling reader.file
Compiling reader.cli
java.lang.IllegalAccessError: wrap-main does not exist, compiling:(app.clj:1:1)
Exception in thread "main" java.lang.IllegalAccessError: wrap-main does not exist, compiling:(app.clj:1:1)
	at clojure.lang.Compiler$InvokeExpr.eval(
	at clojure.lang.Compiler.compile1(
	at clojure.lang.Compiler.compile1(
	at clojure.lang.Compiler.compile(
	at clojure.lang.RT.compile(
	at clojure.lang.RT.load(
Here is my app: I am unable to spot where I commit the mistake. Could you please help me?


I'd expect process-args to blow up if :help wasn't in the opts because the cond is incomplete, but those files look like they should load at a first glance


did you get that error when first starting the app, or when reloading after an edit?


what command showed this error?

Karol Wójcik19:06:00

both lein uberjar and lein run -m -h


for some reason your reader.cli ns is broken - I can't see why though - it loads without error but doesn't define anything


this likely isn't the source of the problem, but those are all terrible namespace names - the point of a namespace is to differentiate something, and and reader.cli etc. are extremely generic and high likelihood to clash with other projects that picked bad namespace names


it's possible that something else on your classpath in fact already defines reader.cli namespace and doesn't have anything in it, but it's unlikely welp, lol


It's definitely a name clash -- I renamed cli.clj to wrap_cli.clj (and changed the ns to reader.wrap-cli and it all worked.


So there's something, somewhere defining reader.cli and clobbering your namespace.


right, pick namespaces that do the job required of a namespace :D

Karol Wójcik20:06:42

Thank you, thank you! I simply do not know how to correctly name them. It's because I came to clj world from the js.


the point of a namespace (as with a js package) is to differentiate things. a generic name is a poor one because of the random likelihood that some other project already used it


a js package named "code" or "app" would have the same problem


the java convention is to reverse a domain you own and use it as a prefix, and I often go with that, eg.

Karol Wójcik20:06:39

Ok thank you for your effort in teaching me. I really appreciate it. I will do like you told me.


Using your GitHub username is often unique enough (, fierycod.reader.cli, fierycod.reader.file)

👍 12

Looks like it's something in Leiningen -- if I fire up @kwcharllie379’s project with clj, I can load the namespace just fine.


It also loads fine in Boot.


Hmm, I'm going to take back that assertion about Leiningen -- since I can create a fresh app, add reader.cli as a namespace (without tools.cli) and it loads just fine...

Karol Wójcik20:06:43

Thank you @seancorfield. Last question is it possible to have a namespace named with dash? Like fierycod-app?

Karol Wójcik20:06:13

I know that it's possible to name it like fierycod_app but I am wondering if dashes are also supported


Yes, namespaces with - are fine -- but the filename must have _ in that position.


so src/fiery_app.clj would have (ns fiery-app)


(although single segment namespaces should be avoided)

Karol Wójcik20:06:35

Ok but what if I want to have src/some-namespace/core.clj

Karol Wójcik20:06:49

how the ns will look like then?


No, the file would have to be src/some_namespace/core.clj with (ns some-namespace.core ...) in it.


_ in filenames, - in namespaces.

Karol Wójcik20:06:54

Ok i see so there is no possibility to have - in filenames


I figured out the reader.cli issue -- you have test/reader/cli.clj which has the same namespace as src/reader/cli.clj so it is overwriting it!

Karol Wójcik20:06:15

I must say that Clojure community is very active and I'm really glad that you're so helpful and so kind for others.

👏 8

Test namespaces should also be unique within your project. For src/reader/cli.clj you would normally write test/reader/cli_test.clj with (ns reader.cli-test ...)

Karol Wójcik20:06:42

Ok understand now. Will note that. Thanks one more time 🙂


In the #beginners channel, we love helping folks who are just learning Clojure!

👍 16
❤️ 20
🚀 16
😀 4
clj 16
Karol Wójcik22:06:23

Got question about LOC of the core.clj. Why the code is so huge and it's not separated into various namespaces? Is there a rationale for that?


Some of the clojure.core namespace is actually spread across multiple files, via calls to "load", so it might even be more LOC than you are currently thinking. I suspect the idea was that everything in the clojure.core namespace is to be considered as a fairly large standard library available in all Clojure programs without having to have another require/use in your code.


Most of those functions I can think of are fairly general-purpose data manipulation functions.