#clojure log - Aug 20 2014

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

0:07 lpvb: window down

0:08 munderwo: Hi all. Im trying to get a random jar into my clojure project. Im not sure what im doing wrong.

0:08 https://www.refheap.com/89290

0:29 sm0ke: ,(System/currentTimeMillis)

0:29 clojurebot: 1408508973210

0:30 sm0ke: ,(Runtime/freeMemory)

0:30 clojurebot: #<CompilerException java.lang.SecurityException: Reference To Runtime is not allowed, compiling:(NO_SOURCE_PATH:0:0)>

0:30 sm0ke: ok whatever clojurebot, but clojure treats freeMemory as a field?

0:31 amalloy: sm0ke: uhhhhh, no? you're trying to access it as if it were static, but it is not

0:32 sm0ke: ugh its not static

0:32 amalloy: ,(.freeMemory (Runtime/getRuntime))

0:32 clojurebot: #<CompilerException java.lang.SecurityException: Reference To Runtime is not allowed, compiling:(NO_SOURCE_PATH:0:0)>

0:32 sm0ke: crap getRuntime has to be used

0:32 amalloy: &(.freeMemory (Runtime/getRuntime))

0:32 lazybot: ⇒ 10343936

0:32 amalloy: i bet lazybot should be blocking that

0:33 sm0ke: &(.totalMemory (Runtime/getRuntime))

0:33 lazybot: ⇒ 61341696

0:33 sm0ke: wow so poor

0:34 amalloy: lazybot is run with a reasonably-sized heap. giving multiple gigs to tiny little processes just makes them run worse

0:34 sm0ke: i think i has a moment

0:34 amalloy: how can it make things worse

0:34 its just misuse

0:35 amalloy: if you let garbage pile up for minutes at a time before cleaning it up, the gc process is long and pointlessly slow

0:35 with a small heap that fills up reasonably quickly, gc is more frequent but much faster

0:36 that's the main issue, but there are probably others

0:36 sm0ke: gc sucks

0:36 i think ruby has far better gc than jvm

0:36 amalloy: that's possibly the worst language you could have picked. the jvm's gc is excellent compared to like every other language that exists, and ruby has one of the worst

0:36 sm0ke: i remember java user agreement used to have a clause for not using java in nuclear reactors and stuff

0:37 mission critical i.e.

0:37 mdeboard: trollin'

0:37 amalloy: $google java is not for nuclear reactors

0:37 lazybot: [Java is no good for nuclear power plants - Everything2.com] http://everything2.com/title/Java+is+no+good+for+nuclear+power+plants

0:37 sm0ke: mdeboard: no its a fact

0:37 look it up

0:37 mdeboard: :P

0:37 amalloy: that part's actually true

0:37 danielcompton: what's the difference between & and , for clojurebot?

0:37 amalloy: everything else you've said is pretty misinformed

0:38 danielcompton: try them both, compare what happens, and see if you can figure it out

0:38 danielcompton: &(+ 1 1)

0:38 mdeboard: Definitely a troll. Join the channel right to throwing bombs :P

0:38 sm0ke: amalloy: really is ruby that bad

0:38 lazybot: ⇒ 2

0:38 danielcompton: (,+ 1 1)

0:38 mdeboard: But hey, enjoy

0:38 amalloy: mdeboard: he always does that

0:38 danielcompton: ,(+ 1 1)

0:38 clojurebot: 2

0:38 sm0ke: i think they made huge improvements lately to their gc

0:38 mdeboard: "Clojure reminds me of hte XBox 360. You take one look at it, do a 360 then walk away"

0:39 amalloy: that's what i hear too, re ruby's gc. i haven't tried the new one

0:39 Clarice: where there's sm0ke there's fire

0:39 mdeboard: "*awaits comments about how 360 is a full circle*"

0:39 maybe i spend too much time on the internet

0:39 sm0ke: Clarice: its true look it up

0:39 Clarice: nobody cares.

0:39 danielcompton: ,(.freeMemory (Runtime/getRuntime))

0:39 clojurebot: #<CompilerException java.lang.SecurityException: Reference To Runtime is not allowed, compiling:(NO_SOURCE_PATH:0:0)>

0:40 danielcompton: &(.freeMemory (Runtime/getRuntime))

0:40 lazybot: ⇒ 26988248

0:40 Clarice: Speaking of garbage collectors, I've been reading about Azul. Really cool technology.

0:41 sm0ke: i rather buy a 5$ ram than a 1000$ tech

0:41 lpvb: ruby runs on the jvm too

0:42 sm0ke: and your pointis?

0:43 Clarice: ,(kick sm0ke)

0:43 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: kick in this context, compiling:(NO_SOURCE_PATH:0:0)>

0:43 Clarice: :'(

0:43 amalloy: danielcompton: have you figured it out yet? if not, here's a hint. pay more attention to who's responding to your eval requests

0:43 sm0ke: try inc Clarice

0:43 danielcompton: amalloy: dur, got it

0:44 I can only run my bitcoin miner on lazybot

0:44 sm0ke: really are people still mining?!

0:45 lpvb: if people weren't mining, bitcoin would cease to operate

0:45 sm0ke: i heard that bitcoins actually was a product from silk market

0:45 those people made it for illegal transactions and now all of sudden its legal everywhere

0:46 amalloy: danielcompton: naw, both bots have plenty of backdoors into eval

0:46 but i bet clojurebot has more free memory for you to mine with

0:46 lpvb: I'm sorry this is off-topic, I won't discuss this with you further.

0:46 joshuafcole: Is there a way to "splat" a list into multiple arg slots of a fn?

0:47 I could do the opposite, apply

0:47 sm0ke: is it? lets make a miner in clojure

0:47 :D

0:47 danielcompton: (inc amalloy)

0:47 lazybot: ⇒ 161

0:47 * danielcompton leaves

0:47 joshuafcole: but the function has 4 params and conjing a bunch of unrelated stuff feels less readable to me

0:48 sm0ke: seems like there already is one https://github.com/pelle/bitcljoin

0:48 terrible name though

0:48 amalloy: i don't understand the question, joshuafcole

0:48 sm0ke: bitcljoin :D

0:49 joshuafcole: I have a function which has a rest param. It calls another function with several fixed params and then a rest param. I'd like to just tack the first rest param into the last fn. In Python, a list can be "splatted" into multiple fn parameters

0:49 Kind of like call-side destructuring

0:50 I don't know of an analog in clojure, but I figure there's probably something I don't know the right terminology to find.

0:50 Clarice: you mean like let [a, b, c] = thatListOrWhatever in f(a,b,c)?

0:50 sm0ke: apply should do that

0:51 amalloy: i think you probably just want apply. if you can't figure out how to use apply for this, then please paste a more specific function definition so you can get concrete advice

0:51 joshuafcole: I could use apply, but there are 3 fixed params before I want to tack the rest param on

0:51 amalloy: (apply f x y z rest)

0:51 joshuafcole: Yeah, it's not that I couldn't, just that it doesn't look readable

0:51 Oh wait

0:51 apply let's you specify fixed params before the rest?

0:52 Clarice: No, but the act of supplying those arguments to f does that.

0:52 lpvb: joshuafcole: yes

0:52 joshuafcole: *checks docs*

0:52 amalloy: even if it didn't (it does), it's not hard to use a baby version of apply

0:52 joshuafcole: Whoops, now I feel silly

0:52 sm0ke: ,(apply + 1 2 3 (range 10))

0:52 clojurebot: 51

0:52 amalloy: (apply f (concat [x y z] rest))

0:52 joshuafcole: exactly what I wanted built in

0:52 Thanks

0:53 sm0ke: seems like clojure has a function for everything

0:54 hey does clojure has a function for finding is a element belongs to a seq ? :P

0:54 heh flame wars

0:58 lpvb: ,(some (partial = 3) (range 1 10))

0:58 clojurebot: true

