#clojure log - Nov 30 2012

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

0:20 nside: in your opinion, what is the greatest clojure program?

0:21 muhoo: is there a contest? "greatest" by what criteria?

0:22 nside: not a contest

0:22 just in your opinion what is the most impressive clojure program

0:22 Raynes: Clojure?

0:22 clojurebot: clojure is not groovy

0:22 nside: in my case it's storm

0:22 https://github.com/nathanmarz/storm

0:23 jyfl987: just found enlive, and i like the idea

0:24 echo-area: nside: But Storm's use of Clojure is not that idiomatic

0:25 nside: echo-area: agreed but that it's used at such at large scale is impressive to me

0:25 TimMc: echo-area: How so?

0:27 nside: I guess that's because there's a lot of java in there

0:27 echo-area: TimMc: IMHO Storm is more using Clojure to glue many parts together. There are lots of mutation in there

0:28 And the mutation is not "managed", as in the facilities Clojure provide

0:29 nside: i'd say orchestrate rather than glue

0:30 Raynes: nside: refheap is the best Clojure program, hands down, no contest.

0:31 nside: never heard of it

0:31 checking

0:31 sounds like self promotion :)

0:32 https://github.com/Raynes/refheap

0:34 echo-area: Groovy?

0:38 zeiris: Impression from first 30 minutes browsing Clojure libraries: what are you crazy brilliant bastards using to generate those cheatsheets?

0:40 Raynes: zeiris: Are you by chance the same zeiris that used to hang out on blizzhacker channels?

0:41 zeiris: Yes.

0:41 Raynes: In that case, hello old friend.

0:41 zeiris: Truly, a small world.

0:42 Raynes: What cheatsheets are you talking about?

0:43 zeiris: The ones for, uh... Oh, I guess it's just Quil and Clojure itself. Thought there was also one for incanter.

0:43 Raynes: Could you link me to it?

0:43 (any one of them)

0:44 zeiris: Nevermind, I thought I stumbled into some kind of documentation secret weapon. https://github.com/quil/quil/raw/master/docs/cheatsheet/cheat-sheet.pdf

0:45 Raynes: Yeah, I don't know about that. The only documentation tools I'm aware of are autodoc, codox, story, and marginalia, and none of them are cheatsheetish.

1:12 zeiris: Out of curiosity, is anyone using lighttable for day-to-day clojure development? Is it still too early, or is it worth playing with as a beginner?

1:19 wingy: zeiris: i am .. its definitely worth checking out

1:19 just remember to fill in issue reports in github when you have improvement suggestions

1:20 its stable enough to be used as primary IDE imo for your clojure projects .. the live repl is amazing

1:21 just remember to back up your project (im using SugarSync). sometimes a file is not saved correctly .. idk if it's my own issue or something others experience as well

1:48 ucb: just in case, is there a way of changing the :encoder and :decoder of an aleph tcp-client while it is open?

1:50 patchwork: Anyone have any insight into this one? http://stackoverflow.com/questions/13639249/clojure-and-ring-utf-8-in-responses-comes-through-as

1:50 I found very little discussion about it

2:06 cemerick: patchwork: (potentiallly) answered

2:07 patchwork: Ah nice, I will try that

2:08 thanks cemerick!

2:08 cemerick: In general, if you're not specifying text encodings (whether in a web context or not), bad things will eventually happen.

2:15 patchwork: I already fought through this issue with mysql

2:16 every step of the way I have had to vet for charset issues

2:19 p_l|work: patchwork: when faced with any charset other than 7bit ASCII, I simply prefer to ditch MySQL

2:19 patchwork: p_l|work: I wish I had the choice!

2:19 We started with postgres which was a dream, then they demanded we host on RDS

2:19 which does not yet support postgres

2:20 p_l|work: there is a lot of issues with how it handled encodings (and way to many points of failure), and I recently heard (I dropped it back in 4.0/4.1 era) that it handles Unicode internally through UCS-2. Not sure if real, but a real blow

2:20 patchwork: Whoa!

2:20 is that true?

2:20 scandal

2:21 p_l|work: I don't know, I think I seen it mentioned among applications that don't support UTF-16 surrogate pairs (so basically pure UCS-2), so I'd recommend running a test

2:21 might depend on exact version of MySQL

2:21 anyway, a mess I won't touch if I can

2:23 I had a surprise emergency migration (3.23.x -> 4.0.x -> 4.1.x iirc) once during a rush job (read: I was modifying code live while it was running, only telling users directly to save their work, then I'd push the change, then they'd reload the page)

2:23 since that one time, I just don't touch MySQL

2:23 too much pain

