Fork me on GitHub

@lgesssler I've heard directly from the person that implemented the foo.core convention in leiningen that it was a way to avoid single segment namespaces with gen-class in them, if you use lein new my.domain/foo you will get instead of foo.core

👍 4

(my.domain/foo makes a directory "foo", makes a directory "" but the contents appear identical)


do any of you guys use clojure.test? if so, is it possible to run all tests except for one (which will be my integration test)? I am trying to just move it to a different folder, but everytime I run lein test it will run every test inside /teste folder.


@brnbraga95 Sounds like you could use test selectors for that...


lein test help should explain that.


You can mark that single test with metadata such as ^:ignore and then define

:test-selectors {:default (complement :ignore)}
in your project.clj


Or if you could could just tell lein test which namespaces you want to test (I don't know how many test namespaces you have).


my test folder is:

I tried something like lein test test/unity but had no luck, I can specify each file lein test :only test/unity/test1.clj but that is not very handy


I am trying to run Cursive in IntelliJ IDEA. I keep getting Could not locate clojure/spec/alpha__init.class or clojure/spec/alpha.clj on classpath.


@seancorfield what does (complement :ignore) means? did not quite understand what it is saying


@brnbraga95 Specify the namespace not the file path.


thanks sean, got it.


(complement :ignore) is a predicate that means "does not have :ignore metadata" in this case.

👍 4

In general (complement foo) is a function that means (not (foo x))

👍 4

@lukasz.pomorski01 Hard to say based on so little information -- try the #cursive channel as @cfleming is usually very responsive there.

Kari Marttila08:04:08

When I start lein figwheel and the REPL starts, and I interact with the REPL the default font color for my input is really difficult to see (light gray - REPL output is black and ok). Is there some way to change the terminal font colors for Figwheel? Or is this something I have to change in my Linux workstation?


@kari.marttila I’m a bit confused, can you post a screenshot?

Kari Marttila09:04:43

The font for namespace is light gray (hardly visible). My workstation is Ubuntu14. The terminal is Terminator.

Kari Marttila09:04:52

I made a workaround - I made a remote REPL connection using Cursive - it is more convenient to use Cursive IDE anyway so this is not such a big issue.

Kari Marttila09:04:33

Damn, this is so much fun to learn how to create a SPA using ClojureScript. 🙂


Heh. I wonder if it accepts changes to the base font colour, but all the differently-coloured bits are set elsewhere (or hard set) and everyone else uses terminals with a black background


That's the first time I've seen a developer's terminal that's dark text on a light background


@kari.marttila well, I don’t seem have syntax highlighting in figwheel shell. Apologies, I have no idea how to address your issue.


Is there any way to apply the namespaced map shorthand syntax to nested keys? That is, is there a briefer way to say #::my-ns{:key1 #::my-ns{:key2 42}}?


Ok, thanks.

Kari Marttila12:04:26

@chokheli and @carr0t: Ok. No problem. I'll investigate my Ubuntu / Terminator configuration. And using remote REPL in IntelliJ IDEA / Cursive is anyway more enjoyable since I have all my favorite hot keys there.


Hi, total Luminus newbie here. I'm reading the book Web Development with Clojure, and I just created a new Luminus app using lein new luminus guestbook +h2. I'm trying to create new migrations using lein migratus create guestbook but I'm getting the error 'migratus' is not a task. See 'lein help'.. Any ideas?


@nikoszp The Luminus website is more upto date. For the first project.

💯 4

@nikoszp I had similar issues, Luminus has changed somewhat since that book has been release. You have to check the Luminus website/Github for changes or use the specific versions within the book.


Thanks! I think I'll stick to the most current version and try to figure things out


lein run migrate


Thats the command used on the website.


Or if your using the latest version it might even be boot dev [run migrate]


I'm looking now, thanks!


No problem 🙂.


How can I do this? ((f a b c) [x y z] => [(a x) (b y) (c z)]. where "a b c" are functions. It would be a nice way of converting a vector of string data to a vector of types (numeric, dates, etc). Thanks!

Alex Miller (Clojure team)14:04:12

map over both functions and data in parallel? (map #(%1 %2) [a b c] [x y z])


Perfect! I was trying out the csv libs, reading in futures data, left with vectors of string data and was thinking...why don't those libs let you pass in a vector of functions to convert all that data to types because that's the first thing one is most likely to do next?


(map (juxt a b c) [x y z]) I think this might work

Alex Miller (Clojure team)14:04:18

I don’t think that’s what you want

Alex Miller (Clojure team)14:04:30

then you be applying a b and c all to x y and z


hey, do you ever use keywords as values in maps?


keywords are very useful for "enum-like" values, such as in this map example {:type :combobox}


thanks 👍

Wilson Velez15:04:56

Hi, I need to transform this map {:1 {:pct 60} :2 {:pct 40}} into this {:1 {:pct 60 :amount 120} :2 {:pct 40 :amount 80}}

Wilson Velez15:04:36

I did it this way (reduce into {} (map (fn [[key pct]] {key {:pct (:pct pct) :amount (utils/round (* 200 (/ (:pct pct) 100)))}}) {:1 {:pct 60} :2 {:pct 40}}))

Wilson Velez15:04:23

I also have a version with merge-with

Wilson Velez15:04:35

(merge-with into mimapa (reduce into {} (map (fn [[key pct]] {key {:amount (utils/round (* 200 (/ (:pct pct) 100)))}}) mimapa)))

Wilson Velez15:04:58

being mimapa (def {:1 {:pct 60} :2 {:pct 40}})

Wilson Velez15:04:54

they work, but are they fine?


hi, they look slightly more complicated than needed, try this one


if you want to go slightly further, first define this


hyper-concise : )

Wilson Velez15:04:56

to much for my level

😂 4

Can you make lein repl require clojure.repl automatically? So I can use doc, apropos, source?


@grierson if you scroll up, @mfikes was just giving some advice on that, I believe:


Normally clojure.repl/doc and friends are automatically referred into your user namespace when you do lein repl


I wonder what the experience would be like if a repl had a mode that auto-referred any unique name across all namespaces.


thanks, that has to be more efficient, since it's just one pass


Another option is using the xform arity of into:

(defn map-vals [f m]
  (into {} 
        (map (fn [[k v]] [k (f v)])) 
that's using the single-arity version of map which returns a transducer. That's also single pass (because of how transducers work)

👏 4

I've been using:

(defn- fmap [f m] (into {} (for [[k v] m] [k (f v)])))
which is almost identical to that last version @seancorfield. Not sure about the performance implications, would be interesting to test.


@andrew354 to make it more like a real fmap, use (empty m) instead of {} - that way it also works on records, sorted maps, etc.

Alex Miller (Clojure team)20:04:12

empty doesnt work on records

👍 4
Alex Miller (Clojure team)20:04:33

generally I would expect reduce or the transducer into forms to perform better than for, which is seq based


it could certainly be more general, but it doesn't really need to be

Alex Miller (Clojure team)20:04:32

there are plenty of map-vals impls out there already in various utility libs too


the reason I suggested something more general is that the name fmap implies something very general

Alex Miller (Clojure team)20:04:53

check out libs like Medley, Plumbing, Useful, Tupelo, etc


some basic benchmarking: (into {} (for [[k v] m] [k (f v)])) 46 µs (into {} (map (fn [[k v]] [k (f v)])) m) 32 µs (reduce-kv (fn [m k v] (assoc m k (f v))) {} m) 28 µs where f = inc and m = (into {} (map (fn [x] {x x})) (range 100))

Alex Miller (Clojure team)20:04:19

the performance aspects split into consumption of the inputs and production of the output. for is seq-based which in a case like this I’d expect to produce more objects and thus be slower.


of course it probably doesn't matter unless it's a hotspot, but it was a fun excuse to use criterium


also there's two ways to use into with map, the one using the map transducer will be faster


it could even be faster than the reduce-kv with assoc


above was the transducer way


it was ambiguous with the way you used the ...


sorry. in all cases I used the implementations from above

Alex Miller (Clojure team)20:04:32

there are also issues on the collection side about whether you’re using transients and also how the entries are created

Alex Miller (Clojure team)20:04:35

there is some optimized code around creating maps from vectors and while it’s not obvious, collecting into a transient vector, then creating a map in one step might actually be faster, esp in small common cases (little harder to bench)

Logan Powell21:04:39

Hi everyone! I'm back with another question... I feel like I just hacked together a solution to get the tests to pass for an exercise Is there a way to bubble/throw up a value instead of an exception? Right now I'm just putting values in that wouldn't ultimately allow for a passing value... I saw this solution from SO, but it didn't work for me:

Logan Powell21:04:28

Also, please let me know if I should put code directly in Slack or if the community prefers links to bins or if I should post the question on SO


Links are better. Less usage of our very limited space on the free plan.

👍 4

@loganpowell: a small thing - you don't need to nest let like that


let is already able to see previous bindings at each step

Logan Powell21:04:20

The lets can be be inline?


You have a cascade of three lets that could all just be one.

Logan Powell21:04:54

thank you 🙂


You could also use destructuring to avoid calling str-2-seq twice:

(let [[digits checkr] (str-2-seq isbn) ...


Also (if condition true false) is the same as just condition.


or (boolean condition) if someone really needs true or false (no code in clojure itself will care)


(that condition yields a true boolean in this case -- and on two boolean operations)


oh, yeah, in that case you don't need boolean

Logan Powell22:04:12

are you guys still talking to me?

Logan Powell22:04:04

haha, sorry, which part/line are you referring to?


exactly - the condition is already true or false so the if is rendundant

Logan Powell22:04:36

so just the (and... would suffice?

Logan Powell22:04:05

cool! I would never have guessed that and definitely would be confused - if you hadn't just told me - if I saw that in someone elses code 😄


The Programming Languages course that Univ. Washington teaches (on Coursera, as well as on site) has that as one of their early lessons (in Standard ML but it applies to any expression-based language): if a true false == a

Logan Powell22:04:55

thank you so much. This is one of those many things that I wouldn't even know to ask for help for


line 37 in your code seems redundant -- was it left over from when you were developing/testing? The chars on its own in the body of the let with the if following it?


let evaluates each expression in the body but returns only the value of the last expression (so it throws away the other values)

Logan Powell22:04:30

ah, yeah, that is not intentional. it's left over from when I was putting it together.

Logan Powell22:04:27

I'm surprised it still worked with that in there


'k... range has a step argument so you can replace (reverse (range 2 11)) with (range 10 1 -1) if you want


Sure, it evaluates chars and then throws away its value.


(let [a 42] 1 2 3 4 5 a) => 42


first-9 can be simplified quite a bit: you don't need to make the sequence of pair and then apply * to each, you could just map * over those two sequences to start with.


for example (map * (range 10 1 -1) [8 5 6 2 3 4])


In your case (map * (range 10 1 -1) (map #(Character/digit % 10) seq))

Logan Powell22:04:03

so map can sort of zip two lists together and apply an operator on the pairs?

Logan Powell22:04:26

wow. that's cool


map can take any number of sequences and applies the function across all of them.

Logan Powell22:04:04

what happens if the input sequences are different lengths?


(map + [1 2 3 4 5] (range 100 110) (repeat 6)) => (107 109 111 113 115) -- it stops after the shortest sequence


In the above, (repeat 6) is an infinite sequence.

Logan Powell22:04:29

very good to know. Man, you're saving me days of learning right now


That's what we're here for 🙂


With this exercise, is there anything specified about what should happen if the inputs are not valid?


For example, first-9 could throw an exception if it is passed invalid data?

Logan Powell22:04:45

That's actually the original question I posted above, I'd like to get the whole thing just to evaluate to false if any of the sub-assemblies don't return valid values

Logan Powell22:04:15

instead, I've just *hacked* in some values that would never work (hopefully)


(try (checking-code ...) (catch Throwable _ false))


@loganpowell: one way that can look is (boolean (some->> input (check-1) (check-2) ... (check-n))) where each check function returns either a map of bindings (including ones created by previous steps), or nil (to indicate some condition wasn't met and it failed)

Logan Powell22:04:57

Sweet! You guys are the best

Logan Powell22:04:47

@noisesmith is that using function composition (`->>`)?


But you could write

(defn first-9 [digits] 
  {:pre [(= 9 (count digits)) (every? #(Character/isDigit %) digits)]} 
  (reduce + (map * (range 10 1 -1) (map #(Character/digit % 10) digits))))
for example, which would throw an AssertionError if the input (`digits`) wasn't ten characters that represented digits.

Logan Powell22:04:23

so, that would avail false ultimately?


@loganpowell: ->> is not function composition (though the end result is similar) - it's a form rewrite

Logan Powell22:04:44

oh boy, I'm in over my head 😄


some->> is like ->> except it stops if any step returns nil and doesn't run any further steps


fair enough!

Logan Powell22:04:21

let me refactor with all these goodies.


@seancorfield: one gotcha there is that catch Exception will not catch a precondition


cough Throwable cough

Logan Powell22:04:04

@noisesmith is there a term for this (boolean (some->> input (check-1) (check-2) ... (check-n)))

Logan Powell22:04:25

like the convention

Logan Powell22:04:51

does it return 'false`?


some->> is a form rewrite, it doesn't have another name that I know of, and boolean turns nil into false


(You'd only want the try/`catch` in your top-level isbn? function tho')

Logan Powell22:04:58

ok, thank you guys again!!! I'll be back


I just did the above as an example.

Logan Powell22:04:35

ah, cool, I tried that in the sub assemblies and it didn't work. I'll try it at the top!


Anyone using secretary? Is there any way of making it match multiple routes for a single URL?


Hi, how do you spec a vector whose first 3 item is fixed string and can accept a flat sequence of keywords


This pass: ["a" "b" "c"] , ["d" "e" "f" :foo :bar :baz ....]


This shall not pass: ["d" "e" "f" 1 2 3]


I was using s/tuple and s/* and it doesn't work since it expects another collection


@mcama200 what would that even mean? the point of a router is to route to one place


i think its common with react-router. From their docs " When a <Route> matches it will render its content and when it does not match, it will render null. " Meaning, it attempts to keep matching unless you specify otherwise. It's useful if you want to render a component or do a specific action for a set of routes


Oh yea no you can’t do that react router 4 thing with secretary