1:00 sm0ke: ,(#{1 2 3 4} 4)

1:00 clojurebot: 4

1:00 sm0ke: doesnt mean anything

1:01 lpvb: sm0ke: what doesn't mean anything?

1:02 sm0ke: since everything in clojure is internally a tree..i think finding an element in a vector can be much more efficient than what you showed

1:03 lpvb: the fact that you cooked up a naive method to do so or i used set's property to find an element

1:03 lpvb: ,(seq? #{1 2 3 4})

1:03 clojurebot: false

1:04 sm0ke: ,(sequential? #{1 2 3})

1:04 clojurebot: false

1:05 sm0ke: ,(instance? ISeq #{1 2 3})

1:05 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ISeq in this context, compiling:(NO_SOURCE_PATH:0:0)>

1:05 sm0ke: ,(instance? clojure.lang.ISeq #{1 2 3})

1:05 clojurebot: false

1:05 sm0ke: ugh

1:08 ,(seq #{1 2 3})

1:08 clojurebot: (1 3 2)

1:08 sm0ke: every function which works for seq like conj, cons, works with set

1:09 its amazing that clojure didnt provide a contains? which is also unified across data structures

1:10 oh wait there is a contains but of different sematics

1:10 ,(doc contains?)

1:10 clojurebot: "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'."

1:29 joshuafcole: I'm getting an illegal state exception when I try to :use clojure.core.matrix.operators (it's complaining that it's trying to overwrite already bound things like ==, which is the idea)

1:30 How do I handle that exception?

1:32 sm0ke: dont use it

1:32 i mean require it as something

1:34 joshuafcole: Well. Yeah, I could not use it.

1:34 But I'd rather use it

1:34 It'd be nice to be able to write (* 10 [1 3 5])

1:34 than having to map and do other silly things for simple vector maths

1:34 sm0ke: then exclude the those from clojure.core

1:34 joshuafcole: I could rename it

1:35 but that's also not quite as nice.

1:35 Oh? I'll look into that, but I imagine it's probably a goodly number of operators

1:35 there's really no way to suppress the exception?

1:36 It really feels more like a warning situation than an exception one in the first place

1:37 Looks like it's only 4 operators in core.matrix, so I'll work with excludes for now. Thanks sm0ke

2:36 justin_smith: joshnz: you can (:refer-clojure :exclude [== ...])

2:36 n/m

2:36 joshnz: wrong josh :)

2:36 justin_smith: yeah, I caught that

2:36 and someone already mentioned what I said anyway

2:58 mskoud: Hi

2:58 Should Compojure routes look like this fx: (GET "/" {{user-email :user-email} :session flash :flash} (home user-email flash)) or am I missing something?

2:59 justin_smith: it uses standard destructuring, so that looks fine

3:00 mskoud: If i need many parameters it is difficult read, but i guess its just to practice...

3:00 justin_smith: you can also use keys

3:01 mskoud: As far as i can see, keys does not get fx session values.

3:01 justin_smith: ,(let [{:keys [a b c]} {:a 0 :b 1 :c 2}] (+ a b c))

3:01 clojurebot: 3

3:01 justin_smith: I mean :keys like that

3:01 like I said, it's normal destructuring

3:02 but no, that wouldn't work in your case since you are digging deeper into session anyway

3:02 mskoud: ok, but thanks.

3:02 justin_smith: (it would work for getting user-email though, and may be worth it if you needed other keys out of the session too)

3:07 sm0ke: in core.async i can use merge to take from multiple channel, is there something similar to put to multiple channels?

3:12 something like a router which can simly do round robin

3:15 kitallis: anyone had success in running lein-daemon on heroku?

3:26 justin_smith: doesn't heroku do its own process management stuff for you?

3:28 sm0ke: something just opposite to http://clojure.github.io/core.async/#clojure.core.async.lab/broadcast

3:29 heck, i will do it myself, but that is a plus to have

3:34 kitallis: justin_smith, yeah, I was trying to setup a lein-daemon as a separate worker process on heroku

4:11 wink: hmm, how do I create an ArraySeq easiest?

4:13 nevermind, stupid unrelated error

4:57 rafalbuda: hi,

4:58 does anyone have problems with ClojureScript "auto" compiling option and Sublime Text 3?

4:59 I mean, when I issue a "lein cljsbuild auto <name>" command and trying to save (and compile) file I'm working on, I get an error saying that "cannot proceed, another thread is using this file"

4:59 mskoud: im using sublime 3 (mac) without issues.

5:00 not using any repl integration though.

5:00 rafalbuda: but it only happens with ST3 - if I edit in other editor (even notepad, by Total Commander), it works

7:54 spradnyesh: the clojure idiomatic way to do A a = new A(); a.foo("foo"); a.bar("bar"); is (doto (A.) (.foo "foo") (.bar "bar"))

7:54 what is the idiomatic way to do A a = new A(); a.foo("foo"); a.bar("bar"); a.c.cat("cat"); a.c.dog("dog");

7:55 llasram: Well, public field access isn't that common :-) But:

7:55 spradnyesh: // assuming that a.c gets created inside A()

7:55 llasram: (doto (A.) (-> .-c (.cat "cat")))

7:56 spradnyesh: llasram: that looks correct; let me try that

7:58 Randoman: I heard this channel is good for programming questions ?

7:58 Or something

7:58 llasram: Well, Clojure programming questions.

7:58 Bronsa: if related to clojure, yes

7:58 hyPiRion: It's good for Clojure-related questions

7:58 spradnyesh: llasram: how about a.c().cat("cat") ?

7:58 llasram: Not good for trolling though

7:59 spradnyesh: Pretty much the same thing: (doto (A.) (-> .c (.cat "cat")))

7:59 spradnyesh: would (doto (A.) (-> .-(.c) (.cat "cat"))) work?

7:59 Bronsa: spradnyesh: also (.. a c (cat "cat"))

7:59 spradnyesh: no no, notice that c is a function that returns an object

7:59 llasram: No. The .- is the "new" field-access syntax

7:59 spradnyesh: Yes. (.c a) will call the `c()` method of `a`

7:59 spradnyesh: Bronsa: i need to apply multiple functions on the object, so would want to try doto before going to ..

8:00 llasram: spradnyesh: (.-c a) accesses the `c` field of `a`

8:01 Also I'd recommend against `..` myself. IMHO it's kind of a redundant wart at this point, confusing the language with multiple ways of doing something

8:01 spradnyesh: llasram: let me repeat my (previously wrong) question

8:01 A a = new A(); a.foo("foo"); a.bar("bar"); a.c().cat("cat"); a.c().dog("dog");

8:01 notice that c is a function (w/o any arguments) that returns an object on which i want to call cat("cat") and dog("dog")

8:02 Bronsa: llasram: there's no reason to prefer (-> a .b .c .d) over (.. a b c d)

8:02 llasram: spradnyesh: Sure. Because `a.c()` becomes `(.c a)`, you can do: `(doto (A.) (-> .c (.cat "cat")))`

8:02 Bronsa: .. is perfectly fine if all you need to do is chain a bunch of interop forms

8:02 llasram: spradnyesh: Or `(doto (A.) (-> (.c) (.cat "cat")))` if you prefered

8:03 Bronsa: I said IHMO :-). It just feels redundant to me.

8:03 spradnyesh: llasram: isn't (.a c) c.a() ? not a.c() right?

8:03 llasram: spradnyesh: Correct, but that doesn't appear anywhere in what I suggested

8:04 spradnyesh: llasram: you said "Because `a.c()` becomes `(.c a)`" above

8:04 llasram: Yes?

8:06 spradnyesh: anyways, my trouble is not taking the cat("cat") individually; rather it's the whole thingy => calling foo and bar on a, but cat and dog on a.c()

8:06 how can i do this in a single "doto"?

8:07 srenatus: hi there. somehow, neither (use 'mine.core :reload) nor using tools.namespace's (reload) seems to pick up my changed function... pebcak?

8:07 spradnyesh: i'm not sure if (doto (A.) (.foo "foo") (.bar "bar") (-> (.c) (.cat "cat") (.dog "dog"))) will work correctly

8:07 Bronsa: spradnyesh: this should work (doto (a.) (.foo "foo") (.bar "bar") (-> .c (doto (.cat "cat") (.dog "dog"))))

8:07 but I honestly wouldn't write it this way, it's really hard to parse.

8:08 spradnyesh: that's why i'm asking what would be an idiomatic way to do this

8:08 llasram: Yeah, you can just call `.c` twice, like in your example. Although w/ proper indentation I think Bronsa's suggestino would actually be okay

8:09 Bronsa: I would (let [a (a.)] (doto a (.foo "foo") (.bar "bar")) (doto (.c a) (.cat "cat") (.dog "dog")))

8:09 spradnyesh: Bronsa: that looks better i think; i'll try that

8:12 that seemed to work; thanks :)

8:12 Bronsa: llasram: I never particularly liked nesting -> and doto more than one level TBH

8:13 llasram: Yeah, it is a little hard to read

8:13 But point-free, man!

8:13 Bronsa: heh

8:14 uhm, is it really point-free if it uses macro transformations rather than function composition?

8:15 llasram: No. So thanks for ruining my "humor"

8:17 clojurebot: Bronsa |ruins| *everything*

8:17 clojurebot: Ack. Ack.

8:18 Bronsa: llasram: my pleasure

8:21 martinklepsch: justin_smith: I'm trying to get your clj-aws-s3 fork working but upload-part (that's used in write-multipart-stream) still contains references to File objects https://github.com/caribou/clj-aws-s3/blob/master/src/aws/sdk/s3.clj#L237 — am I overseeing something?

9:30 clgv: Bronsa?

9:30 clojurebot: Bronsa ruins *everything*

9:31 clgv: :P

9:39 just for understanding: assume I have a deftype T implementing a protocol P inline. at a call site of a method of protocol P Clojure can insert a direct call to the method the interface corresponding to protocol P provided there is a correct typehint on the first parameter of the call form, right?

9:44 llasram: clgv: When you say "method of protocol P" do you mean direct invocation of the JVM method in the protocol's corresponding interface, or do you mean calling a function in the protocol via its var?

9:44 otfrom: is clj-webdriver the best things for scripting the testing of sites in clojure or is there something else people would recommend?

9:45 Bronsa: clgv: kinda sorta; the protofn will always be routed through a Var call

9:46 clgv: it gets compiled to something like this: (defn proto-fn [this arg] (if (instance? ProtoInterface this) (.proto_fn ^ProtoInterface this arg) (internal-poly-f this arg)))

9:46 clgv: Bronsa: to be more specific, I saw in a Decompiler that a call to the corresponding interface is added, when the correct typehint is used

9:47 Bronsa: I just wanted a confirmation that this is usually the case

9:47 s/usually/always/

9:47 Bronsa: clgv: clojure will *never* automatically transform (proto-f this) into (.proto_f this)

9:48 clgv: Bronsa: ok let me check if I have an interop call in the discussed code

9:48 Bronsa: if youre curious, here's the actual bytecode that will be emitted for a protocol function https://github.com/clojure/tools.emitter.jvm/blob/master/src/main/clojure/clojure/tools/emitter/jvm/emit.clj#L565-L597

9:49 it corresponds roughly to the clojure code I gave you a few lines ago, modulo a callsite cache

9:50 llasram: Bronsa: does t.e.j's intermediate Clojure-data representation of JVM bytecode allow subsequent further optimization, or is it just nicer to work with/more abstracted than the raw ASM API?

9:50 clgv: Bronsa: ah right, the pattern you gave is surrounding the direct call

9:51 Bronsa: llasram: there's no infrastructure in place right now for pluggable optimizations on the bytecode representation, but that will happen

9:51 llasram: cool

9:52 Bronsa: llasram: peephole optimizations are really low priority ATM though, so I can't tell you when that capability will be added

9:52 clgv: I'd vote for nicer to work with, since it is declarative and you dont need all those ASM visitors in "application code"

9:53 the jvm analyzer used by eastwood still does not like my project although it compiles cleanly ;)

9:54 +version

9:54 Bronsa: llasram: I mean, if one really wanted, with-redefs https://github.com/clojure/tools.emitter.jvm/blob/master/src/main/clojure/clojure/tools/emitter/jvm.clj#L22 and you can intercept the bytecode before it gets compiled

9:54 llasram: hah!

9:54 Bronsa: clgv: how does it fail?

9:55 llasram: I was just curious :-). Bringing the compilation times down to those of Hickey's implementation probably should come first...

9:56 I am v excited about the project. Wish I had time to contribute, but know my limits

9:56 Bronsa: llasram: yeah definitely, and there's a long way to go until that happens

9:56 llasram: (inc Bronsa)

9:56 lazybot: ⇒ 43

9:56 clgv: Bronsa: NPE and in a different exception it states that it couldnt resolve a variable which is actually a protocol method

9:56 justin_smith: martinklepsch: odd - I wonder if that is from a bad merge from upstream

9:57 martinklepsch: is that preventing the upload of the stream?

9:57 clgv: llasram: damn you ruined the 42

9:58 Bronsa: clgv: well, eastwood still uses t.a.jvm 0.2.x, I'll upgrade it to 0.5.3 next week, a bunch of bugs have been fixed, hopefully that too

9:58 justin_smith: martinklepsch: OK, I am looking at my last merge, and that is an error - you should be able to downgrade to my previous release

9:58 clgv: Bronsa: ha great, I'll wait for the ML announcement ;)

9:59 justin_smith: martinklepsch: try switching from 0.3.9 to 0.3.7, sorry for the mistake

10:12 martinklepsch: justin_smith: thanks, will give it a spin in a bit :)

10:13 clgv: did anyone work on a test library that executes the tests in parallel, yet?

10:14 Bronsa: clgv: I believe test.generative does to some extent

10:16 clgv: Bronsa: I am using test.check lately and it always feels safer to have a lot of runs.

10:31 martinklepsch: justin_smith: ok, works when using 6226621

10:31 justin_smith: would be great to have a more actively maintained s3 lib for clojure

10:39 justin_smith: martinklepsch: yeah, I will try to fix that bad merge, it was a messy divergence between my fork and the original

10:40 come to think of it, that's likely why the PR was not accepted

10:42 martinklepsch: justin_smith: I sent a quick mail to james earlier, maybe he's open to other people taking over some of the maintainance work :)

10:47 lvh: I want to do something else dpeending on whether x is a map, vector or set (it is an arbitrarily nested data structure)

10:48 (condp apply the-thing map? (whatever) vector? (whatever)) looks weird

10:48 is that how you spell it, or is there a better spelling?

10:48 justin_smith: is this when we argue about multimethods versus protocols?

10:49 lvh: clojure has a couple of different ways to nicely express different code running depending on the type of the argument

10:50 lvh: justin_smith: Yes, I remember a couple; I'm trying to figure out what's best here :)

10:50 justin_smith: so, the data structure represents a bunch of requests

10:50 sometimes, it's a simple e.g. single http request; that's a map (with the request details)

10:50 sometimes it's an ordered collection of requests that have to be done in a specific order (vector)

10:50 you can probably guess what a set is :)

10:51 justin_smith: I'd think for the vector and set, you can just use one case: call seq on either and the result should be fine

10:51 Glenjamin: set would be parallel

10:51 justin_smith: could be, sure

10:51 lvh: justin_smith: eh, yeah, so ideally I would do the set in parallel :)

10:51 hi oubiwann :)

10:52 oubiwann-fn: lvh: hello!

10:52 funny seeing you here ;-)

10:52 (not really)

10:53 lvh: for our last hack day, I taught Clojure to a team of folks, and they spend the whole weekend working on problems

