#clojure log - Apr 04 2015

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

2:46 justin_smith: tolstoy: you don't need to .stop the server if you pass it var-quoted (run-server #'my-routes {:port 8001})

2:46 that way if you redefine my-routes, the new def is used

3:12 tsdh: How do I specify a java.util.Comparator in Clojure which can be refered to with clojure.api from the Java side (and cast there to Comparator<Object>)?

3:13 I have already a function with args [a b] which returns 0/pos/neg as required for comparators.

3:13 justin_smith: tsdh: reify java.util.Comparator

3:13 tsdh: justin_smith: Ah, ok.

3:14 justin_smith: and use the code for that function, or the function itself, in the compare method

3:15 amalloy: justin_smith: functions implement Comparator

3:15 justin_smith: amalloy: oh, wow, I had no idea

3:15 even better :)

3:15 (inc amalloy)

3:15 lazybot: ⇒ 252

3:15 justin_smith: actually, you have probably mentioned this before, but I forgot

3:15 amalloy: probably

3:19 TEttinger: ,(def people (doto (ArrayList.) (.add "Mike") (.add "Jim") (.add "Bob")))

3:19 clojurebot: #error{:cause "Unable to resolve classname: ArrayList", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.IllegalArgumentException: Unable to resolve classname: ArrayList, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6732]} {:type java.lang.IllegalArgumentException, :message "Unable to resolve classname: ArrayList", :at [clojure.lan...

3:19 TEttinger: ,(def people (doto (java.util.ArrayList.) (.add "Mike") (.add "Jim") (.add "Bob")))

3:19 clojurebot: #'sandbox/people

3:20 amalloy: TEttinger: (ArrayList. ["Mike" "jim" "Bob"])

