Fork me on GitHub

So I keep getting this error:

Caused by java.lang.IllegalArgumentException
   No matching ctor found for class javafx.scene.image.Image
. But I know that class exists, what's going on?


@donyorm what's the line you're using to construct it look like? it's saying you don't have a constructor of that arity/type signature


Yeah that was it. I was pasing a vector when I meant to pass a vector of vectors, and that resulted in the constructor being passed a character instead of a string


oh, I thought it was where I imported it


I'll check that


it could be the import statement if the import statement is incorrect-enough syntax


Hi peeps. I'm doing some SQL experimentation. I'm successfully connecting to my DB and querying my data. If I print my data, I see the output, but when I use map on it to do things like group-by, I only see the the name of the stored result (e.g. #object[clojure.core$map$fn__4781 0xd76b3 "clojure.core$map$fn__4781@d76b3"]. If I wrap the map call in a print call, I see something like #object[clojure.core$map$fn__4781 0x7664aa clojure.core$map$fn__4781@7664aa]nil. How would I go about printing the output of the map?


(def initial-data [(jdbc/query db "SELECT c.companyID, c.companyName, d.departmentID, d.departmentName
                    FROM c
                    INNER JOIN dbo.companyDepartment cd ON c.companyID = cd.companyID
                    INNER JOIN dbo.department d ON cd.departmentID = d.departmentID")])


(print initial-data) results in:


query is eager by default. So initial-data is a vector of one element, the sequence of results from the query.


[({:companyid 1, :companyname Google, :departmentid 1, :departmentname DevOps} {:companyid 1, :companyname Google, :departmentid 2, :departmentname SysAdmin} {:companyid 1, :companyname Google, :departmentid 3, :departmentname Marketing} {:companyid 1, :companyname Google, :departmentid 4, :departmentname HR} {:companyid 2, :companyname Microsoft, :departmentid 1, :departmentname DevOps} {:companyid 2, :companyname Microsoft, :departmentid 2, :departmentname SysAdmin} {:companyid 2, :companyname Microsoft, :departmentid 3, :departmentname Marketing} {:companyid 2, :companyname Microsoft, :departmentid 4, :departmentname HR} {:companyid 3, :companyname Amazon, :departmentid 1, :departmentname DevOps} {:companyid 3, :companyname Amazon, :departmentid 2, :departmentname SysAdmin} {:companyid 3, :companyname Amazon, :departmentid 3, :departmentname Marketing} {:companyid 3, :companyname Amazon, :departmentid 4, :departmentname HR} {:companyid 4, :companyname Apple, :departmentid 1, :departmentname DevOps} {:companyid 4, :companyname Apple, :departmentid 2, :departmentname SysAdmin} {:companyid 4, :companyname Apple, :departmentid 3, :departmentname Marketing} {:companyid 4, :companyname Apple, :departmentid 4, :departmentname HR})]nil


I was noticing that and was wondering about it


Bear in mind you have a vector of sequences there.


Here is an example of a map that I'm playing with: (map #(group-by (juxt :companyName :departmentName) :initial_data))


(map f) returns a transducer


You have a keyword :initial_data there which is not your defined symbol initial-data above.


did you mean (map #(group-by (juxt :companyName :departmentName) %) initial-data) perhaps?


(and I don't think you want the [ ... ] in the initial-data def in the first place -- query already returns a sequence)


Thanks Sean 🙂


Let me test that out


Normally you'd do something like (jdbc/query db ["select ..." params] {:result-set-fn #(group-by (juxt :companyName :departmentName) %)})


(I think you only needed the map because you had a vector of sequences of hash maps instead of just a sequence of hash maps?)


Maaaaybe? 😆


Everything is behaving much better now


If we had Watney bot in here, I'd give you some karma 🙂


(def atomka (atom {:wsmsg nil}))
(assoc @atomka :wsmsg "d") ; add "d" to wsmsg
(swap! atomka assoc :wsmsg (conj "d")) ; add "d" to wsmsg

but how could I conj in :wsmg?
I would like to get> ["c","d","g"] ; (:wsmsg atomka) 


My question is how could I add new value to > atomka :wsmsg?


The update fn is probably what you’re looking for


update-in + conj?


Ok, thanks I check it


update and update-in are different


update is for a regular key like (update key fn-that-takes-old-value-and-returns-a-new-one)


Ok, I understand! Thanks!!


(update-in [key1 key2 key3 ...] fn-to-update)


One more question


(swap! my-state update :wsmsg #(conj % 4))
(swap! my-state update-in [:wsmsg] #(conj % 4))


which is the best in this case, or the update-in is not correct?


both works


They’re functionally equivalent. update might be marginally faster.


I think you could do, fwiw, (swap! my-state update :wsmg conj 4) no need for the lambda


thanks for all the help!!

Lucas Barbosa20:08:52

Hi guys, I’ve been studying Clojure for the past few weeks and I’m starting to feel a little confident to try to build something more complex than solving exercises in Can someone please point me to some resources regarding the “jump” from toy examples to a “real” project? Stuff like separating concerns in namespaces, good practices, modeling complex domains, etc.? Thank you in advance!


What books/tutorials (if any) have you read so far @lvbarbosa ?


(and thanks for moving the conversation here!)

Lucas Barbosa20:08:50

@seancorfield I’ve read Brave and True and Living Clojure (still completing the weekly training at the end of the book). I’ve also tried to build a restful api using Clojure, but I feel that something is very wrong, like organization or separation of responsibilities (code here ->

Drew Verlee20:08:23

How do you write a test to check if a value is “truthy”. Like i want something like (is (???? [:a :b])) to pass

Lucas Barbosa20:08:43

I’m also reading the community style guide to improve the general code writing


@drewverlee a value just is truthy or falsey -- (is [:a :b]) will pass

Drew Verlee20:08:00

@seancorfield should have guessed. Thanks


@lvbarbosa Cool re: books, so maybe buy Clojure Applied for a more real-world next step?


As for your code, I'd separate the persistence stuff into another namespace so the handlers aren't directly dealing with the database stuff.


Are you familiar with MVC as a design pattern where the model and the controllers are separate?


extrapolating from that, IMHO 80% of “organization” and “domain modeling” in functional programming is solved if you push IO to the outside edges.


(and at some point fairly soon you're probably going to want to learn about Component or something similar so you can package up separately the concerns of creating the pooled DB connection, starting the web server, etc)


(where IO include channels, streams, files, network, and mutation of containers like atoms or refs)


Yup, what @noisesmith said. It's hard with a simple CRUD example since pretty much all you're doing is "read something" and return it, "write something" and return status, but the more you can isolate the direct DB interactions from the rest of your app, the better.

Lucas Barbosa20:08:46

@seancorfield I just read the table of contents of Clojure Applied and it seems very likely this book will help me. I’ll look into purchasing it asap! As for MVC, I have a good background in OOP and on the Java platform. I see that the code I wrote is completely coupled and messy 😅, but I still don’t really know what to do (due to my lack of experience and ignorance on the paradigm). My mind did not shift completely yet. I guess this will come slowly with time and reading other people’s programs. Thank you and @noisesmith for the comments, I really appreciate it!


My inclination is that some things that would be considered “well factored” in idiomatic java are a total coupled mess in clojure, and visa versa. With most of the differences having to do with side effects (clojure works better when you isolate them, java doesn’t usually care), data hiding (java needs it, clojure works better without it), and custom types (java uses them everywhere, good clojure code is much more conservative about creating new datatypes)


If you use something like Component -- it'll be familiar as IoC/DI from Java (if you used Spring or something similar) -- and then you'll be passing components around to functions that need them, instead of relying on globals (as you are now for database connection stuff). The nice thing about that is that it then becomes very clear what dependencies your function have (only on their arguments, not their environment), and it becomes much easier to test them (because you don't have to mock a global environment -- you can test functions in isolation, passing them mock components if necessary).


the combo of components providing stateful things as args, and driving your app with immutable data, means that creating tests that replicate runtime regressions can be very easy if you design things right


eg. reifying important events as data you can store and replay

Lucas Barbosa20:08:08

I’ve seen a talk on the official channel at YouTube where the guy that created Component talks about it, seems very interesting. I’ll definitely give it a try. The DI facility is the aspect that I miss the most when trying to step out of Java EE. I’m so used to annotating, configuring producers and letting the application container do the magic for me that it still feels bad to invoke resources by myself.


clojure is definitely opinionated about explicit rather than implicit things in most cases, but you can still get the good parts of DI under that model

Lucas Barbosa20:08:13

@noisesmith testing is something that I love to do! I did not jump into it on Clojure yet, but is on the backlog for learning


you just need to make sure you have well designed components and that you use them properly


clojure testing is a lot simpler than people expect - most of what makes testing hard is implicit non-local state, and implicit context, and clojure is quite good about minimizing those things if you use it right


I’m trying to make a macro that creates a dynamic var of a string, so far I have this:

(defmacro defvar [le-name]
  (let [n (name le-name)
        le-symbol (symbol (str "*" n "*"))]
    `(def ~le-symbol ^:dynamic
       (or (environ.core/env (keyword ~n)) ~n))))
but it ignores the ^:dynamic:
(macroexpand-1 '(defvar "a"))
(def *a* (clojure.core/or (environ.core/env (clojure.core/keyword "a")) "a"))
I tried using with-meta instead but i’m failing because i cant put metadata on the string itself. can some1 point me out?


the metadata needs to be on the symbol, not the value


and yes, use with-meta so that the metadata is on the form you emit, not the input to the form


so it would look like

`(def (with-meta ~le-symbol {:dynamic true}) ...)


tyvm for clearing this out @noisesmith


@lvbarbosa When you get around to testing, you can either use the built-in clojure.test or if you're used to a more BDD-style take a look at #expectations (disclaimer: I maintain that library!)