10:53 they are *loving* it

10:53 they want to migrate Python services to http-kit, etc.

10:53 lvh: oubiwann-fn: awesome :)

10:54 oubiwann-fn: what is the difference between oubiwann-fn and without -fn

10:54 Glenjamin: one is a macro.

10:54 oubiwann-fn: Glenjamin: haha

10:54 well-said

10:54 -fn is my work machine (I'm in the office right now); the other is my home machine

10:54 (no bouncer set up yet)

11:16 jlongster: hey guys, I was reading over the core.async announcement, and saw this sentence about (timeout): " A nice aspect of this is that timeouts can be shared between threads of control, e.g. in order to have a set of activities share a bound."

11:17 but only one thread can `take` the value, right? so how is it shared?

11:17 Glenjamin: jlongster: you can use (alts) with multiple actions including a timeout to get that effect

11:17 s/actions/channels/

11:18 jlongster: Glenjamin: right, but that sentence led me to believe I can pass a single timeout channel to multiple threads, which all do the alt thing

11:18 dnolen_: jlongster: there's a timeout queue

11:18 jlongster: (obviously that's wrong)

11:18 dnolen_: "threads of control" doesn't mean real threads

11:18 jlongster: yeah, I meant threads in the abstract sense

11:19 dnolen_: explain the timeout queue a little more?

11:19 dnolen_: jlongster: yes if the delta of a timeout channel is within a certain bound it will be bound up with another timeout about to dispatch

11:19 currently hardcoded to 10ms

11:19 so if you (timeout 1) and there's a pending (timeout 10), you will dispatch with that one

11:21 jlongster: dnolen_: interesting, thanks.

11:22 dnolen_: jlongster: the code is relatively straightforward https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/timers.clj#L43

11:22 the CLJS version looks more or less the same 'cept I had to write a SkipList from scratch

11:22 jlongster: nice!

11:22 it's CSP code, of course it's straightforward

11:23 dnolen_: I don't think that's what the original sentence was refering to, but now you have me interested

11:23 is this just an optimization or does it solve a problem?

11:24 dnolen_: jlongster: the sentence describes exactly what this code does

11:24 two different threads of control will share a timeout dispatch

11:24 jlongster: optimization

11:25 jlongster: dnolen_: ah I get it now

11:25 this makes sure that they are coalesced into the same dispatch

11:25 dnolen_: jlongster: yep

11:26 jlongster: now that you're on the JS-CSP thing you should convince them to support transducers ;)

11:26 jlongster: but each of them still has separate timeout channels

11:26 dnolen_: jlongster: yes

11:26 jlongster: dnolen_: oh I want to, one step at a time though :)

11:26 haven't studied transducers (or even reducers, but I get them abstractly)

11:27 I'll probably start writing some small projects in Clojure honestly, I'm so close

11:27 dnolen_: jlongster: it's pretty awesome, no extra async blocks just to get sequence like behavior

11:27 so you can map/filter/take/partition etc. a channel w/ a go block for each step

11:28 w/ -> without

11:28 jlongster: dnolen_: that's awesome. I was noticing those problems with js-csp right when transducers was released

11:28 so definitely going to look at them

11:29 dnolen_: jlongster: yeah it's huge IMO.

11:29 you can have huge event processing pipelines w/ no overhead

11:30 jlongster: definitely need to study it, I don't understand yet but it's fun to learn

11:30 so many iteration libs in JS and they all embrace raw generators/promies/etc and it's all so messy. we need to get on the right track.

11:31 it's like people don't even look around at other languages

11:32 dnolen_: jlongster: yep, anyways transducers are language agnostic will work anywhere you have first class functions - look forward to see people use them over lazy seqs (immutable-js looking at you)

11:33 jlongster: dnolen_: cool! gozala has already ported reducers, but I haven't looked at it yet: https://github.com/Gozala/reducers

11:33 does seem like a ton of extra function allocations, but need to study

11:33 dnolen_: jlongster: yeah transducers really subsume reducers and are more generally applicable

11:33 jlongster: can't use reducers w/ channels

11:35 jlongster: I thought transducers took a `reducer -> reducer` function? or is `reducer` just a more abstract name

11:36 dnolen_: jlongster: nothing to do w/ reducers directly - just an abstract name

11:36 jlongster: oh, that's great then

11:36 dnolen_: can you use them with the lazy seqs in mori?

11:36 (out of the box support, I mean)

11:36 dnolen_: jlongster: haven't exported them yet, but yes planning on that - should just work

11:37 jlongster: woo, cool. I think one of my future posts is going to be the mori+react stuff. people have been dancing around it but nobody's really done it.

11:37 dnolen_: did I tell you at JSConf that I'm pitching a rewrite of the Firefox debugger to use React?

11:37 dnolen_: jlongster: transducers work with everything and more, in fact you can finally use the standard lib on primitive arrays

11:38 jlongster: cool!

11:38 dnolen_: (transduce (comp (map inc) (filter even?)) #(do (aset %1 %2) %1) #js [] #js [1 2 3 4]) -> [2 4]

11:38 no intermediate seqs

11:39 jlongster: wow, neat

11:41 dnolen_: (chan 1 (comp (map inc) (filter even?))

11:41 also just works, and channel that increments it input and drops even numbers

11:41 s/and/a

11:42 jlongster: yeah, I definitely want that

11:42 got a few more things to research first :)

11:54 dnolen_: sorry to ask again, but looking at the code it looks like the timeout stuff does all happen on a single channel; here it gets the existing channel https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/timers.clj#L49

11:54 but multiple threads of control can't take from the same channel, right?

11:54 I thought only one of them would get the value if that happened

11:55 bbloom_: jlongster: read the doc string "will close after msecs"

11:55 jlongster: and https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L97-L99

11:55 jlongster: bbloom_: ooh so it works by closing, duh, thanks

11:55 bbloom_: "will return nil if closed"

11:55 jlongster: yeah, thanks

11:56 makes sense

12:11 clojer: With core.async can Clojure scale horizontally as easily as Erlang, ie. just add boxes to cluster and PIDs indistinguishable whether local or remote?

12:11 martinklepsch: I want to run something each time I start a repl to setup logging — I tried with :injections but I don't think they're the right thing

12:13 rweir: clojer, core.async isn't that high level

12:15 mdrogalis: clojer: No, different use case.

12:15 dnolen_: jlongster: that's awesome re: dev tools!

12:16 jlongster: I don't think you said that, but Nick Fitzgerald was asking me curious questions about the Mori license

12:17 jlongster: dnolen_: we'll see how it goes, but it's a mess of tangled DOM stuff right now. and others on the team have started looking at it

12:17 I think fitzgen was actually thinking about something with the memory profiler regarding mori

12:18 not sure about the licensing stuff

12:18 lvh: I'm playing with core.async in the repl; is there a way to stop (<! c) from blocking if you know it'll never return due to a bug?

12:19 (other than "write a convenience function that alts! over a timeout & that)

12:19 Glenjamin: is take! suitable?

12:19 lvh: that returns nil, right?

12:20 I guess I could do (take! c prn)?

12:22 clojer: mdrogalis: In what sense? Which use case?

12:23 mdrogalis: clojer: core.async is for async event handling on a single box, it doesn't make any attempt to work over a network.

12:23 You can use it in combination with something like websockets, queues, or ZooKeeper though.

12:23 clojer: rweir: I thought core.async was based on Go's CSP implementation, similar to Erlang's green threads?

12:23 mdrogalis: But it's not going to be as "fluid" as what Erlang gives you for actors.

12:24 clojer: Correct. It's strictly a local mechanism in this case, though.

12:24 rweir: clojer, that doesn't get you a network-transparent process model

12:24 clojer, it gets you a very nice way to write async code

12:24 clojer: mdrogalis: Does Clojure have another library suited to the kind of thing Erlang is good at?

12:24 .. ie. horizontal scaling.

12:25 mdrogalis: clojer: Nothing out of the box, but you might try something like Storm or Cascalog.

12:26 clojer: mdrogalis: Sounds like a Clojure on BEAM would therefore be interesting.

12:26 lvh: clojer: LFE is close already :)

12:27 technomancy: LFE is not close

12:27 joxa is close

12:27 clojer: lvh: LFE seems different.

12:27 technomancy: LFE is a lisp-2, so not very good for FP

12:27 mdrogalis: Haha

12:27 Jaood: clojer: check out pulsar

12:27 clojer: technomancy> joxa is close

12:28 technomancy: Has a look at Joxa but you can't even use core functions with 'require' ing core and then prefixing everything joxa.core/

12:28 technomancy: it's also not under active development

12:29 clojer: technomancy: Yes, much smaller community than LFE

12:29 mdrogalis: tldr stick with Erlang for those kinds of problems IMO

12:29 technomancy: well, you have to at least start with Erlang

12:29 clojer: technomancy: Shame really as the creator had the right idea.

12:30 technomancy: once you're an erlang pro, playing with joxa etc, would make more sense

12:30 but if you don't understand the context from which it comes you won't get far

12:30 clojer: technomancy: Decent size community with libs matters so Joxa won't probably cut it for me.

12:30 technomancy: well

12:30 community is one thing, libs is another

12:31 I feel like you could get really far just using erlang libs

12:31 but full ack on the community angle

12:32 clojer: Jaood: Have you used Pulsar? I heard it was similar to Erlang's green threads.

12:33 Glenjamin: it's still within a jvm afaik

12:36 Jaood: clojer: no, started with core.async instead since I can reuse it in cljs

12:37 but yeah, their description is Erlang-like actors for Clojure

12:38 clojer: Jaood: Yes, it has the same stack-per-process model. Excellent.

12:39 Jaood: Still seems to be going strong. I thought it had been supplanted by core.async but I now learn they're different.

12:39 technomancy: any system that is described as erlang-like is a long way away from erlang

12:40 clojer: Jaood: So I can have my Erlang cake and eat it in Clojure :)

12:40 technomancy: unless they describe it as OTP-like, and even then I'd be extremely skeptical

12:40 mdrogalis: I wonder what Erlang cake tastes like.

12:43 justin_smith: mdrogalis: clearly it is distributed among many guests

12:50 mdrogalis: justin_smith: Heh

12:58 lvh: how do you spell "take everything from this channel and dump it in a vec"?

12:59 (<!! (into [] ch)) ?

12:59 hiredman: I dunno, but I doubt that is a good idea, what are you actually trying to do?

12:59 bbloom_: lvh: into operates on reducables, which channels are not, also <!! operates on channels, which a vector (the return value of into []) is not

12:59 lvh: bbloom_: Sorry, I mean core.async's into

13:00 bbloom_: (which returns a channel and works on a vec and a chan)

13:00 err, col and a chan

13:00 bbloom_: lvh: heh, i had no idea that was there

13:00 lvh: hiredman: repl debug my core.async using code to see what its putting on this channel

13:00 bbloom_: i guess i haven't been keeping up with core async's changes

13:02 hiredman: lvh: channels aren't really collections in the normal sense, they are synchronization primitives (you can sort of view them as collections smeared out over time kind of), but treating them as a mutable collection that you can just pour in to another collection seems questionable

13:03 lvh: hiredman: well, sure, but I want to see what my code is putting on this collection

13:03 err, channel

13:03 that sounds like a reasonable test question?

13:04 technomancy: speaking of smearing something over time, I was just thinking of this yesterday as I was falling asleep

13:04 what if you had a record type that was aware of all other versions of it that existed in the past and knew how to translate between them?

13:05 you could keep separate subtrees of dependencies that had old versions of your type and could interop with other versions of itself, and you could easily support hot-upgrades in-place even better than erlang

13:06 hiredman: lvh: sure, you can just spin out a thread that grabs a value from the channel and prints it

13:06 technomancy: you could also make records that could be reloaded and still have their instances be equal to other instantiations with the same definition from a previous reload, which is one of the biggest wtfs with records currently

13:06 ahoenigmann: how to a reload/restart cider in emacs?

13:06 technomancy: ahoenigmann: M-x apropos cider.*restart

13:07 lvh: if I ran a blocking take! in a cider repl that will probably never finish, can I cancel it, or do I have to restart cider?

13:07 justin_smith: try C-c C-c

13:07 (in the repl buffer)

13:08 lvh: justin_smith: thanks! of course Ir ead that after I axe the process...

13:08 will try next time I screw up

13:09 ahoenigmann: when I press space the command buffer inserts a dash “-“

13:09 betweeen apropos and cider

13:09 justin_smith: apropos <return> cider.*restart

13:10 to leave out the <return> is a common emacs shorthand when describing an interactive command

13:10 (commands cannot have spaces in them)

13:10 and don't take arguments in that way

13:11 Jaood: cider-restart has never worked for me

13:12 technomancy: Jaood: iiuc it behaves differently depending on the current dir

13:13 Jaood: technomancy: oh really, I always get connection refused

13:13 * Jaood checks the current dir

13:29 PigDude: oh 300-line stacktraces, how i love to scroll thee. another day in paradise

14:31 ahoenigmann: How do i jump to a function definition? (running cider)

14:32 amalloy: M-.

15:04 fifosine: I have a vector with keywords to values. Is there a function that will return the value associated with a key similar to using get with a map?

15:05 gfredericks: fifosine: why do you have such a thing? it sounds like you want a map.

15:06 it's also not clear if you mean [:foo 1 :bar 2] or [[:foo 1] [:bar 2]]

15:06 mdeboard: I thought you could use get with vectors

15:06 justin_smith: get by index

15:06 mdeboard: oh right

15:06 justin_smith: maybe you want a sorted-map

15:06 or sorted-map-by

15:06 fifosine: gfredericks: It's what's returned to me from instaparse lib

15:06 amalloy: (or possibly something else altogether, gfredericks: "a vector with keywords to values" is super-vague)

15:07 fifosine: looks like this: [:S

15:07 [:AB [:A "a" "a" "a" "a" "a"] [:B "b" "b" "b"]]

15:07 [:AB [:A "a" "a" "a" "a"] [:B "b" "b"]]]

15:07 gfredericks: fifosine: instaparse supports transforming things, so I suggest you use that feature to make the data look how you want

15:07 fifosine: ok

15:07 gfredericks: amalloy: yeah looks like it is something else :)

