Fork me on GitHub

I have some functions that are responsible for the orchestration (I will refer as comp-fns) of some other fns, however these comp-fns receive several arguments (6+) what is the more idiomatic way to handle this situation? Pass the parameters as hash-maps?


yeah, with more than four args I like a hash map with named keys, as it's impossible to tell if the args are right just by looking when there's that many

👍 4

and kwargs aren't usually worth the extra trouble imho


Hi to all

👋 16

Welcome @stevannestorovic! Just started learning Clojure?


@seancorfield not my welcome to take, but funny you ask that as I've been asking myself a lot of things lately. over the past 13 years I've gone ruby -> learning clojure -> go -> ok, i like clojure -> rust -> ok, i'm going to build everything I can build in clojure. which, written out, sounds funny and almost a denial of where terrible orange site comments would tell you to go. just saying, 6 years ago was the best time to pick up clojure, now is the second best time.


a little more difficult given my day to day is working on OSS on kubernetes, but. 😄


My journey has been all over the map over the last 40 years. And it's touched on Lisp a couple of times.


I like Rust. I didn't like Go. Didn't like Ruby either. But languages are very subjective.

Godwin Ko03:08:01

@seancorfield Curious to ask what’s the major reason that you don’t like Ruby? btw, i’ve been programming Ruby for past few years, now just start stepping into Clojure/Clojurescript :face_with_raised_eyebrow:

Godwin Ko03:08:20

and I hate Java, don’t quite like C++ 😂


@godwin.ko Purely subjective. I've been a language designer/implementer since the very early 80's so I have very strong opinions on what makes a readable, maintainable language -- and Ruby fails miserably on my criteria.


I was on the C++ Standards Committee for eight years so you can blame some of your dislike on me 🙂


I co-wrote one of the first three ANSI-validated C compilers. I wrote a C++ compiler front end. I designed an ML-like language/interpreter back in the early 80's.


So... Ruby... bleh 😞 🙂

Godwin Ko03:08:32

but Ruby/Python is good for newcomers with no computer science background, just hack and using whatever popular framework/library, and it works most of the time 😂


Clojure is as close to a piece of perfect language design as I've found in forty years.

✔️ 20
rich 8

Python's fine. I like Python. Such a shame about the 2.7/3.x split tho'.


I liked python too. Used it professionally for many many years. But when they broke compatability going to 3 (even in really silly ways that was totally unnecessary like changing .iteritems to .iter) and I needed to start a new project, it was no longer a python 2 vs python 3 question. As I couldn't just use my old code anyway, it became a python 3 vs all the other cool new langauges than had appeared since python 2 had been released.


and a senior engineer I was working with at the time and really respected told me to learn clojure as he considered it a "next step" coming from a ruby or python background. I'm super glad he did. I haven't looked back.


In fact learning clojure then gave me feelings very reminiscent of when I learnt python 2 back in the day. A feeling of speed and of ease. Of the joy of working with something very clean and well designed. Except more so. Like saying goodbye to classes and the endless "dunder" methods.


was such a joy to learn


This is my story too.

Godwin Ko04:08:33

Clojure is cool, maybe most Lisp dialects are cool in different aspects


I attended PyCon 2013 since it was local and it all looked so promising. They said "about five years" for everything to be cut over to 3.x. Sigh.


But Python 3.x is a nice piece of design.

Godwin Ko04:08:15

that’s not gonna happen, legacy app stay much longer than we think or want :thinking_face:

Godwin Ko04:08:44

it’s funny that, when I talk to every local developers that I’m jumping into Clojure, almost everyone warned me that nobody is using it, hard to recruit developers, hard to train team members, … etc.


No one warned me. No one had heard of it when I started in 2010 🙂

😂 4

Hi guys, I have a basic cljs->js interop question: I need to assign something to an array element, but couldn't find how to do it. I am trying to use sheetjs and trying to use this line wb.Sheets["Test Sheet"] = ws;. I've tried (set! (.-Sheets wb "Test Sheet" ) ws) and (set! (.-Sheets "Test Sheet" wb ) ws) but figwheel throws error.


is ws and wb defined in the cljs? or is it defined in js?


try (aset (.-Sheets wb) "Test Sheet" ws)

👍 4

assuming ws and wb are cljs vars, not js variables


Instead of aset (which operates on JavaScript arrays using numeric indices), consider

(goog.object/set (.-Sheets wb) "Test Sheet" ws)
otherwise warnings or errors will be emitted if :checked-arrays is enabled. See more at

👍 8

Thanks for the help guys 🙂 @U1QQJJK89 yes, those are defined in a let closure above, which I didn't include it here @U04VDQDDY the goog.object method worked fine! For the benefit of future cljs beginners, can we add this into a common place, probably in Clojurescript cheatsheet? Because, it's difficult to find the above article through googling.