2:47 Sgeo__: if (datetime.getMonthOfYear() == 2) { // February is month 2!!

2:47 Why is that amazing, exactly?

3:20 tomoj: hmm https://www.refheap.com/paste/b12a669c45fa02dae18e1ab73

3:21 is that a tree fold?

3:21 I suspect it's something weird

3:21 what should the semantics of returning a reduced during a tree fold be?

3:22 looks more like a walk than a fold to me

3:53 pingtimeout: Hi guys

3:54 I have a question regarding agents

3:55 I have written a small UDP server using an agent (https://github.com/pingtimeout/android-showoff/blob/master/server/src/fr/pingtimeout/androidshowoff/discovery.clj)

3:56 So the main method (line 92) send itself to the agent so that it makes a sort of infinite loop

3:57 The problem is : Now I want to stop the UDP server, and I could only find shutdown-agents, which is overkill

3:58 So, what do you think about that ? Should I use an atom "running" to know whether my agent have to continue ?

4:05 ucb: pingtimeout: why not send a message to the agent to stop itself?

4:06 pingtimeout: see this simple fake-erlang-processes toy example using agents for that https://gist.github.com/4c102e8c225c39037707

4:07 Sgeo__: I...

4:07 WTF nrepl

4:07 It seems to not be seeing that I'm trying to redefine a function

4:07 It's using the old (wrong) function definition

4:10 Oh, I was mislocating the bot

4:10 pingtimeout: ucb: Looking at your link, I think my problem is at line 100, when the processing function send-off itself to the agent

4:24 ucb: pingtimeout: thing is, your processing fn has to take the old value of the agent (the processing function itself) and it seems to take a socket, and then it has to return the new value for the agent (the processing function itself)

4:26 or at least that's how I did it

4:26 perhaps the processing fn can be a closure over the socket

4:34 pingtimeout: ucb: So the agent should not be the socket I am using

4:37 More generally, how would you core a UDP server. I assumed that for IO operations, I had to use agents and send-off. Is this the good solution ?

5:17 ucb: pingtimeout: not sure, I'd probably have an agent with a closure over a socket listening

5:18 pingtimeout: as I mentioned before, the agent has to point to the process function (which is a closure over the socket) and it'll receive itself as argument and be evaled to itself

6:39 borkdude: just a quick question - is it possible to use javascript (and therefore, clojurescript) instead of applescript to create OSX scripts?

7:09 pingtimeout: ucb: Thx for the advice, I'm trying to understand precisely how to do that

7:09 ucb: So the agent should point to the behaviour, not to the data

7:10 ucb: pingtimeout: that's how I did it; doesn't mean you have to do that yourself :)

7:11 pingtimeout: ucb: Actually, I'm trying to find a good (clean) way to do that :p

7:11 ucb: pingtimeout: have you considered aleph?

7:11 I believe it has an udp-server :)

7:14 pingtimeout: I have not tried it yet, I know it exist but it's on my TODO list after the "Release v1.0" :)

7:15 ucb: heh - cool

7:15 pingtimeout: the easiest option really is to just spawn a thread I'd think

7:16 pingtimeout: ucb: I saw an example like that, spawning a thread and using an atom to know whether the thread has to continue

7:16 ucb: I will try that

7:20 ucb: pingtimeout: cool

7:20 clojurebot: No entiendo

7:20 ucb: clojurebot: como que no?

7:20 clojurebot: Anyone can hack! http://images.wikia.com/pixar/images/0/0d/Http_alliedow-files-wordpress-com_2011-01_anyone-can-cook-445x355.png

7:21 dyelar: I've gotten to the point with my clojure understanding that to progress I need to start working on a clojure project. I have one in mind, but it's got a lot of systems programming involved. (Watching/Polling directories for file updates, running a series of external programs on said files, doing fun stuff with the output of the programs, etc.) I haven't seen anything in my somewhat patchy readings on clojure dealing with

7:22 unic0rn: dyelar: all that is possible with java api

7:23 dyelar: Correct. I just wasn't aware of if someone had written a better clojure encapsulation or if a more idiomatic way existed.

7:23 unic0rn: tbh, i'm not aware of that either. if i would have to guess, i would say that perhaps not.