15:08 amalloy: fifosine: suppose you had a function f, which acted like (f '[:AB [:A x] [:B y]]) => '[:A x]

15:08 that function would not be generally useful, because what does it do with (f '[:AAB [:A x] [:A y] [:B z]])?

15:09 you have to be able to ask a more specific question than "what is the value at :A", because there can be more than one

15:30 sdegutis: What's the name behind the story of the "ring" library?

15:31 mdeboard: ?

15:31 You mean story behind the name?

15:31 amalloy: mdeboard: the name behind the story is the lord of the rings

15:32 mdeboard: weird

15:32 "name behind the story" makes my head hurt

15:32 itching behind my eyes

15:32 amalloy: well, mostly because it doesn't make sense

15:33 sdegutis: Thanks in advance.

15:34 fifosine: Can I perform destructuring in a function definition like so: (fn [[a b] [c d]] …)?

15:35 bbloom_: fifosine: why don't you try it?

15:35 you've got a repl, right? :-)

15:35 sdegutis: Does anyone know.

15:36 Is it related to "Rack" that exists for Rails. Thank you?

15:39 !guards

15:40 ~guards

15:40 clojurebot: SEIZE HIM!

15:40 sdegutis: Ah, clojurebot.

15:42 cespare: I can get around private by using #'ns/var but how can I emit this from a macro?

15:42 sdegutis: ,(def a #'if)

15:42 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve var: if in this context, compiling:(NO_SOURCE_PATH:0:0)>

15:42 arrdem: cespare: resolve can get you the backing var from a fully qualified symbol.

15:42 mdeboard: sdegutis: It is an homage to the black plague that rampaged through Europe in the dark ages. its hallmark was a rosey, ring-shaped rash.

15:43 Rich Hickey lost many close friends & relatives in the Black Death and so he vowed that his programming language would have a network adapter library to stand as eternal testament to their memory

15:43 And now you know... the rest of the story.

15:43 arrdem: I KNEW Rich was an Ancient... no mere mortal...

15:44 mdeboard: He's a highlander

15:44 sdegutis: mdeboard: Thank for you providing me the story behind the full name.

15:44 mdeboard: He had to behead Don Knuth

15:44 arrdem: mdeboard: lol

15:44 mdeboard: sdegutis: np

15:44 I know what you're thinking... "But Don Knuth is alive!" Well, that's what they WANT you to think.

15:45 sdegutis: Thanks in advance.

15:45 arrdem: mdeboard: so... will The Art of Computer Programming ever be released in full? :P

15:46 raek: cespare: you could also generate (var ns/var) or (const 'var (symbol the-ns the-var)) from the macro

15:47 mdeboard: it already has, hidden in plain sight, spread throughout the world's grandest libraries, guarded by an ancient order of warriors sworn to its protection.

15:47 raek: clojurebot ,(read-string "#'ns/var")

15:48 er.

15:48 ,(read-string "#'ns/var")

15:48 clojurebot: (var ns/var)

15:48 raek: the #' stuff is just syntactic sugar

15:48 amalloy: raek: there's never any need to write (read-string "#'ns/var") to demonstrate syntactic sugar. just write '#'ns/var; the reader gets applied

15:49 sdegutis: mdeboard: You are a fine bard.

15:50 mdeboard: Blease change your nick to mdebard.

15:50 mdeboard: Well, since you said Blease

15:53 amalloy: ,(let [v 'test] `(foo #'~v))

15:53 clojurebot: (sandbox/foo (var test))

15:54 amalloy: (point being, cespare, that you can just write what you'd write anyway, with the ~ in exactly the place you'd expect to put it, and it emits what you expect)

15:54 cespare: amalloy: yep, i realize my problem is that I don't understand how to refer to a private atom

15:54 only a private fn

15:55 amalloy: cespare: well, the easy way would be to not make it private to begin with, if you're having to write macros that refer to it anyway

15:55 private is not all it's cracked up to be

15:55 sdegutis: mdeboard: Thanks in advance.

15:55 mdeboard: sdegutis: np

15:55 cespare: amalloy: the macros are not for that purpose

15:55 sdegutis: :)

15:55 devn: if this hasn't made the rounds: https://github.com/Dobiasd/programming-language-subreddits-and-their-choice-of-words

15:55 specifically this: https://github.com/Dobiasd/programming-language-subreddits-and-their-choice-of-words/raw/master/img/happy.png

15:55 cespare: amalloy: it's incidental

15:56 amalloy: interesting, devn

15:56 sdegutis: cespare: Check out the book Mastering Clojure Macros, it's a great way to master macros in Clojure.

15:56 cespare: here, i'll write up what I'm trying to accomplish and I'm sure someone can explain a better way

15:58 amalloy: it looks like visualbasic (or maybe objectivec?) has a higher helpful/volume ratio than any other sub. i wonder why

15:58 sdegutis: cespare: I can't recommend the book Mastering Clojure Macros enough if you're dealing with macros.

15:58 mdeboard: shared misery builds close relationshits

15:58 ships*

15:58 sdegutis: cespare: http://pragprog.com/book/cjclojure/mastering-clojure-macros

16:05 SegFaultAX: Haha relationshits.

16:05 That's fun to say: relationshits.

16:06 cespare: ok, question: https://gist.github.com/cespare/6f966059a1b49f3f437c

16:07 mdeboard: that's not a question

16:07 that's a hyperlink

16:07 there are embedded questions

16:07 cespare: mdeboard: did you manage to figure it out anyway?

16:08 mdeboard: cespare: Looks like a protocol might be better fight

16:08 s/fight/fit

16:08 cespare: mdeboard: type is e.g. a record type, not an actual instance of that type

16:08 so I didn't see how a record applied

16:09 unless I wanted to change the API so the caller creates a dummy instance and passes that in

16:09 mdeboard: I see

16:09 cespare: mdeboard: fwiw the opposite operation (serialize type -> bytes) is implemented as extending a protocol

16:09 mdeboard: Does this really allow arbitrary types?

16:10 cespare: mdeboard: no, just a small list

16:10 defined by the user though

16:10 mdeboard: Ah

16:11 amalloy: cespare: i mean, the most minimal change is to emit @#'ns/var

16:12 i'm with mdeboard, though, you want a Parser protocol, so that someone just hands you a Parser object

16:12 cespare: amalloy: i don't follow

16:12 the user doesn't have a parser object

16:13 mdeboard: It seems like the internals of the macro would basically have to be a protocol

16:13 right?

16:14 amalloy: they have a "type". instead of passing you this "type" thing which exists only to be a key in some mutable map, they pass you an instance of the Parser protocol for the type they want to parse

16:14 cespare: amalloy: it absolutely doesn't exist to be a key in the map

16:15 it's like (defrecord Foo [...]) (gen-parsers Foo) and now you round-trip with (parse Foo (serialize (->Foo ...)))

16:17 amalloy: so why do you say (parse Foo ...) instead of (parse foo-parser), where foo-parser is (FooParser.), either inlined or defined ahead of time

16:17 cespare: why should the user know about FooParser

16:17 amalloy: because they are asking you to parse a foo

16:17 seems pretty reasonable

16:18 sdegutis: Can someone recommend a good book for Clojure macros please.

16:18 Thanks.

16:18 cespare: you can apply that argument to expose any internals you want

16:18 arrdem: sdegutis: besides the one you were spamming ten minutes ago?

16:18 sdegutis: arrdem: Oh I thought you had me in permanent-ignore.

16:18 arrdem: sdegutis: well you're headed back there rather fast..

16:19 mdeboard: lol

16:19 such drama

16:19 amalloy: cespare: defining a private mutable map and then creating macros that modify it is much grosser and internal than asking for a foo-parser to parse a foo

16:19 mdeboard: Now now, he said I was a good bard

16:19 cespare: amalloy: meh, i think the API is nicer.

16:20 mdeboard: Maybe but your code to maintain that API is going to be really... tough to maintain

16:20 amalloy: i mean, you're entitled to think so. i already said how to solve the problem in your existing API, so if you don't like my proposed API why are you still arguing with it?

16:20 cespare: it's an interesting discussion?

16:21 thanks for the solution :)

16:21 llasram: cespare: How is parse-from-bytes not literally a multimethod?

16:21 mgaare: cespare: it seems like your original was a re-implementation of protocols

16:21 mdeboard: wow, I said something right?

16:21 nice.

16:21 * mdeboard marks day on calendar

16:21 cespare: llasram: because you give it the type you want it to create, not an instance of that type

16:21 maybe i'm misunderstanding though

16:22 mdeboard: cespare: How does it create the type?

16:22 amalloy: yes, good point, llasram. it's exactly a multimethod

16:22 (not a protocol)

16:22 mdeboard: I almost said multimethod so I'm still counting this as a win

16:22 mgaare: oh, right, I was reading it backwards

16:22 llasram: cespare: multimethods can dispatch on anything. You can call it with a class, and use that class as the dispatch value

16:22 amalloy: i still argue it would be reasonable for it to be a protocol instead, but as-is it's a multimethod

16:22 mdeboard: multimethods are protocols anyway in the general meaning of the word :)

16:23 cespare: llasram: ah yup, I think a multimethod works

16:23 thanks

16:23 virmundi: Hello. I've got a question about how ^dynamic works when compiled/transformed into Java. Then rebound, it a threadlocal modified?

16:24 hiredman: what do you mean by rebound?

16:24 if bound using binding it creates a threadlocal binding

16:24 but only using binding

16:25 virmundi: Ok. So how does one reset the threadlocal?

16:25 hiredman: with-redefs, def, declare, alter-var-root, etc are all not thread local and operate on the var root

16:25 amalloy: hiredman: it's not a real java.lang.ThreadLocal, is it? that might have been the question virmundi was asking

16:26 hiredman: virmundi: binddings established with binding obey a stack discipline and are popped when you leave the dynamic scope of the binding

16:26 ,(def ^:dynamic x 1)

16:26 clojurebot: #'sandbox/x

16:26 virmundi: I'm starting to see. What I'm worried about is the code here

16:26 https://github.com/edlich/clarango/blob/master/src/clarango/core.clj

16:26 hiredman: ,[(binding [x 2] x) x]

16:26 clojurebot: [2 1]

16:27 Bronsa: amalloy_: it uses a ThreadLocal to store the current Frame

16:27 hiredman: virmundi: looks terrible

16:28 virmundi: def inside a function body is always a red flag

16:28 virmundi: Quick side question, would a more Clojure-eque way be to take the connection map with each call?

16:28 That's what the JDBC api does.

16:28 hiredman: yes

16:29 virmundi: I might try making my own ArangoDB drive to learn clojure. The dynamic there scared me. It really scares me since I want to move from ring.adapter.jetty to the new Comsat adapter once parallel universe comes out.

16:30 But, hiredman, I appreciate your help. I like to understand what's going on under the covers. Thanks.

16:31 hiredman: virmundi: are you actually experiencing a performance problem with jetty?

16:32 stuartsierra: https://github.com/edlich/clarango/blob/67b0745290f18b119b1f04b9a80d0d6ab6c90bba/src/clarango/core.clj#L9 is a mis-use of `def` that has a global, not thread-local, effect.

16:34 Jaood: hiredman: you know why the jetty version hasn't been bump up in the jetty adapter?

16:46 rei: Are there any articles or examples of defmulti/defmethod? Particularly with more than one argument. All examples I see online are either one argument or a map.

16:55 SagiCZ1: i have this question which concerns all dynamically typed languages.. in java if i have method foo(Type1 t1, Type2 t2) there is no way i can call it with bad parameter types.. but lets say i have clojure function (foo [m l] ...) and i expect "m" to be map and "l" to be list and treat them as such.. how can i force the caller of this function to use correct types when calling it? this can be a source of very hard to find bugs.. especia

16:56 arrdem: SagiCZ1: you can't force the caller to do anything... but you can use preconditions to check your arguments either manually or with Schema or something.

16:56 SagiCZ1: arrdem: so that would be somewhere in "require:" ? can i check the parameter types there?

16:57 ,(fn? (fn [] 5))

16:57 clojurebot: true

16:57 puredanger: rei: here's a couple in tools.analyzer https://github.com/clojure/tools.analyzer/blob/master/src/main/clojure/clojure/tools/analyzer/ast.clj#L44

16:57 SagiCZ1: ,(list? '(1 2 5))

16:57 clojurebot: true

16:57 llasram: rei: There's no real magic... The `defmulti` dispatch function just needs to have all the arities you want to support and return a dispatch value. The implementations just accept the appropriate arities as wel

16:57 arrdem: SagiCZ1: in your namespace form you can't do typechecking if that's what you're asking...

16:57 mgaare: SagiCZ1: there's an example here: http://onclojure.com/2010/03/05/pre-and-post-conditions-a-quest-for-a-nicer-syntax/

16:57 SagiCZ1: arrdem: but why doesnt clojure do this automatically?

16:58 arrdem: SagiCZ1: because Rich is a believer that types should truly be optional and for performance only

16:58 postpunkjustin: SagiCZ1: because it's dynamically typed?

16:58 arrdem: postpunkjustin: dynamically checked, statically typed.

16:58 mgaare: SagiCZ1: you can also use clojure.core.typed if you have a lot of time on your hands

16:58 arrdem: if typed at all..

16:59 lpvb: SagiCZ1: if you want a very strongly typed functional language look at haskell

17:00 mgaare: SagiCZ1: using preconditions will give you run-time checking. clojure.core.typed will give you compile-time checking

17:00 SagiCZ1: i am not trying to go against clojure philosophy or Rich's ideas and i am not trying to find another language.. but i dont understand how can i reduce the bugs that come from calling a function with parameters in bad type or order

17:01 mgaare: run type checking is fine.. i guess i will look into preconditions then

17:01 mgaare: you can also use assertions wherever you want

17:01 SagiCZ1: whats the difference between precondition and assertion?

17:01 Bronsa: preconditions are syntactic sugars over assertions

17:01 sugar*

17:03 SagiCZ1: alright and if i wanted to hear some personal experience with them? do you guys use preconditions everywhere or nowhere? do you get bugs from wrong parameters passed into functions?

17:03 mgaare: for me, almost nowhere, and yes I do :D

17:03 SagiCZ1: :D

17:04 Bronsa: SagiCZ1: honestly I use plain assertions over preconditions, because with preconditions you have no control over the thrown message

17:04 SagiCZ1: i guess i will get something like "Long cant be cast to IFn" ......... thanks Rich........

17:04 postpunkjustin: SagiCZ1: I use preconditions a lot, especially if I know I'm going to be doing some heavy refactoring or if I have weird bugs.

17:04 SagiCZ1: Bronsa: so it throws messages? does it stop the execution?

17:04 postpunkjustin: thanks for input

17:04 Bronsa: SagiCZ1: yes it throws an exception

17:05 arrdem: SagiCZ1: I tend to write a comment including a type signature before I write a function body... depending on my exhaustion level and the context of the code I may or may not build preconditions.

17:05 SagiCZ1: Bronsa: runtime right? clojure always throws runtime IIRC

17:05 Bronsa: yes, runtime

17:05 rei: puredanger: Thanks!

17:05 SagiCZ1: (doc assert)

17:05 clojurebot: "([x] [x message]); Evaluates expr and throws an exception if it does not evaluate to logical true."

17:05 Bronsa: SagiCZ1: as somebody already said, use core.typed if you want compile time type safety

17:05 rei: llasram: Yeah, that's what I thought, but I can't get my code to work despite that.

17:05 SagiCZ1: Bronsa: runtime type safety is enough for me

17:06 ,(assert "my fail message" true)

17:06 clojurebot: nil

17:06 SagiCZ1: see what i did there?

17:06 llasram: cute

17:06 SagiCZ1: ,(assert true "my fail message")

17:06 clojurebot: nil

17:06 SagiCZ1: ,(assert false "my fail message")

17:06 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: my fail message\nfalse>

17:07 Bronsa: SagiCZ1: honestly I don't even use `c.c/assert`, I manually (if condition (throw (ex-info ..))), that way I can attach info on the exception that I can inspect

17:07 amalloy_: yeah, assert is just not useful

17:07 SagiCZ1: amalloy: hi.. how come?

17:07 llasram: It's okay for debugging sometimes

17:07 SagiCZ1: Bronsa: isn't that a bit tedious? :(

17:08 puredanger: assert states documentation of developer intentions in the form of a runtime check

17:08 hiredman: I do use assert, a lot

17:08 SagiCZ1: puredanger: sounds good to me

17:08 puredanger: it's a bad way to communicate to a user though

17:08 Bronsa: SagiCZ1: (assert (vector? x) "arg x is not a vector") doesn't let me inspect what x was

17:08 SagiCZ1: Bronsa: I see the problem now

17:08 Bronsa: (if-not (vector? x) (throw (ex-info "arg x is not a vector" {:arg x}))) does

17:09 hiredman: I tend to drop (assert nil) at the end of conds and ifs as I building something out if I haven't built that side of the conditional yet

17:09 amalloy: Bronsa: to be truly counter-culture: (clojure.test/is (vector? x))

17:09 hiredman: as I am

17:09 SagiCZ1: Bronsa: can you not attach the "x" to the assert message?

17:09 Bronsa: SagiCZ1: it forces you to attach it as a string

17:09 hiredman: there is a jira issue about making assert carry the lexical environment around

17:09 Bronsa: what if it's a deeply nested map that I need to inspect to understand what's going wrong?

17:10 lpvb: Is there really a point to checking the arg types? For a language like clojure I think the arg types should be specified in documentation

17:10 Bronsa: amalloy: ew

17:10 SagiCZ1: Bronsa: i see.. i cant imagine how would i inspect that anyways though

17:10 hiredman: which is an interesting idea, but can lead to bugs, slingshot did/does that and you can end up holding on the head of seqs that way

17:10 Bronsa: SagiCZ1: ex-data

17:10 amalloy: hiredman: ughhhhh, really? that's a really dangerous thing that causes problems in slingshot

17:10 hiredman: amalloy: right

17:10 SagiCZ1: lpvb: even if they are specified what if the caller makes a mistake?

17:10 amalloy: because you end up closing over infinite sequences and then trying to print them

17:10 oh, i see you said that too

17:10 well done, us

17:10 lpvb: SagiCZ1: then the caller should read the documentation and fix it, it's not hard to re-run the function in the repl

17:11 hiredman: go team venture

17:11 SagiCZ1: lpvb: i know but it could even run fine just with weird results..

17:11 Bronsa: hiredman: I've started placing exceptions on not-finished code paths too lately, it's a good way to make sure you don't forget to implement something

17:12 SagiCZ1: i need like a twitch stream of you guys developing so i can see how its done :D

17:12 amalloy: Bronsa: only works if that code path is actually exercised, though

17:13 hiredman: it is a sort of walking skeleton approach

17:14 mgaare: is there a good resource for clojure livecoding videos?

17:14 hiredman: you get something that compiles and runs, but if you anything it explodes

17:14 do

17:14 Bronsa: amalloy: I can always throw an exception at the top-level for extra safety

17:14 (ns foo ..) (assert nil "FIXME you dumbass")

17:14 amalloy: mgaare: not really. record a video of yourself coding, so that the next guy who asked that question will get a "yes" answer

17:15 mgaare: I've seen a handful here and there

17:15 amalloy: Bronsa: when i want to do that i just embed illegal code in the middle, so that it doesn't even compile. (cond x y, a b, TODO fix this what now)

17:15 hiredman: :(

17:15 amalloy: but obviously that has its own issues

17:16 technomancy: when I did rubby I would just add `raise Hell`

17:16 (which was not defined)

17:17 mdrogalis: Ha

17:22 mdeboard: If I was going to create an impl of the nrepl protocol for a separate language and separate set of tools (i.e. no intention of talking to clojure/java/jvm at all), would it still be an nrepl project?

17:23 I can't sort out where the delineation is between the nrepl protocol and nrepl the whole thing

17:23 spaceballs: the movie

17:24 technomancy: clojure has a proud history of being implementation-defined =)

17:27 mdeboard: technomancy: I don't know what that means :(

17:27 I feel like a jok ejust went over my head

17:27 TimMc: technomancy: Don't smile when you say that...

17:29 * TimMc alter-var-roots *assert* to false before loading Bronsa's code

17:30 TimMc: Bronsa: ... is idiomatic in Racket, I think

17:30 Bronsa: TimMc: if you scroll back, I said that I actually throw ex-info rather than assert, binding *assert* won't save you.

17:31 TimMc: what is idiomatic?

17:31 TimMc: hmm, OK

17:31 three dots in a row, an ellipsis

17:32 I seem to recall it from HtDP.

17:32 rei: llasram: I got defmethod to work all along...it was just a issue between my editor and the repl.

17:32 technomancy: iirc it's a syntax-rules thing?

17:32 TimMc: I guess you want to make sure other code paths through the same fn won't run either, though.

17:32 technomancy: That too.

17:33 cespare: I just put ~'_ insde a macro (inside a `(...) form) so I could get _ as a function param without it being resolved

17:33 is that normal?

17:34 TimMc: It's perfectly normal.

17:35 cespare: Or... hmm, why not _# instead>

17:36 In an ideal world, _ won't collide meaningfully with anything, but if this to get a lexical binding you should use the gensym# form instead.

17:37 ~'foo would be used if you needed a specific non-resolved symbol such as when building a macro to emit a reify (and you need to specify method names)

17:37 clojurebot: Titim gan éirí ort.

17:37 Bronsa: jeez, what's that word that describes a macro that binds something to the lexical environment? the opposite of hygienic somewhat

17:37 puredanger: anaphoric

17:37 Bronsa: thanks

17:46 puredanger: I usually try to write euphoric macros instead

17:49 Bronsa: puredanger: (defmacro euphoric [code] (clojure.walk/prewalk (fn [x] (if (symbol? x) (symbol (str (clojure.string/upper-case (str x)) "!!!")) x)) code)) ?

17:50 ,(defmacro euphoric [code] (clojure.walk/prewalk (fn [x] (if (symbol? x) (symbol (str (clojure.string/upper-case (str x)) "!!!")) x)) code))

17:50 clojurebot: #<CompilerException java.lang.ClassNotFoundException: clojure.walk, compiling:(NO_SOURCE_PATH:0:0)>

17:50 Bronsa: ,(require 'clojure.walk)

17:50 clojurebot: #<SecurityException java.lang.SecurityException: denied>

17:50 Bronsa: :<

17:50 puredanger: you put a lot more thought into that then I did :)

18:04 Bronsa: puredanger: is there any plan to add a fold compatible with transducers?

18:05 puredanger: tricky question :)

18:05 this is an area of some discussion right now so take nothing I say here as final

18:06 but I think current plan is to essentially leave clojure.core.reducers as is

18:06 but we add a parallel transduce path in core (say "produce") that would leverage some of the fold infrastructure

18:06 ha, auto-complete you kill me

18:06 preduce

18:07 not produce :)