I can add / update multiple values in a map using both (assoc {:a 2} :a 5 :b 5) and (merge {:a 2} {:a 5 :b 5). Which one should be preferred ?


hey guys, I’m using atom + protorepl .. starting my new code to use clj tools deps .. how you guys starting the nrepl on your projects ?

Janne Sauvala15:08:34

I start repl manually from my terminal and connect to to it with Chlorine atom package

Janne Sauvala15:08:12

I don’t have the exact clj alias atm (I’m on mobile) but I followed Sean Corfield’s setup to start repl (you can find it from here


@UJZ6S8YR2 Note: @U0C3SLTHP wants ProtoREPL not Chlorine -- although given that ProtoREPL is pretty much unmaintained these days, I'd probably recommend Chlorine instead.

Janne Sauvala19:08:13

Thanks @seancorfield for correcting me. I easily mix up these different REPLs with each other


want to connect, from my atom, using protorepl


I have this:

No such namespace: clojure.core.strint, could not locate clojure/core/strint.cljs, clojure/core/strint.cljc, or JavaScript source providing "clojure.core.strint" in file src/guestbook/core.cljs

Alex Miller (Clojure team)15:08:48

that's a very old ns from clojure-contrib, so yes


gotcha. thanks


Hi folks. I know I’m using with-redefs-fn improperly here but I don’t know what I’m doing wrong.


what is the time namespace?


with-redefs is not the preferred way to do mocking with that lib, check out!


with-redefs has some issues that can make it tricky to use and in particular to understand when it doesn’t work


ah okay, let me fiddle around with that. Thanks!


@schmee that was it. thank you again!


you’re welcome! 🙂


how does refer or refer-clojure differ from require ?


@murtaza52 require loads a namespace (if it isn't already loaded) and can give the namespace a local alias (`:as`) and can also intern symbols from that namespace into the current namespace (so they are accessible without the alias) -- using :refer. refer itself does the same as require's :refer option -- but does not load the namespace first. refer-clojure is a shorthand for (refer 'clojure.core <options>)


It's very rare to use the refer function since you normally need to load a namespace before first use, and it's easier to combine the require and refer operations in a single require with the :refer option.


refer-clojure is generally only needed when you are deliberately defining symbols in your namespace that "shadow" something in clojure.core and want to avoid the warning the compiler gives about replacing symbol definitions.


For example, -- since clojure.string defines replace and reverse that shadow (hide/replace) those two definitions in clojure.core.


@seancorfield so if I understood correctly require loads a ns and refer interns the vars from that ns.


what do you mean by loading a ns ? can you explain that a bit more


Yes. And (require '[some-lib.ns :refer [func1 func2]]) is the same as (require 'some-lib.ns) followed by (refer 'some-lib.ns :only ['func1 'func2])


Loading a namespace -- if it has been loaded yet, find the expected matching file on disk, read it in and compile it form by form.


So, in general (require '[some-lib.ns]) would look for some_lib/ns.clj somewhere on the class path (e.g., in src) and then load & compile it.


@murtaza52 Feel free to ask more questions. I have to step away but I expect someone else can pick up and answer those...


when you say compile, that means JIT kicking in to compile the bytecode down to machine code ?


@seancorfield thanks, your replies were very helpful


Compile = compile Clojure source down to JVM byte code.


@seancorfield so what does the lein compile step do ? Does it only compile AOT classes, and rest is left as source code ? Wouldn’t it make more sense to compile all source code to java byte code at build time, before the jar is deployed to production ? This will reduce latency when code is executed at run time.


AOT compilation can reduce start up time but for long running processes (servers) that's not really a concern.


We do not compile anything at work.


Also AOT "leaks". It compiles the specified namespace and anything it statically depends on.


@seancorfield thanks, that makes sense


The JVM itself handles compilation to native code, as it sees fit (i.e., for hot spots in the code).


Dear cool Clojure people… (.parse (java.text.SimpleDateFormat. "MMM/dd/yy H a") "AUG/10/2019 04:22 AM") any clue on how to parse this date format correctly? I am not sure how to get this date formatter to work.


@cameronleslie I didn't see anyone answer this so

user=> (.parse (java.text.SimpleDateFormat. "MMM/dd/yyyy HH:mm a") "AUG/10/2019 04:22 AM")
#inst "2019-08-10T11:22:00.000-00:00"


I was able to figure out my mistake.


I appreciate the extra help @seancorfield


Probably should be hh, not HH -- the latter is 24 hour clock


Makes sense.


/me shakes fist at API’s that use non-standard time formats


I’m new to LISPs, but i “get” most of what’s going on; but I’ve never used Java, so it’s weird using the interop stuff. I find myself trying to translate what’s going on with the Java methods in my head.


I tried parsing it with the Java Time stuff instead, but LLL won't accept AUG, only Aug, which was a surprise.


(and it won't accept aug either)


There is no justice.toLowerCase()


this is the dataset I am working with: (slurp "")


… also I hate nonstandard datestrings.


Never mind. 😐


It’s always something stupid. ¯\(ツ)

Alex Miller (Clojure team)21:08:41

just fyi, that SimpleDateFormat object is not thread-safe - you're fine there because you're creating a new one every time, but don't like put it in a def and use it from multiple threads


@cameronleslie I recommend using and other java.time over java.util.Date and SimpleDateFormat, if that’s possible in your case

💯 4

@schmee if this small script “turns into a thing”, I will totally follow that advice. Bookmarked. Thank you!


@alexmiller is there a plan to make a second edition of your wonderful "Clojure Applied" or there is not much change since the publishing?

Alex Miller (Clojure team)22:08:03

Definitely could be updated. But we have no imminent plans to do so :)


@alexmiller what would you add or remove (if any) ?

Alex Miller (Clojure team)22:08:17

Would revise some of ch 1 advice on records


do you still consider records for domain modeling? or just plain maps with specs is encouraged nowadays?

Alex Miller (Clojure team)22:08:56

Might add some stuff on clj and tools.deps now.

Alex Miller (Clojure team)22:08:30

Records and maps is a balance. I’d tilt back more towards maps now

Alex Miller (Clojure team)22:08:03

Protocol metadata makes maps suitable in more scenarios than before


@alexmiller thanks, I'm using Programming Clojure 3rd and Clojure applied as learning resource, do you have any recomendations for a " updated , idiomatic and /or best practices " book?

Alex Miller (Clojure team)22:08:09

Russ’s Getting Clojure is great

👍 4

@cameronleslie I didn't see anyone answer this so

user=> (.parse (java.text.SimpleDateFormat. "MMM/dd/yyyy HH:mm a") "AUG/10/2019 04:22 AM")
#inst "2019-08-10T11:22:00.000-00:00"