#clojure log - Nov 09 2014

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

0:02 grandy: justin_smith: ok cool i'll keep investigating.. thanks again for the help

0:04 adereth: ls

0:04 bodie_: does cljs support normal clojure testing or do I need to integrate with a js testing kit?

0:09 TEttinger: ##(* 55 11)

0:09 Guest35098: ⇒ 605

0:09 TEttinger: that's odd

0:13 justin_smith: TEttinger: authentication issues, protected nick

0:13 TEttinger: heh

0:14 justin_smith: I forgot to verify authenticating with nickserv when I did the irclj update

0:15 TEttinger: yay

0:15 Raynes: He oughta stick this time.

0:15 justin_smith: &*clojure-version*

0:15 lazybot: ⇒ {:major 1, :minor 7, :incremental 0, :qualifier "alpha1"}

0:15 justin_smith: WOO

0:16 Raynes: &*clojure-version*

0:16 amalloy: (inc justin_smith)

0:16 lazybot: ⇒ {:major 1, :minor 7, :incremental 0, :qualifier "alpha1"}

0:16 ⇒ 122

0:16 amalloy: (inc Raynes)

0:16 lazybot: ⇒ 53

0:16 TEttinger: (inc justin_smith)

0:16 lazybot: ⇒ 123

0:16 Raynes: (inc justin_smith)

0:16 lazybot: ⇒ 124

0:16 TEttinger: (inc Raynes)

0:16 lazybot: ⇒ 54

0:16 Raynes: lol

0:16 TEttinger: (inc lazybot)

0:16 lazybot: ⇒ 33

0:16 Raynes: That escalated quickly.

0:17 rritoch: TEttinger: What is this (inc username) about?

0:17 justin_smith: so liberal with the karma, what will we do in the dead of winter and the karma fields are frozen over? our egos may starve!

0:17 TEttinger: it's karma for users or other words

0:17 Raynes: It's an ego system.

0:17 justin_smith: rritoch: it's an informal way to say you appreciate someone's work, or agree with them

0:17 TEttinger: $karma rritoch

0:17 lazybot: rritoch has karma 0.

0:17 TEttinger: $karma technomancy

0:17 lazybot: technomancy has karma 155.

0:18 rritoch: Aah, I see

0:18 justin_smith: $karma amalloy

0:18 lazybot: amalloy has karma 187.

0:18 TEttinger: (inc procedural generation)

0:18 lazybot: ⇒ 1

0:19 Raynes: lol

0:19 justin_smith: $karma procedural

0:19 lazybot: procedural has karma 0.

0:19 TEttinger: $karma procedural generation

0:19 lazybot: procedural has karma 0.

0:19 justin_smith: $karma procedural generation

0:19 lazybot: procedural has karma 0.

0:19 TEttinger: hm

0:19 justin_smith: hrmph

0:19 (identity procedural generation)

0:19 lazybot: procedural generation has karma 1.

0:19 TEttinger: I thought you fixed it

0:19 justin_smith: I thought the fix for that regex went in

0:19 Bronsa fixed it, and I made sure to propagate that (or I thought I did)

0:21 Raynes: Kinda losing faith in you guys and your ability to regex.

0:21 :P

0:21 justin_smith: I'ts not the regex at all!


0:21 rritoch: Before I forget to ask again. Is there a good maven repository to use for unofficial (alpha) releases of clojure technologies? I used clojars for my nativedep project, but I'm considering making my web platform public but it's nowhere near ready for a release so I'm not sure where to put the builds so anyone can play with it.

0:21 justin_smith: https://github.com/Raynes/lazybot/blob/master/src/lazybot/plugins/karma.clj#L61 Raynes this is the line that does it

0:21 notice it only looks at first args

0:22 that's the issue

0:22 or wait, should (inc procedural generation) only inc procedural?

0:22 is that it?

0:23 rritoch: there is a lot of sketchy / not ready for prime time stuff on clojars

0:23 Raynes: Actually, yeah, that looks correct.

0:23 TEttinger: What did you expect to be fixed here? :o

0:23 TEttinger: $karma acting like (identity)

0:23 lazybot: acting has karma 0.

0:23 Raynes: Oh

0:24 justin_smith: TEttinger: which one is broken right now

0:24 TEttinger: $karma

0:24 justin_smith: right, so the issue is that call to first

0:24 like I said

0:24 cahnge (first args) to (string/join \space args)

0:24 the regex is fine

0:25 TEttinger: I remember in ##anyone , justin_smith fixed identity, inc, and dec for multiple words

0:25 justin_smith: unless we can get the raw line and use that? that may or may not be better

0:25 Raynes: justin_smith: YES I TOO KNOW HOW TO PROGRAM GOD

0:25 justin_smith: haha

0:25 Raynes: It's 9:30PM on a Saturday

0:25 You're gonna have to be real patient with me.

0:25 :P

0:25 justin_smith: dude, it's pair programming on IRC - fun stuff :)

0:25 my memory of the codebase is pretty fresh

0:26 also I have not been sniffing glue, for a change

0:27 zerkms: hm, why does this http://pastebin.com/1tnv6MPq prints all 3 lines but does not return control back to terminal?

0:27 rritoch: justin_smith: This is fairly far from ready for primetime though I did manage to achieve most of my objectives. I still need to implement the fscript deployment in the default theme and there's a bug in the servlet context wrapper because it isn't grabbing .jsp sources from OSGi packages but once those are done I think I'm going to make it public because I'm loosing interest in the project.

0:27 justin_smith: zerkms: (shutdown-agents)

0:28 zerkms: you have to tell clojure to stop the thread-pool if you used it, basically

0:28 rritoch: justin_smith: It was just too much coding and debugging of systems-level code with so little to show for it, nothing more than a giant just to support a "hello world" app.

0:28 zerkms: okay, I though it would do that itself

0:28 Raynes: $login

0:28 lazybot: You've been logged in.

0:28 zerkms: thanks

0:28 Raynes: $reload

0:28 lazybot: Reloaded successfully.

0:28 Raynes: $karma procedural generation

0:28 lazybot: procedural generation has karma 1.

0:29 Raynes: TEttinger: ^

0:29 justin_smith: there we go, nice

0:29 TEttinger: yaaaay

0:29 justin_smith: $karma karma karma karma karma chameleon

0:29 lazybot: karma karma karma karma chameleon has karma 0.

0:29 justin_smith: (inc karma karma karma karma chameleon)

0:29 lazybot: ⇒ 1

0:30 justin_smith: $karma karma karma karma karma chameleon

0:30 lazybot: karma karma karma karma chameleon has karma 1.

0:30 justin_smith: (inc semantic satiation)

0:30 lazybot: ⇒ 1

0:32 Raynes: $grim clojure.core/some->

0:32 lazybot: http://grimoire.arrdem.com/1.6.0/clojure.core/some->

0:32 Raynes: arrdem: ^

0:32 TEttinger: (inc amalloy)

0:32 lazybot: ⇒ 1

0:32 TEttinger: oh no!

0:32 what could have happened!

0:32 Raynes: wut

0:32 I didn't do that.

0:33 dbasch: $karma police

0:33 lazybot: police has karma 0.

0:33 TEttinger: (inc Raynes)

0:33 lazybot: ⇒ 1

0:33 Raynes: What on earth

0:33 TEttinger: (inc Raynes)

0:33 lazybot: ⇒ 55

0:33 Raynes: ...

0:33 justin_smith: $karma amalloy

0:33 lazybot: amalloy has karma 187.

0:33 Raynes: Okay.

0:33 justin_smith: he is playing games with nonprinting characters :)

0:33 Raynes: OH.

0:33 TEttinger: :D

0:33 Raynes: I HATE YOU.

0:34 TEttinger: panic attack for a second there?

0:34 justin_smith: (dec amalloy)

0:34 lazybot: ⇒ 0

0:34 Raynes: Briefly

0:34 justin_smith: it's the evil twin

0:34 Raynes: no need for you to panic, I would have been the one to blame after all

0:34 Raynes: I don't think that would be the case as I made a change immediately prior to the purported breakage.

0:35 justin_smith: &(map int "amalloy")

0:35 lazybot: ⇒ (97 65279 109 97 108 108 111 121)

0:35 TEttinger: the character is \ufeff btw

0:35 justin_smith: &0xfeff

0:35 lazybot: ⇒ 65279

0:35 justin_smith: indeed it is

0:36 silly TEttinger, putting BOMs in things

0:36 TEttinger: (let [ss (java.awt.datatransfer.StringSelection. "(inc a\ufeffmalloy)")] (.setContents (.getSystemClipboard (java.awt.Toolkit/getDefaultToolkit)) ss ss)) ;; in a repl generates whatever untypeable chars I want

0:36 justin_smith: not the inverse mind you, that would be crude

0:44 john2x: how do I update my repl session with changes in my project.clj? (not dependency changes, just updated :dev values)

0:44 justin_smith: john2x: lein is not a runtime tool

0:45 john2x: that said, you can use, for example, pallet/alembic to add dependencies from maven at runtime based on your project.clj

0:50 john2x: oh ok. thanks.

0:56 technomancy: I think he said not dependency changes

0:57 john2x: some changes can be done on the fly and some can't

0:57 rritoch: justin_smith: I just opened the source, so it is officially public though I still need to fix some issues, document, and properly license everything

0:57 technomancy: :dev values is kind of imprecise

0:57 justin_smith: technomancy: oh, I missed the not depenency part, oops

0:59 rritoch: https://github.com/rritoch/clj-grid - Leiningen Plugin

0:59 https://github.com/rritoch/clj-grid-kernel - Kernel

0:59 https://github.com/rritoch/clj-grid-mvc - MVC Support

0:59 https://github.com/rritoch/clj-grid-core - Core Library

0:59 https://github.com/rritoch/clj-grid-version - Example app

1:00 john2x: nah I think I'll be fine restarting for now.. just found out about :headless repl, and the startup isn't too bad (at least it feels like it)

1:00 rritoch: With no docs open sourcing this monster is probably futile, but it is the first MVC web platform for clojure

1:01 john2x: now if only I could figure out how to make cider "refresh" the repl connection. or is cider smart enough to detect the restarted repl?

1:02 justin_smith: john2x: no it isn't. What kind of stuff are you trying to reset? you may want to look at stuartsierra's component system if you have things that need to restart / reset.

1:02 godd2: hyPiRion I just read your blog posts on persistent vectors and transients in Clojure. Thanks for the clear explanations :)

1:03 rritoch: I also need to move this junk to clojars I guess

1:03 home.vnetpublishing.com is my development server and isn't up 24/7