7:25 as far as my understanding of clojure goes (and it's still very little, because of lack of time), it's designed in such a way that makes using java stuff very straightforward from lisper's point of view.

7:25 so it wouldn't make much sense to encapsulate java stuff, it would probably just overcomplicate things, imho

7:26 what has to be encapsulated, is

7:26 dyelar: Yeah, it hasn't been bad when I've been hitting Java APIs, but having worked with perl,python,etc, Java's not exactly been the greatest systems programming language.

7:26 It'll work though.

7:26 abp: dyelar, unic0rn At least there's https://github.com/pjstadig/nio

7:26 unic0rn: as a language, it's a boilerplate crap. but api isn't half bad

7:27 ucb: dyelar: for running stuff on a shell there's conch https://github.com/Raynes/conch

7:28 dyelar: Very nice.

7:28 unic0rn: abp: interesting. i guess it just goes down to the fact if someone is already very familiar with java api or not. a matter of taste, more or less.

7:50 tgoossens: in the namespace "roborally.piece" i have defined keywords ::robot ::wall ::battery

7:50 in the namespace "roborally.board" i want to use those keywords

7:50 but I don't want to type everytime

7:50 :roborally.piece/robot

7:51 how can i "import" these ns-bounded keywords?

7:53 hyPiRion: tgoossens: You could probably make a macro to make stuff easier.

7:53 tgoossens: hypirion , intersting never made a macro before (never had the need)

7:53 solussd: tgoossens: you can add (:require [roborally.piece :as p]) to your ns declaration at the top of the file and then refer to the namespace qualified keywords like this: :p/robot, :p/wall, etc

7:54 tgoossens: solussd: that is probably the easiest solution

7:54 solussd: that's what I do, frequently. :)

7:54 hyPiRion: solussd: That works? Humm.

7:54 solussd: sure does

7:55 oops

7:55 tgoossens: hyPiRion: you have to refer to them as ::p/robot, ::p/wall, etc

7:56 the two colons are still needed, but it'll expand the namespace component if aliased using require

7:56 hyPiRion: Ah

7:56 I wondered how : could just magically expand stuff, but that makes sense.

7:57 Sweet trick anyhow.

7:57 tgoossens: :D

7:57 also another thing

7:57 if i want to play with things in the repl

7:58 somehow i can't get it to work when having two different namespaces

7:58 in (ns roborally.board)

7:58 i do

7:58 (use 'roborally.piece)

7:58 FileNotFoundException Could not locate roborally/piece__init.class or roborally/piece.clj on classpath: clojure.lang.RT.load (RT.java:432)

7:58 borkdude: technomancy cemerick nice mostly lazy episode, tnx

7:58 tgoossens: apparently it searches for a file

7:58 instead of using the namespace i created earlier (ns roborally.piece)

7:59 what must i do to be able to play with it?

8:04 borkdude: tgoossens is there actually a file roborally/piece.clj ?

8:04 tgoossens: that doesn't matter here

8:05 i just open a repl session in a terminal

8:05 i copy the entire piece.clj (ns roborally.piece) into the repl

8:05 then the same for (ns roborally.board)

8:07 Foxboron: Looking for someone programming Clojure with Sublime Text 2 to give their opinions on a upcomming plugin.

8:07 tgoossens: i work with sublime text 2

8:08 but unfortunately i almost have to leave for class :S

8:08 Foxboron: tgoossens, just PM me when you come back :D

8:08 tgoossens: k

8:08 Foxboron: Its about some functionality for a documentation searcher :P

8:08 tgoossens: sounds interesting

8:09 Foxboron: it is :)

8:09 borkdude: tgoossens https://www.refheap.com/paste/7172

8:10 tgoossens you need refer

8:10 tgoossens: ok cool

8:10 borkdude: tgoossens require and use both try to load from file (if I'm not mistaking)

8:11 tgoossens: that did it

8:11 thanks!

8:12 borkdude: :)

8:13 tgoossens: but now the

8:13 (use [roborally.piece :as p]) doesn't work (i mean i cannot use :as in refer

8:13 borkdude: tgoossens you can also use load or load-file to load files directly

8:16 tgoossens look at clojure.core/alias for this

8:16 tgoossens: ok thanks

8:16 g2g now

8:16 borkdude: http://www.clojureatlas.com/org.clojure:clojure:1.4.0?guest=t#clojure.core/alias

9:22 Anderkent: Any ideas why a binding might become Var$Unbound?

9:22 Mr_Bond: different scope?

9:23 Anderkent: don't think so, it's (binding [name (ref [])] (...) (code-that-crashes-with-unbound))

9:23 so it's within the binding

9:24 i guess something might be redefing the name in the (...) part

9:24 rhickey: Has everyone participated in this: http://www.infoq.com/research/next-jvm-language ?

9:25 Mr_Bond: I have now :)

9:25 fojure: Yes, my vote for Ceylon has been registered! ;-)

9:26 Mr_Bond: Oh, you voted Ceylon as well? :)

9:26 </joking>

9:26 ah fuck, you have to sign up with facebook

9:26 I don't want that :/

9:27 Anderkent: yeah that made me stop as well

9:27 rhickey: Top candidate names for test->, let-> and when-> are: cond->, as-> and some->

9:27 Mr_Bond: I used google id

9:27 Mr_Bond: I can try that, I don't want that page accessing my facebook data, posting on my wall, etc

9:27 rhickey: I don't have a facebook account

9:28 abp: rhickey, I voted yesterday, put Clojure so much into both axes that it fall of the diagram and wasn't counted in my vote..

9:28 Mr_Bond: ok, that was better. voted.

9:28 oh noes, scala is winning!

9:28 rhickey: cond-> gets this "Note that, unlike cond branching, cond->> threading does not short circuit

9:28 after the first true test expression."

9:29 cond-> and ->>

9:30 interested in feedback on some-> which now threads when not nil

9:31 thought about making (some coll) do same (note no pred). That would bridge some to Maybe world, without introducing Maybe to Clojure

9:32 open door to if-some, when-some