18:08 Bronsa: puredanger: once/if core has a fj-based transduce, what would reducers have to offer more? am I right in thinking that they could be deprecated at that point?

18:08 mdrogalis: puredanger: What's the justification behind that path?

18:11 puredanger: Bronsa: it's really a different way of rendering the same idea. the intention there was to retain a more similar shape to nested transformations. transducers have gone in a different direction that emphasizes separating algorithm from application. they are not in conflict, just different paths. But I suspect transducers will get future attention, not reducers.

18:11 gotta run ...

18:12 Bronsa: puredanger: got it, thanks a lot

18:12 mdrogalis: Hm

18:30 danielcompton: Is there a way to cycle through emacs minibuffer lists without using the arrow keys?

18:30 technomancy: danielcompton: C-s / C-r would do it

18:30 also try ido-vertical; it's neat

18:31 danielcompton: technomancy: thanks!

18:31 * danielcompton looks up ido-vertical

18:31 technomancy: it sounds terrible but grows on you once you give it a try

18:32 danielcompton: Does it make the minibuffer that size all the time?

18:33 technomancy: yeah

18:33 but it goes away when you press enter, so it doesn't really bug me

18:34 danielcompton: I'll give it a go, I'm not a big fan of windows changing size but it still sounds interesting

18:37 technomancy: Have the emacs starter kit functions like esk-cleanup-buffer been moved to new projects?