1:05 It is also no open to the public so I guess none of this code is functional without an account on my dev server :(

1:06 john2x: justin_smith: oh just trying to figure out a smoother workflow.. trying to start a new project using vagrant. so the repl needs to run in the vagrant VM. I was used to just cider-jack-in and then cider-restart, but jack-in starts its own repl.

1:07 *afaik

1:07 justin_smith: john2x: right, it does. component gives a really nice flexible way of resetting the state of various parts of your code without having to shut down the repl.

1:08 john2x: in terms of workflow, I like to start lein repl manually in a terminal, then use M-x cider to connect to it

1:09 among other things that means I can directly access it to quickly shut it down if it has frozen up my editor (which luckily only happens if I make big mistakes...)

1:10 john2x: ah good point on that. do you know if cider-restart remembers the parameters you passed to M-x cider?

1:10 justin_smith: I have never used cider-restart

1:11 technomancy: justin_smith: ya know, if you use a stable cider then the ability to quickly shut down when it freezes isn't actually all that useful =)

1:11 justin_smith: technomancy: I switched to 0.6.0 recently, maybe my habits will change

1:13 technomancy: bet you can make your emacs repl freeze up by printing a series of very long lines full of unprintable objects

1:13 there's a regex matcher that freaks the fuck out, and the more unreadable objects on a line the worse it gets

1:13 maybe one day I will try to narrow down and fix it

1:15 rritoch: justin_smith: Can you check out the example app https://github.com/rritoch/clj-grid-version and let me know what you think about the end product, and provide some feedback? I would like to move away from the gen-class's and move to pure clojure but since clojure doesn't have namespace inheritance I'm not sure that will be possible.

1:15 justin_smith: rritoch: sure, I am getting more and more braindead tonight, but I'll leave it open and check it out

1:17 TEttinger: have you seen nanogenmo? https://github.com/lizadaly/nanogenmo2014 seems up your alley, they are making pretty cool stuff

1:17 maybe not to late to enter the competition?

1:18 *too

1:18 https://github.com/dariusk/NaNoGenMo-2014

1:19 rritoch: justin_smith: I think it's going around... I've been working on this thing for about 3 months (on and off) and I've lost all direction which is the main reason I've decided to open source it to let the internet community decide it's future.

1:20 justin_smith: Security wise it is a trade off, in the publics hand security holes can be discovered and repaired sooner, but it's also less secure since anyone can review the code and abuse any security flaws they find.

1:27 TEttinger: hm wha

1:27 justin_smith: pretty cool and flasy for an algorithmically generated text

1:27 *flashy

1:28 TEttinger: neat, justin_smith

1:28 rritoch: I opened up the apache server @ http://home.vnetpublishing.com:8080/~vwpdev/ where you can see the hello world in action, the version app is implemented as an OSGi plugin @ http://home.vnetpublishing.com:8080/~vwpdev/?app=version accept it doesn't work because the bug I mentioned where the securitycontext wrapper isn't looking into the OSGi plugins, it's currently only looking into tomcat paths.

1:28 justin_smith: TEttinger: whether or not I submit anything, it will be cool to see the results. But that manuscript is a tough act to follow

1:28 TEttinger: yah

1:31 justin_smith: I have a character-token markov chain, I may try tweaking it and putting together a submission. Feeding it the gettysburg address + little red riding hood got me some amusing results.

1:34 zerkms: guys, any hint why this notifies about every line twice: http://pastebin.com/zkMRL3Sv

1:34 ?

1:34 tailer sources: http://commons.apache.org/proper/commons-io/apidocs/src-html/org/apache/commons/io/input/Tailer.html#line.395

1:38 rritoch: If you want to break it to see a stack trace you can request a non-existant app... http://home.vnetpublishing.com:8080/~vwpdev/?app=fu

2:05 luther07: 01:03 [ certainty ] [ ggherdov ] [ karls ] [ nhanH ] [ shem ] [ yogthos|away ]

2:22 john2x: where can I read about testing with fixtures? e.g. how to properly setup a test database all the way up to writing the actual tests?

3:11 arrdem: Raynes: Fuck yeah.

3:12 TEttinger: what's up, arrdem?

3:12 arrdem: TEttinger: just got back from Interstellar, saw Raynes testing the new $grim command

3:12 TEttinger: cool!

3:13 Interstellar is that thar space movie then?

3:13 arrdem: for "testing" here defined to be "my patch made it live"

3:13 TEttinger: :D

3:13 arrdem: TEttinger: yeah. I can't say anything because it's very spoilers sensitive, but as a bit of a space geek it was a v good albeit emotional movie

3:14 TEttinger: I do know it has space in it because it's called Interstellar

3:14 arrdem: hehe

3:14 $grim clojure.core/concat

3:14 lazybot: http://grimoire.arrdem.com/1.6.0/clojure.core/concat

3:14 arrdem: noice

3:14 TEttinger: $grim join

3:14 $grim clojure.core/join

3:14 lazybot: http://grimoire.arrdem.com/1.6.0/clojure.core/join

3:14 arrdem: TEttinger: you have to fully qualify it at present :/

3:14 TEttinger: $grim clojure.string/join

3:14 lazybot: http://grimoire.arrdem.com/1.6.0/clojure.string/join

3:15 arrdem: Grimoire won't get a "real" search feature until 0.4.0, which is still in the works, so $grim is a bit of a hack :P

3:16 it parses a fully qualified symbol, checks that it's in the Clojure core lib, and only then generates a URL.

3:16 Ex.

3:16 $grim me.arrdem.detritus.logging/debug

3:17 not in a core namespace, so lazybot doesn't bother trying to generate a bad URL

5:02 godd2: is it possible to destructure params to an anonymous function?

5:09 TEttinger: godd2: ##(map (fn [[x y]] (+ x y)) [[1 2] [2 3] [3 4]])

5:09 lazybot: ⇒ (3 5 7)

5:11 godd2: TEttinger I'm a dummy

5:11 Is it possible to do it with the #(...) form?

5:11 TEttinger: no worries

5:11 not with #()

5:12 you can however do...

5:12 ##(map (let [[x y] %] (+ x y)) [[1 2] [2 3] [3 4]])

5:12 lazybot: java.lang.RuntimeException: Unable to resolve symbol: % in this context

5:12 TEttinger: ##(map #(let [[x y] %] (+ x y)) [[1 2] [2 3] [3 4]])

5:12 lazybot: ⇒ (3 5 7)

5:12 TEttinger: since let allows destructuring too

5:13 godd2: ooh I like that. okay awesome thank you :)

5:13 TEttinger: np

5:23 supersym: oh, the bot had an upgrade some time as well... nice

5:24 something ##(map list '[bim bum bam])

5:24 lazybot: ⇒ ((bim) (bum) (bam))

5:24 supersym: cute

5:36 TEttinger: ##(doc map)

5:36 lazybot: ⇒ "([f] [f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted... https://www.refheap.com/92975

5:37 TEttinger: ##(map inc)

5:37 lazybot: ⇒ #<core$map$fn__4338 clojure.core$map$fn__4338@3020a258>

5:40 TEttinger: ,(def xf (map inc))

5:40 clojurebot: #'sandbox/xf

5:40 TEttinger: ,(sequence xf (range 6))

5:41 clojurebot: (1 2 3 4 5 ...)

5:41 TEttinger: ,(def xf2 (comp (filter odd?) (map inc)))

5:41 clojurebot: #'sandbox/xf2

5:41 TEttinger: ,(sequence xf2 (range 6))

5:41 clojurebot: (2 4 6)

5:42 TEttinger: ,(into [] xf2 (range 6))

5:42 clojurebot: [2 4 6]

5:42 TEttinger: neat

5:54 rritoch: TEttinger: Is that a bug? The documentation for comp says it applies functions from right to left, if that was true shouldn't your example be dumping the odd values?

5:55 TEttinger: hmmm

5:55 Bronsa: rritoch: no, that's how transducers work. by composing they create a stack of transformations that are applied from the outermost to the innermost

5:55 TEttinger: ,(doc comp)

5:55 clojurebot: "([] [f] [f g] [f g & fs]); Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc."

5:56 TEttinger: Bronsa, right, but here it applies the transducers left to right

5:56 metellus: ,(filter odd?)

5:56 clojurebot: #<core$filter$fn__4368 clojure.core$filter$fn__4368@683f5>

5:56 Bronsa: TEttinger notice the "from the outermost to the innermost" part of

5:57 TEttinger: in the docs for comp?

5:57 Bronsa: ((comp f g) x) -> (f (g x))

5:57 TEttinger in my message :)

5:57 TEttinger: ,(do (def xf3 (comp (map inc) (filter odd?))) (into [] xf3 (range 6)))

5:57 clojurebot: [1 3 5]

5:57 Bronsa: TEttinger rritoch the way transducer seem to apply from right to left has nothing to do with comp

5:57 it has to do with how transducers are implemented

5:58 TEttinger: the docs for comp should be updated, this is confusing

5:58 rritoch: ,((comp str +) 8 8 8)

5:58 clojurebot: "24"

5:58 metellus: how recently were the single arity versions of filter and map added?

5:58 Bronsa: TEttinger again, this has *nothing* to do with comp

5:58 metellus: 1.7

5:58 metellus: neat

5:58 Bronsa: metellus: which is still in alpha

5:59 metellus: that makes me feel better about not expecting them to work in the first place, then

5:59 TEttinger: so... if the docs don't go in the fn you're using, where do they go?

5:59 Bronsa: TEttinger this behaviour is documented in the clojure.org page for transducers

5:59 TEttinger: k

6:00 I'm getting too sleepy to understand this

6:00 night

6:01 Bronsa: ,(def f (fn [f] (fn [x] (println "1") (f x))))

6:01 clojurebot: #'sandbox/f