9:32 mefisto: pretty dead heat between clojure and scala on that now

9:33 fojure: I suspect that very few people are using data literals ATM... I think we'd see more grumbling if they did.

9:34 rhickey: A Lisp's inclusion in that poll, never mind that kind of showing, is itself a big win

9:35 abp: :(

9:38 foodoo: I wanted to vote as well, but I also failed with the logins. I'll check back later again if they also enable infoq logins

9:40 abp: rhickey, what's the reasoning for some->?

9:41 fredyr: where do I find information about these new threading macros btw?

9:41 foodoo: fredyr: http://clojure.github.com/clojure/branch-master/clojure.core-api.html

9:41 fredyr: thanks

9:43 borkdude: @rhickey I voted .. twice now I believe..

9:44 @rhickey so I made up for abp ;)

9:50 rahcola: I want to run two computations in parallel and return with the value that finishes first

9:50 who to do this?

9:50 as a bonus, I would like to kill the remaining thread

9:51 borkdude: rahcola erlang? (kidding)

9:52 cgrand: rahcola: two futures delivering to a promise, wait on the promise then kill the futures

9:53 abp: borkdude, thanks! :)

10:01 rahcola: cgrand: thx, knew this had to be possible in Clojure

10:06 auastro: hi all

10:06 I'm trying to fix a weird bug that crops up when reloading code in ring

10:07 it seems if one reloads some invalid code, in a try statement in that code itself the exception can't be caught

10:08 *code = namespace there

10:10 mmitchell: technomancy: hi there. Is there a way to alter the class path in development (leiningen 2) ?

10:12 borkdude: Raynes btw I like what I see about regexps in Haskell so far

10:34 I would have preferred Haskell having dash-notation instead of camelcasing though..

10:34 S11001001: yep

10:36 borkdude: I think the author of RWH gets camelcasing wrong

10:37 splitFileName instead of splitFilename

10:48 Mr_Bond: borkdude: yes

10:49 rhickey: last call on cond->, as->, some-> https://groups.google.com/d/msg/clojure/67JQ7xSUOM4/7v3M96EfJq8J

10:52 antoineB: the syntax (defn add [a b] "doc" {:pre [(even? a)]} (+ a b)) don't works

10:52 http://clojuredocs.org/clojure_core/clojure.core/defn

10:53 but: (defn add [a b] {:pre [(even? a)]} (+ a b)) works

10:55 stuartsierra: antoineB: your docstring is in the wrong place

10:56 antoineB: right

11:00 TimMc: abp: You voted incorrectly in the infoq JVM language thing because their poll was a piece of crap. Go back and re-read those axes...

11:01 fojure: If I have a project B that uses project A, I can break B by adding the use of internal tagged literals in A and then updating B with the new code. B *never* uses A's literals, but building B fails with an unbound tag literal failure.

11:01 TimMc: abp: The lower left corner is where a fanatic would vote.

11:02 abp: TimMc, yes, I'am absolutely fanatic and pulled over the axes. :D

11:03 TimMc, at least I can't see Clojure when I look at my vote. Probably I should've put competitors into the upper right corner, out of the axes, too.

11:04 competitors => other languages

11:06 TimMc: Oh, you mean you put Clojure too far to the lower left? I see.

11:06 ANyway, I suspect the results are going to be unusable -- that chart is rather confusing.

11:09 zaiste: is it possible to upgrade Clojure to 1.5 in lein repl ? I cannot find it in docs

11:09 TimMc: Nooope, not voting -- infoq wants to see my name, photo, gender, birthdate, country, language, timezone, and email address -- from now forward.

11:09 abp: TimMc, yes, besides everything else that's wrong with such a poll in general.

11:10 nDuff: zaiste: the version of clojure you want goes in your project.clj

11:10 zerokarmaleft: seqs aren't Iterables, are they?

11:11 nDuff: zaiste: ...in this case, 1.5.0-alpha4

11:12 zaiste: nDuff: yes, but i'd like to load that version by default in repl (not for a specific project)

11:13 * nDuff has "using lein repl outside projects" mentally filed under "things crazy people do". :)

11:13 rhickey: zerokarmaleft: in general, yes they are

11:13 nDuff: ...I mean, you're going to have libraries and whatnot you want to use when you're experimenting from a REPL

11:13 so it makes sense to have a project even then, even if it's just one you keep around for only that purpose

11:13 zaiste: nDuff: ok ;)

11:15 zerokarmaleft: rhickey: so if a java method is expecting an Iterable<T>, i can just pass a seq or is there some munging required?

11:15 TimMc: ~generics

11:15 clojurebot: java generics are http://en.wikipedia.org/wiki/Generics_in_Java

11:15 TimMc: bah

11:16 zerokarmaleft: Generics are a Java fiction, mostly. Those <T>s get erased at compile time.

11:16 rhickey: zerokarmaleft: no munging required

11:17 S11001001: zerokarmaleft: which, believe it or not, is a highly positive feature from the java-alternative perspective, in more ways than clojure exploits