18:37 I was thinking about creating some if they weren't already

18:38 technomancy: danielcompton: I think the tiny ones like that don't have a home

18:38 amalloy: technomancy: can confirm, ido-vertical sounds terrible but might grow on me

18:39 it's like a ton of wasted space, right? if you're going to use up eight whole lines, why not a grid like ls uses?

18:39 danielcompton: technomancy: I may look at making new homes for them, but at that point I'm just about remaking emacs-starter-kit anyway

18:39 * danielcompton ponders

18:39 technomancy: amalloy: it's easier to scan

18:40 blunte: Hi folks. I'm stumped (and still rather new to Clojure). I'm trying to write a function that will return the index of the first occurrence of a value found in a list.

18:40 (find-first-index ("a" "b" "c") "b") should return 1

18:41 amalloy: (first (keep-indexed __ coll)) - try to fill in the blank, blunte

18:45 blunte: ,(def ar2 ["pkey" "pkey" "" "" ""])

18:45 clojurebot: #'sandbox/ar2

18:45 blunte: ,(keep-indexed #(= "pkey" %) ar2)

18:45 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: sandbox/eval48/fn--49>

18:47 amalloy: blunte: you're on the right track, but look more at the docstring for keep-indexed. what arguments does it pass your function?

18:48 blunte: amalloy: ahh, I think...

18:49 ,(keep-indexed #(if (= "pkey" %2) %1) ar2)

18:49 clojurebot: (0 1)

18:49 blunte: amalloy: awesome, thanks

19:03 llasram: blunte: ##(.indexOf [:a :b :c :d :e] :c)

19:03 lazybot: ⇒ 2

19:03 llasram: blunte: If you're trying to write your own, great, but if not... :-)

19:04 amalloy: llasram: meh

19:04 blunte: llasram: haha, no it was not my intent to reinvent something as wonderfully simple as that. Thanks :P

19:04 but it's good now that I know of keep-indexed as well

19:04 amalloy: .indexOf is not great really. it works if you're looking for a specific element, but most of the time you have a predicate

19:04 plus working in terms of list indices is usually an indication you're doing something wrong *anyway*

19:05 blunte: my need for index is valid in this case, and I'll spare you some gory meta meta business spreadsheet reader explanation

19:06 llasram: amalloy: I like to use it to turn O(1) algorithms into O(n) or O(n^2) versions

19:06 It's a hobby of mine

19:07 pmonks: ‘(inc llasram)

19:07 #selffail

19:07 amalloy: llasram: another advantage is it's horizontally scalable. you can turn n^2 into n^3 just as easily

19:08 llasram: :-)

19:15 numberten: is there a defn- (private) equivalent for def?

19:15 fifosine: Is there a good library for building an interactive cli using clojure?

19:15 mdeboard: fifosine: What would such a library have in it?

19:16 technomancy: jline2 I guess

19:16 necessary but not sufficient

19:17 fifosine: mdeboard: I don't know, I'm more looking to explore. I'm looking for a library with helper functions to allow me to create a program that when run allows the user to enter an interactive mini-shell

19:17 for doing whatever

19:17 mdeboard: Oh, you probably want to write an nrepl client

19:17 right? someone smarter than me?

19:18 technomancy: fifosine: for clojure programmers, or general use?

19:19 fifosine: technomancy: The library? For general programmers. The program I'm writing, for general use

19:19 Jaood: numberten: (def ^:private

19:20 numberten: Jaood: alright thanks :)

19:22 Jaood: numberten: defn- just adds the ^:private metadata for you

19:22 numberten: yeah

19:23 i wasn't sure if there was a def- or something defined

19:23 guess I could always write a macro for it though

19:23 fifosine: technomancy: Does what I'm asking for make sense?

19:24 technomancy: fifosine: I was just trying to see if it'd be appropriate to embed a repl or if you want your own mini-language

19:24 fifosine: oh, mini-language definitely

19:24 technomancy: so probably jline2+instaparse?

19:24 or mapping input to command vars more directly if you need extensibility

19:25 (the latter is kind of what mire does, but over the network)

19:26 https://github.com/technomancy/mire

19:30 casperc: I am having a wierd problem that I am wondering if anyone can help me solve or diagnose

19:30 TEttinger: casperc, ask away

19:31 casperc: basicly we have a project that uses clojure.java.jdbc which is working fine. My problem is that every query takes around 5 s, no matter what

19:31 This has suddenly started happening and is only on my machine

19:32 amalloy: have you tried turning it off and on again?

19:32 casperc: i have :)

19:33 i am running OSX maricks and I have a similar machine with the same setup that does not have the problem

19:33 and it is only me, now the other members of my team

19:33 mdeboard: are you sure your db server is running and accepting connections

19:33 if everything is terminating after 5 seconds that sounds like a client timeout

19:34 casperc: no the query goes through just fine, it just takes 5 seconds when it should be taking about 100 ms tops

19:34 mdeboard: Oh, "every query takes around 5s", implying they're succeeding?

19:34 i see

19:34 amalloy: i would say whatever is wrong is related, not to clojure, but to something else on your machine

19:34 mdeboard: ya

19:34 Are you using a connection pooler

19:34 casperc: i agree, but I can't just figure out what

19:34 mdeboard: have you tried turning it off and back on?

19:34 llasram: My guess would be DNS / nsswitch config

19:34 justin_smith: mdeboard: regarding some scrollback, I just got out of a bad relationshit, and appreciate this new word you have invented

19:35 mdeboard: justin_smith: Oh I didn't invent it, I heard it long ago

19:35 justin_smith: (inc mdeboard)

19:35 lazybot: ⇒ 7

19:35 justin_smith: oh, OK

19:35 mdeboard: But, sure, I'll take credit

19:35 Reaping those sweet lazybot points

19:35 casperc: llasram: would that not affect other connections? I am not seeing any problems when surfing the net or creating other connections from the program

19:36 amalloy: justin_smith, mdeboard: have you guys read cryptonomicon? i remember the chapter where bobby shaftoe is on a ship of some kind, and everyone decides they don't like the ship so they start replacing "ship" with "shit" in every word that has it

19:36 justin_smith: amalloy: I barely started it, I am sure I should read it

19:37 (ages ago that is)

19:37 amalloy: it's an excellent book. i've read it about three times

19:37 llasram: casperc: Can depend on how the various name services handle the particular name. Is the DB on localhost or resolved by an actual host name (even if on your same system)? If the latter, what happens if you try to `host` that name?

19:37 mdeboard: amalloy: No I avoid Neil Stephenson's books

19:37 I don't have the temperament for them

19:38 too many diversions/tangents/hyperfocus on minutiae idgaf about

19:38 casperc: llasram: It is not localhost, it is by hostname i'll give it a go

19:38 amalloy: mdeboard: sounds like you should not read his books, yeah. those were my favorite part

19:38 mdeboard: Just my opinion obv, people I respect really like his writing

19:38 casperc: it is several (different environments) this is going on for though

19:38 mdeboard: diff'rent strokes etc

19:38 technomancy: the only way I got through cryptonomicon was because I had a job that involved sitting around doing nothing for hours on end in school

19:38 llasram: casperc: Hmm

19:38 mdeboard: casperc: Sounds like a misconfig in your db server then IMO. Or bad disk maybe, or some such.

19:39 I assume you're tailing logs on the db server and see nothing incriminating.

19:39 casperc: mdeboard: but when connecting from a similar machine it doesn't happen, so I don't think that can be the case

19:39 technomancy: tape drive maybe?

19:40 mdeboard: casperc: But you said it's happening from diff environments right? Are all these environs using the same network conn to get to the db ?

19:40 if it's happening across multiple environs on different networks then something's fucky with your db server config

19:40 Oh

19:40 casperc: mdeboard: There are several versions of the DB it is happening for: dev, test, prod dbs

19:40 mdeboard: How much working memory do you have configured

19:41 casperc: it is only happening FROM one machine

19:41 mdeboard: I see

19:41 casperc: on the repl?

19:42 mdeboard: Do you have enough RAM for the query plan computation & query execution computation to be held in RAM? Or is the server having to swap to disk

19:42 That would cause a significant slowdown... speaking of, have you inspected the query plan to see what it says?