3:20 TEttinger: ,(Collections/sort people #(> (.length %1) (.length %2)))

3:20 clojurebot: #error{:cause "No such namespace: Collections", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: No such namespace: Collections, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "No such namespace: Collections", :at [clojure.lang.Util runtimeException "Util.java" 221]}],...

3:20 TEttinger: ,(java.util.Collections/sort people #(> (.length %1) (.length %2)))

3:20 clojurebot: nil

3:21 TEttinger: ,(vec people)

3:21 clojurebot: ["Mike" "Jim" "Bob"]

3:21 amalloy: TEttinger: that doesn't look like a correct comparator

3:21 justin_smith: it should return an integer, right?

3:21 amalloy: yes

3:21 justin_smith: neg, zero, or pos

3:21 TEttinger: yep, I have never used comparators :|

3:21 amalloy: justin_smith: though of course ##(doc comparator) exists

3:21 lazybot: ⇒ "([pred]); Returns an implementation of java.util.Comparator based upon pred."

3:22 amalloy: to convert a predicate to a comparator

3:22 tsdh: amalloy, justin_smith: No matter if with plain function or reified comparator, I get "clojure.lang.Var cannot be cast to java.util.Comparator" on the java side.

3:22 justin_smith: amalloy: wow, cool

3:22 amalloy: well don't pass it a var

3:22 tsdh: amalloy: ?

3:22 justin_smith: tsdh: get the thing the var holds - automatic deref of vars doesn't happen in java

3:22 TEttinger: ,(java.util.Collections/sort people #(- (.length %1) (.length %2)))

3:22 clojurebot: nil

3:22 TEttinger: ,(vec people)

3:22 clojurebot: ["Jim" "Bob" "Mike"]

3:22 TEttinger: there we go!

3:22 justin_smith: tsdh: deref will give you the thing in a var

3:23 TEttinger: you need an IFn I think

3:23 tsdh: But there's no deref method (or Var) in clojure.api. All you get is IFn which you can just call() or invoke().

3:23 justin_smith: tsdh: uhh...

3:23 ,(deferf #'+)

3:23 clojurebot: #error{:cause "Unable to resolve symbol: deferf in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: deferf in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: deferf in this context", :at [...

3:23 justin_smith: err

3:23 haha

3:24 ,(deref #'+)

3:24 clojurebot: #object[clojure.core$_PLUS_ "clojure.core$_PLUS_@13b78423"]

3:24 TEttinger: was that a definition or a deref, justin_smith?

3:24 justin_smith: yes, you can deref vars, they are a mutable container

3:24 amalloy: the clojure.java.api.Clojure API is very minimal

3:25 justin_smith: ,(.deref #'+)

3:25 clojurebot: #object[clojure.core$_PLUS_ "clojure.core$_PLUS_@13b78423"]

3:25 justin_smith: you can use the deref method too

3:25 amalloy: if you have a var which contains a value, and you need the value instead of the var (because it's not a function, you'll have to get the var for deref, and call it on your var

3:25 justin_smith: c.j.api.Clojure gives you everything as IFn, not even Var

3:25 justin_smith: ahh

3:25 amalloy: so you'd have to cast it to var and then call .deref

3:26 but better to find the var for deref and use that

3:26 tsdh: amalloy: Got the same error when my clojure-defined comparator as a plain function.

3:26 justin_smith: interesting

3:27 tsdh: Hm, indeed (supers (class (fn [a b]))) says it implements Comparator.

3:28 justin_smith: tsdh: and you are definitely getting the fn and not the var holding it?

3:28 tsdh: I do final static IFn MATCH_COMPARATOR = Clojure.var(SOLUTION_NS, "match-comparator"); in java.

3:28 justin_smith: yeah, that's the var (as IFN, which is a super of var)

3:29 tsdh: I did the same with other fns which I can myIFn.invoke(args); in java.

3:29 justin_smith: tsdh: yeah, calling a var implictly derefs when invoking

3:29 ,(#'+ 1 2)

3:29 tsdh: I guess I could invoke my comparator with myComp.invoke(a, b); but I need to pass it on to some framework.

3:29 clojurebot: 3

3:31 amalloy: tsdh: (Comparator)deref.invoke(myvar)

3:31 tsdh: Aha: comparator = (Comparator<Object>) ((Var) FunnyQTBenchmarkLogic.MATCH_COMPARATOR).deref();

3:32 amalloy: Ah, requirirng deref and invoking it on my var would also work. Anyway, gotta run. Thank you both!

3:32 amalloy: well i did suggest that a few times

3:33 justin_smith: haha

3:33 that amalloy, he gets no respect I tells ya what

3:34 amalloy: all i get is this useless karma

3:35 TEttinger: (dec amalloy's respect)

3:35 lazybot: ⇒ -1

3:35 TEttinger: (inc amalloy)

3:35 lazybot: ⇒ 253

3:35 TEttinger: less than no respect!

5:31 constl: What does the "&" mean in a general form? e.g. (while test & body)

5:32 TEttinger: constl, it means that you can pass additional args after the & and they will be available as a seq with the name body (there, at least)

5:32 so "& args" in the typical clojure -main fn means you can pass a number of arguments and get them from a seq called args

5:33 constl: TEttinger: So in my example it means that body can have multiple s-expressions ?

5:34 TEttinger: yes, since an s-expression is just a form. hm, that isn't a an argvector though so....

5:34 actually I haven't seen that in a general form

5:34 can you link to the code where that was?

5:35 it's possible there's some surrounding macro that defines & in its body

5:35 (doc while)

5:35 clojurebot: "([test & body]); Repeatedly executes body while test expression is true. Presumes some side-effect will cause test to become false/nil. Returns nil"

5:35 constl: This reference is from a book called "Clojure in action" and it is explaining the functional iteration capabilities

5:35 so to examplain the while general form it gives that example

5:37 Sorry my English doesn't make any sense in the above two sentences. But i think you've answered my question already

5:37 TEttinger: ,(while (not= 0 (rand-int 10)) (def inner-form 1) (def another 2) (+ inner-form another))

5:37 clojurebot: nil

5:37 TEttinger: ,(while (not= 0 (rand-int 10)) (def inner-form 1) (def another 2) (print (+ inner-form another)))

5:37 clojurebot: 333333333

5:38 TEttinger: I think the & is a typo in there

5:38 it makes sense in an argument list

5:38 well, argument vector

5:38 unless it's using that as pseudocode to mean one or more forms in body

5:39 constl: Well it is also found when describing the "when". e.g. (when test & body)

5:39 TEttinger: (which is totally useful to be able to write that, but they should have explained it better)

5:39 yeah, when also allows multiple forms, unlike if

5:39 constl: and it gives this explanation, (when true (do-this) (and-that) (and-return-this))

5:39 TEttinger: yep

5:40 ,(if true 15 :not-found :something-not-allowed)

5:40 clojurebot: #error{:cause "Too many arguments to if", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Too many arguments to if, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6732]} {:type java.lang.RuntimeException, :message "Too many arguments to if", :at [clojure.lang.Util runtimeException "Util.java" 221]}], :trace [[cloju...

5:40 TEttinger: ,(when true 15 :not-found :something-that-is-allowed)

5:40 clojurebot: :something-that-is-allowed

5:41 TEttinger: but when is pretty much exactly the same as (if test (do & body))

5:42 the only difference between an if with a do block for the "test is true" condition and no "test is false" block...

5:42 constl: ,(if true (do 15 :not-found) :something-that-is-allowed)

5:42 clojurebot: :not-found

5:42 TEttinger: the only one i can think of is that when is usually used by clojure programmers to show that it's being used for something stateful or side-efecting

5:43 exactly

5:43 and do is the simplest example of what the book would use & for

5:43 (do & body)

5:43 it just does every form in the body

5:43 in order

5:43 constl: Right!

5:44 Cheers for the insight

5:47 TEttinger: great! clojure's a fun language. (I think the most fun part is when someone else is writing java code and your clojure version ends up being a quarter the size)

5:48 (not accurate in the general case, I've had it be a fifth sometimes and 2/3 maybe sometimes)

5:48 constl: TEttinger: Well coming from a Java background and being an average Joe i would say it boils my brain

5:52 TEttinger: it was hard for me for a long time, tbh. it did click, in parts, the more I wrote

5:52 4clojure helped, if I was starting today I'd read the heck out of brave clojure

5:57 constl: TEttinger: Well i started with brave clojure but somehow i felt it moved too fast so i resorted to Clojure in action and it seems its ok for me.

5:57 What's 4clojure ?

5:57 TEttinger: it's an excellent koan-like site. it presents you with fill-in-the-blank problems

5:58 you write code that solves all of the blanks on the page

5:58 like one could be simple, (= 2 (+ _ 1))

5:58 so for that one you just enter 1

5:59 constl: I ll check that then, sounds fun

5:59 TEttinger: the next will be trickier, like (= "Hello, World!" (_ "World"))

6:00 where you would need to fill in a function that it would run with the arg "World"

6:01 by maybe 10-20 problems in (maybe earlier, I don't remember) they start being very tricky and challenging. a lot have you re-implement fns from clojure's library, without using those fns or sometimes certain similar ones

6:01 the one that has you reimplement nth is a fun one

6:02 constl: Do i have to register to start ?

6:03 I mean when you registered you are presented with a sequence of problems or is it just that you simply select which one to solve?

6:03 TEttinger: yeah, it's a good idea to register to keep track of your progress

6:03 you usually start with Number 1

6:03 (not sure if there's a 0)

6:04 a good piece of info that may be handy for the one with nth: several data structures clojure provides are also usable as functions, like maps can be used as functions that take a key as an argument and try to get that key in the map

6:04 ,({"alpha" 1 "beta" 2} "alpha")

6:04 clojurebot: 1

6:05 TEttinger: experiment a bit with what you can do there, trying a list, a vector, and a set for example

6:07 constl: but it will need to go hand by hand with some learning material, it's a learning source by itself right?

6:08 TEttinger: yeah, you would still need the book

6:08 it's more practice or exercises to test your knowledge in ways that you might not get otherwise

6:09 constl: hmm

6:10 is there a way to submit its form without the mouse ? like a keyboard shortcut ?

6:11 TEttinger: might be a good issue report, Raynes I think is a primary author

8:25 constl_: ,(println "Hello chan")

8:25 clojurebot: Hello chan\n

8:26 constl_: Im trying to create a simple function that you can pass two numbers and it will countdown from first to second

8:26 gfredericks: countdown like by printing?

8:27 constl_: gfredericks: Yes, and i'm using loop and recur but somehow the code i came up with doesn't look very optimal

8:27 Can i paste here for your opinion to this trivial question ?

8:27 gfredericks: use refheap.com

8:29 constl_: https://www.refheap.com/4f21f193624bf80669e7e6c16

8:30 gfredericks: constl_: the loop part is redundant, you can recur to the function itself

8:31 you can also replace (if c (do ...)) with (when c ...)

8:31 not sure what else you don't like abou it

8:32 constl_: gfredericks: So if i understood correctly its better to remove loop, and rebind decremented value to x and call that function again ?

8:35 Something like this https://www.refheap.com/99226

9:03 gfredericks: constl_: yeah it's a little simpler

9:03 constl_: you might also look at range and doseq for an alternative approach

10:11 catern: dear clojure fans

10:11 how would I idiomatically get the sequence of partial sum of another sequence?

10:12 i.e.: [1 2 3 4 5] -> [1 3 6 10 15]

10:12 (preferably lazily)

10:26 dysfun: catern: i'd probably do something like this:

10:26 ,(->> [1 2 3] (reductions conj []) rest (map (partial apply +)))

10:26 clojurebot: (1 3 6)

10:26 catern: :(

10:26 that does a lot of unnecessary work

10:27 wait!

10:27 dysfun: you're being silly!

10:27 reductions is the function to use

10:27 that's all I was looking for :)

10:27 ,(reductions + [1 2 3 4 5])

10:27 clojurebot: (1 3 6 10 15)

10:28 dysfun: aha, that's pretty nice

10:28 i haven't woken up properly today :)

10:28 i'm in grunt mode, so i'm writing tests

10:35 justin_smith: ,(reductions + [1 2 3 4 5])

10:35 clojurebot: (1 3 6 10 15)

10:35 justin_smith: ^ catern

10:35 oh, never mind

10:35 haha

10:37 expez: I think I'm making this harder than it should be, how can I get the content of a clj file without the (ns ..) form?

10:38 justin_smith: expez: as a string?

10:38 expez: justin_smith: yes

10:41 My first attempt skips into the ns form and then drops tokens from the string until a paren count of 0 is reached. But then I realized parens might occur (without being balanced) in the docstring so I would have to account for that.

10:41 catern: on the off chance

10:42 does anyone/can quickly think of a way to nicely and idiomatically do a queueing process simulation?

10:42 justin_smith: yeah, it's not an easy problem

10:42 catern: brb, /me goes off to think about it

10:42 justin_smith: sorry, expez: that is not an easy problem

10:43 catern: queueing process simulation, I would use either agents (which are all backed by queues they use to implement send / send-off) or core.async (channels are queues)

10:44 catern: justin_smith: not quite like that :)

10:44 gfredericks: expez: read can do this actually

10:44 justin_smith: oh, of course

10:44 catern: justin_smith: as in, I draw values from a distribution and accumulate them to get arrival times

10:44 but I just realized that I could search for examples in Haskell or something

10:44 gfredericks: ,(def my-file (java.io.StringReader. "(ns foo) (hey) (hooray)"))

10:44 clojurebot: #'sandbox/my-file

10:44 gfredericks: ,(read my-file)

10:44 clojurebot: #error{:cause "java.io.StringReader cannot be cast to java.io.PushbackReader", :via [{:type java.lang.ClassCastException, :message "java.io.StringReader cannot be cast to java.io.PushbackReader", :at [clojure.core$read invoke "core.clj" 3630]}], :trace [[clojure.core$read invoke "core.clj" 3630] [clojure.core$read invoke "core.clj" 3628] [clojure.core$read invoke "core.clj" 3626] [sandbox$eval47 i...

10:45 gfredericks: ,(def my-file (java.io.PushbackReader. (java.io.StringReader. "(ns foo) (hey) (hooray)")))

10:45 clojurebot: #'sandbox/my-file

10:45 gfredericks: ,(read my-file)

10:45 clojurebot: (ns foo)

10:45 gfredericks: ,(read my-file)

10:45 clojurebot: (hey)

10:45 gfredericks: ,(read my-file)

10:45 clojurebot: (hooray)

10:45 gfredericks: expez: ^

10:45 expez: gfredericks: that was my first though, to read the entire file and drop the first form I read, but that would change the formatting of the file when I spit it back out.

10:45 justin_smith: catern: ahh, not processes with queues for communication, but simulating the process of a queue

10:45 catern: justin_smith: indeed

10:46 gfredericks: expez: maybe you want a reader that knows how much has been read

10:46 justin_smith: catern: if you had an ordered list of entities, and some way to calculate how long each takes to get served, I would use reductions to get a series of wait times

10:46 gfredericks: there's gotta be something for that; all you need to know is the position of that last paren

10:47 expez: gfredericks: yeah

10:47 justin_smith: expez: shell out to elisp :P find the matching paren to the ns form, and drop the form

10:47 or call read to drop the ns form, and then slurp to get the rest unchanged, maybe

10:48 expez: justin_smith: the current implementation uses mechanical turk for human assistance, but since the op is sync this caused some users to complain about performance

10:48 gfredericks: ,(def my-file (java.io.PushbackReader. (java.io.StringReader. "(ns foo) (hey) (hooray)")))

10:48 clojurebot: #'sandbox/my-file

10:48 gfredericks: ,(read my-file)

10:48 clojurebot: (ns foo)

10:48 gfredericks: (slurp my-file)

10:48 ,(slurp my-file)

10:48 clojurebot: " (hey) (hooray)"

10:48 gfredericks: nice

10:48 justin_smith: there we bo

10:48 haha, go

10:49 expez: damn, that's hot stuff. Thanks!

11:21 catern: okay, I have an idea for my queue simulation

11:22 but I need to map over two seqs, and my mapping function needs to know the last value I created

11:22 ,(map f (range 5) (range 5 10))

11:22 clojurebot: #error{:cause "Unable to resolve symbol: f in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: f in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: f in this context", :at [clojure.lang.Ut...

11:23 catern: ,(map + (range 5) (range 5 10))

11:23 clojurebot: (5 7 9 11 13)

11:23 catern: but + also needs to have access to 5 while calculating 7, 7 while calculating 9, etc.

11:23 should I just mantain some mutable variable or is there a nice way to do that?

11:23 justin_smith: ,(map list (partition 2 1 (range 5)) (partition 2 1 (range 5 10)))

11:23 clojurebot: (((0 1) (5 6)) ((1 2) (6 7)) ((2 3) (7 8)) ((3 4) (8 9)))

11:24 gfredericks: does that sound like reduce at all?

11:24 justin_smith: gfredericks: sounds like a reduce to me yeah

11:24 catern: gfredericks: a little, but doing it with reduce would also be weird

11:24 because I'd need to recalculate the last value every time

11:25 (which would be fine, it'd just be weird... also what if there was randomness or state in the calculation of the last value?)

11:25 justin_smith: catern: you can do whatever you want to calculate each value, but the previous is an input, sounds like reductions

11:26 catern: justin_smith: not sure how reductions is any different from reduce here

11:26 justin_smith: catern: gives you the series

11:27 catern: yeah, but I can't access that series while I'm calculating it... well, I could, I suppose, but specifically I can't access the last element of that series

11:27 justin_smith: ,(reductions (fn [prev [a b]] (+ (/ prev 10.0) a b)) 0 (map list (range 5) (range 5 10)))

11:27 clojurebot: (0 5.0 7.5 9.75 11.975 ...)

11:27 justin_smith: catern: reduce makes it easy to access your previous result

11:27 as does reductions

11:28 catern: hmm

11:28 I'll try it

11:28 justin_smith: catern: and you absolutely can always get the previous value returned, it is the guaranteed first arg to your function in reductions or reduce

11:33 catern: so you want a running sum but also the previous args?

11:33 catern: justin_smith: yes, I think

11:34 justin_smith: ,(reductions (fn [[sum prev] [a b]] [(+ sum a b) [a b]] [0 0] (map list (range 5) (range 5 10)))

11:34 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

11:34 justin_smith: ,(reductions (fn [[sum prev] [a b]] [(+ sum a b) [a b]]) [0 0] (map list (range 5) (range 5 10)))

11:34 clojurebot: ([0 0] [5 [0 5]] [12 [1 6]] [21 [2 7]] [32 [3 8]] ...)

11:35 justin_smith: second one should have had nil as the init

11:35 but hopefully the idea should be clear - first item in pair is the running sum, second item is the previous pair

11:44 dysfun: win 20

11:45 catern: hey, yeah, reductions works perfectly, thanks justin_smith

11:45 justin_smith: np

11:48 wirrbel: Running lein ring server-headless, shouldn't my server just rebuild upon source changes?

11:49 justin_smith: no, it doesn't and won't

11:50 wirrbel: if you pass your app/handler whatever as a var, the server will see updates to the definition though

11:50 eg. #'my-app.core/handler instead of my-app.core/handler

12:24 gfredericks: when passed no args, alter-var-root returns a destructive transducer that just messes everything up

13:45 CL4Y3RSCLUB: SO?

13:52 justin_smith: ~so

13:52 clojurebot: so is (add-to-list 'erc-keywords '("\\bso\\b" erc-default-face))

13:52 Bronsa: makes sense clojurebot

13:53 justin_smith: oh, of course, that's how to unhighlight so, who isn't around anymore

13:53 $karma so

13:53 lazybot: so has karma -34.

13:53 justin_smith: the poor sould

13:53 *soul

13:54 Bronsa: lol

14:08 catern: (inc clojure)

14:08 lazybot: ⇒ 21

14:09 justin_smith: $karma Clojure

14:09 lazybot: Clojure has karma 21.

14:09 justin_smith: ahh, ignores caps

14:09 (inc clojure)

14:09 lazybot: ⇒ 22

14:09 justin_smith: $karma Clojure

14:09 lazybot: Clojure has karma 22.

14:14 justin_smith: noncom: I found support for unquoted field names in cheshire

14:14 noncom: https://github.com/dakrone/cheshire/blob/master/src/cheshire/factory.clj#L15

14:30 gfredericks: justin_smith: oh hey look at those dynamic vars

14:30 I'm trying to figure out if they can be used to solve the global extensibility problem

14:30 justin_smith: gfredericks: that's what I was looking for when I found those actually :)

14:31 gfredericks: ,'com.fasterxml.jackson.core.JsonFactory

14:31 clojurebot: com.fasterxml.jackson.core.JsonFactory

14:31 justin_smith: sadly I don't think the coercions are per-factory

14:31 gfredericks: ,com.fasterxml.jackson.core.JsonFactory

14:31 clojurebot: #error{:cause "com.fasterxml.jackson.core.JsonFactory", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.ClassNotFoundException: com.fasterxml.jackson.core.JsonFactory, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.ClassNotFoundException, :message "com.fasterxml.jackson.core.JsonFactory", :at [java.net.URLClassL...

14:31 gfredericks: &com.fasterxml.jackson.core.JsonFactory

14:31 lazybot: ⇒ com.fasterxml.jackson.core.JsonFactory

14:31 justin_smith: if they were, yeah, the logger could have its own factory

14:31 gfredericks: &(.isInterface com.fasterxml.jackson.core.JsonFactory)

14:31 lazybot: ⇒ false

14:32 gfredericks: hmph

14:33 yeah I guess if cheshire coerces everything beforehand

14:33 justin_smith: yeah, it uses the JSONable protocol, with a single method, to-json

14:33 and that can't be a local binding

14:35 and clojure.data.json has the JSONWriter protocol, with -write method

14:37 gfredericks: I feel like I asked stu about this assymetry a couple years back, but have no idea what he said

14:40 maybe that was more about data readers

14:42 I guess transit avoids the global thing a bit better than clojure's printer does

14:45 justin_smith: gfredericks: oh, that's a great point, maybe transit would be the best backend for this

14:45 gfredericks: what

14:45 for what

14:45 what are we

14:45 is this even talking about

14:48 justin_smith: never mind, I may have been confusing transit for something else

14:48 I thought it would work with various formats, but no

14:48 that's not the one

14:49 gfredericks: no transit is like a frontend

15:00 tomjack: isn't transit what happens between ends?

15:01 (and starts and stops I suppose)

15:03 justin_smith: tomjack: there is a specific lib for sending data between processes called transit

15:03 tomjack: yes :)

15:04 but the name was chosen with some care, I presume

15:17 matthavard: How would I add this library as a dependency: https://github.com/dcolthorp/matchure

15:17 oh oops there's an installation section ignore me

15:18 justin_smith: matthavard: have you tried [matchure "0.10.1"] ? that's what it has in the project.clj

15:18 oh yeah, that's what it would tell you to do also

15:18 matthavard: Yeah haha I'm dumb I was trying [org.clojure/matchure "0.10.1"]

17:20 sveri: Hi, how can I define a return type of Foo[] for a clojure method? (defn ^Foo[] fname seems not to work for me

17:31 scottj: sveri: maybe ^"[Lnamespace.Foo;"

17:33 sveri: scottj: I just found some thread from 2009 suggesting this should work: #^"[Lnamespace.Foo;" But your one looks like it works in the latest clojure, at least that how ever return type definitions are declard

17:33 Thank you very much

17:35 scottj: ^ used to be #^, afair

17:35 sveri: Yea, that makes sense :-)

18:47 noncom|2: is there any particular reason on why a lein's project file is a call to some (defproject ..) instead of being a simple edn {} ?

18:49 tolstoy: noncom|2: Total guess, but defproject is a macro and probably does some lightweight transformation?

18:50 justin_smith: yeah, I think that's pretty much it

18:50 noncom|2: tolstoy: yeah, sure, i think.. but i totally see no reason for it being this way. afaik project.clj is a plain data map, so why complicate the file with a call to some fn or macro?

18:50 justin_smith: tolstoy: it supports heavy weight transformation via ~

18:50 noncom|2: ah, so it's about ~

18:50 justin_smith: that could be part of it, at least

18:50 you can evaluate arbitrary code in there

18:51 noncom|2: uh..

18:51 does not seem to clean though.. but probably useful at times

18:51 s/to/too

18:51 justin_smith: I'm not saying it's a good idea

18:51 I am saying it's possible

18:52 and it would make reading a project.clj as edn a problem

18:52 also, a project.clj is only the parts of the config you altered, it gets merged with the base options

18:52 unless you used ^:replace, etc. etc.

18:53 btw, noncom|2, did you see my link earlier about being able to replace cheshire's json-factory with one that supports raw keys in maps?

18:53 it's in factory.clj

18:54 noncom|2: i did not see the link! but i know that it is possible to (binding ..) factory for a json operation, but it only affects reading..

18:54 was there something about writing a json string too?

18:54 justin_smith: factory is for generating

18:55 well, maybe not only for generating, but it definitely affects generation

18:55 tolstoy: You can have multiple forms in project.clj, so one of 'em has to be tagged as the project.

18:55 noncom|2: it's like string -> factory -> clojure data struct

18:55 justin_smith: it's also like clojure data struct -> factory -> string

18:55 noncom|2: wow, did not notice that this was possible

18:55 tolstoy: https://github.com/technomancy/leiningen/blob/master/leiningen-core/src/leiningen/core/project.clj#L398-L405 Suggests that (def project {}) works, too.

18:55 noncom|2: do you still have the link?

18:56 justin_smith: https://github.com/dakrone/cheshire/blob/master/src/cheshire/factory.clj#L15

18:56 tolstoy: I am enlightened but not surprised :) cool

18:56 noncom|2: tolstoy: yeah, looks like we have the potential to write another OS with lein projects :D

18:56 justin_smith: haha

18:57 noncom|2: note that the comments there explicitly state that the factory is used for both encoding and decoding

18:59 noncom|2: justin_smith: so, this factory, yes.. i tried it, but i only managed to make cheshire use it when reading.. the properties are mapped to JsonParser class.. which sounds like it parses the string. however, right.. the comment says both enc/dec..

18:59 i must give it a second, closer look at monday

19:00 playing with neo4j, yeah, in making a little mudy thing :)

19:00 this neo4j takes in this wrong kind of json as parameters for its objects. the json kind without the quotes on fields names

19:06 underplank: So Im trying to get a repl working in emacs using cider-jack-in command. And the repl seems to be starting, but I can get the buffer to open. Any ideas how to get that to happen?

19:07 justin_smith: underplank: can you use M-x cider to connect to a repl that is already open?

19:09 underplank: hmm… thats wierd. I dont get a prompt or anything.

19:09 It looks like I have the connections, but nothing executes.

19:12 justin_smith: underplank: has cider ever worked for you in the past? do you have the cider-nrepl plugin set up?

19:13 underplank: I’ve had it working in the past. lein deps :tree shows that I have 0.8.2 installed. I do that in my lein profiles.clj

19:13 Do I need to have that in my project.clj as well?

19:13 justin_smith: no

19:14 underplank: hmm.. I didnt think so.

19:14 justin_smith: if it has worked in the past, the likely problem is that you upgraded your cider elisp without deleting the elc files

19:14 cider breaks binary compatibility, and elc doesn't handle that nicely

19:17 underplank: ahh. that might make sense. I think my emacs.d folder is in a … not great state..

19:18 justin_smith: find . -name '*.elc' will show you where they are

19:18 because of how elisp works, it can be effected by elc files that are not part of cider proper, if they call things in cider

19:19 underplank: yeah looks like I have like three versions in here or something.

19:19 whoops!

19:19 justin_smith: when I said "binary compatibility" above, I should have said API compatibility (argument types, counts, etc. etc.)

19:19 well, that can be fine, as long as you are loading the right one

19:19 heh

19:20 underplank: are elc files just like compiled version of source, so If I blow them away it will rebuild the ones it needs?

19:20 justin_smith: they are like aot

19:20 if they don't exist, emacs will just use the source files

19:20 and startup may take a little longer

19:20 underplank: ahh great.. thats what I thought.

19:27 justin_smith: works! just cleaned up a few packages and installed the latest.. thanks!

19:27 justin_smith: np

19:28 bordatoue: could anyone please tell me how to change nrepl version 0.2.6 to 0.2.8 under lein , currently I had created ~/.lein/profiles.clj file with the following setting {:user {:plugins [[cider/cider-nrepl "0.9.0-SNAPSHOT"]]

19:28 :dependencies [[org.clojure/tools.nrepl "0.2.7"]]}}

19:29 justin_smith: why do you ask for 0.2.7 ?

19:29 bordatoue: ok need to change it from 0.2.6 --> 0.2.7 ; the

19:29 the problem is it downloads the 0.2.7 jar but still startsup with 0.2.6

19:30 tolstoy: bordatoue: It's up to 0.2.10 now.

19:30 bordatoue: it seems to only work if I add the dependencies under the project.clj file

19:30 tolstoy: the point is i can't get it to work with any version other than 0.2.6 it keeps chaning every day

19:31 justin_smith: bordatoue: there's a weird issue, you may also be able to use :dev rather than :user in profiles.clj to get the proper version

19:31 tolstoy: bordatoue: I added 0.2.10 under {:dev {:dependencies ...}} as it's just used for nrepl. Seems to work okay.

19:32 bordatoue: i can't understand this why they keep chaning this all the time , everytime i update my emacs then the entire repl breaks

19:32 tolstoy: I will try that, thanks a lot

19:32 justin_smith: bordatoue: this is why I stopped using cider, the development is too chaotic

19:32 tolstoy: yeah, that's what I was trying to suggest :)

19:32 bordatoue: justin_smith: what do you use

19:33 justin_smith: bordatoue: inferior-lisp, which has 0 features, but it actually works

19:33 bordatoue: have you tried intellij plugin for clojure is it any good

19:33 justin_smith: eg. I don't even get completion or anything

19:33 bordatoue: i don't mind any feature but consistency is my top priority

19:33 justin_smith: bordatoue: I'm too much of an emacs addict, but I have heard nothing but good things about it, and have watched people use it and been pretty impressed

19:34 cursive that is

19:34 mfikes: bordatoue: Yes, Cursive is great.

19:34 justin_smith: bordatoue: yeah, I switched to inferior-lisp because I was tired of the break / update cycle

19:34 bordatoue: great guys, I will give it a try

19:35 tolstoy: I stuck with 0.8.2 for a long while. Seemed stable to me.

19:35 inf-clojure has its appeal.

19:38 bordatoue: tolstoy: can you please paste what you have entered in your profile.clj file

19:38 i tried :dev :dependencies and it is still not working

19:38 tolstoy: bordatoue: Sure, but I don't use profiles.clj for that anymore.

19:39 bordatoue: then what do you use ? are u adding it to the project.clj file

19:39 tolstoy: What's the refthingy we can paste to?

19:39 justin_smith: http://refheap.com

19:40 freddd: can anyone tell me if transducers and reducers play nice? as in, is it possible to use transducers for most of a pipeline, but use reducers/fold for the final combination for the fork/join parallelism benefits?

19:40 tolstoy: https://www.refheap.com/99240

19:41 bordatoue: Here's a more complete :profiles vector in my project.clj file (for a super new project): https://www.refheap.com/99241

19:42 underplank: Hi all.. When using uberjar what is the difference between the standalone jar and the uhh non-standalone jar?

19:42 freddd_: dang, got cut off just after asking my question regarding reducers/transducers. if anyone replied, would you mind replying again? :)

19:42 bordatoue: so everytime you create a project you need to explicitly add this

19:43 justin_smith: underplank: one contains your project, the other contains your project plus all deps, it uses the project one as part of constructing the other one

19:43 tolstoy: bordatoue: I do that just for my own self so that I'm super clear what's interfering with my project. Personal taste.

19:43 underplank: ahh.. is there a reason you would want to use the non-standalone?

19:43 justin_smith: freddd_: as long as you are using transducers and reducers properly, they should combine just fine, yes

19:44 underplank: not really, it gets created as part of making the other one

19:44 bordatoue: tolstoy: thanks

19:44 underplank: is there a way you can tell uberjar to just make the standalone one?

19:44 BengComps: I have been trying to run clojure on a macbook has anybody succedeed?

19:44 justin_smith: underplank: like I said, it uses it while making the other one, so the option isn't to make it or not, it is to delete it or not, but I don't think it has an option for deleting it

19:45 underplank: BengComps: doing it right now. what seems to be your problem?

19:45 justin_smith: fair enough

19:45 BengComps: any link should help, where to start underplank

19:45 underplank: I would start with Leiningen.

19:45 justin_smith: BengComps: I think more people use osx for clojure than use windows

19:46 underplank: http://leiningen.org/

19:46 justin_smith: lein is just a single download

19:46 very easy to use

19:47 BengComps: Thanks a lot guys

19:47 Right on it

19:47 just for curious sake does any of you uses latex? and if so how do you run texmaker on yosemite

19:48 justin_smith: someone was talking the other day about using org mode with latex and clojure together, but now I forget who it was

19:49 to do inline calculations, then charts and such from those calculations

19:50 BengComps: I have been using sharelatex.com but the online compiler crashes as soon as my documents has a lot media content in it

19:52 tolstoy: Ugh. It's difficult when folks use that graphic for Clojars dependency declarations. Can't select it!

19:53 justin_smith: tolstoy: that graphic is svg, svg is selectable

19:53 unless your browser is bad

19:53 tolstoy: I mean select it to paste it into Emacs. Hm.

19:53 justin_smith: tolstoy: right, it has real text in it

19:54 which you can Control+F for, or drag and select etc.

19:54 tolstoy: Yeah, it doesn't select for me. Safari loses?

19:54 justin_smith: I guess

19:54 hmm, one moment

19:54 tolstoy: remind me again one of the libs that uses that?

19:54 tolstoy: https://github.com/xsc/pandect ;; works for you there?

19:55 justin_smith: tolstoy: oh man, they way they embed it, it doesn't actually work

19:55 underplank: oh.. yeah that does seem anoying… is it because it comes straight from clojars?

19:55 so they dont have to update it?

19:55 tolstoy: No idea.

19:55 justin_smith: so I guess I should have said, svg text *should be* selectable

19:56 andyf: BengComps: There is a program called MacPorts that lets you install many different open source software packages, including latex.

19:56 underplank: Yeah. Its way of getting the latest version from clojars in the README and not have it out of date.

19:56 the md is [![Clojars Project](http://clojars.org/pandect/latest-version.svg)](http://clojars.org/pandect)

19:56 justin_smith: underplank: I knew it - you have to open the svg itself

19:56 https://camo.githubusercontent.com/63193fb6d7a245fd83b93937eed69353e06121f9/687474703a2f2f636c6f6a6172732e6f72672f70616e646563742f6c61746573742d76657273696f6e2e737667

19:57 on the svg itself (accessed via right-click / open image in new tab) you can select the text

19:57 underplank: annoying..

19:57 justin_smith: the problem is the way it is embedded, or the css in the parent document

19:57 tolstoy: You might as well just click on it, _then_ select the text.

19:58 justin_smith: right, but theoretically, since it is an svg, the text should be selectable

19:58 underplank: I guess the problem is making it a cross realm query… svg/images makes that easy. I guess if you wanted it as text you would have to soemthing else? jsonp or something?

19:58 justin_smith: but it isn't when inside that page, for some weird reason

19:59 underplank: yeah, I think that's part of it

20:00 I've always thought svg was underutilized and poorly exploited. The fact that you can exactly control the display, and it has selectable / copyable text is awesome

20:00 and under utilized

20:00 Frozenlock: It is.

20:01 A project in cljs almost entirely in SVG https://labs.hvac.io/editor

20:01 justin_smith: cool, is that yours?

20:01 Frozenlock: yes

20:01 justin_smith: very nice!

20:02 tolstoy: That's really great.

20:03 * justin_smith is making an hvac katamari ball out of everything on the itnro page

20:03 justin_smith: lol

20:03 Frozenlock: justin_smith: Make sure to save it :-p

20:04 justin_smith: nice!

20:05 Frozenlock: was this a student thing, or a learning exercise?

20:06 Frozenlock: No, it's a project in development for my own needs.

20:07 justin_smith: cool

20:11 Frozenlock: (thus the rough edges)

21:16 catern: I have two infinite sequences

21:16 I'd like to merge them, sorted by some comparator

21:16 idiom?

21:17 TEttinger: I'm not sure if there's a way to sort a literal infinite sequence

21:17 catern: ah... good point...

21:17 andyf: I think catern means to merge them, producing a new infinite sequence?

21:17 catern: both of them are increasing sequences, though

21:18 andyf: I assumed you meant that the two were already sorted

21:18 catern: andyf: yes

21:18 (temporarily forgot that after TEttinger's remark)

21:18 andyf: Merging them is possible. Can hack up a few lines of code here in a minute or three. No 1-line version I?m aware of

21:18 justin_smith: I know I've written this function before

21:18 and yeah, it was like a three liner

21:19 catern: three lines?! so verbose ;_;

21:19 TEttinger: ha

21:19 ccallebs: Is there a specific clojure beginners channel?

21:19 catern: #clojure-beginners

21:19 ccallebs: Ah, nevermind. I see it in the MOTD :)

21:19 catern: :)

21:19 ccallebs: Sorry, using a new IRC client and it wasn't immediately obvious.

21:20 catern: so, what would be the general approach to this merging?

21:20 i mean

21:20 I guess I know how to actually manually do this

21:20 * catern ratchets down his brain from higher-order-functions-land

21:25 sobel: why might timbre prevent a (fairly simple) program from exiting after its -main returns?

21:25 i've narrowed it down to: if i call (info) to make a log entry it doesn't exit.

21:25 if i don't make any log calls, it exits normally

21:29 justin_smith: ,(defn merge-sort [& seqs] (let [[[s0 & ss :as s] & seqs] (sort-by first (remove empty? seqs))] (lazy-seq (when (seq s) (cons s0 (apply merge-sort (cons ss seqs)))))))

21:29 clojurebot: #'sandbox/merge-sort

21:29 freddd_: hey, again. i'm mapping over a list of files and would like to ultimately have a hash-map output with keys of the file names and values of the file contents. the solution i'm using seems lacking, and i'm wondering if anyone can offer some advice. mock code here: https://www.refheap.com/99243

21:29 justin_smith: ,(merge-sort [0 1 2 3] [2 3 4] [-1 8 9 10])

21:29 clojurebot: (-1 0 1 2 2 ...)

21:30 justin_smith: that's a mouthful of a destructuring

21:31 freddd_: you can use a vector instead of a hash-map for each one

21:31 freddd_: also, unless the keywords ever get used as literals in your code, it's better to just keep the strings as keys

21:32 sobel: try shutdown-agents

21:32 sobel: timbre might be using futures in order to avoid slowing down your code, since the logging produces no result your code needs

21:32 sobel: likely

21:33 justin_smith: sobel: it uses a future to get your hostname? not seeing other usages of future (other than logged-future, but I don't see any calls to that within its codebase)

21:33 freddd_: justin_smith: isn't it still wasteful to create some inner collection that just gets flattened anyway?

21:33 justin_smith: anyway, all it takes is one call to future, then you need shutdown-agents

21:34 freddd_: the vector does not get flattened, because maps are made of two element vectors

21:34 sobel: justin_smith: thanks! that was far from clear to me.

21:34 justin_smith: and it can reuse the underlying datastructure (and does)

21:35 sobel: (and fixed my not-exiting problem, which i diligently chased from the stupid start of my processing chain)

21:35 justin_smith: freddd_: eg. ##(seq {:a 0 :b 1 :c 2})

21:35 lazybot: ⇒ ([:c 2] [:b 1] [:a 0])

21:35 sobel: s/diligently/stupidly

21:35 justin_smith: freddd_: those are the vectors I am talking about ^

21:35 catern: oh, I forgot to highlight you when I pasted my merge-sort above

21:36 anyway, my merge-sort, which I pasted above, should do what you want

21:36 catern: justin_smith: yeah, I got it. I actually need to do sort-by kind of thing, so I'm modifying it

21:36 andyf: catern: Not nearly as pretty, and only works for 2 input sequences, but https://gist.github.com/jafingerhut/41e9ceb258d1ddf05eff

21:37 sobel: one more i haven't solved: i got timbre logging to a file but can't disable console output

21:37 justin_smith: andyf: that one is likely faster for the two list case than mine though

21:37 sobel: did you remove the console logger from its config atom?

21:38 sobel: justin_smith: not finding the key easily

21:39 aha :standard-out

21:39 justin_smith: sobel: it will be one of the :appenders

21:39 yeah

21:40 you should be able to dissoc that from the atom

21:40 catern: hmmm

21:41 sobel: it has a convenienc fcn

21:41 ok, sweet. shoulda come here sooner. haha. and had more confidence in the WORKING part of my code.

21:42 justin_smith: heh

21:45 catern: thanks again justin_smith

21:46 yours is cool too andyf :)

21:47 morgan_: hi all, i have a question about clojure's data representation philosophy. when i have some data, do i annotate it with type information even when this is unnecessary for the logic of the program?

21:48 simple example. to represent a point in the plane, should i just use a pair [x y] of doubles

21:48 or should i define a record, like

21:48 (defrecord point [x y])

21:52 justin_smith: morgan_: a record is an extended hash map, so it is easy to code with maps {:x 1 :y 3.3} and upgrade to a record later if you need it

21:53 also, records are idiomatically capitalized, because they generate a Class

21:54 morgan_: justin_smith: thanks! so let me see if this correct: in idiomatic clojure, you wouldn't define a record for a type of data unless you needed the special capabilities of records (ability to implement protocols, etc., i assume). correct?

21:55 justin_smith: right

21:55 catern: zomg

21:55 morgan_: ok, thank you!

21:55 catern: why is dissoc even in the language when disj is there

21:56 justin_smith: because sets are not associative?

21:56 ,(disj {:a 0} :a)

21:56 clojurebot: #error{:cause "clojure.lang.PersistentArrayMap cannot be cast to clojure.lang.IPersistentSet", :via [{:type java.lang.ClassCastException, :message "clojure.lang.PersistentArrayMap cannot be cast to clojure.lang.IPersistentSet", :at [clojure.core$disj invoke "core.clj" 1453]}], :trace [[clojure.core$disj invoke "core.clj" 1453] [sandbox$eval25 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval...

21:57 catern: aw :(

21:57 justin_smith: ,(dissoc #{:a} :a)

21:57 clojurebot: #error{:cause "clojure.lang.PersistentHashSet cannot be cast to clojure.lang.IPersistentMap", :via [{:type java.lang.ClassCastException, :message "clojure.lang.PersistentHashSet cannot be cast to clojure.lang.IPersistentMap", :at [clojure.lang.RT dissoc "RT.java" 806]}], :trace [[clojure.lang.RT dissoc "RT.java" 806] [clojure.core$dissoc invoke "core.clj" 1438] [sandbox$eval49 invoke "NO_SOURCE_FI...

21:57 catern: (i thought disj worked on maps)

21:57 justin_smith: catern: it would make sense to have one function that does both

21:57 catern: would it?

21:57 justin_smith: but probably too late for that design decision

21:57 catern: an inverse of conj, I guess

21:58 catern: yeah

21:58 disj

21:58 justin_smith: catern: but conj works on maps

21:58 and lists

21:58 catern: yeah, disj should work on them

21:58 justin_smith: and vectors

21:58 TEttinger: and sets

21:59 justin_smith: TEttinger: well, luckily disj already works on one of these things

21:59 TEttinger: heh

21:59 ...futures?

22:04 justin_smith: ,(clojure.string/join "☃" "")

22:04 clojurebot: "☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃â˜

22:04 justin_smith: &(clojure.string/join "☃" "")

22:04 lazybot: ⇒ "☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃â˜

22:04 justin_smith: omghax

22:05 TEttinger: ,(count "")

22:05 clojurebot: 135

22:05 * justin_smith giggles.

22:05 TEttinger: I had to press left a lot to get through all them BOMs

22:06 ,(map int "")

22:06 clojurebot: (65279 65279 65279 65279 65279 ...)

22:08 TEttinger: ,(distinct "")

22:08 clojurebot: (\)

22:11 Seylerius: What was clojurebot's prefix for an inline eval?

22:11 TEttinger: lazybot uses ##

22:11 like this ##(+ 1 2 3)

22:11 lazybot: ⇒ 6

22:12 justin_smith: Seylerius: but it needs some matching pair of brackets, otherwise talking about certain IRC channels would get annoying

22:13 catern: maybe it's ,,(inc 1)

22:14 sobel: how would i figure out, short of trying it, whether Robert.Hooke works in ClojureScript?

22:16 justin_smith: I forget whether clojurescript has vars (wiki still says no) but if not, then it won't work at runtime

22:16 afaik

22:16 https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure#concurrent-programming

22:17 Seylerius: TEttinger, justin_smith: Thanks. I thought I saw something about clojurebot being able to do that too, but I can't find where someone mentioned it.

22:39 d9k_: Hi! How to check in clojure module whether it's running from LightTable instarepl or from lein run?

22:50 justin_smith: d9k_: for one thin, lein run will call -main, the instarepl will not

22:50 unless you make it do that, of course

22:52 eraserhd: I'm having a huge brain fart.... how does one lexicographically compare vectors?

22:52 justin_smith: eraserhd: compare

22:53 ,(compare [:a :b :c] [:b :c :d])

22:53 clojurebot: -1

22:54 eraserhd: justin_smith: Thanks.

23:00 getting close to the next avi release: searching (`/`, `?`, `n`, `N`, `*`, and `#`).

23:00 I shall implement syntax highlighting as my next big project, I think.

23:09 d9k_: How to check in clojure module whether it's running from LightTable instarepl or from lein run? [2]

23:09 justin_smith: d9k_: -main will get run from lein run, but probably not from an instarepl

23:10 d9k_: also, there is a :repl profile in lein, which you could combine with environ for some detection magic

23:10 d9k_: but your question makes me suspect that you have top level side effects, and you wouldn't need to worry about this if you moved them into function definitions

23:16 d9k_: justin_smith, thanks, better than nothing

23:17 justin_smith: d9k_: unless you need to call -main from the instarepl, I would just set a var inside -main

23:26 tolstoy: How do you tell if a Datomic db has been initialized with the attributes you want?

23:26 If you transact all the attributes over again, you get a new "hash value" back when you (d/db conn).

23:32 I suppose I can use d/attribute to see if any of the attributes have been defined.

Logging service provided by n01se.net