11:24 zerokarmaleft: cool...thanks, all

11:37 cwy: e

11:39 ivenkys: hmm - is anyone else having problems with the IDEA clojure repl - it stops responding in between

11:40 - latest version of everything - if that helps

11:48 Anderkent: Ideas for why jvm shutdown might be taking forever (~ 50s)?

11:48 llasram: Anderkent: daemon vs non threads. Use http://clojuredocs.org/clojure_core/clojure.core/shutdown-agents before exiting

11:49 Anderkent: Thanks, lets see if that helps :)

11:49 right, that does it

12:10 jondavidjohn: is there a quick way to flip a positive int to a negative?

12:10 other than...

12:10 ,(- 5 (*5 2))

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

12:11 jondavidjohn: ,(- 5 (* 5 2))

12:11 clojurebot: -5

12:11 ibdknox: ,(let [x 5] (- x))

12:11 clojurebot: -5

12:11 ucb: ,(doc bit-flip)

12:11 clojurebot: "([x n]); Flip bit at index n"

12:11 ucb: jondavidjohn: ^^

12:11 jondavidjohn: ,(bit-flip 5)

12:11 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core$bit-flip>

12:11 jondavidjohn: ,(bit-flip 5 0)

12:11 clojurebot: 4

12:11 jondavidjohn: ,(bit-flip 5 5)

12:11 clojurebot: 37

12:12 jondavidjohn: hah, i guess i don't get what it means by index

12:12 ibdknox: just do (- x)

12:12 ucb: that'd do too

12:12 jondavidjohn: ,( - 5)

12:12 clojurebot: -5

12:12 jondavidjohn: nice

12:13 pretty obvious...

12:13 llasram: ucb: You need the 2s complement to do it via bit-flipping. I bit awkward to do a bit at a time :-)

12:13 jondavidjohn: idiot

12:13 myself ^

12:14 ucb: llasram: indeed, I was just trying to confuse matters there :)

12:14 jondavidjohn: am I gaining much by converting a range to a vec before using for rand-nth?

12:14 I know random access on vecs is quick, but what about the time it takes to convert a seq to a vec?

12:14 llasram: jondavidjohn: Honestly, I'd convinced myself there was a `negate` function and was confused about where it had gone

12:15 jondavidjohn: Conversion only helps if you're going to many indexed lookups into the structure. Otherwise `vec` is O(n) and `rand-nth` is O(n)

12:16 jondavidjohn: cool

12:26 hyPiRion: Psh

12:27 jondavidjohn: can someone help me understand the #() function shorthand?

12:27 when I try to use it, it gives me an arity error

12:27 hyPiRion: Real men negate through ##(inc (bit-not 5))

12:27 lazybot: ⇒ -5

12:28 jondavidjohn: and when you expand it into (fn [i] ) even when I don't actually want to use `i` it works fine

12:31 dnolen: bbloom: patch applied - analysis errors are much more informative now.

12:32 piranha: hmmm... I cannot 'lein test' my cljs library, right?

12:32 or maybe I can publish clj library as cljs somehow on clojars?

12:32 joef_: jondavidjohn, you need to have at least '%' (or '%1'/etc) inside the #() to indicate the arity of the function

12:32 joegallo_: jondavidjohn: you are probably trying to create a function of one argument that will disregard the argument or arguments that it is called with. #() doesn't work very well for that.

12:33 jondavidjohn: thanks

12:33 joegallo_: (fn [_] ...) or (fn [& _] ...) is probably more conventional for that.

12:34 Anderkent: Does anyone know when and why are dynamic classloaders created? I'm having issues with a class being defined twice (by defrecord), and then instance? checks fail

12:35 llasram: Anderkent: Because you can't ever really redefine a class. Instead you create a new class with the same name backed by a new classloader which answers future resolution attempts for that name

12:36 Otherwise deftype at the REPL would be horrible (or "even worse," depending on your perspective)

12:36 Anderkent: mhm, but it seems the static references are not resolved to this new definition

12:36 i.e. (instance? my.record.Type coll) will start failing

12:36 when coll is created using the new my.record.Type

12:38 llasram: Hmm... Are you sure that's what's happening? Example:

12:38 Actually, lazybot won't let you deftype

12:39 But still -- fully qualified name resolution hits the most recent version of the class for me

12:39 If you're crossing namespaces and imported the class into another namespace, I believe that one will have the class basename symbol still referencing the old version

12:39 Anderkent:

12:39 22 incanter.core.Dataset #<DynamicClassLoader clojure.lang.DynamicClassLoader@dcca29c>¬

12:39 21 incanter.core.Dataset #<DynamicClassLoader clojure.lang.DynamicClassLoader@c6cb458>¬

12:40 well, I'm doing quite a bit of magic so it might be a bug in my code

12:40 still I'm surprised it's even possible to get the old reference

12:41 llasram: It's just names pointing at immutable objects

12:41 But yeah, does cause some occasional annoyances