19:42 * llasram get some popcorn

19:42 mdeboard: explain select etc.

19:42 {blake}: I'm having laziness troubles. Also, problems with my Clojure code. (Heyo!)

19:42 mdeboard: {blake}: bazinga

19:42 llasram: (inc {blake})

19:43 casperc: mdeboard: it can't be the db server itself because it doesn't happen from other clients.

19:43 mdeboard: haha

19:43 Oh, you said "now my coworkers machines"... I guess you meant not your coworkers

19:43 technomancy: have you made any sysadmin enemies recently?

19:43 mdeboard: casperc: TCP windowing?

19:43 casperc: the query itself doesn't make a difference. "select 1 from dual" takes 5 seconds for instance

19:43 TEttinger: firewall stuff, port stuff...

19:43 {blake}: Specifically, I've got this structure when I do a "get-in" it returns the value for that key, but if I do a "str (get-in...)" I'm getting back "clojure.lang.lazySeq".

19:44 llasram: {blake}: Try `pr-str`

19:44 casperc: mdeboard: dunno

19:44 {blake}: I'm having trouble duplicating this in a small scale. llasram, 'k, thx.

19:44 llasram: ,(str (range 10))

19:44 clojurebot: "clojure.lang.LazySeq@9ebadac6"

19:44 llasram: ,(pr-str (range 10))

19:44 clojurebot: "(0 1 2 3 4 ...)"

19:44 mdeboard: casperc: start netstat then run your query again.

19:44 casperc: also this happens both when being on the same network as the db and remotely via vpn

19:45 mdeboard: could be an idea

19:45 mdeboard: casperc: better yet, install dstat if you can, then run that while your query executes

19:45 {blake}: llasram, OK, so that works. Cool. I don't really get what's going on, though. I assume "pr-str" realizes the seq. But I did try prefacing with "doall" and that got a lazySeq.

19:46 fifosine: technomancy: Is the type of program that fits my description called a "line editor"?

19:46 mdeboard: see what, i fanything, goes weird

19:46 hiredman: a forced lazyseq doesn't change its type

19:46 llasram: {blake}: Do you know Python? It's kiiiind of like the difference between `str()` and `repr()`

19:46 mdeboard: a tiger doesn't change its stripes

19:46 hiredman: it just means all the values have been realized and cached in the lazy seq

19:48 {blake}: llasram, Yeah. Oh, so pr-str is more like python's str (human-readable), and repr is more like python's str?

19:48 llasram: {blake}: Other way around :-)

19:48 Buuut I can see why that's confusing here

19:49 casperc: mdeboard: I am not sure how to use either of those tbh, but i'll give it a go. Currently I am installing mavericks in a fresh virtual machine to see if that has the same trouble

19:49 {blake}: llasram, Right. Wait. So "str" = "str", essentially? Maybe the analogy won't work for me.

19:50 hiredman, mdeboard Good point. Maybe need to dig into the source a little.

19:50 mdeboard: casperc: The beauty of dstat is you don't need to know how to do much of anything other than type "dstat"

19:50 fifosine: technomancy: I've found an equivalent library in Python: https://docs.python.org/2/library/cmd.html

19:50 mdeboard: {blake}: Oh I was just rhyming with what he said with a semantically similar metaphor

19:50 which also now that I think about it has the same meaning.

19:50 llasram: {blake}: `str` -> JVM .toString, which is for generically turning an object into a string, such as for formatted display to end-users. `pr-str` is for a (Clojure) printed/ideally-`read`able representation of the data.

19:50 ,(str "some string")

19:50 clojurebot: "some string"

19:50 llasram: ,(pr-str "some string")

19:50 clojurebot: "\"some string\""

19:50 llasram: If that helps

19:51 TEttinger: ,(str {:some :string})

19:51 clojurebot: "{:some :string}"

19:51 llasram: There isn't really sensible end-user thing to display for a data-structure like a lazy sequence, so it just punts

19:51 TEttinger: ,(pr-str {:some :string})

19:51 clojurebot: "{:some :string}"

19:51 TEttinger: hm

19:51 llasram: TEttinger: thanks for muddying the waters :-p

19:51 IMHO that's a wart

19:51 TEttinger: ,(str (map inc [1 2 3]))

19:51 clojurebot: "clojure.lang.LazySeq@7c42"

19:52 TEttinger: ,(pr-str (map inc [1 2 3]))

19:52 clojurebot: "(2 3 4)"

19:52 llasram: Yeah, so it doesn't help that some data structures do print as their stucture, but with weird results:

19:52 ,(str ["some" "vector" "of" "strings"])

19:52 clojurebot: "[\"some\" \"vector\" \"of\" \"strings\"]"

19:52 llasram: Hmm

19:52 ,(str (seq ["some" "vector" "of" "strings"]))

19:52 clojurebot: "(\"some\" \"vector\" \"of\" \"strings\")"

19:52 llasram: Ok, somewhere in here is the weirdness I wanted :-)

19:53 {blake}: OK, I'm actually somewhat comforted that this is a little...imponderable.

19:53 TEttinger: I think the str on (map inc [1 2 3]) is pretty illuminating

19:54 since map is so common, that's a frequent source of "LazeSeq@blah" prints

19:55 amalloy: {blake}: doall does realize the input sequence, but it doesn't change its type (and thus, its printed representation). you get a "lazy sequence" with five realized elements, but it still prints like a lazy seq (ie, illegibly)

19:56 i wonder whether it'd be crazy for (doall xs) to act like (apply list xs), so that what you get back *isn't* a lazy seq anymore. it sure seems to confuse a lot of newcomers that you get back a lazy seq, even though it's entirely reasonable

19:56 {blake}: amalloy, Right. The thing I'm not getting (in this case) is why it's even a lazy sequence. It's a PersistentHashMap inside a PersistentArrayMap, but it all seems to be realized.

19:57 amalloy, You may have just restated my confusion, yes.

19:57 amalloy: {blake}: no, you're wrong. if it prints like LazySeq@..., then it's a lazy sequence

19:57 it is not a hashmap inside an arrayman

19:57 *map

19:57 llasram: AH!

19:57 amalloy: (new superman villain: ArrayMan)

19:57 llasram: ,(pr-str (java.util.ArrayList. ["foo" "bar" "baz"]))

19:57 clojurebot: "[\"foo\" \"bar\" \"baz\"]"

19:57 llasram: ,(str (java.util.ArrayList. ["foo" "bar" "baz"]))

19:58 clojurebot: "[foo, bar, baz]"

19:58 llasram: There we go

19:58 fifosine: Does anyone know of a library that allows the creation of an interactive command interpreter? Something that's analogous to the cmd module in Python https://docs.python.org/dev/library/cmd.html

19:58 llasram: That's what I was trying to remember, which either explains things or leaves them hopelessly muddled forever

19:59 {blake}: *regrouping*

19:59 llasram: OTOH, why don't LazySeq's just toString as their realized portion?

20:00 TEttinger: llasram, because it could be infinite?

20:00 llasram: #<LazySeq (1 2 3 4 ...)>

20:00 TEttinger: ,(str (repeat :infinite))

20:00 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

20:00 TEttinger: uh ok

20:00 amalloy: TEttinger: as you've just discovered, that's a problem anyway

20:01 because the @foo part is the object's hashCode, and the hash of a lazy seq depends on all of its elements

20:01 TEttinger: ,(pr-str (repeat :infinite))

20:01 clojurebot: "(:infinite :infinite :infinite :infinite :infinite ...)"

20:01 TEttinger: haha

20:02 {blake}: amalloy, Well, here's what I'm seeing: https://www.refheap.com/89324

20:03 I haven't been able to recreate the complex structure and get the same results, so there's something I'm missing, obviously. "get-in" shouldn't create a lazy sequence (though I guess it could return one?)

20:03 amalloy: get-in will return whatever is there inside the map

20:03 you are storing lazy sequences in your map

20:04 danielcompton: Is it expected behaviour that leiningen will overwrite a "Main-Class" specified in :manifest with clojure.core if :main isn't specified?

20:04 amalloy: which is a totally fine thing to do, of course

20:05 technomancy: danielcompton: not sure what you mean by "overwrite"

20:05 danielcompton: technomancy: replace

20:05 technomancy: it shouldn't replace anything

20:05 llasram: Sounds like an explicit "Main-Class" :manifest entry?

20:06 danielcompton: llasram: I've got an explicit "Main-Class" entry without a :main, and it's being replaced with clojure.core

20:06 {blake}: amalloy, I can't see the lazySeq. In the repl it looks like ":_sub {:name :_sub, :value ({:b 1, :c 1, :a 2})".

20:06 danielcompton: Is https://github.com/technomancy/leiningen/commit/0f5905449726926760e1a6454286ad2e693f4cc0 relevant?

20:06 technomancy: danielcompton: oh, I see. yeah, it will check :main but not :manifest. there is a way to disable that though

20:06 amalloy: {blake}: ({:b 1, :c 1, :a 2})

20:07 this is a seq, and probably lazy

20:08 (indeed, evidently lazy based on your refheap paste)

20:09 danielcompton: technomancy: so you should set :main to nil if you want to specify "Main-Class" in your :manifest?

20:10 {blake}: amalloy, So...if it was unrealized at some point, and then realized, it remains lazy. Do we ever de-lazify (neologism!) sequences?

20:11 hiredman: {blake}: in the jvm is not possible for the type of a refence to change

20:11 fifosine: How do I input the EOF character and also read for it?

20:11 justin_smith: fifosine: in a *nix terminal, you can input it with Control+D

20:11 hiredman: {blake}: if x is a lazy seq, and you realize it walk it with doseq, x is realized, but the type of x cannot change

20:12 {blake}: hiredman, OK, then. Much to ponder. Thanks all.

20:12 hiredman: {blake}: you may not be aware of the features of lazy seqs that dictate their behaviour, checkout http://clojure.org/sequences

20:13 danielcompton: fifosine: I don't think EOF is a 'character', it's system defined AFAIK

20:13 fifosine: danielcompton: Does that mean there's not a way to specify functionality if it's read?

20:13 danielcompton: fifosine: wait think i got that wrong

20:13 justin_smith: yeah, it's more of a "condition" of the input stream - but you can send it with C-d

20:13 fifosine: it isn't read so much as detected

20:14 fifosine: justin_smith: err… how's that?

20:14 justin_smith: since it isn't a piece of data

20:14 llasram: There's the EO*T* character, ASCII/Unicode CP 4, usually entered via ^D

20:14 justin_smith: it's a state of the stream you get data from

20:14 {blake}: hiredman, Thanks. I keep going back to that, understanding bits and pieces. It's a journey. A journey of a thousand steps begun by walking backwards.

20:14 llasram: fifosine: Do you just want the EOT character, or are you actually trying to detect when you reach the end of a file?

20:15 justin_smith: fifosine: because we need to be able to input every possible byte (think image files), and when reading an image file or some other binary, still need to know whenthe input is closed

20:15 amalloy: llasram: he's trying to write a repl of some kind

20:15 fifosine: llasram: I'm trying to write an interactive command interpreter, so I want to be able to know when the user wants to exit by entering an EOF and detecting that

20:15 llasram: fifosine: Ah, then you -- you want EOT, which is character 4

20:16 justin_smith: which is control+d, which was the first thing mentioned up there

20:16 fifosine: llasram: So how do I read for "character 4" from what's returned from (read-line)

20:17 llasram: Oh, from `read-line`? I don't think that you do

20:17 justin_smith: fifosine: I think you just check if *in* is closed

20:18 fifosine: ugh I'm so lost, there isn't any documentation on doing something like this with clojure

20:18 llasram: fifosine: You do it just like you do from Java

20:18 justin_smith: this is not really clojure specific, you should read up on the relevant java classes