6:01 rritoch: Bronsa: It's not so late here and I don't quite follow... (comp (filter odd?) (map inc)) should => (filter odd? (map inc args#)) shouldin't it?

6:01 Bronsa: ,(def g (fn [g] (fn [x] (println "2") (g x)))

6:01 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

6:01 annelies: hi

6:01 Bronsa: ,(((comp f g) identity) 3)

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

6:02 Bronsa: as you can see this runs f before g even thoug composition is left to right

6:02 though*

6:02 rritoch: no. transducers """compose""" right to left

6:03 rritoch: you can think of comp as ->> when using transducers

6:03 "The transducer xf is a transformation stack that will be applied by a process to a series of input elements. Each function in the stack is performed before the operation it wraps

6:03 Composition of the transformer runs right-to-left but builds a transformation stack that runs left-to-right (filtering happens before mapping in this example).

6:03 As a mnemonic, remember that comp of transducer functions is applied in the same order as ->> with sequence functions.

6:03 rritoch: this is what's written in http://clojure.org/transducers, if that's clearer to you

6:05 metellus: if you look at the example I just evaluated in clojurebot you'll understand how transducers seem to compose right to left

6:05 rritoch: ,((comp (partial str "A") (partial str "B") (partial str "C")) "=IN=")

6:05 clojurebot: "ABC=IN="

6:05 Bronsa: rritoch*

6:05 (metellus sorry the message was not for you)

6:06 metellus: 'sok

6:06 rritoch: Bronsa: So basically the documentation is wrong?

6:06 Bronsa: rritoch: no the documentation is right

6:06 rritoch: https://clojuredocs.org/clojure.core/comp

6:06 Bronsa: rritoch: again, composition always happens left to right

6:06 rritoch: That says functions are applied right to left, output of rightmost fed to the next

6:07 Bronsa: durr, right to left

6:07 rritoch: did you look at my example? I'll paste it again in a nopaste

6:07 rritoch: http://sprunge.us/QIah

6:08 rritoch: notice that it's not invoking directly the result of (comp f g)

6:10 rritoch: I see your example, it is running left to right but the documentation says right to left

6:10 Bronsa: no.

6:10 one sec, I'll try to make this clearer

6:11 rritoch: ((comp println inc) 1)

6:11 ,((comp println inc) 1)

6:11 clojurebot: 2\n

6:11 rritoch: ,((comp str inc) 1)

6:11 clojurebot: "2"

6:12 rritoch: ,((comp even? inc) 1)

6:12 clojurebot: true

6:12 Bronsa: rritoch: http://sprunge.us/FLZV?clj take a look at this

6:12 rritoch: you can see it's printing g before f, showing that the composition does happen right to left

6:13 rritoch: but the composition of those two function doesn't yield a function that can be invoked directly, rather invoking *that* function will return another function to be invoked

6:14 rritoch: inside *that* function f and g run in the "opposite" order

6:15 rritoch: the key to understanding this is to notice that it's not doing ((comp f g) val), but (((comp f g) h) val)

6:18 rritoch: https://www.youtube.com/watch?v=6mTbuzafcII&t=25m30s here's how Rich Hickey explained this

6:22 rritoch: if you still don't understand how this works, take my example an try to manually comp f and g and follow the execution flow

6:23 rritoch: I'm actually still trying to figure out how to load that youtube link, I'm using synergy so copy/paste between machines doesn't always go smoothly

6:25 ,((comp (filter odd?) (map inc)) (range 6))

6:25 clojurebot: #<core$filter$fn__4368$fn__4369 clojure.core$filter$fn__4368$fn__4369@b1567b>

6:25 Bronsa: rritoch: transducers are not partially applied functions

6:27 rritoch: ,(((comp (filter odd?) (map inc)) (range 6)))

6:27 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn>

6:28 rritoch: ,(take 3 ((comp (filter odd?) (map inc)) (range 6)))

6:28 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$filter$fn__4368$fn__4369>

6:28 hyPiRion: godd2: good to hear you found them useful :)

6:29 rritoch: What kind of voodoo is this?

6:30 In my first test it says it returned a lazy sequence, so I try totake 3 from it and it says the result was a function

6:30 Is there comprehensive documentation on this comp function?

6:31 Bronsa: rritoch: for the nth time, comp has nothing to do with this and transducers are not partially applied functions

6:31 rritoch: read this http://clojure.org/transducers

6:31 rritoch: ,(type ((comp (filter odd?) (map inc)) (range 6)))

6:31 clojurebot: clojure.core$filter$fn__4368$fn__4369

6:34 rritoch: Bronsa: Well, thanks for your patience, as you can guess I've never used comp or transduce in any of my code but I really thought it was like a partial that combined functions together

6:35 Bronsa: rritoch: that's your mistake. (map f) is not (partial map f)

6:35 rritoch: if you're interested I suggest you read the page I just linked, transducers are really powerful

6:37 rritoch: I'm reading it now, and going to run over these examples for a bit, but right now it still looks like voodoo to me

6:39 luxbock: rritoch: I'd really recommend watching the entire talk from the youtube link Bronsa linked here

6:46 rritoch: ,(type ((comp (filter odd?) (map inc)) (range 6)))

6:46 clojurebot: clojure.core$filter$fn__4368$fn__4369

6:46 rritoch: Hmm

6:47 I don't see why that doesn't throw an exception either, I took a look at the source code for comp and it's just a function

6:47 ,(filter odd?)

6:47 clojurebot: #<core$filter$fn__4368 clojure.core$filter$fn__4368@99b936>

6:47 rritoch: Hmm

6:47 What happened there?

6:47 Locally I get an arity exception

6:48 Bronsa: rritoch: you're using clojure <=1.6.0

6:48 rritoch: the transducer arity was added in 1.7.0-alpha1

6:49 rritoch: Ok, I think that clears up my confusion a bit

6:52 ,((comp (partial str "A") (partial str "B") (partial str "C")) "=IN=")

6:52 clojurebot: "ABC=IN="

6:53 rritoch: So in this simple example, The innermost (first action) returns "C=IN=" and the string gets built backwards

6:54 Bronsa: yes

6:55 rritoch: Ok, so it is really these transducers that threw me, when I saw this example I was thinking that comp was a macro which was moving things around and creating a function out of the result.

6:56 Bronsa: no, comp is just a regular function

6:56 (comp f g) === (fn [& args] (f (apply g args)))

6:58 rritoch: ,((filter odd?) (range 6))

6:58 clojurebot: #<core$filter$fn__4368$fn__4369 clojure.core$filter$fn__4368$fn__4369@fe1155>

7:02 rritoch: ,((filter odd?) 1)

7:02 clojurebot: #<core$filter$fn__4368$fn__4369 clojure.core$filter$fn__4368$fn__4369@171dea8>

7:03 rritoch: ,(((filter odd?) 1))

7:03 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

7:05 rritoch: ,(transduce (filter odd?) 1)

7:05 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/transduce>

7:07 rritoch: ,(transduce (filter odd?) + (range 5))

7:07 clojurebot: 4

7:07 rritoch: ,(transduce (filter odd?) + (range 99))

7:07 clojurebot: 2401

7:08 rritoch: ,(transduce (filter odd?) identity (range 99))

7:08 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/identity>

7:10 rritoch: ,(transduce (filter odd?) (fn [&x] (last x)) (range 99))

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

7:11 rritoch: ,(transduce (filter odd?) (fn [& x] (last x)) (range 99))

7:11 clojurebot: 97

7:11 rritoch: ,(transduce (filter odd?) (fn [& x] (last x)) (range 101))

7:11 clojurebot: 99

7:11 rritoch: ,(transduce (filter odd?) (fn [& x] (last x)) (range 100))

7:11 clojurebot: 99

7:12 rritoch: ,(transduce (filter odd?) (fn [& x] (last x)) (range 49))

7:12 clojurebot: 47

7:12 rritoch: ,(range 9)

7:12 clojurebot: (0 1 2 3 4 ...)

7:12 rritoch: ,(last (range 9))

7:13 clojurebot: 8

7:15 kzar: Has anyone made a chrome extension using clojurescript before? I'm trying to figure out how it would fit together

7:19 mi6x3m: hey clojure, any off-the-shelf function to zip data through ZipOutputStream?

7:26 rritoch: mi6x3m: I think doseq is your best option

7:30 kzar: I've never used clojurescript before, but I have made chrome plugins, as far as I can tell you should just be able to drop the generated .js file from compiling the clojurescript into your plugin (folder) and it should just "work". I don't know how you call javascript from clojurescript but that is what you'll probably need to do to register listeners, etc.

7:32 kzar: rritoch: That's not my issue, the thing is you traditionally have separate Javascript files for chrome extensions. One for the popup page, one for the background "page", one for options or other pages. Clojurescript compiles down all the clojurescript files to one Javascript file normally. I think you can have them separate but then I think you have the Google closure dependencies etc in there once for each separate

7:32 page

7:32 mi6x3m: rritoch: I settled for that yeah, but what is a proper argument name for a stream?

7:33 kzar: rritoch: It's not a complete disaster, just wondered if anyone had figured out all those issues before or not

7:35 rritoch: kzar: The plugins I was working on were all in one source file which used ajax+eval for all additional functionality. Fundamentally that isn't really too much different than clojure bringing everything to a single source file.

7:36 kzar: rritoch: You didn't need separate functionality between the popup page and the background "page" for example?

7:37 rritoch: mi6x3m: I use "path" for my argument name when creating jars

7:38 mi6x3m: rritoch: I mean parameter name in a clojure function :) when passing a stream

7:38 I just use dst now

7:41 rritoch: THe code I use is @ https://github.com/rritoch/clj-grid/blob/master/src/leiningen/grid/bundle.clj#L239-L249

7:43 mi6x3m: I just loop over the paths that I want in the jar, and then dig into each path for all of the entries which get placed individually via a "write-entry" function which uses clojure.io/copy to add files to the jar

7:51 ,((comp clojure.string/trim (partial apply str)) (conj (range 6) " "))

7:51 clojurebot: "012345"

7:54 rritoch: ,((comp clojure.string/trim (partial apply str) (conj \")) (conj (range 6) " "))

7:54 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Character cannot be cast to clojure.lang.IFn>

7:55 rritoch: ,((comp clojure.string/trim (partial apply str) (partial (conj \"))) (conj (range 6) " "))

7:55 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Character cannot be cast to clojure.lang.IFn>

7:57 rritoch: ,((comp clojure.string/trim (partial apply str) (fn [& x] (conj x \"))) (conj (range 6) " "))

7:57 clojurebot: "\"(\" \" 0 1 2 3 ...)"

8:03 rritoch: ,((comp (fn [& x] (str \" (pr-str x) \")) clojure.string/trim (partial apply str) ) (conj (range 6) " "))

8:03 clojurebot: "\"(\"012345\")\""

8:03 elsen_: Hey guys, what's up?

8:03 BenceF: Hi, i'm having trouble with tools.namespace

8:04 its page says it is deprecated (but doesn't name an alternative)

8:04 rritoch: ,((comp (fn [x] (str \" x \")) clojure.string/trim (partial apply str) ) (conj (range 6) " "))

8:04 clojurebot: "\"012345\""

8:04 BenceF: maven says it has 0.2.7 but I can't seem to name it right

8:05 Bronsa: https://github.com/clojure/tools.namespace where does it say it's deprecated?

8:05 BenceF: https://clojure.github.io/tools.namespace/index.html

8:06 "This namespace is DEPRECATED; most functions have been moved to other namespaces"

8:06 I need .repl btw

8:06 but don't know how to add it to my dependencies

8:07 Bronsa: BenceF: that's referring to the "clojure.tools.namespace" namespace only, the functions have been moved to "sub" namespaces

8:07 toxmeister: hey, anyone seen or experienced this too? https://github.com/ato/clojars-web/issues/270 - would be grateful for some interim workarounds...

8:08 BenceF: i tried these: [org.clojure.tools.namespace "0.2.7"] then clojure.tools.namespace then tools.namespace

8:08 Bronsa: BenceF: the docstring for each function in that namespaces tells you where to find the new version

8:08 BenceF: and try to do a lein deps and it says it can't find it in maven

8:08 Bronsa: BenceF: https://github.com/clojure/tools.namespace#releases-and-dependency-information

8:09 BenceF: ahh I need a slash!

8:09 thank you Bronsa

8:10 found it thank you :)

8:13 oh but i need to require it as (require '[clojure.tools.namespace.repl :refer [refresh]])

8:13 seems a bit inconsistent

8:14 rritoch: Where is volitile! documented? I see it being used in the "Transducers with reduction state" example, but I'm not familiar with volitile symbols.

8:16 Bronsa: rritoch: that's another new 1.7 function

8:16 rritoch: hmm, I feel like I'm living in the stone ages, I really need to upgrade

8:16 Bronsa: BenceF: why does it seem inconsistent to you?

8:17 rritoch: no, this is all new stuff, 1.7.0 isn't out yet

8:17 rritoch: Is there any "WHats new" documentation for 1.7?

8:17 Bronsa: rritoch: yeah in the changelog

8:17 rritoch: Aaah

8:17 Bronsa: rritoch: https://github.com/clojure/clojure/blob/master/changes.md

8:18 BenceF: once you use a / then a .

8:18 Bronsa: BenceF: those are completely unrelated things

8:19 BenceF: one is a clojure namespace, the other is a maven dependency coordinate

8:19 BenceF: a lib could be called foo/bar and provide a baz.buz namespace, there's no correlation between those

8:20 BenceF: ah ok

8:23 elsen: What's the current way to work on a clojure backend and clojurescript frontend at the same time?

8:23 I'm trying to setup a clojure REPL to run my backend, and a clojurescript one connected to the browser

8:26 I setup austin to run a REPL in the browser, but it replaces the current REPL that run the clojure backend, am I missing something to work in both REPL at the same time?

8:29 rritoch: Is rich taking requests for the new version? I think clojure.core/in? and clojure.string/ucfirst would be useful addons. I have them isolated in my apps since they're so commonly needed.

8:29 https://github.com/rritoch/clj-grid-kernel/blob/master/src/com/vnetpublishing/clj/grid/lib/grid/util.clj

8:38 ingsoc: in list comprehensions the keyword :when is used to apply a filter. I thought keywords where just symbolic identifiers ?

8:46 rritoch: ingsoc: They are, the macro applies the functionality to it.

8:47 ingsoc: rritoch: so what is the macro

8:48 rritoch: ingsoc: https://github.com/clojure/clojure/blob/clojure-1.6.0/src/clj/clojure/core.clj#L4254-L4339

8:48 Thats the macro for "for"

8:51 ingsoc: ok so a keyword is just being used by the macro to trigger the filtering logic as it doesn't make sense to use up another name that could otherwise be used as a variable ?

8:51 rritoch: ,(macroexpand '(for [x '(9 10 11) :when (not= x 10)] x))

8:51 clojurebot: (let* [iter__4763__auto__ (clojure.core/fn iter__27 [s__28] (clojure.core/lazy-seq (clojure.core/loop [s__28 s__28] (clojure.core/when-let [s__28 (clojure.core/seq s__28)] (if (clojure.core/chunked-seq? s__28) (clojure.core/let [c__4761__auto__ (clojure.core/chunk-first s__28) size__4762__auto__ (clojure.core/int #) b__30 ...] (if (clojure.core/loop # #) (clojure.core/chunk-cons # #) (clojure.core...

8:52 rritoch: Hmm, it got cut, but in the full version you can see the not= in the resulting code

8:59 ingsoc: Yes the keyword is used to trigger the filtering logic, I believe it's possible to change macro expansion based on the symbols passed, but it would probably be ambiguous to use the symbol 'when instead of the keyword :when

9:00 ,(let [when 5] when)

9:00 clojurebot: 5

9:06 rritoch: ,(defmacro foo [& x] `(println (str ~@(map name x))))

9:06 clojurebot: #'sandbox/foo

9:06 rritoch: ,(foo bar)

9:06 clojurebot: bar\n

9:10 rritoch: ,(defmacro foo [x] (println ~(if (= x (symbol "foo")) "FOO!" "NOT FOO!"))

9:10 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

9:10 rritoch: ,(defmacro foo [x] (println ~(if (= x (symbol "foo")) "FOO!" "NOT FOO!")))

9:10 clojurebot: #'sandbox/foo

9:10 rritoch: ,(foo foo)

9:10 clojurebot: #<CompilerException java.lang.IllegalStateException: Attempting to call unbound fn: #'clojure.core/unquote, compiling:(NO_SOURCE_FILE:0:0)>

9:11 rritoch: ,(defmacro foo [x] ~(println ~(if (= x (symbol "foo")) "FOO!" "NOT FOO!"))

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

9:11 rritoch: ,(defmacro foo [x] ~(println ~(if (= x (symbol "foo")) "FOO!" "NOT FOO!")))

9:11 clojurebot: #'sandbox/foo

9:11 rritoch: ,(foo bar)

9:11 clojurebot: #<CompilerException java.lang.IllegalStateException: Attempting to call unbound fn: #'clojure.core/unquote, compiling:(NO_SOURCE_FILE:0:0)>

9:12 rritoch: ,(defmacro foo [x] `(println ~(if (= x (symbol "foo")) "FOO!" "NOT FOO!")))

9:12 clojurebot: #'sandbox/foo

9:12 rritoch: ,(foo bar)

9:12 clojurebot: NOT FOO!\n

9:12 rritoch: ,(foo foo)

9:12 clojurebot: FOO!\n

9:12 rritoch: There we go :)

9:40 rdsr: has anyone tried setting jvm-opts when using CCW with eclipse?

9:40 I can't get this to work..

9:43 I've searched online and found a few posts around it. Mostly the solution seems to be to modify the launch configuration of the clojure application ran before… But the under the clojure tree in the "run-as" menu I don't see any entry .

10:01 justin_smith: rdsr: does counterclockwise run clojure in a separate vm?

10:02 rdsr: um I'm not sure

10:04 I'm checking that right now

10:09 yes, so I'checked that it is starting two jvm..

10:10 I think one is the nrepl server?

10:12 justin_smith: is it using lein to launch the clojure process?

10:15 rdsr: I've searched a little… I think it does uses lein partially.. in that is uses the dependencies I've added in the project.clj.. but it skips the jvm-opts I've specified there

10:15 justin_smith: are you using ^:replace as a metadata for the jvm-opts?

10:16 rdsr: no

10:16 here's my jvm-opts from lein…

10:16 justin_smith: it merges options by default, in order to get certain configurations the ^:replace metadata is needed

10:16 rdsr: jvm-opts ["-Dsun.security.krb5.debug=true -Djava.security.auth.login.config=conf/user.conf -Djavax.security.auth.useSubjectCredsOnly=false"]

10:17 justin_smith: what if you start counterclockwise with those options?

10:17 rdsr: u mena I add the metadata in my project.clj?

10:17 *mean

10:18 somethign like…. :jvm-opts ^:replace […] ?

10:18 justin_smith: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L76 it's described for the :repositories key here, but yeah

10:18 because sometimes opts dont' work because they are merged with the defaults

10:18 I don't know if that is the case with your setup though

10:18 rdsr: let me try this ou

10:18 *out

10:20 justin_smith: rdsr: this thread says you want to look at "Run Configurations" https://groups.google.com/forum/#!topic/clojuredev-users/_NkhrgJOaAw

10:21 perhaps counterclockwise just can't / won't use your jvm opts from lein?

10:21 rdsr: another option would be starting "lein repl" yourself and telling counterclockwise to connect to its port

10:21 if that is an option

10:24 rdsr: cool.. I'll try that too

10:24 thks

10:25 justin_smith: rdsr: with emacs, I prefer to launch my repl from the terminal and connect via the port, rather than launching automatically

10:25 rdsr: it eliminates a point of failure when things get weird :)

10:25 rdsr: oh… well.. it is working somehow with replace … but I'm not sure how

10:26 justin_smith: oh nice!

10:26 that was a long shot, but glad it works

10:26 rdsr: but the jvm-opts are not here :/

10:26 :jvm-opts concat "[\"-Xdebug\" \"-Xrunjdwp:transport=dt_socket,server=y,suspend=n\"]"

10:26 justin_smith: some jvm opts are mutually incompatible, so you need ^:replace before some configurations work

10:27 rdsr: those jvm-opts (the one I pinged) are from the command-line ccw used to startup a repl

10:27 justin_smith: odd

10:28 yeah, seems like counterclockwise is not respecting your full project.clj config - the thread I linked to indicates that at some point that was considered a feature for the future?

10:29 rdsr: ohk

10:38 csd_````: How would would I cast a str "(foo bar)" as a list, i.e. as if I were using (read) and then wanted to use first/second on it?

10:39 gfredericks: csd_: read-string

10:40 csd_: thanks

10:48 gfredericks: $findfn "[:a :b]" [:a :b]

10:49 csd_: one other question, how would I map `quote` across a list?

10:49 lazybot: [clojure.core/load-string clojure.core/read-string]

10:49 gfredericks: csd_: you wouldn't, that doesn't make sense; can you give an example use for that?

10:49 justin_smith: csd_: read-string does not eval

10:50 gfredericks: ,'(a b c)

10:50 justin_smith: if that is your concern

10:50 clojurebot: (a b c)

10:50 justin_smith: &(read-string "[a b c]")

10:50 lazybot: ⇒ [a b c]

10:50 csd_: id like to read in "foo bar" and then eval (foo 'bar)

10:51 justin_smith: csd_: you need to write some string transformation code then

10:51 csd_: CL lets you map quote, i'm surprised clojure doesn't

10:51 justin_smith: csd_: read-string works by sexps

10:51 ,(read-string "foo bar")

10:51 clojurebot: foo

10:52 justin_smith: you need read, and a pushbackreader, to get all the sexps

10:52 or make sure it is all in one sexp

10:52 either way

10:52 gfredericks: ,(str "(\n" "foo bar" "\n)")

10:52 clojurebot: "(\nfoo bar\n)"

10:52 annelies: clojurebot I love you

10:53 Bronsa: it's a shared feeling

10:53 csd_: ,(read-string (str \( "foo bar" \) ))

10:53 clojurebot: (foo bar)

10:53 justin_smith: gfredericks: yeah, like I said, string transformation. Btw lazybot is cool too ##(println "hi")

10:53 lazybot: ⇒ hi nil

10:53 Bronsa: lazybot: isn't bad either

10:53 annelies: Bronsa: I don't think so :'(

10:53 justin_smith: and I got lazybot updated!

10:53 Bronsa: &*clojre-version*

10:53 lazybot: java.lang.RuntimeException: Unable to resolve symbol: *clojre-version* in this context

10:53 justin_smith: &*clojure-version*

10:53 lazybot: ⇒ {:major 1, :minor 7, :incremental 0, :qualifier "alpha1"}

10:53 Bronsa: &*clojure-version*

10:53 lazybot: ⇒ {:major 1, :minor 7, :incremental 0, :qualifier "alpha1"}

10:53 Bronsa: w00t

10:53 justin_smith: hehe

10:53 Bronsa: (inc justin_smith)

10:53 lazybot: ⇒ 125

10:55 justin_smith: $karma procedural generation

10:55 lazybot: procedural generation has karma 1.

10:55 justin_smith: that works now :)

10:56 csd_: So if I have (foo bar) as output by read-string, what's the easiest way to do the transform to map ' ? Am I best served by doing it before applying read-string?

10:56 justin_smith: csd_: why would you need to map ' on it?

10:57 Bronsa: csd_: ##(map #(list 'quote %) '(a b))

10:57 lazybot: ⇒ ((quote a) (quote b))

10:57 csd_: justin_smith: I'm trying to translate some of the code in Land of Lisp from CL to clj

10:57 The code is sort of goofy, basically evals directly what the user types in

10:58 justin_smith: an amusing failed attempt ##(map #(quote %) '(a b c))

10:58 lazybot: ⇒ (p1__17767# p1__17767# p1__17767#)

10:58 csd_: so if I type in "foo bar" it evaluates it as (foo 'bar)

10:58 Bronsa: justin_smith: wait what

10:58 justin_smith: csd_: clojure has nothing that prints as 'bar

10:58 Bronsa: ah.

10:58 justin_smith: Bronsa: yeah, tricky :)

10:58 csd_: justin_smith: what do you mean?

10:58 justin_smith: nothing prints naturally as 'bar

10:58 ,'bar

10:58 clojurebot: bar

10:59 csd_: defun game-read ()

10:59 (let ((cmd (read-from-string

10:59 (concatenate 'string "(" (read-line) ")"))))

10:59 (flet ((quote-it (x)

10:59 justin_smith: 'bar is a read syntax, but not part of any printing syntax

10:59 csd_: (list 'quote x)))

10:59 (cons (car cmd) (mapcar #'quote-it (cdr cmd))))))

10:59 that's the code in CL

10:59 Bronsa: csd_: please use a nopaste

10:59 csd_: sorry

10:59 justin_smith: csd_: I am sure common lisp does this, clojure does not

11:00 you can fake it if you like, or alter print-method for symbol I guess?

11:00 but nothing in clojure prints with a leading ' naturally

11:01 csd_: interesting, ok

11:01 justin_smith: csd_: would it butcher the whole thing to use keywords instead?

11:02 ,:bar

11:02 clojurebot: :bar

11:03 csd_: justin_smith: i don't think it would butcher it, although it'd definitely require rewriting some of the earlier code

11:04 justin_smith: it might be a more natural fit, since they have a proper print/read conversion

11:04 or, I mean, print/read/eval

11:12 csd_: justin_smith: could it be done with a recursive macro? Something like `('~foo (macro-name (rest input)))

11:18 TimMc: lazybot: #1

11:18 justin_smith: csd_: that still would not print with a '

11:19 csd_: i just need to eval it so that all symbols but the first are treated as if quoted, not to print to screen with '

11:19 justin_smith: oh, than don't eval

11:19 just read

11:19 Bronsa: csd_: what you need is (some-function "identity foo") ;-> foo?

11:20 technomancy: (apply (resolve (first x)) (rest x))

11:20 Bronsa: ^

11:20 well, after read-string'ing obviously

11:21 technomancy: you don't even need eval, assuming the first refers to a var

11:24 csd_: technomancy: perfect!

11:27 Does the CL code I pasted overcomplicate the CL solution, or is there no better way for them to do the above?

11:58 thesaskwatch: Hello, how to start with ClojureScript if I have some Clojure knowledge, but 0 about CS?

12:02 Glenjamin: thesaskwatch: do you have something in mind to build?

12:03 thesaskwatch: Glenjamin: yes, github milestone / issues visualization

12:04 Glenjamin: hows your JS?

12:04 and have you done any previous work with React?

12:04 thesaskwatch: Glenjamin: good js, I understand how react works

12:04 Glenjamin: cool, so i'd say try figwheel with reagent

12:04 thesaskwatch: Glenjamin: thanks

12:06 Glenjamin: if you want a proper repl, try weasel or austin, but they're a little fiddly to link to figwheel

12:08 on the subject of clojurescript, does anyone know if there's an open bug for giving a better message than "cannot call method 'call' of undefined" when the fn being applies is missing? I'm searching jira atm but can't see anythin

12:08 afhammad: I have record A implemented in ns x.a, and record B in ns x.b. How can I use A in an instance of B and vice versa?

12:10 Glenjamin: afhammad: if you need the underlying Record type, you need to use :import in the (ns) form with the JVM name

12:10 but if you just want to create one, you can import the factory function ->MyRecord

12:11 or did you mean how to resolve the circular dependency?

12:11 afhammad: yes, circular dep. does importing the factory func get around it?

12:11 thesaskwatch: Glenjamin: are there any basic concepts I should start with? I see that at least cljbuild is one

12:11 Glenjamin: thesaskwatch: yeah, cljsbuild is probably the main one, but the defaults figwheel generates are reasonable

12:12 apart from that it's a lot like clojure in terms of the core fns

12:12 thesaskwatch: Glenjamin: ok, great

12:12 Glenjamin: and there's some fancy stuff like #js and js* but you should be able to avoid them until you need them

12:15 afhammad: Glenjamin: yes, circular dep. does importing the factory func get around it?

12:15 Glenjamin: http://stackoverflow.com/questions/3084205/resolving-clojure-circular-dependencies seems sensible

12:16 tl;dr is have a namespace with the types in

12:19 afhammad: Glenjamin: yeh read that, saying a refactor is required is fine, but no one gives an example of what that might look like. I am using records to represent db models, dumping them all into one ns isnt really a great option

12:20 Glenjamin: why do you say that?

12:20 you could also just combine the ones which are circular

12:21 if they're coupled to each other, you're probably not gaining much from separating

12:24 afhammad: how are models represented in clojure, where you are trying to encapsulate a certain domain into a ns? For example a "Project" and a "User" are totally diffrerent things, why would I want to combine them

12:25 rweir: why would you combine them? put them in different namespaces

12:26 Glenjamin: afhammad: perhaps the question then becomes, why is there a circular dependency between them if they are totally different things?

12:29 afhammad: Glenjamin: because things need to talk to each other in order for a system to work, otherwise whats the point. A better example, I have a Project and a Feature, where a Project might want to grab features that it is associated with without rewriting the db call, while a feature wants to grab a project is bleongs to.

12:29 Glenjamin: afhammad: sorry, i'm not trying to be snarky, just trying to get at the core of why it's currently structured this way

12:30 there's a few valid constructions for that, and circular dependencies is one of them - but not supported in Clojure

12:31 you could have the records be in a namespace that contains only records, while functions live elsewhere

12:31 you could say "projects and features are related, so they live in the same ns"

12:32 you could have a namespace that contains cross-model fns, while encapsulated things stay in the same ns as the records themselves

12:32 if you treat it as a model/mapper separation, i think that would work also

12:34 afhammad: Glenjamin: hmm ok thanks, i'll think about those some more.

12:45 justin_smith: afhammad: one option is to define (a) protocol(s) that both A and B know how to access, and write all their code that touches one another in terms of (those|that) protocol(s)

12:47 so User and Project could be protocols (each with their own ns) and then your records would implement User and access a Project and visa versa

12:47 afhammad: this is quite clean in practice, and as a bonus allows easy outside extension

12:48 afhammad: everywhere where I say protocol above, you could instead use a group of multimethods if you prefer the flexibility of doing it that way, but your design as expressed so far sounds more protocol friendly

12:49 afhammad: justin_smith: they both implement ModelBase protocol which contains the fns that I need right now. Lets say in fn get-one of Project I need to call get-all of Feature. what would that look like?

12:49 justin_smith: afhammad: another thing to consider, backing up Glenjamin's reasoning, is that in clojure we decouple data from code, and that is actually a Good Thing™

12:49 afhammad: are get-one and get-all part of the ModelBase protocol?

12:50 afhammad: justin_smith: yes

12:50 Glenjamin: this sounds quite active-record-like

12:50 justin_smith: then call the protocol method

12:50 you don't need to know anything about the concrete implementation, that's the point of protocols

12:50 a Project shouldn't have to know the concrete type of a Feature, just that it implements some protocol Project cares about

12:51 afhammad: what does that call look like? just so I follow along

12:51 justin_smith: call the protocol method on the object

12:52 it works just like a function in clojure (proto-ns/proto-method thing)

12:52 if you give me concrete names of things I can make that example more specific

12:53 afhammad: mind you the protocol function is namespaced to where the protocol is defined, not to where the implementation is defined

12:53 Glenjamin: presumably the problem is you want to do (defn features [project] (features/get-all :project-id (:id project))

12:53 afhammad: so for example, Project's get-one needs to call Feature's get-all

12:53 justin_smith: is features a protocol namespace?

12:53 Glenjamin: and also (ns features) (defn project [feature] (project/get-one :id (:project-id feature)))

12:53 justin_smith: if not you are doing it wrong

12:54 Glenjamin: n/m sorry, I got confused about who was pasting what

12:54 afhammad: get all and get-one should not belong to Project or Feature, they should belong to some protocol

12:55 if you are using protocols, use protocol methods and treat the class of the argument as irrelevant

12:55 afhammad: justin_smith: well they do, but they are implemented in record Project in (ns x.project) and record Feature in (ns x.feature)

12:55 justin_smith: afhammad: place of implementation does not matter!

12:56 you call the protocol method based on the namespace where the protocol is defined

12:56 that's the point of protocols

12:56 the calling code should only know the protocol, and know nothing about the objects that implement them

12:57 afhammad: justin_smith how does it know which implementation to use?

12:57 justin_smith: afhammad: it doesn't

12:57 Glenjamin: justin_smith: that would still require a protocol per entity, in this scheme, would it not?

12:57 justin_smith: the protocol knows

12:57 afhammad: how does the protocol know?

12:57 justin_smith: afhammad: extend / defrecord tell the protocol who extends it

12:57 Glenjamin: he wants them to both be based on the same protocol, or so he said

12:58 Glenjamin: right, but the problem is they want to both reference each other

12:58 justin_smith: afhammad: you call the protocol, the protocol calls the method that that object registered with that protocol

12:58 Glenjamin: feature would load it's parent project, and projects would load their child features

12:58 i don't see how a single protocol helps there

12:58 justin_smith: Glenjamin: they shouldn't reference each other, only instances of the protocols one another implement

12:58 Glenjamin: this is how nearly the entirety of clojure.core is done, it works

12:59 Glenjamin: it can be N protocols

12:59 Glenjamin: right, the protocols (types) live separately from the implementation

12:59 afhammad: justin_smith: when you call the protocol, are you supposed to pass in an instance of the record? are there any examples of this

12:59 justin_smith: the point is no circularity is needed if both objects call protocol methods, and both can know all protocols involved

12:59 afhammad: exactly, the first argument to a protocol method is the thing extending it

13:00 afhammad: all the container knows is "this is an instance of Foo" and it call some protocol method of Foo on it

13:00 Foo being a protocol of course

13:00 afhammad: so basically I need to pass an instance of the other record in the function i'm calling, in order to pass it to the protocol call?

13:01 Glenjamin: afhammad: can you provide a sample of what you'd like code that uses these models to look like?

13:01 justin_smith: Glenjamin: afhammad: to be more concrete - the protocols, however many exist, clearly don't need to know about one another. By coding in terms of these isolated protocols (implementing them, calling their methods) you get arbitrary interoperation with no circularity

13:02 afhammad: right, and if something needs to know about both User and Project, then it must be a higher order thing that works with both

13:02 Glenjamin: justin_smith: right, but you still need to extract a bunch of protocols into a separate namespace from the implementations, and i don't think that abstraction is worth it over a similarly structured non-protocol approach in this case

13:02 justin_smith: and it can put them together as it likes

13:02 Glenjamin: assuming i'm understanding the problem statement properly

13:02 justin_smith: Glenjamin: fair point, that is often the case

13:03 Glenjamin: I am trying to present how one properly uses a technique afhammad already started using (definign and implementing protocols)

13:03 afhammad: justin_smith: I THINK that solves the issue, was hoping it didnt come to that, but i guess thats it

13:03 Glenjamin: on the surface, it sounds like you're trying to build quite and OO-style active-record-style api, which I don't think works all that well in Clojure

13:03 justin_smith: afhammad: I don't know your code, but that almost always works

13:03 Glenjamin: well, activerecord was one of his premises, arguing about that is another can of worms altogether :)

13:04 Glenjamin: heh, very true

13:04 justin_smith: but yes, proper clojure design is often about decoupling data and functions

13:04 in a way that is very unlike OO

13:04 Glenjamin: i think it's possible that the complexity here comes from trying to build an api that isn't very clojurey

13:05 justin_smith: Glenjamin: yeah - but clojure CAN do that stuff, if you use the tools as intended

13:05 afhammad: justin_smith: Glenjamin: perhaps, not because i want to, but because i have yet to see a decent clojure approach to it, do you know of any?

13:05 justin_smith: afhammad: use vanilla datastructures. Write functions that work on said vanilla datastructures. Rely on immutability and purity of functions instead of data hiding and encapsulation.

13:06 Glenjamin: afhammad: personally i would keep separate the definitions of my models & pure functions that deal with them, form the code which marshalls them to and from the database

13:07 and then you'd end up with something like (app.feature-mapper/get-all project) and (app.project-mapper/get-one feature)

13:08 afhammad: justin_smith: Glenjamin: Thanks for the input guys, will need to rethink the structure with the points uv raised

13:10 justin_smith: afhammad: I find that I use protocols etc. for things that really benefit from OO. Unlike some clojure folks I think there are some problem domains where that really is the case. But Clojure style OO is about interfaces and message passing, not inheritance and encapsulation.

13:10 well that binary may be overstated, but that's where the emphases / deemphases are

13:12 afhammad: justin_smith: The only reason i went down the protocol/record path is because I thought i would solve my circular dependency issue

13:13 justin_smith: afhammad: the alternate solution is to use generic data structures (things like maps, vectors, lazy-seqs, sets, + keywords as markers)

13:13 you can easily write code that utilizes these without circular dependencies

13:14 afhammad: justin_smith: the records arent really holding any data, they just have a bunch of fuctions

13:14 justin_smith: the functions return what ever data they get to you, not persisted to the record

13:14 justin_smith: afhammad: aha, implicit in that approach is that the data comes first, and the functions are just ways to gather / massage the data

13:15 so you would have functions that can grab each data source, and functions which perform the transformations you need

13:15 the approach is a tradeoff compared to OO, but it really does have powerful aspects

13:24 engblom: Is it possible to "configure" clojure to automatically switch from integer to biginteger instead of throwing an exception.

13:24 =

13:25 s/./?/

13:25 arrdem: You can switch to using +', -' and soforth...

13:26 the "normal" core math functions will never auto-promote

13:26 $grim clojure.core/+'

13:26 lazybot: http://grimoire.arrdem.com/1.6.0/clojure.core/+'

13:27 arrdem: but there isn't some configuration dynamic var you can bind to alter the behavior of + if that's what you're looking for.

13:29 engblom: arrdem: +' -' etc are what I am looking for

13:42 razum2um: can delete/yank a version from clojars?

13:43 AeroNotix: razum2um: nope

13:43 Not without someone at Clojars doing it for you

13:43 arrdem: in general no, however technomancy has been prevailed upon in the past when there was a good reason to do so

13:43 justin_smith: razum2um: you can ask one of the folks who run clojars nicely, if there is a security or stability issue

13:43 razum2um: the people who can do that tend to hang out here, and also #leiningen

13:44 razum2um: but is this intentionally or just nobody pushed a PR?

13:44 AeroNotix: intentionally

13:44 justin_smith: intentionally

13:44 razum2um: wtf?

13:44 AeroNotix: razum2um: think about it

13:44 If someone pushed a dependency, then people depended on it, then someone deleted it. What happens then?

13:45 A good dependency management system needs immutable dependencies

13:45 End of story as far as I am concerned.

13:46 justin_smith: AeroNotix: I make exceptions for greivous security concerns, where it's better that your app crash rather than run said code

13:46 razum2um: AeroNotix: not exaclty. a good dependency tool can let specify dependencies like bundler ~> 1.0 this means 1.x but not 2.0, and it will just fetch latest version of 1.x branch

13:46 justin_smith: razum2um: that really sucks in practice

13:46 razum2um: AeroNotix: this way yanking is nothing special

13:46 justin_smith: razum2um: you can do that with mvn, it just breaks all sorts of things

13:47 AeroNotix: razum2um: dependency ranges are not incongruent with immutable dependencies

13:47 justin_smith: dependency ranges suck though

13:47 Glenjamin: being able to yank a dependency seems reasonable

13:47 being able to change one is terrible

13:47 justin_smith: agreed

13:47 Glenjamin: the assumption is that people wouldn't yank without a good reason

13:48 AeroNotix: Glenjamin: which is why the option goes through humans, I think it's a reasonable way to do it

13:48 like justin_smith said, security threats are a good reason to yank a version

13:49 arrdem: the only things I remember technomancy or anyone else removing from clojars were internal dependencies that shoudln't have been deployed

13:51 razum2um: and what about some sad hotfixed versions, which are pushed and then realized some bug, fix it and push another one again, is this a good practice to leave known buggy version out there?

13:52 AeroNotix: razum2um: push a new version and live with your mistake

13:52 you shouldn't be pushing new things willy-nilly

13:52 andyf: razum2um: Which versions don't have bugs?

13:53 razum2um: AeroNotix: ok then )

13:53 Glenjamin: it'd be nice to be able to mark versions as "don't use this because X"

13:54 while still leaving them public

13:54 but i've never used a package registry that did that

13:55 andyf: Glenjamin: Kind of like a signed addendum to a released version of "This has bugs with severity >= n" ?

13:55 One that a dependency manager tool like Leiningen would be able to inform you of with a certain command?

13:55 Glenjamin: yeah, that'd be neat

13:58 andyf: Maybe that would be a Clojars enhancement that Nelson Morris could find a way to get paid for.

13:58 justin_smith: andyf: Glenjamin: doesn't lein ancient help with this

13:58 andyf: I'll send him a message in case it helps

13:59 justin_smith: it would be cool if lein ancient said 1.x has a newer version, also you could upgrade to 3.x

13:59 andyf: justin_smith: It tells you whether there are newer versions, not how severe any known bugs are

13:59 justin_smith: andyf: right

13:59 Glenjamin: justin_smith: it does that, but doesn't distinguish between "is fundamentally broken" vs "has new stuff"

13:59 arrdem: andyf: random tooling idea I've been kicking around

13:59 justin_smith: yeah - a bug/security metadata feature for versions would be awesome

14:00 arrdem: andyf: take the set of var/fns and their arities, spit it to a file, compare between "releases" to confirm at least nominal SemVer adherence

14:01 andyf: arrdem: I'll send that idea to Nelson, too, giving you credit, if you don't mind.

14:01 arrdem: andyf: go for it. I think it'd be nice to see.

14:01 Glenjamin: xeqi: ping?

14:01 andyf: Not sure if it will go anywhere, but I know he has been looking for ways to get paid for Clojars work that adds value.

14:02 xeqi: Glenjamin: surprise pong

14:02 Glenjamin: oh neat, lazybot counts

14:02 we were discussing some potential money-worthy clojars features just up

14:05 xeqi: https://www.youtube.com/watch?v=JjYAnBhF2JU has some neat ideas in this general area as well

14:09 andyf: xeqi: Cool. I sent you an email with a couple of ideas just discussed in the last few minutes here, in case they are useful. I have no idea what paying customers are interested in, though.

15:07 martinklepsch: whats the syntax in enlive to do whats in css slectors "#a, #b" ? [:#a :#b] means it looks for #b in #a

15:09 justin_smith: martinklepsch: intuitively I would expect #{:#a :#b}

15:09 since that is unordered

15:15 borkdude: what's the recommended way to embed a video in an octopress blogpost?

15:30 annelies: martinklepsch: from the documentation:

15:30 csd_: Why is it that sometimes my nREPL session becomes borked up and I can't (read-line) anymore without opening a new REPL?

15:30 annelies: > At the top level you can have a big "or" between selectors by wrapping several selectors in a set. #{[:td :em] [:th :em]} is going to match any em insides either a th or a td. This is equivalent to [#{:td :th} :em].

15:31 justin_smith: annelies: cool, I guessed right

15:31 annelies: Or rather

15:31 > Similarly, sets group predicates in an union.

15:31 justin_smith: annelies: also, regarding that markov thing you shared the other day, did you hear about the generative text competition going on?

15:32 annelies: No!

15:32 justin_smith: https://github.com/dariusk/NaNoGenMo-2014

15:32 there is some stiff competition already

15:33 https://github.com/lizadaly/nanogenmo2014 this thing is amazing, even if it weren't algorithmically generated

15:33 annelies: I don't like competitions. :p

15:33 justin_smith: hehe

15:34 anyway, that lizadaly project is like, wow

15:34 martinklepsch: annelies: what documentation did you find this in?

15:34 annelies: enlive readme

15:34 martinklepsch: oh

15:34 I was thinking this was most extensive about selectors: http://cgrand.github.io/enlive/syntax.html#selector-step

15:34 annelies: > #{selector-step*} ; union

15:34 That page also mentions it!

15:35 martinklepsch: I misunderstood that then. Was expecting something different with union. anyways thanks to both of you :)

15:38 justin_smith: annelies: I go to liza daly's web site, and see why her contribution is so good: http://lizadaly.com/ she's in the digital publishing business

15:40 csd_: ,(do (print-str "aaa") (Thread/sleep 5000) (print-str "bbb"))

15:40 clojurebot: "bbb"

15:40 csd_: Someone care to explain this?

15:40 justin_smith: csd_: print-str does not do what you think it does

15:41 csd_: It just returns as string?

15:41 justin_smith: ,(do (println (print-str "aaa")) (Thread/sleep 5000) (print-str "bbb"))

15:41 clojurebot: aaa\n"bbb"

15:41 justin_smith: right

15:41 ,(do (prn (print-str "aaa")) (Thread/sleep 5000) (print-str "bbb")) ; prn, so we see the data more clearly

15:41 clojurebot: "aaa"\n"bbb"

15:41 AeroNotix: anything for libnotify ?

15:41 csd_: justin_smith: playing around in the REPL, i've experienced a few times where i'll read in, printing will fail, and then when i call the same command again,w hat should have been printed the first time is then printed.

15:42 what exactly are the mechanics behind that?

15:42 i'm guessing its a buffer that doesn't get released the first time around

15:42 justin_smith: csd_: print or println?

15:42 csd_: the default in the jvm is to buffer until newlines

15:42 csd_: using print-str only

15:42 justin_smith: print-str is not a printing function

15:43 (doc print-str)

15:43 csd_: i've never used it until now, but it seemed to be working, until it wasnt

15:43 clojurebot: "([& xs]); print to a string, returning it"

15:43 justin_smith: it is a string function

15:43 your stuff was only accidentally working

15:44 csd_: is there a corollary to print/println that flushes the read buffer?

15:51 annelies: csd_: not in clojure.core

15:51 justin_smith: println flushes

15:51 because newlines flush

15:51 and there is also the flush function

15:51 ,(doc flush)

15:51 clojurebot: "([]); Flushes the output stream that is the current value of *out*"

15:51 annelies: it flushes the output buffer, not the input buffer, right?

15:51 justin_smith: annelies: oh right, my bad

15:51 annelies: also depends on *flush-on-newline*

15:51 justin_smith: I misread

16:38 technomancy: I saw discussions above about clojars deletions... a compromise that we're open to is allowing deletions for packages that have no downloads.

16:38 but no one has submitted a patch for this yet.

16:38 also allowing "do not use this" advisories is something we'd consider a patch for

16:45 thesaskwatch: Hi, I'm trying to use figwheel and I'm getting a Caused by: java.lang.RuntimeException: No such var: clojure.core.cache/through error. Anyone has an idea what's wrong?

16:46 that's my project.clj https://gist.github.com/mateusz-fiolka/d8f45b656c449861724b

16:46 Jefffrey: Morning

16:46 arrdem: thesaskwatch: not having org.clojure/core.cache in your deps?

16:47 thesaskwatch: arrdem: the tutorial doesn't say it's needed. Example pom in figwheel repo doesn't have it.

16:47 annelies: hi Jefffrey

16:47 arrdem: Raynes: is there a lazybot plugin for searching up the latest clojars version of something?

16:47 Raynes: $search useful

16:47 thesaskwatch: arrdem: https://github.com/bhauman/lein-figwheel/blob/master/example/project.clj

16:47 Raynes: I'm sure there is somewhere.

16:47 Somewhere in there.

16:48 arrdem: thesaskwatch: it's a transitive dep.

16:48 Raynes: $latest useful

16:48 lazybot: [useful] -- https://clojars.org/useful

16:48 thesaskwatch: arrdem: then shouldn't it just be dependency of figwheel?

16:48 Raynes: hm

16:48 technomancy: thesaskwatch: there's a bug in clojure's AOT compiler that causes problems like that some times with plugins

16:48 clojurebot: Huh?

16:48 Raynes: Oh

16:49 arrdem: There's a function that does screen scraping.

16:49 thesaskwatch: technomancy: ok, thanks

16:49 Raynes: arrdem: But it's broken due to the design changes a while back.

16:49 arrdem: fix plz

16:49 Bronsa: thesaskwatch: I believe some of your deps requires a version of core.cache, and another pulls in an older version

16:49 arrdem: Raynes: :/

16:49 Jefffrey: Hi annelies

16:49 Raynes: arrdem: It's the latest command in clojure.clj

16:49 thesaskwatch: Bronsa: any way to do something like maven dependency:tree with lein?

16:49 Raynes: lein deps :tree

16:50 arrdem: Raynes: yeah I'll take a look later

16:50 technomancy: thesaskwatch: sounds like this problem is related https://github.com/technomancy/leiningen/issues/1563

16:52 thesaskwatch: looks like core.async needs it

16:52 I'll add it explicitly

16:56 technomancy: so what's the workaround? specifying latest core.cache in dependencies doesn't help

16:57 technomancy: thesaskwatch: it's a bug in the clojure compiler. you can't work around it in a plugin.

16:57 I guess the workaround is to not use a plugin.

16:58 Bronsa: technomancy: how is that a bug in the clojure compiler?

16:58 thesaskwatch: technomancy: I'm confused. This is my first approach to clojurescirpt. I thought that figwheel is an often used plugin. Does it mean it's broken?

16:59 technomancy: thesaskwatch: dunno, I've never heard of figwheel before

16:59 lots of the clojurescript tooling is broken though from what I can tell just observing on irc

16:59 Bronsa: hrm. I may be getting this confused with an earlier bug.

16:59 thesaskwatch: technomancy: ok, thank you

17:00 arrdem: Raynes: wait why are you doing screen scraping?

17:00 technomancy: Bronsa: I know there are issues with mixing AOT and non-AOT, which is why I try to AOT as late as possible.

17:00 plugins make this difficult.

17:00 Raynes: arrdem: uh, because it was the only trivial way to do it at the time?

17:00 arrdem: 's legit

17:03 Bronsa: thesaskwatch: you might have more luck asking in the #clojurescript channel when there's more activity btw

17:03 thesaskwatch: Bronsa: yes I just joined it :)

17:09 justin_smith: anyone recall how to get a binary data source from clj-http?

17:10 n/m, found it

17:16 arrdem: at macro invocation time, *ns* will be the expansion context namespace right?

17:17 Bronsa: yes

17:40 cristian: Hi guys. Is there any function that allows me to convert a clojure map to a Java bean? There's a function called `bean` that converts from Java bean to clojure map... I'm looking for the opposite.

17:43 justin_smith: cristian: maybe this is what you want? https://github.com/clojure/java.data/blob/master/src/main/clojure/clojure/java/data.clj#L93

17:45 cristian: actually, maybe this http://clojure.github.io/java.jmx/#clojure.java.jmx/create-bean

17:45 I guess you need to put it in an atom first?

17:46 or maybe jmx beans are different...

17:47 cristian: Yes, JMX is a different beast. By bean I mean just simple POJOs

17:47 justin_smith: right, right

17:49 cristian: according to this, sometimes a record works (if you can make a record with the fields that matter) https://groups.google.com/forum/#!topic/clojure/Z7MwDUys8NA

17:50 arrdem: dnolen_: damn thanks for the fast turnaround :D

17:50 dnolen_: arrdem: np

17:53 cristian: justin_smith: Thanks, I'll take a look at that

17:58 justin_smith: cristian: just figured this out in my repl https://www.refheap.com/93004

17:58 cristian: depending how specifically you know the fields you care about beforehand, that approach should be usable

17:58 cristian: the trick is that you need the protocol in order to have the getX methods

18:00 arrdem: dnolen_: I messed up and forgot the namespace separator. Shall I just update the ticket?

18:00 cristian: justin_smith: interesting!

18:00 justin_smith: cristian: Clojure is very opinionated about implementing to an interface rather than a class, so you can only create the methods if you get them from a defined interface

18:01 cristian: a protocol is just a clojure abstraction for an interface (and java can use what it creates as an interface)

18:01 dnolen_: arrdem: fixed in master

18:01 arrdem: dnolen_: thanks.

18:03 justin_smith: cristian: to be clear "bean" is for turning beans into hash-maps, so an instance of Foo should work where a bean is expected

18:04 cristian: if not, you could instead reify the FooProto and use that

18:05 cristian: ok

18:10 Glenjamin: does anyone know of a good primer/cheatsheet on clojure syntax?

18:10 arrdem: reidrapper's clojure tutorial posts are good...

18:10 bbloom: Glenjamin: http://clojure.org/reader

18:11 Glenjamin: and http://yobriefca.se/blog/2014/05/19/the-weird-and-wonderful-characters-of-clojure/

18:11 Glenjamin: this is to use as a reference for a cljs workshop where people won't know any clojure

18:11 but will be familar with FP

18:12 i've written half an app, so the plan is they'll be able to finish it

18:12 bbloom: the second one is probably the easiest to use as a quick reference

18:12 Glenjamin: i might try and write something that only covers the bits i'm using

18:13 can't decide whether to reduce myself to a smaller subset

18:13 maybe remove any destructuring and use (fn [] over )#()

18:14 justin_smith: Glenjamin: "reduce myself to a smaller subset" sounds like nerdy jargon for going on a diet

18:18 Glenjamin: cheers for the links bbloom

18:18 what language intro tutorial do people tend to recommend these days?

18:31 dnolen_: Glenjamin: the best ones are the books still - there are several things online now that's useful - http://www.braveclojure.com/, Kyle Kingsbury's (aka aphyr) intros

18:31 Timothy Baldridge and Eric Normand have nice inexpensive videos

18:36 razum2um: can I composite filtering functions via "and" & "or" (say I have divisible-by-3 and divisible-by-5) or do I need to stick with #(and (divisible-by-3 %) (divisible-by-5 %)) because "and" is a macro?

18:37 i mean is there a more "clojurish" way to comp them?

18:39 metellus: ,(doc every-pred);; razum2um would this do what you want?

18:39 clojurebot: "([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]); Takes a set of predicates and returns a function f that returns true if all of its composing predicates return a logical true value against all of its arguments, else it returns false. Note that f is short-circuiting in that it will stop execution on the first argument that triggers a logical false result against the original predicates."

18:39 Raynes: I believe so.

18:40 razum2um: metellus: that's ok, thanks, but there is some-pred for OR ?

18:40 justin_smith: ,((every-pred #(zero? (mod % 5)) #(zero? (mod % 3))) 15)

18:40 clojurebot: true

18:41 razum2um: ,(filter #(or (divisible-by-3 %) (divisible-by-5 %)) (range 20))

18:41 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: divisible-by-3 in this context, compiling:(NO_SOURCE_PATH:0:0)>

18:42 razum2um: but you got the idea

18:42 justin_smith: ,(filter (every-pred #(zero? (mod % 5)) #(zero? (mod % 3))) (range))

18:42 clojurebot: (0 15 30 45 60 ...)

18:42 metellus: some-fn, maybe?

18:42 justin_smith: oh you want or, not and?

18:42 metellus: he asked for both

18:43 razum2um: justin_smith: yes, wrote it twice already

18:43 justin_smith: razum2um: sorry, I missed that

18:43 * Raynes raises an eyebrow

18:43 razum2um: i just wonder why (comp & fns) is so neat and logical composition not

18:43 justin_smith: ,(filter (some-fn #(zero? (mod % 5)) #(zero? (mod % 3))) (range))

18:44 clojurebot: (0 3 5 6 9 ...)

18:44 Raynes: In these cases I tend to just use for.

18:44 justin_smith: logical composition is neat

18:44 Raynes: It represents these complex structures better.

18:44 justin_smith: you just need to use the right functions

18:44 every-pred for and, some-fn for or

18:44 Raynes: filter, map, etc are great, but they're usually unwieldly when the predicate gets hairy.

18:44 razum2um: ok, we have "some-fn" and "every-pred" - very consistent :D

18:44 Raynes: Don't be afraid to use for just because it's for.

18:45 arrdem: for is one of my favorite features of Clojure

18:45 razum2um: but again, it's not equal to logical AND'ing and OR'ing functions

18:45 Raynes: Neither are doorknobs.

18:49 metellus: razum2um: juxt might be useful here

18:49 as another option for combining functions

18:59 razum2um: metellus: thanks! I needed exactly these to build what i need: (defn and-fns [& fns] (fn [& args] (every? true? (apply (apply juxt fns) args))))

19:00 and (defn or-fns [& fns] (fn [& args] (some true? (apply (apply juxt fns) args))))

19:00 justin_smith: razum2um: how are those better than some-fn and every-pred?

19:00 razum2um: justin_smith: they are better composable

19:01 justin_smith: in what way?

19:01 razum2um: and resulting function can be composited with other

19:01 justin_smith: these things are all true of some-fn and every-pred?

19:02 razum2um: some-fn and every-pred are very limited in usage

19:02 justin_smith: no they aren't

19:03 arrdem: some-fn and every-pred have the same type signatures as your and-fns and or-fns. what on earth do you mean they aren't equally composable.

19:03 actually they don't, because or-fns isn't gonna be lazy...

19:03 and ever-pred is explicitly lazy

19:05 razum2um: hm, you're right

19:05 my bad, sorry,

19:09 crack_user: hello guys

19:09 some one knows a good way to start in clojure?

19:11 TEttinger: crack_user, what experience do you have in other languages?

19:11 crack_user: ruby, rails

19:12 I am rails guy basicaly, and I find some dificult to start in clojure

19:12 is very diferent to I am used to do

19:12 TEttinger: http://www.braveclojure.com/ I have heard good stuff about

19:12 I used 4clojutr

19:12 4clojure

19:13 $google 4clojure

19:13 lazybot: [4clojure – Welcome!] https://www.4clojure.com/

19:13 justin_smith: yeah 4clojure / clojure koans can help you get a feel for things

19:13 ~koans

19:13 clojurebot: Gabh mo leithscéal?

19:13 justin_smith: clojurebot: koans |is| http://clojurekoans.com/

19:13 clojurebot: In Ordnung

19:13 justin_smith: ~koans

19:13 arrdem: of all the "learn clojure" resources that aren't print books, the koans have had the most effort put into them

19:13 clojurebot: koans is http://clojurekoans.com/

19:13 arrdem: ,(+ 1 2)

19:13 clojurebot: eval service is offline

19:14 TEttinger: ##(+ 1 2 3)

19:14 lazybot: ⇒ 6

19:14 TEttinger: (inc lazybot)

19:14 lazybot: ⇒ 34

19:14 arrdem: no... clojurebot is fine I'm checking to see if I'm still on hiredman's blacklist

19:15 TEttinger: lol

19:15 oskarkv: ,(+)

19:15 clojurebot: 0

19:15 crack_user: thx, I whill check theses links

19:15 TEttinger: how'd that happen, arrdem?

19:15 arrdem: TEttinger: hell if I know. I assume I got the stick transitively when bitemyapp did

19:16 TEttinger: are you on the same box?

19:16 justin_smith: cristian: updated the paste with an example of using reify, which is more succinct if you are only doing it once https://www.refheap.com/93004

19:16 arrdem: nah

19:16 https://github.com/hiredman/clojurebot/issues/5

19:28 cristian: justin_smith: awesome, thanks dude

19:30 justin_smith: I haven't really played with gen-class, since I haven't done much of the sort of interop that requires it. Is there a way to play with gen-class in the repl? does that even make any sense?

19:59 amalloy: justin_smith: no, you can't

20:00 justin_smith: amalloy: OK, that's what I was afraid of

20:00 verified: the truth hurts

20:17 technomancy: hm; can't you just bind *compiling-files* or whatever?

20:18 err--not bind, but change

20:19 justin_smith: ,(apropos "compiling")

20:19 clojurebot: ()

20:19 justin_smith: ,(apropos "files")

20:19 clojurebot: (clojure.core/*compile-files*)

20:20 justin_smith: &(doc *compile-files*)

20:20 lazybot: ⇒ "; Set to true when compiling files, false otherwise."

20:21 justin_smith: technomancy: but I would still need to put the class definition into a file before it could be compiled though I think

20:22 rritoch: @justin_smith: There is another way, I believe I talked to you about it but the code is now open sourced.

20:22 justin_smith: rritoch: oh yeah, I still intend to look at that

20:22 rritoch: I think it's in the kernel, I"m checking now

20:22 justin_smith: I tried to run marginalia but it couldn't resolve some of the deps

20:23 rritoch: Yeah, because it's linked to my private repository, I need to move everything to clojars

20:24 justin_smith: Take a look at this code https://github.com/rritoch/clj-grid-kernel/blob/master/src/com/vnetpublishing/clj/grid/lib/grid/kernel.clj#L500-L503

20:24 This compiles from a URL as an inputstream

20:24 justin_smith: OK

20:24 rritoch: So there's no need to write a file first

20:28 technomancy: justin_smith: are you sure?

20:28 I don't see why

20:28 rritoch: Anyhow, today is my day off so I hope to resolve the final resource loading issue with the servletcontext, and move everything to clojars (in that order).

20:28 technomancy: afaik compiling is just loading with *compile-files* set to true

20:29 justin_smith: technomancy: right, so I need to load something, it isn't a repl thing

20:29 technomancy: that's all I meant

20:29 technomancy: or do you mean if I turn *compile-files* on, things I enter in the repl will get compiled?

20:29 technomancy: sorry, not loading, evaling

20:30 ~tias

20:30 clojurebot: Try it and see! You'll get results faster than asking someone in #clojure to evaluate it for you, and you'll get that warm, fuzzy feeling of self-reliance.

20:30 justin_smith: ahh, interesting

20:30 technomancy: heh, I forgot that factoid had that commentary attached to it

20:31 rritoch: technomancy: That is not completely true, setting compile-files to true doesn't generate the __init classes needed to instantiate gen-class's

20:31 technomancy: rritoch: hm; ok. interesting.

20:31 justin_smith: technomancy: https://www.refheap.com/93012

20:32 rritoch: technomancy: That is why I had to hack directly into the compiler and call Compiler/compile to get those __init classes

20:32 technomancy: now we know =)

20:32 rritoch: technomancy: Personally though I think it would be much better if simply enabling *compile-files* would compile everything that gets eval'd

20:33 technomancy: rritoch: yeah, me too.

20:33 are they emitted by c.c/compile?

20:34 oh, probably that's just a wrapper around Compiler/compile

20:37 rritoch: technomancy: The code which does it is @ https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7378-L7382

20:40 techmomancy: As for the clojure.core/compile, that wraps clojure.lang.RT/load

20:41 technomancy: That is what caught me while trying to figure out how to compile an input stream because I was confusing Compiler/load with clojure.lang.RT/load which are two entirely different things.

20:48 luther07: uther07(+i)] [2:freenode/#clojure(+cnt)] [Act: 1]

21:00 rritoch: Is there a "with" syntax for calling a method on an object if the passed object argument isn't null?

21:02 This is the code I have but it seems like there must be a good way to reduce (golf) this code... (defn -getResourceAsStream [this path] (let [r (get resource path)] (if x (.openStream r))))

21:03 err: it's (get-resource path) not (get resource path) ...

21:05 amalloy: rritoch: do you mean x there, or r?

21:06 justin_smith: (defn -getResourceAsStream [this path] (if-let [r (get-resource path)] (.openStream r)))

21:06 rritoch: amalloy: r

21:06 justin_smith: thx, that is much better

21:06 amalloy: s/if/when

21:06 rritoch: justin_smith: It is such a common case though, there should really be a macro for it

21:07 justin_smith: if-let / when-let are said macros

21:07 amalloy: indeed. and if you really want to, you can write a more specialized version yourself

21:07 justin_smith: oh, there is some-> too

21:07 rritoch: justin_smith: Like (if-with ob (.Somefunc arg1 arg2 ...))

21:08 justin_smith: (defn -getReasourceAsStream [this path] (some-> (get-resource path) .openStream))

21:08 amalloy prefers () around the .openStream

21:08 rritoch: Hmm... I'll need to check that out, I never used some->

21:09 justin_smith: it is that common case you talked about - it stops chaining if any of the results are nil

21:09 rritoch: justin_smith: Yeah, I think some-> is what I want :)

21:09 amalloy: it's true, i do prefer (.openStream)

21:10 crack_user: hey guys

21:10 what its the bets way to resolve this koan

21:10 (= (__ (list 1 2 3 4 5)) 4)

21:10 I made "(fn [x] (first (rest (reverse x))))"

21:11 there is a better solution?

21:12 rritoch: Are you allowed nth? #(nth (reverse %) 1)

21:13 justin_smith: ,(first (take-last 2) [0 1 2 3 4])

21:13 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core/take-last>

21:13 justin_smith: err

21:13 ,(first (take-last 2 [0 1 2 3 4]))

21:13 clojurebot: 3

21:15 crack_user: thx for the answers guys

21:16 justin_smith: the doc-string on take-last is a bit iffy - "Depending on the type of coll may be no better than linear time" - then it does a loop over seq no matter the input type

21:16 so it should just say "no better than linear time"

21:20 TEttinger: crack_user: #(dec (count %))

21:21 rritoch: Bah!

21:21 I resolved the resource loader issue and ran into another nasty bug

21:21 http://home.vnetpublishing.com:8080/~vwpdev/?app=version

21:21 justin_smith: take-last could theoretically use rseq,take,reverse on vectors...

21:22 crack_user: TEttinger this is like a cheat, xP

21:25 justin_smith: TEttinger: surely you mean (comp dec count)

21:25 rritoch: I've gone to great lengths to avoid making a custom class loader for this system but I think this the JSP servlet is going to force me :(

21:29 YAY!

21:29 Clojure classloader worked

21:29 http://home.vnetpublishing.com:8080/~vwpdev/?app=version

21:31 The some-> syntax is MUCH cleaner..... https://github.com/rritoch/clj-grid-core/blob/master/src/com/vnetpublishing/clj/grid/lib/grid/webapp/servlet_context_wrapper.clj#L73-L74

21:31 Anyhow, now to "fight" with clojars

21:31 justin_smith: yeah, some-> is very nice

21:32 (inc some->)

21:32 lazybot: ⇒ 1

21:32 rritoch: I have no idea where I put my clojars key

21:32 The only clojars project I have so far is clj-nativedep https://github.com/rritoch/clj-nativedep/blob/master/README.md

21:34 I coded it a long time ago, it's still in C-style formatting

21:35 dbasch: crack_user: for that matter, (constantly 4) would work too :)

21:36 crack_user: yep :D

21:38 rritoch: Do I need to add clojars to my project.clj :repositories to do a lein deploy clojars ?

21:41 Also... What java version should I deploy with? I'm currently using java 1.8 but should I use 1.6 or lower for compatibility purposes?

21:41 justin_smith: rritoch: I think clojure will target 1.6 regardless?

21:42 perhaps not though

21:43 rritoch: It doesn't. I specifically had to install this version of java because it's what my client uses, I usually prefer to stick with oracle releases but at the time oracle didn't yet have 1.8.20+ released so I had to use openjdk

21:44 Can I add something to my project.clj to force compiling to 1.6 using the 1.8 JRE?

21:45 Hmm, actually I guess I need 1.7+ since it uses tomcat libraries

21:50 Ok, I see this here..... https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L248

21:50 But I'm not sure about this -Xlint:-options param.

21:52 I guess I'll just try it and see if it burns to the ground

21:59 liathit: Which is web framework most popular now?

21:59 Jodo, luminus, etc..

22:05 rritoch: liathit: Do you have a link for Jodo? I honestly haven't heard of either framework, but I'm developing my own clojure/mvc framework

22:06 liathit: My framework is targeting Web 4.0 -> Web 5.0 technology though so it won't be market ready for awhile.

22:07 liathit: rritoch, http://www.joodoweb.com/

22:08 rritoch: thx

22:08 liathit: from my research all I could find was that most lojure web-apps were built on the back of ring

22:08 I had to forsake ring though because my framwork provides jsp support which is mutually exclusive with ring at this time.

22:10 ddellacosta: rritoch: why, curious?

22:11 liathit: I don't know that frameworks are that heavily used by people doing "real" Clojure web dev, but if anyone is I'd guess luminus

22:12 rritoch: ddellacosta: Ring provides it's own javax/servlet/Servlet.class and forbids any external libraries which incliude that class. Since the tomcat libraries which provide JSP support include that class there it won't load from ring.

22:12 ddellacosta: rritoch: ah, I see

22:13 rritoch: ddellacosta: Tomcat isn't the only JSP compiler on the market though, I suppose there may be one that's compatbile with ring, but the tomcat version is most widely tested and has the best licensing in my opinion so for now I don't have any ring support

22:14 ddellacosta: Though I still have some code fragments remaining incase this issue gets resolved

22:14 https://github.com/rritoch/clj-grid-core/blob/master/src/com/vnetpublishing/clj/grid/lib/grid/ring/core.clj

22:15 It doesn't work anymore but I'll maintain that piece of code if I can convince the ring team to allow tomcat dependencies

22:17 Without ring I'm probably going to need to add a standalone server from lein eventually, but for now I just use a CGI-like execution to test with, and I deploy to tomcat.

22:20 I set :javac-options ["-target" "1.7" "-source" "1.7" "-Xlint:-options"] in my project.clj and the generated class files are saying major version: 49 ???? How do I get these to compile to 1.7?

22:23 justin_smith: you may need :javac-options ^:replace there

22:23 not sure though

22:24 but wait, javac options are only for javac

22:24 clojure code is not compiled with javac

22:24 it's compiled with asm.java

22:24 rritoch: justin_smith: Aaah, that makes sense

22:26 justin_smith: So is there any way to alter the version of the .clj gen-classes?

22:27 justin_smith: I really don't know

22:27 49 is pretty conservative

22:27 nobody should be using an older version than that

22:27 rritoch: I guess it doesn't matter, these 49's are working inside Tomcat7 which is good enough for me

22:27 Tomcat7+ is my target

22:27 justin_smith: 49 is java 5

22:28 I don't know if you can make clojure output a different target version or not

22:28 major versions as documented here: http://en.wikipedia.org/wiki/Java_class_file#General_layout

22:29 rritoch: justin_smith: What is the normal way to deal with these private repositories in :repositories

22:30 justin_smith: I don't know, I have never used private repositories actually

22:30 rritoch: justin_smith: end-users shouldn't have to deal with the gpg-authentication since they won't have access to my private repositories anyhow, will they be auto-ignored since they're not listed in the users local gpg credentials?

22:30 justin_smith: rritoch: gpg credentials are only for uploads

22:31 if they want to upload, they can make their own clojars or maven-central account

22:31 rritoch: justin_smith: No, I get queried for gpg credentials on compiles, probably because these are private repositories, only members can read

22:31 justin_smith: weird, I have no idea

22:31 like I said, I have never used private repos

22:32 rritoch: I guess I'll just remove these repositories, since I'm moving to clojars anyhow I shouldn't need the local copies anymore anyhow

22:36 Hmm, I really lost my clojars keys

22:37 Aah, I figured it out, I entered the wrong password *doh*

22:40 Ok, clj-grid-kernel is now on clojars, I should have the rest up soon

22:41 justin_smith: That should solve any problems you're having with the sources, but you should probably checkout again

22:41 after I'm done with all these uploads

22:42 err: git update = checkout again

22:43 The version plugin gets built via "lein grid bundle" which should be available once I have all of this stuff uploaded

22:49 justin_smith: rritoch: thanks, I hosed libc on a server today, otherwise I would have taken the time to look it over today

22:49 haha

22:50 rritoch: owech

22:50 justin_smith: rritoch: I was able to fix it though :)

22:50 it's fun using a system that has no glibc installed

22:52 rritoch: Hmm, last I recall nothing runs without glibc if it utilizes any shared libraries. I once built a custom (LFS) system and ran into a lot of malfunctioning states like invalid glibc

22:52 justin_smith: yup, the first part is figuring out what doesn't use shared libs

22:52 busybox is a lifesaver

22:53 luckily every distro makes sure it is installed

22:53 ed for editing files :)

22:54 bonus points: make sure you have a user whose login shell is statically compiled, then you may even be able to execute new logins

22:56 rritoch: hmm, well back when I played with LFS entering single user mode via the bootloader was trivial and standard practice so I didn't need a valid login, but that does sound like a good trick

22:57 I think for "catostrophic" states I had a static chroot setup and would chroot to a 100% static environment

22:57 Not ram efficieint, but it worked

23:11 justin_smith: Ok, clj-grid* is now deployed to clojars

23:12 Just let me know if you run into any more issues. These have snapshot dependencies, which I believe my machine is specifically setup to allow which may cause a problem for users.

23:13 But this codebase is really not ready for any kind of release

23:13 Even trivial things like delivering javascript resources contained in OSGi modules for <script src=...> hasn't been dealt with.

23:17 The next stage of development for the grid platform is to implement the fscript deployment for optimization purposes, and then deal with the resource delivery issues.

23:19 This is why I'm losing motivation, I've been digging through the "trenches" of systems-level code for so long that when it finally functioned correctly it was an anti-climax.

23:53 TEttinger: hiredman, arrdem, ddellacosta: I am curious what led to this https://github.com/hiredman/clojurebot/commit/fd3d1a7c036118ba4a3984fa789227c138133630

23:54 ddellacosta: TEttinger: yeah, me too, and also curious why hiredman doesn't respond to this: https://github.com/hiredman/clojurebot/issues/5 , but I've basically given up on him

23:55 ,(println "freaking lame")

23:55 clojurebot: eval service is offline

23:55 ddellacosta: &(println "luckily lazybot exists")

23:55 lazybot: ⇒ luckily lazybot exists nil

23:56 justin_smith: ddellacosta: and check this, I got him updated ##(clojure-version)

23:56 lazybot: ⇒ "1.7.0-alpha1"

23:56 ddellacosta: justin_smith: oh, nice. :-)

23:57 justin_smith: no more 1.4 ghetto for the ignored folks

23:57 ddellacosta: hahaha...sweet.

23:57 * ddellacosta bows to justin_smith

23:57 seancorfield: justin_smith: any reason for alpha1 rather than alpha3? :)

23:58 justin_smith: seancorfield: has to do with the version that was current when I started doing my update

23:58 seancorfield: it's a simple pr if you care to make it :)

23:58 seancorfield: Ah ok

23:59 justin_smith: really I should have double checked the current clojure cutting edge release before submitting my pr to raynes/lazybot

23:59 stapler: is there a "clojure in a box" for windows?

23:59 oh gee nevermind, answered my own question.

Logging service provided by n01se.net