12:41 Anderkent: in general the way it treates class names specially sometimes-but-not-always is a bit annoying

12:42 llasram: I think there's been some recent tooling work to help reload affected namespaces when these things happen, but the details are alluding my lunch-needing mind

12:42 Anderkent: i.e. I can't do (. -classname- getClassLoader)

12:42 I have to do (let [clazz -classname] (. clazz getClassLoader))

12:43 I guess (. (do -classname-) getClassLoader) works.

12:44 llasram: Huh. My model of Clojure evaluation does not explain what's happening there

12:45 Anderkent: . treats class names specially (. Class method) -> static method on class

12:45 (. (do Class) method) -> dynamic method on Class.class

12:45 it's really confusing and magical

12:45 llasram: Ahh, that makes sense, while agreed being confusing

12:55 Anderkent: well, managed to fix it, even though I don't yet understand how D:

12:56 llasram: yay?

12:56 clojurebot: yay is sweet

13:00 seangrove: bittersweet, I think you'll find, clojurebot

13:13 lynaghk: ping: alex_baranosky

13:32 pinkiesOut: Anyone present who can give advice on using seesaw for GUIs? I have a GUI button whose font color is set (using (config!)) depending on whether a port on the localhost is open. It works perfectly, but I would like the color state to change automatically whenever the port is opened/closed by another service. Any suggestions on how to monitor for this without listening for specific actions (mouse clicks, mouseover, etc)?

13:50 Foxboron: Need some testers for a Sublime Text 2 plugin. Any takers?

14:35 lynaghk: ping: dakrone

15:26 dakrone: lynaghk: pong

15:27 lynaghk: dakrone: I just commented on a github issue for cheshire; I ran into an issue where I couldn't do custom serialization of one of my types

15:27 dakrone: lynaghk: okay, I'll take a look at it

15:28 lynaghk: dakrone: the cheshire.generate/generate function has a toplevel condp that runs before protocol dispatch has a chance

15:28 dakrone: cool, thanks. I'm not blocking on it though---that and another issue and I've decided to go with EDN instead.

17:16 augustl: any suggestions for getting a list of items twice or more in a vector?

17:17 AimHere: You want a list of all the items that have more than two entries?

17:17 augustl: yeah

17:18 I can think of a few ways, but perhaps there's something built-in