20:18 InputStream etc.

20:18 llasram: Or probably using JLine, if you want full terminal input funtimes

20:19 fifosine: https://github.com/jline/jline2

20:19 justin_smith: yeah, technomancy mentioned JLine above, and it makes this all much easier

20:19 if what you want is a shell like experience for the user

20:20 fifosine: docs of jline aren't that great

20:20 justin_smith: http://jline.sourceforge.net/javadoc/

20:21 fifosine: ok, I'll read up on it, thanks

20:24 technomancy: justin_smith: jline2 is a fork of jline, so those docs are probably not right

20:25 justin_smith: technomancy: oh, he said jline, so I linked the jline javadoc

20:26 technomancy: fifosine: https://github.com/trptcolin/reply uses jline2 if it would help to see some sample code

20:26 from clojure

21:01 lepah: Sorry, I was looking for Bronsa

21:01 Where is he?

21:02 justin_smith: Bronsa: you are being pinged

21:02 lepah: he is on this channel, but may not be around right now

21:03 lepah: I see

21:26 mynomoto: Is it possible to use double-check for async tests like cljs.test?

21:29 hiredman: it seems unlikely, there are no blocking operators in the cljs version of core async, so no way to return control to double-check's logical thread

21:44 mdeboard: technomancy: lein repl starts an nrepl server itself?

21:44 well, nevermind, I guess it just calls out to tools.nrepl to do so?

21:45 so concise

21:45 leiningen.repl is

21:45 :megusta:

21:49 technomancy: cant-tell-if-serious.jpg

21:50 Jaood: technomancy: you don't have a pic for that?! ;)

21:52 mdeboard: technomancy: dead serious

21:53 technomancy: I'm fumbling through how this stuff works atm irl bbq

21:53 brehaut: mdeboard: have you visited https://github.com/trptcolin/reply yet?

21:53 mdeboard: Yes

21:53 just now

21:53 after you linked it

21:54 I'm doing this for a different language's toolkit

21:54 The more examples the better though, thanks brehaut

21:55 If nothing else I've learned more about how nrepl, cider, etc. fit into the clojure ecology

22:01 rei: I'm using Vim, so I'm curious is there are any issues in Emacs reloading a namespace with a defmethod in it?

22:02 mdeboard: rei: What kind of issues?

22:04 rei: mdeboard: It reloads without error, but the defmethod/defmulti is exactly the same even though I changed it.

22:04 If I restart lein repl it works as expected.

22:04 mdeboard: rei: I see, I don't actually have any idea what vim's behavior is--

22:04 Shit, I thought this was in a different channel, sorry.

22:04 rei: Can you paste your code up somewhere and I can try it maybe?

22:05 rei: mdeboard: Yes, give me a moment.

22:09 mdeboard: Here's a reduced form of what I was doing. https://www.refheap.com/89326

22:10 I had messed up the defmulti earlier (it was only taking one argument), and when I switched it to two and reloaded it kept saying it wanted only one argument.

22:11 mdeboard: I edited the paste with what I had done wrong, but it through testing it was any modification.

22:12 mdeboard: rei: Works fine

22:12 rei: mdeboard: Alright, thanks. I guess it may be an issue with the vim plugin.

22:12 mdeboard: rei: I mean, I changed "site.com" to "foo.com", and ran `(parse-site "foo.com" {:blah :blah})` and still got :b

22:13 Jaood: rei: did you use :reload ?

22:13 mdeboard: (I changed it after I ran it against site.com and got :b)

22:14 rei: mdeboard: Ah...can you try changing the defmulti function? Maybe just have it return "foo.com".

22:14 That's where I ran into an issue.

22:14 Jaood: I did.

22:15 Jaood: And :Reload!

22:18 mdeboard: giving it a whirl

22:19 rei: Seems to work fine but only if I restart CIDER (emacs repl). if I just re-evaluate the defmulti it doesn't take hold

22:20 rei: mdeboard: Hmm...okay, perhaps that's the equivalent of me restarting the lein repl here.

22:20 mdeboard: yeah it is, I'm pretty sure

22:21 rei: mdeboard: Very weird...okay, thanks very much!

22:22 acebulf: hey guys, is there a Lispbox for Clojure on Linux?

22:32 Jaood: acebulf: what's lispbox?

22:33 justin_smith: Jaood: pre-configured emacs+lisp+package-manager

22:35 acebulf: lein is better than pretty much any other package management scheme out there, and is the tool you should use to run your repl and to package your library or app

22:35 regarding a full package like that, I don't know of one, but I wouldn't be surprised if there is one somewhere

22:50 acebulf: thanks @ justin_smith

22:50 munderwo: any tips on setting a value in a Java object? Im not sure of the syntax? its for swt

22:50 the java code is "gridData.horizontalAlignment = GridData.FILL"

22:51 danielcompton: munderwo: (.horizontalAlignment gridData GridData/FILL) ?

22:52 justin_smith: danielcompton: I think he needs to use set!

22:52 munderwo: yeah thats what I thought. But horizontalAlignment doesnt seem to be a method?

22:53 justin_smith: (set! (. instance field1) expr)

22:54 I only know this from looking it up, I don't mess with mutation much even in interop if I can help it, but that syntax should work

22:54 munderwo: woohoo! thanks justin_smith !

22:54 justin_smith: so it did work?

22:55 munderwo: Yup!

22:55 justin_smith: cool

22:55 munderwo: Im only doing the mutation to get a sample of Java to work.

22:55 justin_smith: right, I am not saying it is never needed

22:55 munderwo: and it looks like its normal practive in swt soo… ahh well..

22:55 justin_smith: I consider luck that I have avoided it so much so far :)

22:55 munderwo: hopefully the luck keeps rollin!

22:55 thanks!

22:55 justin_smith: np

23:04 xeqi: rei: defmulti has some sort of defonce semantics, so either removing the binding or restarting the repl is required

23:05 I feel like I've seen technomancy complain about this somewhere

23:06 bbloom_: use ##(doc ns-umap)

23:06 (doc ns-unmap) ; rather

23:06 clojurebot: "([ns sym]); Removes the mappings for the symbol from the namespace."

23:07 bbloom_: the defonce-ish semantics are a massive pain for multimethods

23:08 rei: xeqi: Thanks, I tried reading the code, but I couldn't make sense of it.

23:08 bbloom_: Oooh, let me give that a shot.

23:09 technomancy: or (def mymulti nil)

23:12 rei: bbloom_: The Vim plugin did not want to co-operate with me, but the technomancy trick worked.

23:12 bbloom_: technomancy: clever

23:18 dogonthehorizon: Greetings folks. I have a vector of keys and a list of vectors that I would like to join together. (zipmap keys vecs) isn't quite what I'm after and (apply zipmpap keys vecs) gives me an arity error... my next idea is to do this with loop/recur, however I'm curious to know if there's a cleaner way?

23:20 justin_smith: can you give a simplified example of the inputs you get and the outputs you expect?

23:21 is it something like [:a :b :c], [[0 1 2] [3 4 5]] -> {:a [0 3] :b [1 4] :c [2 5]} ?

23:21 dogonthehorizon: justin_smith: Yes that's exactly what I'm after

23:22 justin_smith: ,(zipmap [:a :b :c] (map vector [0 1 2] [3 4 5]))

23:22 clojurebot: {:c [2 5], :b [1 4], :a [0 3]}

23:22 dogonthehorizon: Essentially I have a response from clojure.java.jdbc/query where the first element of the sequence is a vec of keys and (rest response) is the list of values. I was hoping to use zipmap in some way to label the data

23:22 Ah. Let's give that a try then!

23:24 justin_smith: (partial map vector) swaps columns / rows in a sequence of sequences

23:24 it would likely have a handy name like rotate2d if it weren't already so concise

23:26 dogonthehorizon: Well actually no, looking at this answer again this isn't what I'm after. What I'm after is a result that looks more like this: [:a :b], ([0 1] [2 3] [4 5]) -> ({:a 0 :b 1} {:a 2 :b 3} {:a 4 :b 5})

23:27 justin_smith: ,(map zipmap (constantly [:a :b :c]) [[0 1 2] [3 4 5]])

23:27 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$constantly$fn__4178>

23:27 justin_smith: ,(map zipmap (repeat [:a :b :c]) [[0 1 2] [3 4 5]])

23:27 clojurebot: ({:c 2, :b 1, :a 0} {:c 5, :b 4, :a 3})

23:27 justin_smith: that should be it

23:31 dogonthehorizon: justin_smith: Oh, this is nice; I hadn't thought of using repeat in this way. Thanks for the help!

23:31 justin_smith: np

23:38 munderwo: Hmm..im having trouble linking to native libraries on OS X? getting Caused by: java.lang.UnsatisfiedLinkError: /Users/mlakewood/projects/indifference/indifference-app/lib/libchromium_loader.dylib: dlopen(/Users/mlakewood/projects/indifference/indifference-app/lib/libchromium_loader.dylib, 1): Library not loaded: @executable_path/Chromium Embedded Framework

23:39 Im not sure how to workout where it thinks @executable_path is going to be?

23:39 long shot that anybody has had anything to do with this.

23:40 justin_smith: munderwo: try running ldd on the artifact, it should tell you where all the shared libs it needs are

23:40 and which are perhaps missing

23:41 (the artifact meaning the .dylib file)

23:41 munderwo: So I know which ones are missing.. I just dont know where to put them.

23:41 the reference for @executable is an OS X thing that I dont know much about

23:42 justin_smith: yeah, I am not an OSX user, and have had no luck with trying to use native deps, hopefully someone else can help you

23:42 munderwo: thanks for trying.. I think it might be one of those things that is between two fields of experts...

23:43 justin_smith: ##java will likely say "don't do native code", but if you ask at the right time someone there may just be able to help

23:45 munderwo: oh thats a good thought

23:50 puredanger: munderwo: are you setting DYLD_LIBRARY_PATH ?

23:51 munderwo: nope. not at the moment. I just came across something that says I can use DYLD_FALLBACK_LIBRARY_PATH to specify a fallback dir to look in?

23:55 oooh… just got a little further! thanks for the tip puredanger !

23:55 ls

23:55 puredanger: munderwo: no idea what the fallback thing is

23:55 you need to actually load the library via java interop

23:56 presuming you've used JNI to generate a Java interface, you should just be able to call it then

23:56 munderwo: Its apparently where the system looks to find the library if it cant find it in all the normal places.

23:56 puredanger: (System/loadLibrary "foo") is the call to make to load

23:56 munderwo: yeah. It finds the dylib… but then it goes looking for another file and couldnt find it.. I put it in the right place and it seems happier now?

23:57 joshuafcole: If I have a folder full of files that I would like to require, is there a suggested way to do that? (Or alternatively, is there a better architecture approach I should consider?)

23:57 munderwo: Im actually useing a java library that wraps that.. But Its install story is… umm not great… or Im messing it up completely… either could be true

23:58 justin_smith: joshuafcole: in order to use require, the directory structure should reflect the namespace structure

23:58 joshuafcole: Use case is a folder of renderer's in a component entity system.

23:58 Okay, I've got that much in place

23:58 justin_smith: ie. my.app.foo should be in my/app/foo.clj somewhere under the soruce path

23:58 joshuafcole: but right now I'm manually requiring each renderer

23:58 e.g.

23:59 *quickly hacks :require to something manageable*

23:59 (:require [overcode.sces :as sces]

23:59 [tetsujin.renderers.pacman :as pacman]

23:59 [tetsujin.renderers.block :as block])

23:59 justin_smith: yeah, that's pretty much how its done

23:59 joshuafcole: the format is identical for each of the renderer files, is there a way I could map over all the ones in the folder without needing to list them by hand?

Logging service provided by n01se.net