17:18 AimHere: Something like (map first (filter #(> (second %) 1) (frequencies myvector)))) is my first thought

17:19 Or if performance was an issue, knocking up some function to sift them properly

17:19 augustl: nice :)

17:19 wasn't aware of frequencies

17:21 clj_newb_2345: does clojure reserve vars that start with the _ character?

17:21 TimMc: I recently used frequencies as a quick way of checking what characters were in a file.

17:21 clj_newb_2345: I'm thikning of a programming style where all local bindings start with "_", this way, when I look at a function, I can clearly see what is and what is outside of the current lexical scope

17:21 just by looking at the var name

17:22 muhoo: frequencies is pretty awesome. basically a historgram

17:22 TimMc: (->> (slurp "suspicious-characters.txt") frequencies keys (remove #(< 31 (int %) 127)) sort (map (juxt identity #(format "U+%04x" (.codePointAt (str %) 0)))))

17:22 muhoo: histogram

17:22 AimHere: TimMc, why not use distinct for that?

17:22 TimMc: AimHere: Because I didn't think of it. :-)

17:23 It was a one-off.

17:23 Alternatively, ##(into #{} "hello")

17:23 lazybot: ⇒ #{\e \h \l \o}

17:36 bbloom: Lately I've been experiencing "[trace missing]" with nrepl… what causes that?

17:52 devn: Where do I set the option for nrepl to boot with more memory?

17:53 cemerick: devn: just use your lein options

17:53 devn: and nrepl-jack-in respects that?

17:54 cemerick: jack-in just starts a headless nrepl process via lein AFAIK

17:54 so, yeah

17:54 devn: also, nrepl doesn't seem to showing anything that would have went to *out* in my repl

17:54 it might just be emacs-live, which i should stop using...

17:54 cemerick: devn: note, I mean the relevant options in project.clj, not whatever heap lein itself starts with

17:54 devn: *nod*

17:55 cemerick: Presentation of *out*, etc. is entirely up to the client. I'm blissfully uninvolved in the nrepl.el. ;-)

17:55 s/in the/with

17:56 Sgeo__: I tried println'ing in another thread, it went to where I started lein repl :headless

18:02 spaceships: when i print to *out* from lein run, it works. but when i try to use an uberjar, println works, but my function taht goes to *out* doesnt... confused.

18:04 devn: this is the reason im still using swank :\

18:04 unfortunately it is not compatible with the latest 1.5.0

18:07 muhoo: devn: it's been discussed,IIRC there was an issue open on it

18:07 on nrepl.el. it's been a very long time though, maybe it's been fixed already

18:11 TimMc: Anyone else unable to use Home and End in nrepl?

18:11 C-a and C-e are great and all, but...

18:21 clj_newb_2345: with defrecord, is there a way to have the defrecord be in one file, and the implementation functions be in another file?

18:22 nDuff: clj_newb_2345: protocol implementations, you mean? Certainly.

18:23 clj_newb_2345: nDuff: yes, can you point me to sample code?

18:24 nDuff: The only code I personally have isn't public, but... it's also not complex enough that it _needs_ an example; you just qualify your namespaces.

18:24 Where are you having a problem?

18:25 clj_newb_2345: err, if I can just see a 5-line example, with a defrecord in src/foo.clj and the implemenration in sr/bar.clj, i'd be convinced

18:25 i'm not even sure how to "split" it right now

18:25 bbloom: clj_newb_2345: defrecord's body is just shorthand for extend-type

18:25 (doc defrecord)

18:25 clojurebot: "([name [& fields] & opts+specs]); Alpha - subject to change (defrecord name [fields*] options* specs*) Currently there are no options. Each spec consists of a protocol or interface name followed by zero or more method bodies: protocol-or-interface-or-Object (methodName [args*] body)* Dynamically generates compiled bytecode for class with the given name, in a package with the same name as the current namespace, the given fie

18:25 bbloom: (doc extend-type)

18:25 clojurebot: "([t & specs]); A macro that expands into an extend call. Useful when you are supplying the definitions explicitly inline, extend-type automatically creates the maps required by extend. Propagates the class as a type hint on the first argument of all fns. (extend-type MyType Countable (cnt [c] ...) Foo (bar [x y] ...) (baz ([x] ...) ([x y & zs] ...))) expands into: (extend MyType Countable {:cnt (fn [c] ...)} Foo {:baz (fn (

18:26 clj_newb_2345: bbloom: nice, this is what I was looking for; thanks

18:26 bbloom: which is, in turn, shorthand for extend :-)

18:26 (doc extend)

18:26 clojurebot: "([atype & proto+mmaps]); Implementations of protocol methods can be provided using the extend construct: (extend AType AProtocol {:foo an-existing-fn :bar (fn [a b] ...) :baz (fn ([a]...) ([a b] ...)...)} BProtocol {...} ...) extend takes a type/class (or interface, see below), and one or more protocol + method map pairs. It will extend the polymorphism of the protocol's methods to call the supplied methods when an AType is

18:26 clj_newb_2345: in particular, http://clojuredocs.org/clojure_core/clojure.core/extend-type

18:26 bbloom: likewise with extend-protocol, but from the other direction

18:27 clj_newb_2345: this is kind of insane: so I can define a record, later define a protocol -- and after having defined the record, then extend the record to implement th eprotocol?

18:27 bbloom: clj_newb_2345: the power of "open" :-)

18:28 clj_newb_2345: embrace the dynamism

18:28 clj_newb_2345: it lets you extend your protocols to types you haven't defined too! especially nice because protocols are themselves namespaced, so you won't break anybody else as long as you own the protocol

18:33 clj_newb_2345: let's take this slowly

18:33 let me rewrite my code first

18:34 then one day, I will be facing some problem I can't solve, and I'll be: hmm, I wish I could extend protocols to types I haven't defined yet,

18:34 then I'll remember this conversation, :-)

18:34 bbloom: heh

18:35 clj_newb_2345: extend still doesn't quite do what i want.

18:35 bbloom: clj_newb_2345: you generally shouldn't use extend directly, prefer extend-protocol or extend-type

18:36 clj_newb_2345: I want "type.clj: (defprotocol IFoo "IFoo" (foo [obj])) (defrecord Foo [] IFoo)" "impl.clj: (extend Foo IFoo {:foo (fn [] ... )})" -- the problem here, is that Foo already implements IFoo

18:37 so in the type.clj file, I wna tto make it clear tat record Foo implements protocol IFoo

18:37 however, I just want to impelment Foo.foo later

18:38 bbloom: clj_newb_2345: what is the quoted "IFoo" about?

18:38 clj_newb_2345: it's a comment

18:38 habit

18:40 bbloom: clj_newb_2345: omit the "IFoo" from the defrecord

18:40 clj_newb_2345: you don't need to declare it up front

18:40 clj_newb_2345: I do want to declare it up front

18:40 so that when I'm viewing my types.clj files

18:41 I know what records implements what protocols

18:41 when I look at types.clj, I want to know whicih record implements which protocol; I just want the implementation to be elsewhere so as to not clutter the file

18:41 bbloom: what benefit does declaring it up front provide you?

18:41 clj_newb_2345: when I look at types.clj, I know what record implements which protocol

18:41 without having to dig through all the implementation files

18:42 bbloom: clj_newb_2345: don't do that :-P code to protocols, not to types

18:42 clj_newb_2345: I am coding to protocols; I just want to know which records implement whic protocols ...

18:42 bbloom: records are types

18:43 generally, if you have a lot of kinds of records with complex protocols, you're probably thinking OOPs and not clojure-y

18:44 most meaty use cases need to define a very small number of protocols

18:45 sometimes zero :-P

18:45 clj_newb_2345: argh; time to hack up some macros :-)

18:45 bbloom: clj_newb_2345: and don't overuse macros either :-) prefer data and functions!

18:46 macros are primarily useful for shorthand, but you shouldn't really write a macro until you've written it long hand at least 3 times

18:46 clj_newb_2345: i had some amazing macros for extending let forms to allow ajax calls

18:47 (in clojurescript)

18:47 bbloom: that's neat. i started doing that more generally for any type of future/promise with a CPS transform

18:50 clj_newb_2345: I figured out aw ay to avoid using macros here

18:50 instead, I will write, in types.c: (defrecord Cat [ ... ]) ; IAnimal . Then, in impl.clj, I can (extend-type Cat IAnimal ... )

18:50 comments are pretty powerful too

19:51 antoineB: still someone here?

19:52 abp: antoineB, yes

19:52 antoineB: ok

19:53 I have a (defprotocol IAbc (abc ...)) and (defprotocol IEfg (efg ...)) and two deftype ObjA and ObjB

19:54 how do i make those two type ObjA and ObjB share the same implementation of IAbc without copy and paste?

19:55 i work with clojurescript

19:55 dnolen: antoineB: doesn't matter - break out the shared functionality and call it.

19:55 abp: antoineB, dnolen was faster. :)

19:56 antoineB: dnolen: i don't understand

19:56 dnolen: create a fn that the protocols fn implementations call

19:56 abp: dnolen, let me ask you a thing or two about graphs.. ;) No, what's the best way to traverse clojure-code like a list?

19:57 dnolen, so I can filter out just the symbols in a fn-body for example

19:58 dnolen: abq: clojure.walk is one way if you have modest requirements.

19:59 antoineB: (defn foo [x]) (deftype A [] IFoo (-foo [this] (foo this)) (deftype B [] IFoo (-foo [this] (foo this))

20:00 antoineB: dnolen: so i need a little of copy paste

20:01 ok

20:01 dnolen: antoineB: yes, though I haven't found it to be much of a problem myself.

20:02 antoineB: you could also build some kind of delegation system - but I think your use case would really need to be able to gain some benefit that kind of additional complexity.

20:03 antoineB: and game or a very complex gui maybe are only two cases where I'd personally bother.

20:03 antoineB: my current solution is a central map like {:type #{:foo :bar}) and then dispatch with multimethods

20:04 dnolen: i try to do some complex gui

20:04 dnolen: antoineB: so you can delegate, delegation is inheritance at runtime.

20:05 antoineB: you can define a default case for a protocol that looks for a component in the delegate that actually implements the protocols

20:05 (deftype Foo [a b components])

20:06 (extend-type default IBar [x] (-bar (-> x :components :bar-component) ...))

20:06 abp: dnolen, I'm already using clojure.walk, but don't get how to pull symbols into a list.

20:07 dnolen: abp: I generally use an mutable to collect what I want during the walk

20:07 abp: tree-seq is a more functional way to do this.

20:07 mutable atom

20:08 abp: dnolen, so tree-seq is probably a performance hit?

20:08 dnolen: abp: no idea, never benchmarked

20:08 antoineB: dnolen: you mean (deftype Foo [a b components] IBar) no?

20:09 dnolen: antoineB: I do not.

20:09 abp: dnolen, ah ok, then how comes that you used walk with an atom?

20:09 dnolen: abp: no real reason - I tried it first and it worked

20:09 antoineB: ok "default" don't care the type has IBar as protocol

20:10 abp: dnolen, thanks for the hints. :)

20:10 dnolen: antoineB: exactly, default means it will by tried for all values.

20:11 antoineB: does protocol use javascript prototype? and is protocol more performant than multimethods?

20:11 dnolen: antoineB: I recommend reading "Organizing Programs w/o Classes" or any posts about Entity/Component systems for games

20:12 antoineB: CLJS protocols are way faster than CLJS multimethods - multimethods in CLJS have seen little performance work.

20:13 antoineB: that said CLJS protocols are also 1.5X-2X slower than JS fns because of indirection - which isn't true for protocols in Clojure JVM.

20:14 antoineB: is use transient for make a map mutable, is this better to do (set! (.-prop this) (assoc map :some "stuff")) than (assoc! transient-map :some "stuff") ?

20:15 *i use

20:16 dnolen: antoineB: if perf is the main concern - (set! (.-prop x) ...) is much faster

20:16 antoineB: though for guis I'm not really convinced that this matters - for games yes.

20:16 solussd: why can't multimethods have pre/post conditions, as a way to enforce constraints on methods added to a multimethod?

20:17 antoineB: dnolen: i plan to do some sort of schema drawer (in svg), so performance does matter as much

21:07 Hodapp: are the contents of :sigs in a protocol considered pretty much an implementation detail, liable to change?

Logging service provided by n01se.net