#clojure log - Dec 21 2011

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

0:01 akhudek: success, one project updated to 1.3!

0:29 amalloy: akhudek: lists mean something different. and matches are looked up by hashcode: the clojure sequential collections all hash the same regardless of type

0:34 qbg: ,(case '(:a :a) (:b :a) 1 (:a :a) 2)

0:34 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Duplicate case test constant: :a>

0:34 akhudek: amalloy: thanks for the info. For some reasons I thought the data type would matter and also figured that escaping the list would disable the default evaluation semantics. Not sure why I would think this.

0:35 qbg: ,(case 1 (1 2 3) :low (4 5 6) :high)

0:35 clojurebot: :low

0:36 akhudek: whoa, actually in 1.2 it does behave oddly

0:36 with quoted case statements

0:37 qbg: Doesn't do error checking?

0:37 akhudek: (case '(:a :b) '(:a :a) 1 '(:a :b) 2 '(:b :a) 3 '(:b :b) 4) returns 2

0:37 (case '(:a :b) (:a :a) 1 (:a :b) 2 (:b :a) 3 (:b :b) 4) throws a no match error

0:37 oh well, 1.3 doesn't allow this wonky thing

0:37 amalloy: that's because you can't just arbitrarily quote something and expect it to mean the same thing

0:37 qbg: Second one is wrong

0:37 akhudek: I know

0:38 was just exploring if quoting works like I thought it did in 1.2

0:38 qbg: ,(case '(:a :b) ((:a :b)) 1)

0:38 clojurebot: 1

0:38 akhudek: oh, interesting, I see

0:38 didn't know you could do that

0:38 qbg: Lists are shorthand for multiple cases

0:39 akhudek: right, it makes sense now that I think about it

0:39 qbg: And that is why quoting doesn't work

0:40 akhudek: quoting oddly enough did work in 1.2

0:40 qbg: Didn't check for dups back then it looks like

0:41 Since you effectively had (case '(:a :b) (quote (:a :a)) 1 (quote (:a :b)) 2 (quote (:b :a)) 3 (quote (:b :b)) 4)

0:42 jkkramer: amalloy: (just read through some backlog) FYI, you get 750 free dyno hours per heroku app, not per account

0:42 akhudek: I see, that explains it. Thanks. :)

0:43 jkkramer: citation: http://devcenter.heroku.com/categories/billing and my november invoice

0:44 amalloy: ah, thanks jkkramer. that makes a lot more sense

0:44 $mail technomancy btw, looks like it's 750 h/mo/app

0:44 lazybot: Message saved.

0:46 technomancy_: no kidding

0:47 ibdknox: oh, it's per app?

0:47 sweet

1:24 jli: man, I have a really hard time understanding what Java Beans are

1:26 brehaut: jli objects that conform to a reflectiony interface for getters and setters

1:26 jli: enterprise beans are a world of hurt more complicated

1:26 jli: reflectiony?

1:26 brehaut: its an interface based on the names of methods, rather than a concrete interface

1:27 imagine a retarded hashmap with a fixed set of keys a, b and c that you can read with getA, getB, and getC and set with setA, setB, and setC

1:28 ,(bean (java.util.Date.))

1:28 clojurebot: {:seconds 46, :date 20, :class java.util.Date, :minutes 28, :hours 22, ...}

1:29 brehaut: jli: compare that with http://docs.oracle.com/javase/6/docs/api/java/sql/Date.html

1:30 jli: so beaniness is just having getters and setters for all your fields?

1:30 brehaut: bingo

1:30 jli: wtf.

1:30 brehaut: welcome to java ;)

1:30 you know what is also cool? acres of xml

1:31 java has some awesome stuff. and some stuff that is not awesome

1:32 jli: do the getters and setters actually have to correspond to real fields? I guess I don't see the point.

1:35 brehaut: yeah i think thats the point

1:35 its encapsulation at its finest

1:36 jli: :/

1:42 EJB is a server-side model that encapsulates the business logic of an application.

1:42 wut

1:43 ibdknox: java makes me sad

1:43 jli: EJB: it's code!

1:43 I don't understand :/

1:48 ibdknox: anyone have a good explanation of state monads somewhere?

1:48 hiredman: imagine a burrito

1:49 they are similar in that you can imagine either of them

1:49 ibdknox: lol

1:49 well done :p

1:51 jsnikeris: Hi all. I'm trying to play around w/ the internals of clojure.pprint. I'd like to call some of the fns in dispatch.clj directly, such as pprint-code-list. However, when I do so, I get an exception: java.io.PrintWriter cannot be cast to clojure.lang.IDeref. Any ideas what's going on?

1:52 replaca: jsnikeris: you need to call those functions with a pretty writer

1:52 which is the extension of Writer that keeps track of line breaks and columns

1:53 jsnikeris: replaca: ah OK. I see a with-pretty-writer fn

1:53 replaca: yup, that's the easiest wat to do it

1:54 jsnikeris: Is there a pretty writer already set up in a special variable?

1:54 hiredman: ibdknox: http://channel9.msdn.com/shows/Going+Deep/Brian-Beckman-Dont-fear-the-Monads/ I don't thing he goes it the state monad specificly, but if you are look for a generally intro to monads it's a pretty good video

1:54 replaca: or you can call get-pretty-writer: http://clojure.github.com/clojure/clojure.pprint-api.html#clojure.pprint/get-pretty-writer

1:54 jsnikeris: no, they're created on demand when you call pprint

1:55 unless you already have one bound to out

1:55 *out*, I mean

1:56 jsnikeris: ah, I got it

1:56 (with-pretty-writer *out* form) did the trick

1:57 replaca: thanks for the help

1:58 replaca: jsnikeris: np

3:34 Blkt: good morning everyone

3:35 (yes, it is a /amsg, but I love to greet everyone)

3:37 guns: g morning; where are you in the world?

3:37 Blkt: Italy

3:53 Scriptor: new york city

3:53 I wonder if a speaker has been lined up yet

3:53 rfgpfeiffer: good morning

4:14 kral: namaste

4:37 Vinzent: when I have some ns with vars conflicting with clojure.core ones it compiles for the first time, but throws exception on second. Why?

4:41 clgv: Vinzent: you can use (refer-clojure :exclude [stupid-command-that-conflicts])

4:42 Vinzent: clgv, of course, but why the behaviour is so strange? It first compiles with warnings, but then doesn't compile at all

4:43 always compile with warnings seems like a more reasonable behaviour

4:43 clgv: what is first and second time? first time = open repl, second time = reload in running repl?

4:43 tscheibl: Vinzent: maybe because the second time it tries to override your overriden functions with the core ones again...

4:43 clgv: thats thecase where I noticed that

4:44 tscheibl: ...which may cause a different behaviour

4:44 clgv: I think it is a one way street: you can override core-fns but when reloading core-fns would replace your local definitions it throws the error

4:45 tscheibl: ..that's what I wanted to say

4:45 Vinzent: clgv, yeah, first = just after starting slime, second - compiling it again after first one

4:45 clgv: tscheibl: right. you got the same idea.

4:46 Vinzent: tscheibl, yeah, I think so too, but what's wrong with doing so?

4:47 tscheibl: clgv: as a non native english speaker (writer) I cannot alway be sure that people understand what I try to say :)

4:47 clgv: tscheibl: what origin?

4:47 tscheibl: Austria

4:47 ..no Kangaroos :)

4:47 clgv: ah well then you might like #clojure.de as well ;)

4:49 tscheibl: must have a look if telepathy alows me to join more than one channel on the same IRC network...

4:49 I'm not an IRC pro I must say

4:50 clgv: me neither

5:06 Vinzent: how can I destructure nested map? e.g. I have {:a {:x 1 :y 2}}, how to get x and y?

5:08 clgv: should be ##(let [{{x :x y :y} :a} {:a {:x 1 :y 2}}] [x y])

5:08 lazybot: ⇒ [1 2]

5:10 Vinzent: ah, right, thank you

5:12 although, it's not very readable, I'd better won't use it in my case

5:13 clgv: VInzent: you can also use 'get-in like ##(get-in {:a {:x 1 :y 2}} [:a :x])

5:13 lazybot: ⇒ 1

5:14 Vinzent: clgv, yeah, but i'd better stick with {:keys [a] ...} in let and (:x a) (:y a) in body

5:15 clgv: Vinzent: If you only query one value dont use destructuring at all

5:16 (let [c (:a m)] [(:x c) (:y c)]) is sufficient^^

5:17 Vinzent: yeah, but actually it's in a for loop: (for [{:keys [price] :as i} items] ...)

5:19 clgv: Vinzent: you also do it like (for [i items :let [p (:price i)]] ...) - only showing you the options ;)

5:20 Vinzent: right :)

7:05 I'm trying to use lobos. It throws "java.lang.String cannot be cast to java.lang.Number" (and long creepy stacktrace) when I'm calling migrate or rollback. Have somebody faced it too?

7:20 clgv: Vinzent: well, any idea where you might have put a string that should be a number according to the api docs?

7:21 stacktraces are best dealt with by filtering all the clj stacktraceelements

7:21 Vinzent: clgv, I don't have ANY strings in that namespace

7:21 well, except the db spec

7:21 clgv: yeah, probably some configuration

7:22 Vinzent: But direct call to (create ...) works fine. I'm trying to reproduce it in the new project now...

7:22 yep - same thing

7:31 accel: is I need to pass a null to java; can I do it with nil from clojure?

7:35 clgv: accel: pass the nil

7:36 acced: it's just a different name in clojure

7:41 accel: clgv: worked; thanks!

7:42 I am familiar with clojure's proxy (proxied a few AWT event listeners). However, now I need a way to create a new Java class (from Clojure land) that inherits from a Java class + adds a few member fields to it. Is this do-able with proxy? [All examples of proxy I have seen only adds new member functions; but does not attach member fields.]

7:44 clgv: accel: you always have the option to just write that class in java if you need almost all of javas oop

7:45 accel: I'm converting a java code base to clojure + rewriting it

7:45 So I'm basically taking Java classes, and knocking them off one by one.

7:46 clgv: that process is probably not a good one

7:46 accel: it induces OO code in lisp syntax?

7:48 clgv: you shouldnt try to reimplement your java class structure in clojure.

7:49 accel: It's a Java library that I did not write; I'm simutaneosuly trying to understand it + use it.

7:49 Rewriting it in Clojure + rewriting it in a functional style seems like the best way to go.

7:50 clgv: if you rewrite it in a functional style that will work. but if you stick to the class hierarchies you wont get much more benefits from that

7:51 accel: Agreed. However, I prefer to do incremental rewrites onw orking code.

7:51 Thus, it's beneficial to me if I can rewrite the java code in a OO manner in clojure first before making it functional.

7:52 clgv: accel: that will cause a lot of overhead

7:52 you could work from small simple task implementing them functional to the more complex onex incrementally

7:53 minikomi: hi there!

7:54 accel: i have a Java function that takes two constructors. Animal(Foo foo); Animal(Bar bar); how do I tell clojure to call Animal. on Foo ?

7:54 minikomi: just got rolling with clojure on arch linux, using rxvt, but the repl seems a little strange.

7:54 clgv: accel: typehints

7:54 minikomi: i installed jline, but deleting removes the user=> prompt

7:54 clgv: like: (Animal. ^Foo obj)

7:54 accel: clgv: noted; thanks

7:55 rabbler: minikomi: JLine behaves poorly for me too, on OS X Lion. I haven't really looked into it. Hopefully someone has a tip.

7:55 minikomi: ah..

7:56 clgv: I recommend rlwrap instead of JLine

7:56 rabbler: the previous (0.9.x something) works better for me.

7:56 minikomi: clgv: thanks I'll look into it

7:56 rabbler: same here.

7:59 clgv: well, that just worked for me… Thanks. Will read the docs for more info.

7:59 clgv: rabbler: there is a wikibook for clojure that explains a good rlwrap setup

8:00 rabbler: clgv: will google.

8:00 minikomi: clgv: on it right now :P

8:00 should have known to rtfm haha

8:02 gtrak```: minikomi, why not just emacs and slime?

8:02 minikomi: diehard vim user :/

8:02 baby steps, baby steps.

8:05 accel: is there an easy way to inject type checking assertions into clojure?

8:05 to have exceptions thrown when an function gets an argument that is not of a certain type

8:05 gtrak```: :pre

8:05 rabbler: gtrak```: I still can't get my head around emacs. One issue I have is that it's just so fugly and feels overly complex to me. Plus, I just can't seem to ever get it to work. I wish there were a github fork of emacs with all settings ready for Clojure users.

8:05 accel: I love how clojure's anser to everyhting is a function.

8:06 rabbler: I can't figure out why its so much work to get it to function.

8:06 accel: unless its a value. hah.

8:06 gtrak```: rabbler, well the emacs-starter-kit is a good start

8:06 rabbler: accel: which could be a function, or a native something or other… I'm just joking around here.

8:08 gtrak```: I'll look at it again. Its just that I have 3 different machines that need to be configured and each is different. Using a simple repl and a separate editor (vim or IntelliJ) have been fine (for now).

8:08 gtrak```:and that sounded redundant…heh.

8:08 gtrak```: rabbler, yea, some guys don't even go full slime, just emacs and inferior-lisp mode

8:09 being able to quickly execute stuff without having to copy-paste is a good thing

8:09 rabbler: gtrak```:and whatever 'inferior-lisp' mode is. I haven't googled that term yet.

8:09 gtrak```: basically a dumb repl in another emacs buffer

8:10 rabbler: gtrak```: Thats what I have been using IntelliJ for. The plugin is clunky and needs work, but it has simple 'select and execute' functionality.

8:10 gtrak```: vimclojure probably does that too

8:12 rabbler: gram```: One major issue I have with emacs is that I have 3 versions and don't know which to use: Aquamacs, gnu emacs (gui) and the terminal version.

8:12 minikomi: ok

8:13 that setup from the wikibook did the trick!

8:13 thanks for that. have a nice evening / day!

8:14 gtrak```: rabbler, ah, you're on the mac, yea, no idea

8:14 though people do it here all the time

8:14 i think no one uses aquamacs

8:15 rabbler: i'll look around. Thanks.

8:16 clgv: gtrak: I saw aquamacs in a couple of videos. the last one was about midje,

8:17 gtrak```: I heard things to that effect, I don't have any data :-)

8:18 but you don't really need the gui anyway after a day or os

8:18 so(

8:18 so* :-)

8:19 accel: what sodes the % do in clojure? it looks like a way to create anonymous functions

8:19 i.e. even shorter than fn

8:19 gtrak```: % is a shorthand for a parameter

8:19 ,(#(+ 1 %) 2)

8:19 clojurebot: 3

8:19 duck1123: accel: you can use :pre and :post checkers to assert types, but you're still trying to impose strongly-typed ideals onto clojure's dynamic types

8:20 gtrak```: accel, #( actually makes the anonymous fn

8:21 accel: duck1123: I'm not trying to build haskell. I just wish to catch run time errors when they happen (rather than when it crashes).

8:21 gtrak```: accel, you would rather get a IllegalArgumentException than a NullPointerException? what's the difference except more code?

8:22 accel: I want to get the error when I _store/pass_ an object of an inappropriate type

8:22 not when I retrieve/use the object.

8:22 gtrak```: ah, I guess it makes sense there

8:22 but that's what you get for using mutable state :-)

8:23 accel: Perhaps I am doing somethign wrong here: imagine the stack frames of clojure. At the top post frame, we use the argument; 7 layers lower is where we call the function.

8:23 I want to catch it when I pass the argument; not when I use it.

8:23 gtrak```: yea

8:23 accel: gtrak```: In this paritucar case, I don't have mutable state; I just have nested functions.

8:23 gtrak```: well, you should sanitize user-input, then assume that everything's fine past that barrier, imo

8:24 duck1123: accel: http://clojure.org/special_forms#Special%20Forms--%28fn%20name?%20[params*%20]%20condition-map?%20exprs*%29

8:24 gtrak```: just do that kind of stuff in the top layer

8:26 accel: duck1123: In addition, % may be used in a post-expr to refer to the function's return value. <-- got it. Thanks :-)

8:27 gtrak```: accel, I guess the issue I have with it is you're conflating (I'm starting to get annoyed with complect) interface with implementation details, clojure's function signatures care about data structures and parameters, not so much concrete types

8:28 accel: gtrak```: what's complect?

8:28 gtrak```: a word Rich Hickey made up to mean to interleave two things unnecessarily :-)

8:28 it's become very popular for some reason :-)

8:29 duck1123: "To join by weaving or twining together; interweave."

8:29 it's latin

8:29 mdeboard: gtrak```: Because it's very apt

8:29 A much-needed word

8:29 gtrak```: how's it different from conflate, tho?

8:29 mdeboard: much-needed/underutilized

8:30 accel: honest queston: since I can't specify type signatures on the input/output of a clojure function; what is the signature of a clojure function besides arity?

8:31 mdeboard: gtrak```: Because the common usage of conflate, at least as I usually hear it, is as a synonym for confuse. Regarding two different things as essentially the same thing, or two parts of the same whole. Where as complecting, to me, is the active process of unnecessarily joining two things together.

8:31 gtrak```: accel, the java arity is behind the scenes, the clojure arity is just another case of structure

8:32 mdeboard, ah, I guess that's persuasive

8:33 accel, you can even do named parameters if you like, it's basically building a hashmap from the varargs

8:34 mdeboard: gtrak```: Here is an excellent real world example that I'm dealing with atm. A Django project I work on has several template files that consist entirely of Javascript, except that some of them have Django's template language mixed in. Some javascript files are saved as .html; Some HTML files are saved as .js files. We had until recently (after I fixed it) a file called "pager_js.html" which was a javascript module th

8:34 at rightly should've been called "pager.js" but the previous developer had conflated the template scheme, javascript and HTML into one big horrible hairy mess. That to me is conflation (and I said as much in the commit message fixing it). Complecting doesn't fit there, IMO.

8:35 Anyway.

8:35 gtrak```: ah

8:36 accel, http://stackoverflow.com/questions/3337888/clojure-named-arguments

8:36 accel, I would just say, generally stick with a hashmap, vector or seq except for really low level stuff

8:37 accel: How does this help me solve my problem of "types do not match?"

8:38 gtrak```: I don't really understand why they wouldn't match, I guess I'm talking about that problem

8:38 you already have the answer with :pre

8:39 accel: In Clojure, can I check that a list of homogeneous w/o running through all elements?

8:40 duck1123: can you do that elsewhere?

8:40 accel: C++ sure; std::list<int>

8:40 :pre seems a bit expensive on complicated structures

8:41 if I have to traverse the entire structure to check whether it satisfies typing constraints

8:41 [I realize this soudns trolling ish; but I'm writing a large0ish WYSIWYG editor; and catching errors early is very important to me.]

8:42 duck1123: but with a c++ list, it's checking as the elements are inserted, so that is still going through the elements (in a way).

8:42 accel: yeah; but :pre is called on every function call, no?

8:42 I would very much so like to have the cost occur only once; not every time I check it

8:43 clgv: accel: then check when you create that list ;)

8:44 accel: this is non-trivial

8:44 since clojure is about creating new objects; not modifying existing ones

8:44 types works great when you can attach tyeps to varaible names

8:44 and modify those variables via their names

8:44 clojure objects --- new ones are created all over the palce from old ones

8:45 clgv: accel: actually you are quite near at modifying existing ones although the old ones dont change ;)

8:45 accel: my point is that suppose oldList = homogeneous

8:45 there's nothign taht says newList = (conj elem oldList) should be homogeneous

8:45 whereas oldList.add(elem) implies elem should be homogeneous of the same type as oldList

8:46 clgv: accel: I think you thinking is quite natural when comming from java, but not very well suited to work with clojure unchanged

8:46 duck1123: you could write a function that checks the type, and adds to the list only if it satisfies your requirements

8:47 you can always use straight up java arrays

8:47 Chousuke: isn't oldList.add() heterogeneous too.

8:47 clgv: accel: as well, you can make this list a deftype with a modification protocol where add-method checks the type like duck1123 suggested

8:47 Chousuke: since you only add Objects

8:48 the compiler might do some type checking but that won't stop someone from giving you a heterogeneous list.

8:50 accel: the best way to go about this is just assume the list is homogeneous and document the requirement. Also you can write some tests if you want to :P

8:52 clgv: accel: I think you have the two option: (1) expensively checking the list on top-level (2) assuming the list is valid, letting the bottomlevel throw on error and implementing a handler for that in the toplevel to signal a more specific error to the caller

8:53 Chousuke: I suppose you could write your own typed list structure too

8:54 that implements conj in a way that checks the type of the arguments

8:54 accel: hmm

8:54 why not put clojure's ability to generate java clsses on the fly to good use? :-P

8:55 Chousuke: pretty much all type checking you do must be runtime though.

8:55 unless you want to go ahead and implement that predicate-based static checking tool/sufficiently smart compiler that has been sometimes discussed :P

8:56 gtrak```: it's just the wrong approach for clojure, you should be able to trust the code you write to work correctly, but you have to sanitize input from the outside.

8:56 Chousuke: There's nothing that really prevents Clojure from having static checking

8:56 it's just not implemented :P

8:56 clgv: Chousuke: isnt someone trying to build that on a clojure fork?

8:56 Chousuke: I'm not aware of anything like that

8:57 clgv: someone mentioned it here in #clojure

8:57 duck1123: Sometimes, if you find that Clojure is making what you want to do difficult, you have to ask if you're really going at it the right way.

8:58 clgv: Chousuke: one could even build some of the typechecking via macro like specialized defn-something...

8:58 Vinzent: what's the most idiomatic way to get the string without last n characters?

8:59 gtrak```: we'd need a generics library like java's

8:59 Chousuke: clgv: yes.

8:59 clgv: have you seen typed racket?

8:59 gtrak```: protocols, covariance

9:00 Chousuke: Vinzent: just make a substring. though beware, the whole string will remain in memory.

9:02 Vinzent: Chousuke, ok (I thought maybe there is some special fn for that)

9:03 gtrak```: accel, really you should be using lazy seqs anyway :-), running through it to check the type is bad for laziness

9:03 duck1123: Vinzent: I think there used to be a contrib fn for that, but it didn't make the cut

9:05 Vinzent: http://clojuredocs.org/clojure_contrib/clojure.contrib.str-utils2/butlast

9:06 Vinzent: duck1123, thanks, but it's contrib and I have clj 1.3 project

9:06 duck1123: Vinzent: just look at the source, if you ignore the if part of the code, it's just a simple .substring

9:08 Vinzent: duck1123, ah, I've already written .substring version, just enlarging my knowledge :)

9:11 CmdrDats: does this work? ##(let [string "hello world" len 5] (apply str (take (- (count string) len) string)))

9:11 lazybot: ⇒ "hello "

9:11 CmdrDats: that was fun :)

9:13 Vinzent: CmdrDats, use drop-last then

9:14 CmdrDats: awesome - learn something new everyday

9:14 thanks

9:15 duck1123: also, the built in .substring is surely more efficient than converting the string into a sequence of characters and then building it up into a string again

9:16 Chousuke: unless you're chopping a huge string into many small strings.

9:16 since creating a new string will allow the huge one to be GC'd

9:17 CmdrDats: ye, i was just thinking 'idiomatic clojure'

9:17 duck1123: does substring prevent the original from being GCed?

9:30 clgv: Chousuke: no not yet. is "typed racket" A LIB?

9:30 Chousuke: yes

9:31 clgv: ok, google on^^

9:31 Chousuke: it extends the racket language by adding static typing.

9:31 it's pretty cool

9:36 clgv: ll

9:57 TimMc: duck1123: Yeah, we discovered that here at work. >_<

9:58 duck1123: Tokens were taken via substring from documents and used in a hash table. As long as the hash table was around (i.e. forever), all the documents were too.

9:59 duck1123: TimMc: that's interesting. I'll have to keep that in mind

10:01 TimMc: It would be awesome if there were some kind of java.lang.ref.WindowReference wherein if that was the only type of reference to an object, the GC would ask all the holders to compute explicit copies of the information they were using from the main object.

10:02 Or maybe that would be hella complicated and not all that much of a gain.

10:03 samaaron: TimMc: sounds fancy, but i have no idea what you are talking about.

10:03 what would be the problem it is trying to solve?

10:04 TimMc: samaaron: substring and subvec hold a reference to the original, possibly much larger data structure.

10:05 I'm trying to solve the problem of having to create copies every time you take a relatively small window on a large data structure.

10:05 samaaron: makes sense

10:09 misfo: Does anybody familiar with moustache know why ring's wrap-session wouldn't work within a nested `app` macro?: https://gist.github.com/1506329

10:11 gfredericks: are there any built in functions for translating between native JS data and CLJS data?

10:11 (or equivalently, cljs<->json)

10:22 kral: are there any libraries for iptables/ipfilter for clojure?

10:23 already googled it, but I found nothing

10:30 samaaron: kral: there should be some java iptables/ipfilter libs you can just use

10:31 i.e. a quick google search returned this: http://jipfire.ilug.gr/

10:36 simard: is there a function that does this: (doall (map ..)) ?

10:37 samaaron: simard: no, you need to compose the fns like you indicated to force the lazy seq to be evaluated

10:37 are you looking to get the actual returned seq, or are you just running this for the side effects?

10:37 simard: side effects (spit)

10:38 samaaron: well, then you should use dorun instead of doall

10:38 duck1123: there's always doseq

10:38 samaaron: doall holds onto the head and therefore consumes more memory

10:38 * gfredericks likes doseq too

10:38 simard: dorun, doall, doseq.. ok :)

10:39 samaaron: use the one that fits best :-)

10:39 although only use doall if you want to do something with the returned seq

10:39 gfredericks: for some reason doseq feels like the side effects are less hidden

10:41 samaaron: gfredericks: that shouldn't be the case - doseq is explicitly for generating side-effects :-)

10:42 in fact, all the do* fns are about doing stuff now

10:42 gfredericks: um...yes. I think what I meant is that you have a body instead of an impure function

10:43 simard: so the difference between dorun and doseq is only with respect to the usage of it, ie.: doseq provides for like synthax ?

10:43 gfredericks: simard: yes

10:43 simard: so doseq is better if you would otherwise be creating an anonymous fn

10:44 I like it better in any case, but people must use dorun for something, so I probably don't know what I'm talking about

10:44 simard: lol

10:44 well, thank you for your help

10:45 semperos: it's been a while since I've used clojureql, but I recall it having a dedicated site with good documentation (clojureql.org, I believe), but that seems down

10:45 has it been replaced by something else?

10:46 cemerick: semperos: the original maintainer has moved on, I think.

10:46 Many people are moving to http://sqlkorma.com AFAICT.

10:46 semperos: another of ibdknox's creations, yeah?

10:46 cemerick: yeah

10:46 semperos: alrighty

10:47 I saw that Lau didn't put out the latest artifact release of clojureql

10:47 cemerick: There are people still working on clojureql, but there's some uncertainty at this point, anyway.

10:47 semperos: but its docs still point to that clojureql.org site

10:47 replaca: cemerick: did Lau leave us? I had noticed that I hadn't heard much from him in a while

10:47 cemerick: replaca: He's here (hi LauJensen), but perhaps not present?

10:54 jakeskik: cemerick: Hmm..any idea how one would handle migrations with clojure? Is there something like rails (= ActiveRecord) migrations?

10:54 semperos: jakeskik: this has migrations support: https://github.com/budu/lobos

10:54 cemerick: jakeskik: I'm absolutely not the person to ask about RDBMS stuff. :-)

10:54 jakeskik: semperos: thanks

10:54 cemerick: hehe, ok :)

10:54 semperos: and conjure has its own as well, worth a look

10:55 jakeskik: ty, i'll take a look

10:55 semperos: np

10:57 Vinzent: semperos, clojureql with 1.3 support was released yesterday, so the project surely isn't dying or anything

10:58 semperos: Vinzent: I figured it wasn't dying; my question was about the documentation's current home

10:58 couldn

10:58 *couldn't find the main body of examples and nice docs that used to be at clojureql.org

10:59 ejackson: jakeskik, semperos : They've just pulled the migration side of thinsg out of Conjure and into its own library http://github.com/macourtney/drift

10:59 jakeskik: ah, nice

11:01 Vinzent: semperos, ok, just to be sure that people don't think anything like that about clojureql :) I haven't found the source for the site too, so I'm using version from the yandex cache now: http://yandex.ru/yandsearch?text=clojureql&site=clojureql.org&clid=46510&lr=11108

11:01 looks like google already removed it from the index

11:01 semperos: yes, they have

11:03 Vinzent: thanks for the link to the yandex results

11:03 * semperos copies those cached pages now

11:03 mrb_bk: I'm a clojure noob -- if anyone feels like ripping apart some clojure code, here's something small I'm working on: https://gist.github.com/1504840

11:04 Right now it validates that a Redis .rdb dump file is in fact a dump filee

11:04 Any comments appreciated

11:05 Vinzent: semperos, np. Is it possible to have these pages on clojureql.github.com? Or some actions from repo's owner (Lau) required to do that?

11:06 semperos: owner would need to do that, as far as I know

11:06 it can be added to its wiki, for now

11:06 Vinzent: yeah, better than nothing

11:06 semperos: better than sending folks to a Russian search engine :)

11:06 for cached copies

11:07 Vinzent: hah, sure :)

11:07 kumarshantanu: semperos: Vinzent: One good thing may be to setup a Google group for ClojureQL (just an idea)

11:08 semperos: probably something better started by the folks who maintain it

11:08 jhirn: m4b_bk: you might want to look at clojure.java.io instead of using interop for Files http://richhickey.github.com/clojure/clojure.java.io-api.html

11:08 lazybot: Nooooo, that's so out of date! Please see instead http://clojure.github.com/clojure/clojure.java.io-api.html and try to stop linking to rich's repo.

11:08 Vinzent: mrb_bk, I didn't actually read the code, but it's a good style to use ;; instead of ; in your code (; for inline comments)

11:08 jhirn: or, what lazybot sait =)

11:09 licenser_: Raynes: I love you for lazybot saying that

11:09 mrb_bk: Thanks everyone

11:09 I couldn't get clojure.java.io to read bytes easily

11:11 jhirn: I like lazybot for that too. I always end up on the wrong doc page.

11:11 Now I know.

11:12 I need to just remember to use clojuredocs.org

11:12 mrb_bk: jhirn: So you're saying I should use make-input-stream?

11:13 jhirn: mrb_bk... I think so . Experiment with calling class on what it returns. I beleive it might return an InputStream.

11:17 gfredericks: why does my clojurescript code clobber the $ variable?

11:20 Vinzent: semperos, do you know is bendlas hanging here? Seems like he is the most active maintainer and I can't send him a message on github

11:20 semperos: I don't know

11:22 ejackson: Vinzent: he posted to the list recently

11:24 actually, you replied to his email :) He's Herwig.

11:26 triyo: What would be the cleanest way to have a config clj file that contains some global vars (*is-prod*, etc.). These globals in config file are populated from the command line args when the program's process is launched.

11:26 Maybe there is a better way to do this all together.

11:31 semperos: triyo: you can define your "global vars" in you regular source code

11:31 then as part of your CLI handling (suggest clojure.tools.cli if you're not using it) you can change the value of those var's

11:32 triyo: semperos: right, I am using CLI :)

11:32 its great

11:32 semperos: e.g., doing a (swap! *is-prod* value-from-command-line) if you're using atoms for those

11:32 triyo: so I have a config.clj and it contains *is-prod*, *webapi-host*, etc.

11:33 And the CLI lives in the main.clj

11:33 semperos: your config can just be a clojure map

11:33 soemthing like {:env "prod", :host "localhost"} etc

11:33 you can use the (read) fn to read that map as a Clojure datastructure straight from the file

11:34 triyo: for sure, thats true... However what is the best way to set this *config-map* that lives in config.clj so the entire app in this running process has access to it

11:35 So here is the scenario...

11:35 semperos: posting what you have in a gist might also help

11:36 triyo: Shell -> java -jar myapp.jar --env prod --host xxxx --port 8000

11:36 main.clj makes sense of args via CLI

11:36 semperos: right, which gives you an options map including {:env "foo" :host "foo"}

11:36 triyo: and then it sets the config.clj global *config-map* to what was passed in.

11:37 semperos: if config-map is an atom, for example, you can just do (swap! *config-map* options), with options being the options that c.t.cli gives you from parsing the command-line arguments

11:38 triyo: Now, when a part of my app calls, myapp.config/*config-map* or even better, one of its accessors function (production?), it gets what was passed in when process was started

11:38 Vinzent: ejackson, ah, it was he :)

11:38 semperos: right

11:38 triyo: semperos: I'll give it a try..

11:38 semperos: I understand what you're trying to do, not sure where your question still is

11:39 triyo: Don't think there is one, guess I'm just thinking out loud now ;)

11:39 semperos: alrighty

11:39 no harm there

11:50 examples of what specs look like with clojure.java.jdbc/create-table ?

11:51 nm: http://en.wikibooks.org/wiki/Clojure_Programming/Examples/JDBC_Examples#Creating_a_Table

11:57 ibdknox: I wish ddl stuff weren't such a disaster

12:31 CmdrDats: hey everyone - I'm needing to create a fairly simple queue system to get forms to run in a GUI thread

12:32 currently, I have an action-list ref, a simple enlist function that conj's a form onto it and a handle-actionlist! function that pops the forms off and evaluates it (which i run from the main thread)

12:32 does that sound like an ok solution?

12:36 amalloy: CmdrDats: sounds like you've reinvented agents using refs

12:37 CmdrDats: ye :/ but i'm not sure how to make an agent run in a pre-existing thread

12:37 I'm working on the jMonkeyEngine - it hands me a thread and says 'only make changes to the scene on here'

12:38 cgray: any idea why this snippet https://gist.github.com/1506911 doesn't work properly? it's not appending to the end of the file -- just overwriting the file every time the fn gets called

12:39 amalloy: yeah, i thought that might be the case. i don't think you can really do that with an agent

12:41 CmdrDats: ok, cool - thanks - was hoping there was something i didn't know about

12:45 cemerick: cgray: FileOutputStream overwrites by default

12:45 use (FileOutputStream. "path" true)

12:45 cgray: cemerick: yeah, I figured it out...

12:45 thanks though

12:54 choffstein: Anyone familiar with congomongo and know how to fetch an entry by id value and not an id object? I am trying to seriealize an id object to a redis queue and can't seem to do it, but also can't seem to fetch by the value of the id -- I need to recreate the object somehow

12:57 ddudey: I've done this recently, I think you can fetch where :_id is whatever you want

12:59 Or do a (ObjectId. "xxxx") to get an object for value

13:01 TimMc: try-CLJS sucks a little less now; it can evaluate (clojure.core/first (clojure.core/map clojure.core/+ [1 2] [300 500])) correctly.

13:02 Also, def and defn work.

13:02 choffstein: ddudey: Yeah, I feel like an idiot. just saw `object-id` in the congomongo source

13:20 General design question: I am trying to build a web API on top of Ring that takes a request, checks if the answer exists in a MongoDB, and if it doesn't, fires off a job on redis (via resque) and then tries to read the result from MongoDB, eventually timing out with an error if it doesn't find the result. My questions are, 1) What is the best way to poll without hammering the DB? Can I sleep the Thread? 2) Can I set it up so that while I am polling

13:20 DB, I am not blocking?

13:20 gfredericks: choffstein: for 2) I think you want to use aleph?


13:21 choffstein: gfredericks: Like … with wrap-aleph-handler?

13:22 gfredericks: isn't that the one that does synchronous responses?

13:22 which would defeat the purpose of using aleph

13:23 choffstein: the point is that aleph (I think) ignores the return value of your handler function, but gives you a mechanism to respond later. Thus you're not blocking.

13:23 choffstein: gfredericks: Gotcha. Hmm, I'll check it out

13:24 gfredericks: choffstein: relevant docs here: https://github.com/ztellman/aleph/wiki/HTTP

13:24 choffstein: thanks

13:27 gfredericks: do cljs doc-strings do anything that comments don't?

13:28 I guess they're easier for code-reading tools to find

13:31 cgray: gfredericks: I think they put into the output js as comments as well (though I'm not sure that regular comments don't)

13:36 semperos: using h2, I've created a table called "events"

13:36 here is my trying to use it with Korma and getting an error about the table not existing:

13:37 https://gist.github.com/1507124

13:37 I've checked the h2 database file with a GUI app and verified that the table does, in fact, exist

13:37 and I used the same connection spec to create it in the first place

13:37 any thoughts?

13:49 CmdrDats: emacs users: how do explore java libraries for method names/import paths?

13:49 I'm using eclipse/netbeans to alt+enter auto-import and then copy and paste the import into my clojure

13:49 technomancy: CmdrDats: C-c S-i works great on java libraries

13:50 java classes, rather

13:50 the only thing it's missing is method argument names, but you can see methods, constructors, fields, interfaces, and it's all hyperlinked

13:50 CmdrDats: hmm, my C-c S-i is undefined

13:50 semperos: nice

13:50 gfredericks: the leiningen README says "You can also include one-off tasks in your src/leiningen/ directory if they're not worth spinning off; the plugin guide shows how."

13:50 semperos: CmdrDats: are you using slime/swank ?

13:50 CmdrDats: ye

13:51 gfredericks: assuming "the plugin guide" is /doc/PLUGINS.md, I'm not sure where it's mentioned.

13:51 semperos: CmdrDats: I just tried it at a REPL (I use elein-swank to connect) on String and it worked fine

13:51 gfredericks: is there any documentation on how to do per-project lein tasks?


13:51 CmdrDats: semperos: hmm, i'm using slime-connect

13:52 technomancy: gfredericks: hm; looks like it's not addressed specifically.

13:52 semperos: seems like my Korma issues have to do with case...

13:53 technomancy: gfredericks: oops; got disconnected; how much of that came through?

13:53 gfredericks: technomancy: just you noting that it's not addressed

13:53 technomancy: gfredericks: there's nothing special needed though; you just put the file in src/ instead of in the src/ dir of its own project.

13:54 CmdrDats: semperos: if you describe the key (C-h k C-c S-i) what do you get?

13:54 gfredericks: technomancy: okay, so I'll look at the regular plugin docs for the rest of it then; thanks

13:54 semperos: CmdrDats: reconnecting usine slime-connect...

13:55 CmdrDats: haha

13:55 nvm - figured it out

13:55 semperos: CmdrDats: does slime-inspect

13:55 good

13:55 CmdrDats: Shift-i

13:55 semperos: I didn't know about it myself

13:55 CmdrDats: not cmd-i....

13:55 semperos: yep

13:55 CmdrDats: s-i = cmd+i on my mac

13:55 semperos: good ol' meta keys

13:56 CmdrDats: ok, but now - i know that KeyTrigger is somewhere in my classpath

13:57 C-c S-i is super handy though, thanks technomancy :D

13:57 technomancy: it's the best!

13:57 CmdrDats: how do i find out what I need to import to get KeyTrigger :/

13:57 besides heading off to javadocs/netbeans

13:58 semperos: for KeyTrigger, what does it say its class is?

13:58 CmdrDats: unable to resolve

13:59 i haven't :import'ed it into my namespace

13:59 semperos: right

13:59 CmdrDats: but in order for me to import it…. i need to know where it is xD

14:00 i've been spoilt with years of eclipse

14:00 technomancy: CmdrDats: C-c S-i has tab completion

14:00 so if you know its general vicinity it shouldn't be too hard to track down

14:01 CmdrDats: technomancy: that's always the problem though - some libraries are really… interestingly.. laid out

14:02 and then the samples they provide (w/o looking at source code downloads) usually omit import statements

14:03 technomancy: yeah, that's super-lame

14:03 you can always try slamhound

14:03 CmdrDats: you can always open the jar file in emacs and do C-s though

14:03 CmdrDats: hmm, my tab completion doesn't work.. something about fuzzy-complete-symbol being void - maybe i haven't installed something

14:03 i can open a jar in emacs??

14:03 lazybot: CmdrDats: Definitely not.

14:04 technomancy: lazybot: LIES

14:04 CmdrDats: sure you can

14:04 you can even edit the bytecode if that's how you roll

14:04 CmdrDats: hehehe

14:04 semperos: option-.

14:04 M-.

14:04 jodaro: straight up byte code editing playah

14:04 semperos: will open a jar up and take you to the source

14:04 * ekoontz works on my mac emacs 23.2 (9.0)

14:05 ekoontz: the M-. doesn't work for me tho :(

14:05 technomancy: I don't think M-. works on classes

14:05 semperos: ah, that's true

14:05 technomancy: it would be rad if that could run it through javap though

14:06 CmdrDats: hehe, this is emacs, after all

14:06 ekoontz: semperos, what is the long form of it (the M-x ...something)

14:06 hiredman: https://github.com/hiredman/javap-mode doesn't work on class files in jars yet

14:07 http://www.thelastcitadel.com/images/javap-mode.png

14:07 ekoontz: interesting, thanks hiredman for the link

14:07 CmdrDats: O.o awesome being able to browse jars!

14:07 technomancy: hiredman: would be a great holiday-time hack project though, eh? =)

14:08 semperos: ekoontz: slime-edit-definition

14:08 defined in slime.el

14:08 technomancy: hiredman: did you ever get that on marmalade?

14:08 hiredman: nope

14:09 CmdrDats: hiredman: that is awesome

14:10 anyhow - back to binding my little cube to keys so i can start moving it around

14:10 jMonkeyEngine rocks

14:16 technomancy: gfredericks: https://github.com/technomancy/leiningen/commit/579fef7337962a21c764a361040a4f91cb89023a

14:24 aravind: hi

14:25 I am failing at understanding why this won't work, (Math/sqrt 2) works, but (map Math/sqrt [2]) doesn't. I have to do something like (map #(Math/sqrt %1) [2]).. I don't quite understand why..

14:27 pandeiro: is it possible to do (ns foo.core (:use bar.core [baz.core :only baz]))?

14:27 hiredman: aravind: seriously?

14:28 aravind: what is the difference between 2 and [2]? or 2 and {:two 2} or 2 and (atom 2)?

14:28 technomancy: hiredman: I may be hallucinating, but I think there's a batshit crazy lisp dialect out there that will automatically translate calls like that into map calls.

14:29 hiredman: technomancy: :|

14:29 semperos: aravind: map takes a function as its first argument, Math/sqrt isn't a function

14:29 aravind: okay, if it isn't a function, then why does (Math/sqrt 2) work?

14:30 semperos: (macroexpand '(Math/sqrt 4))

14:30 ,(macroexpand '(Math/sqrt 4))

14:30 clojurebot: (. Math sqrt 4)

14:30 semperos: that's what's happening under the hood

14:30 interop sugar

14:30 technomancy: hm; misread that; I was thinking of something that would translate (f [x]) into (map f [x])

14:31 which I really hope is something I invented in some kind of feverish dream rather than an actual language.

14:31 aravind: semperos: ah okay.. I am mistaking java interop stuff as straight supported function calls..

14:31 semperos: exactly

14:31 aravind: cool, thank you.

14:31 semperos: np

14:31 aravind: if you dig deep

14:32 you see that the f needs to have implemented clojure.lang.IFn

14:33 using lobos for schema definition and table creation, anyone know how to set the default column value?

14:33 aravind: semperos: how would I have found that on my own? this seems like something I should have known, before begging for help..

14:34 semperos: the Java method vs. Clojure function distinction is a common learning point

14:35 Raynes: And it is explained in all of the books and probably that ociweb tutorial.

14:35 semperos: not sure there's one "how" to getting that down in all places

14:36 technomancy: if only clojure.lang.IFn could be a protocol. =(

14:36 Raynes: Not that I'm criticizing you for not knowing it. It isn't a big deal that you asked. :p

14:36 semperos: if you're comfy with it, looking at the source never hurts

14:36 Raynes: It's what the channel is here for.

14:36 semperos: technomancy having more feverish dreams ;-)

14:37 gfredericks: technomancy: how do I use the "src/leiningen" strategy with a different :source-path?

14:37 Raynes: gfredericks: You can't, IIRC.

14:38 aravind: Raynes: yup, I read those, but I guess I never made the jump between sytactic sugar and it not behaving like a regular function (when used in map)..

14:38 in any case, thanks for the help.

14:38 technomancy: gfredericks: he's right; it's unpossible

14:38 gfredericks: Raynes: guess it's about time to check out that lein-cljs plugin then

14:38 technomancy: because the classpath must be known at launch

14:39 Raynes: I'm not a big fan of those plugins.

14:39 technomancy: agreed

14:40 very few projects necessitate plugins that aren't general purpose

14:40 pandeiro: is it possible to use :use foo and :use [bar :only baz] in the same ns?

14:40 Raynes: They just grab a version of cljs and stuff it clojars and are like "here ya go, fresh clojurescript. no worries that critical bugs are fixed every other day, just use this"

14:40 gfredericks: Raynes: technomancy: you two are talking about different things aren't you? :)

14:40 technomancy: oh

14:40 yeah

14:40 I'm talking about plugins-in-src/ in general, though I agree re: unofficial cljs packaging.

14:41 gfredericks: my imminent issue is that the cljsc script sets the classpath to "src/clj" and "src/cljs"

14:42 Raynes: technomancy: I have a plugin internal to tryclj that pulls down my javascript dependencies.

14:42 I guess that could be external and public, but then I'd end up writing a Javascript package manager and I'd have to hang myself.

14:42 gfredericks: yeah it takes extra work to generalize things

14:43 technomancy: it's always The Right Thing, whether it's Right for Right Now or not.

14:44 gfredericks: technomancy: xkcd.com/974?

14:44 technomancy: pretty much

14:48 Raynes: gfredericks: It is illegal to link to something without prefixing it with http:// and thus making ERC link it without having to take a massive regex to it.

14:48 gfredericks: Raynes: what is the penalty for infringement?

14:48 Raynes: Death.

14:49 gfredericks: well then I hope my life has been a lesson to all other potential violators. I assume they're all watching right now.

14:49 pbuckley: I'm completely deterred.

14:49 gfredericks: or if not I'm sure my story will be taught in middle schools everywhere

14:50 thank you Raynes, you have given my life a purpose.

14:51 duck1123: Here lies gfredericks, he forgot the http://

14:52 jodaro: probably preschools by now

14:52 "and remember, children, if you forget the http:// in irc, your mommy and daddy will stop loving you."

14:55 duck1123: "Daddy, check my closet for Raynes"

15:02 gfredericks: does the cljs compiler assume that all code is in the directory you pass it?

15:06 it is complaining that my macro ns's are not on the classpath :/

15:12 cgray: gfredericks: when i was hacking cljs a couple of months ago, i had to put my macros in the cljs source dirs to get them read... it's probably changed since then, but it's worth a try

15:12 gfredericks: cgray: that's where I've got it

15:12 cgray: and it still doesn't work?

15:12 gfredericks: nope

15:13 reading the cljsc script, it doesn't put any of the dirs from my project on the classpath

15:13 so maybe I need to hack it to add that in...

15:13 cgray: gfredericks: oh, i meant in CLJS_HOME

15:13 gfredericks: aah

15:15 I like hacking the cljsc script slightly better, and that seemed to work

15:25 Kenth: Hi, I'm on page 92 of the Joy of Clojure book, where they use defmethod and '<- and '-< . I looked up stuff on clojure docs, however they use defmulti before defmethod, there is nothing for -< and <- mentions a datalog rule

15:26 Can someone explain what print-method is doing to the queue?

15:26 hiredman: they are adding a print method for the queue type

15:26 ,clojure.lang.PersistentQueue/EMPTY

15:27 clojurebot: #<PersistentQueue clojure.lang.PersistentQueue@0>

15:27 Kenth: why are the arguments split into [q , w] ?

15:27 hiredman: doesn't have a nice printable form

15:27 print-method part of clojure, and it's arguments are defined there

15:27 is

15:28 so if you look through the clojure source you will find the defmulti for print-method

15:28 or if you just check the metadata for where it is defined

15:30 Kenth: is there a function to pull the metadata up?

15:30 Raynes: &(meta print-method)

15:30 lazybot: ⇒ nil

15:30 Raynes: Duh.

15:30 &(meta #'print-method)

15:30 lazybot: ⇒ {:ns #<Namespace clojure.core>, :name print-method, :line 3253, :file "clojure/core.clj"}

15:30 hiredman: surely it's in the joy of clojure

15:33 Kenth: Yep, page 71. I forgot about it

15:36 jodaro: i started putting those sticky tabs on important pages in JofC

15:36 but i ended up stopping cuz like every page seems to have one

15:37 its like when you highlight the whole textbook

15:37 and then you go back to review

15:37 and end up reading the whole thing again

15:42 bweaver: Hello, I'm experimenting with the `checkouts` folder in a leiningen project for the first time. I notice that it adds the sub-project's `src` folder to the CLASSPATH, but not the deps in the sub-project's `lib` folder. Am I doing something wrong?

15:43 devinus_: how do you guys repeat the last slime line?

15:43 gfredericks: bweaver: I think you have to have the proj declared as a dep, which presumably means maven is taking care of the indirect deps?

15:43 duck1123: devinus: M-p

15:44 devinus: duck1123: what about the opposite?

15:44 duck1123: M-n

15:44 devinus: sweet, thanks

15:44 bweaver: gfredericks: Oh, so if I have `checkouts/sub-project` I need to add `[sub-project "x.y.z]` to my `:dependencies`?

15:44 duck1123: also, if you start typing part of the line, it'll go through lines that match what you typed

15:44 gfredericks: bweaver: yep

15:45 bweaver: I don't know if it reads the sub project's project.clj or not

15:45 bweaver: from the lein readme: "Note that this is not a replacement for listing the project in :dependencies; it simply supplements that for tighter change cycles."

15:45 duck1123: The checkouts folder is if you're hacking on a dependency of a project. It save you from constantly having to install, change directories then deps

15:45 bweaver: gfredericks: I was wondering what that meant...

15:46 gfredericks: Looks like if I add `[sub-project "0.1.0"]` to my `:dependencies` and to a `lein deps`, it blows up trying to fetch `sub-project` from a remote repo :(

15:47 Things seem to work OK if I hoist sub-project's dependencies up into the `:dependencies` of the parent project. That just seems a little messy so I thought I might be doing something wrong.

15:47 duck1123: bweaver: install the sub-project at least once

15:48 gfredericks: duck1123: would he have to install it whenever the sub-project's deps change?

15:49 duck1123: no, lein is going to try to download the deps like normal, so it has to be in your ~/.m2, once that's done, it'll use the checkouts copy

15:49 bweaver: duck1123: aha, thanks

15:50 That makes sense, the `checkouts` folder is a trick. It just shadows the jar in `lib` by being earlier on the CLASSPATH.

15:50 And `lein install` on `sub-project` allowed `lein deps` to run successfully.

15:50 Thanks!

16:00 * technomancy wonders if there is a clearer way to explain it

16:00 technomancy: everyone is confused about checkout deps, and I can't figure out why

16:01 hiredman: technomancy: I got your back

16:02 technomancy: hiredman: time for a factoid?

16:02 maybe calling it "checkout dependencies" is confusing because it implies that the checkout is a dependency declaration?

16:02 brehaut: technomancy: is that like a non-polymorphic factad ?

16:03 hiredman: co-dev-dep

16:03 technomancy: probably

16:05 hiredman: what about just "checkouts"?

16:05 too vague probably

16:07 gfredericks: fun fact: clojurescript causes a bug in the underscore library, which assumes that strings don't have a 'call' method

16:09 Raynes: gfredericks: Fun fact: ClojureScript is a bug. :P

16:09 gfredericks: squish it!

16:09 Raynes: ~guards

16:09 clojurebot: SEIZE HIM!

16:12 TimMc: Raynes: I believe it.

16:13 kotarak: ~suddenly

16:13 clojurebot: BOT FIGHT!!!!!111

16:13 kotarak: Not CLABANGO anymore?

16:14 gfredericks: kotarak: probably does that too?

16:14 ~suddenly

16:14 clojurebot: CLABANGO!

16:14 blakesmith: Raynes: I haven't played with ClojureScript yet, but I'd like to hear more about what you don't like about it.

16:14 kotarak: gfredericks: ah. there it is. :)

16:15 * blakesmith was considering giving it a try for a small side project soon.

16:15 Raynes: blakesmith: I was just being annoying.

16:15 gfredericks: blakesmith: he didn't say he didn't like it, just that it's alpha

16:15 Raynes: It's kind of buggy, but it's also kind of brand new and thus understandably kind of buggy.

16:15 jodaro: no excuse!

16:15 all clojure is to be bug free the instant it is written

16:16 TimMc: technomancy: Rename the "checkouts" folder to "symlinks-to-projects-you-already-have-listed-in-dependencies".

16:17 blakesmith: I just assume all developers don't like bugs. ;-)

16:17 TimMc: blakesmith: It is extremely alpha.

16:18 technomancy: there is a sense in which software that "feels polished" is less likely to get patches because users are more likely to assume that quirks are intentional.

16:18 jodaro: TimMc: derive worked exactly as i needed it to, thanks again

16:18 technomancy: OTOH with core's attitude toward contributions this seems unlikely to apply to clojurescript.

16:20 TimMc: CLJS is more like... rosh, or some other Phoenician letter. Pre-alpha.

16:21 devinus: anybody know how to kill and restart slime without killing emacs and jacking-in again?

16:22 technomancy: M-x clojure-jack-in

16:24 TimMc: as many times as necessary

16:24 just like LaTeX

16:24 gfredericks: ~rimshot

16:24 clojurebot: Badum, *ching*

16:25 devinus: technomancy: thank you. btw, did you happen to see my last comment in https://github.com/technomancy/swank-clojure/issues/88 ?

16:25 technomancy: yeah, not sure what's going on there

16:25 devinus: technomancy: this is in both my OS X and Ubuntu environement (both Emacs 24). i'm willing to do w/e it takes to help debug this

16:26 technomancy: does it happen if you use -Q to skip all your personal config and load just the stock clojure-mode plus that snippet?

16:26 devinus: technomancy: all i have in my personal config is this snippet :P

16:26 other than i'm using emacs starter kit

16:27 technomancy: hmmmmm

16:27 devinus: from marmelade

16:27 i'm not sure how it fixed it for that one dude

16:27 weird that it fixes it for one person but not me, even though we had the exact original problem

16:27 :-/

16:28 technomancy: how recent is your 24 build?

16:28 devinus: technomancy: very recent. most recent build in OS X from http://emacsformacosx.com/builds

16:28 on Ubuntu i use emacs-snapshot PPA package

16:29 to be honest I don't mind having hackish elisp in my .emacs. i just hope it's not indicative of a larger problem, you know?

16:29 otherwise i honestly could care less

16:31 technomancy: yeah, unfortunately I have no idea why your setup would behave differently

16:31 devinus: i'll keep an eye out as i upgrade emacs versions

16:32 maybe track it down

16:45 technomancy: starter-kit-lisp automagically turns paredit on for clojure code?

16:46 technomancy: right

16:47 devinus: that's hot

16:47 technomancy: necessarily

16:57 zdod: Anyone in NYC know if the Clojure Meetup is happening tonight at Google?

17:28 technomancy: o_O

17:28 weavejester: may I interest you in a https://github.com/technomancy/s3-wagon-private ?

17:29 weavejester: technomancy: That looks interesting!

17:30 technomancy: weavejester: better than dumping it on clojars anyway =)

17:30 weavejester: technomancy: For open source stuff?

17:30 technomancy: you don't even necessarily need to make it private; that plugin works for public s3:// repos as well.

17:30 weavejester: I can see it being really useful for private repos!

17:31 But does it have any advantages over Clojars for public ones?

17:31 technomancy: weavejester: well I assume dep-a and friends are not real dependencies but some kind of test, right?

17:31 so s3 has the advantage that you can delete them when you're done testing

17:31 weavejester: Ohh, right!

17:32 Duh, yeah, sorry, I didn't put 2 and 2 together there.

17:32 technomancy: heh; sure

17:33 weavejester: I was just trying to figure out whether it's better to specify [org.clojure/clojure "1.2.1"] or [org.clojure/clojure "[1.2.1,1.3.0]"]

17:35 technomancy: I'd go with the latter if you're trying to communicate to consumers that you're targeting both versions

17:35 weavejester: Well, the problem with the latter is that it's saying 1.3.0 maximum, no exceptions.

17:36 So if Clojure 1.3.1 comes out, you wouldn't be able to use it with a project that specifies a Clojure version of [1.2.0,1.3.0]

17:36 technomancy: for a library or for an application?

17:37 weavejester: For a library. A dependency

17:37 technomancy: the thing about specifying a dependency on Clojure in a library is that practically speaking it is always a mechanism for communicating to the author of an application

17:37 weavejester: e.g. If B 1.0.0 => A [1.0.0,1.1.0]

17:37 technomancy: it has no bearing on what version of Clojure will actually be used

17:38 since the consumer will always pick that, and the version they specify will take precedence

17:38 weavejester: Is Clojure treated specially?

17:38 technomancy: no, but Clojure is the one thing that consumers are guaranteed to declare a dependency upon

17:38 weavejester: Okay, so I ran some tests...

17:39 technomancy: the more direct declarations always win

17:39 amalloy: if you want to allow 1.3.1, you can specify [1.2.0,1.4.0)

17:39 weavejester: Apparently not.

17:39 I ran a few tests...

17:40 I had B 1.0.0 depend on A [1.0.0, 1.1.0]

17:40 And if I included two dependencies in a new project

17:40 A 1.1.1 and B 1.0.0

17:40 Then I got A 1.1.0 and B 1.0.0

17:41 I tried swapping round the order of dependencies too

17:41 Same result

17:41 technomancy: wow, really?

17:41 weavejester: The [1.2.0,1.3.0] syntax ensures that 1.3.1 is never chosen

17:41 technomancy: Unless I've made a mistake... but I double-checked

17:41 technomancy: lemme see if I can repro

17:42 weavejester: technomancy: I'd appreciate it if you could. It's a really weird result.

17:43 TimMc: I think "1.3.0" is a soft requirement, and "[1.3.0]" is hard.

17:43 technomancy: yeah, it may be that the range is given precedence because it's considered more specific

17:43 amalloy: right. "1.3.0" means "I'd like 1.3.0 but am willing to try whatever you want"

17:43 weavejester: Yeah, but I'd expect that a more direct dependency to override

17:44 amalloy: "[1.3.0]" is: this library will not work with any version but 1.3.0, refuse to build

17:44 weavejester: So if I specify A 1.1.1 and B 1.0.0, I wouldn't expect A 1.1.0 and B 1.0.0

17:44 I'd expect A 1.1.1 to be the nearer dependency and override B's dependency of A [1.0.0, 1.1.0]

17:44 amalloy: weavejester: if your main project asked for [1.1.1], then you wouldn't get an override

17:44 you'd get a build failure instead

17:45 but if you ask for 1.1.1, you're agreeing to let maven do its best

17:45 weavejester: amalloy: I'm saying if a *dependent* library asks for [1.0.0,1.1.0]

17:45 amalloy: uh huh...

17:45 weavejester: e.g. B depends on A [1.0.0,1.1.0]

17:45 pandeiro: is the (some #{foo} my-vector) idiom the fasted way to test a vector for a specific value?

17:46 amalloy: and your project asked for 1.1.1, right?

17:46 weavejester: And C depends on A 1.1.1 and B 1.0.0

17:46 amalloy: or C does, whatever

17:46 technomancy: wow, ok... I'm swearing off ranges.

17:46 weavejester: Then in my lib directory for C I get A 1.1.0 and B 1.0.0

17:46 technomancy: this is just too confusing.

17:46 weavejester: technomancy: Got the same result?

17:46 technomancy: yeah

17:46 amalloy: but it's not in brackets: C is saying it's willing to try other versions

17:46 i agree it's kinda a dumb system, but the results are consistent with the meanings of [x,y] and x

17:47 weavejester: Yeah, it makes sense...

17:47 Because B is saying "I will *only* accept versions between 1.0.0 and 1.1.0"

17:47 But in practise I'd like a nearer dependency to override it.

17:48 I wonder what happens if C tries to force it with a "[1.1.1]"

17:48 technomancy: seems crazy to implement that without a way to say "no really, ignore the fact that this certain dependency doesn't know about this newer version that it happens to be totally compatible with"

17:48 amalloy: weavejester: build failure, i think, which is what i said earlier

17:48 weavejester: Yeah, build failure

17:48 technomancy: "The artifact has no valid ranges"

17:49 weavejester: It is pretty crazy.

17:49 If you had specified a library to work with Clojure [1.1.0,1.2.0] for instance

17:49 * technomancy deletes the section of the lein tutorial mentioning ranges

17:49 weavejester: Then you couldn't use Clojure 1.2.1 in any dependent project.

17:50 technomancy: right; there's no way to know whether future versions are backwards-incompatible or not, so it's crazy to declare an upper-bound unless an incompatible version has already been released.

17:50 in which case you should just upgrade your code. =(

17:51 amalloy: technomancy: of course, if semver were unversally followed, you could know some versions won't be compatible

17:51 but i don't think any projects out there actually follow semver to the letter

17:52 technomancy: amalloy: sort of. a library could still introduce a breaking change in a namespace you don't use.

17:52 amalloy: sure

17:53 weavejester: amalloy: The problem is that if a dependent project releases a new patch version, if you use hard version ranges, no-one can you your project with the new patch version

17:53 amalloy: Even if it was sematically versioned correctly

17:54 amalloy: weavejester: [1.0.0,2.0.0)?

17:54 i mean, i recognize version ranges have serious issues

17:54 weavejester: amalloy: Doesn't that mean 1.0.0 <= x < 2.0.0 ?

17:55 amalloy: Ohhh. I see what you mean.

17:55 amalloy: yes. so their patch version would go from 1.0.0 to 1.0.1

17:55 TimMc: Except that doesn't work.

17:55 amalloy: but the free-for-all approach of "i want 1.3.0, but i'll try anything once!" has issues too

17:55 weavejester: amalloy: Yeah, so breaking changes involve changing the major version in sematic versioning.

17:55 TimMc: If you do [1.2.0,1.4.0), you'll get 1.4.0 alphas and/or SNAPSHOTs.

17:55 amalloy: TimMc: ewwwwwww

17:56 TimMc: Yup.

17:56 weavejester: TimMc: Ah, good point!

17:56 TimMc: I was all :sadface: when I discovered that.

17:56 amalloy: jesus. [1.2.0,1.3.4654321564567]

17:56 TimMc: Haha, yeah.

17:56 1.3.9999999999999999999999999

17:57 amalloy: see if you can find an Integer.parseInt bug in maven

17:57 brehaut: you guys have made me paranoid that ive got bad version strings now

17:57 im using in my one publicly released library "[1.2.1],[1.3.0]" is that great badness?

17:57 amalloy: brehaut: at least it's a big club you've just joined

17:58 brehaut: amalloy: lol :(

17:58 amalloy: wait what does that range even mean

17:58 brehaut: amalloy: i *think* it means either 1.2.1 exactly, or 1.3.0 exactly?

17:58 TimMc: I think Maven provides a way to override dependencies' version requirements.

17:58 Somelauw: Is read-string considered a safe function or is it as dangerous as eval?

17:59 brehaut: i went spelunking a while ago and came back with the first thing that worked

17:59 Somelauw: Should it be used on user input?

17:59 weavejester: I'd have just gone with "1.2.1"

17:59 technomancy: Somelauw: you can disable read-eval

17:59 TimMc: Somelauw: ##(read-string "#=(+ 1 2)")

17:59 lazybot: java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.

17:59 brehaut: Somelauw: if you have *read-eval* set to true its dangerous, otherwise safe

17:59 amalloy: Somelauw: it's as unsafe as eval, unless you turn off that feature

17:59 i think clojail exposes a read-string-safely function, or something like that

17:59 brehaut: weavejester: would that let it use 1.2.1 and up?

18:00 Somelauw: And its enabled by default?

18:00 technomancy: yeah, as far as what you actually *want*, clojure version declarations in libraries should function as documentation to the consumer

18:00 amalloy: brehaut: it lets it use 0.0.0 and up, but expresses a preference for 1.2.1 :P

18:00 TimMc: Somelauw: read can also run out of stack, I think.

18:00 technomancy: but for that purpose, lein-multi is probably better

18:00 TimMc: ,`````````````````f

18:00 weavejester: brehaut: Yeah. "Prefer 1.2.1 if nothing else is specified, but accept any version above it too."

18:00 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.StackOverflowError>

18:00 brehaut: amalloy: ah. that definately wont work for necessary evil ;) it breaks on 1.2.0

18:00 amalloy: weavejester: it allows lower versions too, doesn't it?

18:01 weavejester: amalloy: I didn't think so...

18:01 amalloy: i could definitely be wrong there

18:01 weavejester: amalloy: Let me test!

18:01 amalloy: like if you publish a lib that depends on "1.3.0", and your app depends on "1.2.1", you get 1.2.1

18:01 betraying the lib's preferences

18:01 TimMc: clojurebot: read-string |is| as unsafe as eval unless *read-eval* is bound to false.

18:01 clojurebot: Roger.

18:02 brehaut: ~read-string

18:02 clojurebot: read-string |is| as unsafe as eval unless *read-eval* is bound to false.

18:02 TimMc: augh

18:02 amalloy: TimMc: the extra || confused him

18:02 amusingly

18:02 TimMc: horrible

18:02 amalloy: he learned it using the second "is" as the separator

18:02 TimMc: clojurebot: botsmack

18:02 clojurebot: Owww!

18:03 amalloy: and iirc with his current parser there's no way to un-teach him the thing he just learned. hiredman to the rescue?

18:04 weavejester: amalloy: You're correct

18:05 amalloy: A nearer dependency with a lower version will override a further dependency with a higher dependency

18:05 amalloy: Assuming neither dependency uses ranges or []

18:05 brehaut: half an hour ago, i thought maven versions were unbelievably complicated. turns out i was wrong by an order of magnitude

18:07 TimMc: weavejester: So it's some kind of lexicographic sort?

18:08 Never mind, I don't want to know.

18:08 brehaut: TimMc: it all starts with a lamb…

18:09 amalloy: weavejester: well, [] is a range too. just a small one

18:10 TimMc: amalloy: The question is, is [] a higher empty interval than []?

18:10 I guess it really should be () and ().

18:10 iruediger: \join #enlive

18:10 TimMc: iruediger: DENIED

18:11 amalloy: TimMc: weavejester meant single-size "ranges" like [1.3.0], i'm fairly sure

18:17 weavejester: Yeah, assuming all versions are "1.0.0" style

18:17 No ranges

18:17 Or single-size ranges

18:17 Then you can use a lower version number if you put it in your project.clj file

18:17 Even if a dependent library uses a later version

18:18 But if ranges or single-size ranges are involved

18:18 It's very strict.

18:18 amalloy: right. version numbers are hard

18:19 for a while i specified [1.2.0,), which gets you the "sure, you can use a higher version if you want" behavior

18:19 but is obviously a lie: my code won't work with clojure 5.7

18:38 weavejester: Hm, even [1.0,1.1] doesn't allow you to use 1.1.1

18:39 I think I'll just swear off ranges :)

18:42 Raynes: weavejester: Thank you.

19:05 accel: is ther ea init.clj somewhere that gets executed every time I run java clojure.main ?

19:05 i.e. there are some scripts that I want executed every time I load up the clojure repl

19:05 technomancy: accel: user.clj will, but it must be on the classpath

19:05 accel: anyehwere in the classpath, or in clojure.jar?

19:06 technomancy: anywhere

19:06 accel: technomancy: nice; it worked!

19:06 (inc technomancy)

19:06 lazybot: ⇒ 21

19:06 accel: (inc lazybot)

19:06 lazybot: ⇒ 3

19:07 technomancy: in general it's probably not a good idea to rely on that because it means every manually-constructed invocation of "java -cp [...]" needs to place the directory containing user.clj on the classpath

19:07 but there are some cases where it's nice to have

19:08 accel: technomancy: This suffices; it's purely for development purposes.

19:13 technomancy: choffstein: did you see this? https://github.com/heroku/heroku-buildpack-clojure/tree/private-repo

19:20 weavejester: you know these kinds of tests work fine out of ~/.m2, right? =)

19:20 weavejester: technomancy: Oh, I hadn't thought of that. Easier just to lein-push though

19:21 technomancy: only by three keystrokes

19:22 weavejester: technomancy: Oh, there's a lein command to deploy a jar locally?

19:22 technomancy: weavejester: "lein install" does that. =)

19:22 weavejester: technomancy: Ohhh

19:22 technomancy: Ah well

19:29 technomancy: anyone else interested in running a private repo want to test out https://github.com/technomancy/s3-wagon-private ?

19:38 qbg: Is there a reason why Clojurescript doesn't generate arity checks for fns?

19:39 cgray: qbg: I think it does

19:39 qbg: I just pulled down master and I'm not seeing them

19:40 For instance, this evaluates: ((fn [x] (* x 2)))

19:40 to NaN

19:40 And if you print the fn you see no check

19:41 cgray: how about if you do ((fn ([x] (* x 2)) ([x y] (+ x y)))) ?

19:42 qbg: That throw an arity exception

19:42 hiredman: qbg: are you running code through the optimizer?

19:42 qbg: No

19:43 Just ./script/repljs

19:43 I guess the Closure compiler would catch that

19:44 cgray: probably, and it'd slow things down quite a bit to generate an arity check for every single-arity fn

19:45 qbg: Now I'm wondering if advanced optimizations could remove that check if it existed

19:45 To the internet!

19:46 cgray: it seems like something that could be checked at compile-time, but i'm sure there's some diabolical example that shows I'm wrong

19:46 qbg: Nope

19:47 You wouldn't know the type of the function at compile time in all cases

19:47 HoFs would make that hard

19:47 cgray: true

19:49 qbg: Is there a way to pretty print an object in ClojureScript, showing its actual impl? (so you see what a vector looks like under the covers for example)

19:50 brehaut: qbg: can you console.log it if thats possible and explore it with the inspector?

19:51 qbg: What is the syntax for js*?

19:51 Or how should I invoke console.log?

19:52 brehaut: err (.log js/console …) ?

19:52 * brehaut guesses from a quick googling

19:53 cgray: brehaut: that's right

19:54 qbg: Yep. Only Rhino doesn't have a console object :(

19:54 brehaut: oh. rhino.

19:54 qbg: I thought there was a web browser powered repl somewhere?

19:55 Supposedly there is one included with ClojureScript now

19:59 Okay, I think I know how to get to it

20:00 Be nice if there was a script for it, and the readme pointed to https://github.com/clojure/clojurescript/wiki/The-REPL-and-Evaluation-Environments instead

20:03 accel: in a clojure map (which cuases lazy seq); is it guaranteed that each element is evaluated _at most_ once?

20:04 i.e. after the first time it ahs been evalutaed, is it gaurnteed to be memoized rather than re-excuted the next time the value is needed

20:04 hiredman: yes

20:04 accel: cool; not taht I distrust you; but can you provide a link? I would like to read up on related material on how all of this works (laziness + interacting with Java code scares me a bit)

20:04 hiredman: well, actually, I forget, there may be a race to memoize

20:04 accel: read the source

20:05 (there isn't the relevant methods are synchronized)

20:06 cgray: the results of map aren't memoized

20:07 TimMc: accel: If map uses lazy-seq, then it is guaranteed to realize each cons only once.

20:07 brehaut: if you hold onto the head they are

20:07 accel: how do you retain access to a map w/o hodling on to head?

20:07 hiredman: accel: don't

20:07 accel: and it isn't a map

20:08 a map is a {:foo 1}

20:08 accel: err, how to you retain acess to a lazy list w/o holding on to head?

20:08 hiredman: (map … …) creates a lazy sequence

20:08 why do you want to do that?

20:08 cgray: brehaut: i'm thinking there's confusion here between "memoize" and "realize"

20:08 accel: hiredman: I want to understand the weird case where the results of map aren't memoized.

20:09 hiredman: accel: there aren't any

20:09 accel: what was cgray referring to?

20:09 brehaut: cgray: memoization isnt just the use of the function memoize

20:09 hiredman: dunno

20:09 accel: but when in doubt feel free to trust what I say over what he says

20:10 cgray: hiredman: very true

20:11 brehaut: to me, memoization means storing the result of a function given its inputs... what does it mean to you?

20:11 brehaut: cgray: its storing the result of a computation to avoid recalculating it later

20:11 hiredman: lazy seqs are internally a series of no argument functions, the values of which are stored for later

20:11 TimMc: "memoization" can mean either a certain computational strategy or the specific technique of using the memoize function.

20:12 brehaut: hiredman puts it much more clearly than i can

20:13 qbg: brehaut: Yep, console.log shows the interesting guts. Thanks

20:13 accel: hiredman , cgray , TimMc : got it; thanks :-)

20:14 TimMc: accel: https://github.com/clojure/clojure/blob/1.3.x/src/jvm/clojure/lang/LazySeq.java is pretty interesting

20:14 That's what map uses (by calling lazy-seq).

20:16 brehaut: ,(let [s (map (fn [x] (Thread/sleep 100) x) (range 4))] (dotimes [_ 2] (time (doall s))))

20:16 clojurebot: "Elapsed time: 404.038 msecs"

20:16 "Elapsed time: 0.021 msecs"

20:17 accel: TimMc: added to reading list.

20:18 An unrelated question: is there a way to tell clojure: when printing out stack frames in REPL, only show me stacks that involve *.clj files, and ignore the ones involving *.java files?

20:18 I often times find myself scrolling through pages of *.java invocations to find the *.clj error

20:18 qbg: clojure.repl/pst does some of that

20:18 But not all of what you want

20:19 accel: how do I use clojure.repl/pst? my current invocation is: "java clojure.main"

20:19 qbg: Are you in the user namespace?

20:20 accel: I think so.

20:20 qbg: If so, (pst) will print the stacktrace of the last exception

20:20 ,(doc clojure.repl/pst)

20:20 clojurebot: "([] [e-or-depth] [e depth]); Prints a stack trace of the exception, to the depth requested. If none supplied, uses the root cause of the most recent repl exception (*e), and a depth of 12."

20:20 accel: ah, it only shows one *.clj line

20:20 but it's the one I care about

20:39 simard: Is there a better way to do that ? http://pastebin.com/1nCfvYK1

20:40 In particular, should I use recur instead ?

20:42 brehaut: ,(taken-nth 2 (range 10))

20:42 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: taken-nth in this context, compiling:(NO_SOURCE_PATH:0)>

20:42 brehaut: ,(take-nth 2 (range 10))

20:42 clojurebot: (0 2 4 6 8)

20:43 brehaut: simard: but lazy-seq seems correct there; recur would give you a strict list

20:43 simard: ok this function is basically the same as mine

20:43 good to know, there's always a bunch of already existing functions I don't know about .. :)

20:43 brehaut: simard: with the appropriate check for sequenceness ;)

20:43 simard: yeah

20:43 hehe

20:43 forgot about that.

20:44 I should skim through core.clj somesay

20:44 someday, to get that "I've seen this before" feeling.

20:44 brehaut: simard: a good starting place is the clojuredocs quick reference

20:44 http://clojuredocs.org/quickref/Clojure%20Core

20:54 TimMc: simard: There's also $findfn.

20:54 $findfn 2 2 4

20:54 lazybot: [clojure.core/unchecked-multiply clojure.core/+ clojure.core/* clojure.core/unchecked-add clojure.core/+' clojure.core/unchecked-multiply-int clojure.core/*' clojure.core/unchecked-add-int]

20:54 TimMc: ...best used in private /msg

20:55 seancorfield: simard: don't forget the Clojure Atlas - a great way to explore the library space! http://clojureatlas.com

20:56 simard: $findfn (1 2 3 4) 2 (1 3)

20:56 lazybot: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn

20:57 TimMc: simard: Try quoting those lists.

20:57 simard: TimMc: right.

20:57 seancorfield: $findfn '(1 2 3 4) 2 '(1 3)

20:57 lazybot: []

20:57 simard: $findfn 2 '(1 2 3 4) '(1 3)

20:57 lazybot: [clojure.core/take-nth]

20:58 simard: there :)

20:58 how does it work ?

20:58 can't be brute force or is it ?

20:58 TimMc: it is!

20:58 alexbaranosky: that's sweet

20:59 simard: very nice

20:59 TimMc: simard: lazybot goes through basically all the sandbox-allowed functions in core.

21:00 You can also get find-fn as a lein add-on or something. The syntax is slightly different, but it works the same way.

21:00 alexbaranosky: I am so fed up with try-cljs. It works differently on kibble than on my local machine.

21:02 qbg: Wow. vector is defined pretty late in core.cljs

21:02 alexbaranosky: TimMc, well it can always chill out on the back burner for a bit

21:02 TimMc: qbg: I guess everything before it uses an RT method?

21:03 qbg: ClojureScript here

21:03 alexbaranosky: dang, Midje is so cool (caveat: imho) and I am constantly surprised how few people have used it... argg!!!

21:03 qbg: LazySeqs and lists come first

21:03 TimMc: qbg: Oh, CLJS, got it.

21:04 qbg: Still, shows that you don't need vector too much

21:04 alexbaranosky: on a related note, have you guys used core.match or core.logic to do anything neat?

21:04 qbg: core.cljs is really beautiful

21:05 simard: cljs ?

21:05 qbg: alexbaranosky: I was going to write a Sudoku solver using core.logic, but got stuck figuring out where to start

21:05 simard: https://github.com/clojure/clojurescript

21:05 simard: no way, that's cool.

21:06 TimMc: simard: Not yet.

21:07 Hasn't even had an alpha release yet, and there are a *lot* of design decisions still to be made.

21:07 Don't get me wrong, I'm excited about it -- but it is a very young project.

21:09 simard: bah I can wait. I was working on a webapp for which the server side ran on clojure and the client side JS + webgl. I found that the JS side was dirty. Hopefully CLJS can reduce the impedance mismatch between the client and the server.

21:10 qbg: You have the reader available at runtime

21:10 Might be useful

21:10 simard: and dangerous :)

21:10 qbg: You don't have eval though

21:11 simard: having the reader is quite cool. that's a whole protocol that needs not be designed.

21:12 (I mean, when replacing a JS client by a CLJS client)

21:12 will it be possible to execute JS code from CLJS ?

21:12 brehaut: simard: do you mean call external JS?

21:13 simard: yes, I mean that. not eval.

21:13 accel: I need some advice. I'm writing a WYSIWYG editor. I want to ahve a var (call it "root") that keeps track of the DOM tree. I know that at times, there are goign to be exceptoions thrown. I want to have a setup of something like this: forever, (if exception, ignore it), then just reload document @ root and continue on. Is this a reasonable appraoch? suggetions?

21:13 alexbaranosky: I think I just wrote a abstract for Clojure/West about TDD with Midje.... but now I'm scared to submit it :)

21:14 qbg: simard: Yes, you can call external js

21:15 accel: What type of exceptions?

21:18 accel: qbg: ones I did not accept

21:18 *expect*

21:19 qbg: Probably want to at least log the exception

21:20 And then during the reload die if another exception occurs to prevent a possible infinite loop

21:20 simard: I'm writing a macro that takes a vector of symbols (not bindings) and a body, what name should I give the vector of symbols ? vars ? syms ?

21:21 choffstein: Hey all. Can anyone provide some idiomatic clojure code for repeatedly polling a database using aleph? I basically want to have a database poll that times out if a background job doesn't post to the database fast enough -- but I can't seem to come up with a good method for repeated polling on the sever side

21:22 amalloy: you should call it whatever the symbols are for

21:22 or syms, if you think that's more useful

21:22 but it's like: "I'm writing a function that accepts some integers, what should I call it?" kinda depends what you do with the ints

21:23 simard: yeah but there's that naming convention for arguments out there, x, y, n, coll, fn, etc..

21:27 brehaut: x and y arent good examples; they have very specific meanings

21:31 qbg: subvec uses v for the vector

21:32 brehaut: functions (and macros) that operate generically on their arguments use generic names. if they operate specifically on their arguments, they more often have specific names

21:35 simard: makes sense. is defstruct still used ?

21:35 brehaut: no defstruct is largely deprecated

21:35 use plain maps or records

21:57 benares_98: Is there any difference between (partial filter odd? x) and (filter odd? x) ?

21:57 brehaut: benares_98: yes, one of them returns afunction the other returns a list

21:57 ,(filter odd? (range 10))

21:58 clojurebot: (1 3 5 7 9)

21:58 brehaut: ,(partial filter odd? (range 10))

21:58 clojurebot: #<core$partial$fn__3796 clojure.core$partial$fn__3796@1f2e6d8>

21:58 brehaut: ,((partial filter odd? (range 10)))

21:58 clojurebot: (1 3 5 7 9)

21:59 brehaut: benares_98: in this case, the partial version is a bit redundant given lazy seqs are only realized on demand anyway

21:59 benares_98: thanks that's what I was thinking, I saw a solution with partial and thought it wasn't necessary

21:59 going through 4clojure

22:00 brehaut: benares_98: presumably the partial is there because the solution called for a function

22:00 benares_98: I thought that too but (filter odd? x) worked too.

22:00 brehaut: i presume someone just did somethng weird then

22:01 benares_98: thanks!

22:01 brehaut: what question btw?

22:01 benares_98: http://www.4clojure.com/problem/25 Find the odd numbers

22:02 brehaut: hah my solution is (partial filter odd?)

22:03 i haven managed to grasp 4clojure solutions as literally putting your solution into the slot in the sexp

22:04 benares_98: yeah I'm still learning the language and I love that there's a website for quiz oriented learning

22:05 simard: benares_98: have a look at project euler, the solutions there often include neat clojure code

22:06 benares_98: Thanks simard!

22:06 brehaut: simard: 4clojure is a better learn clojure resource because its focused on a wide range of things rather than being heavily math oriented

22:08 amalloy: 4clojure is a bit more guided, too. you won't see an euler problem about how to use 'map

22:09 simard: of course not, but it's still great to see solutions 5x shorter as your own :)

22:09 I didn't know about 4clojure.. I'm registering just now, gonna have some fun.

22:10 amalloy: hm, we should add a problem that introduces/teaches 'for, but i don't know how to write such a problem

22:10 accel: I need to be able to catch Java exceptions from clojure land. What should I google to read up on? (URLs are acceptable too.)

22:11 brehaut: http://clojure.org/special_forms#Special%20Forms--(try%20expr*%20catch-clause*%20finally-clause?)

22:11 amalloy: maybe something like "transform the map {a {x 1 y 2} b {p 3 q 4}} into {[a x] 1 [a y] 2 [b p] 3 [b p] 4}, and btw you might want to use 'for"?

22:12 accel: brehaut: noted; thanks

22:12 brehaut: clojure.org is surprisingly concise + useful

22:12 it's like people put thought into writing this documentation

22:12 brehaut: amalloy: ithink you'd want a series; for as map, for as filter, for as cross product

22:13 and disallow map, filter, mapcat, reduce and recur i guess?

22:13 amalloy: brehaut: well, it doesn't have to work that way either. you could be like "here's a for expression, what does it evaluate to"

22:13 brehaut: ah true

22:14 Raynes: accel: Surely not. I usually just slap my keyboard to write docs.

22:14 brehaut: amalloy: what about (for [____] x) ?

22:14 amalloy: interesting

22:15 Raynes: (for [___________________________________] x), more like.

22:15 You should have seen the `for` that amalloy wrote earlier.

22:15 It did everything but fix me breakfast.

22:16 alexbaranosky: Raynes: no breakfast? ... meh

22:16 ;)

22:17 brehaut: Raynes: if your for's dont have the full complement of destructirings and keyword subforms, you arent really putting enough efford into things

22:17 s/bad spelling/good spelling/

22:17 amalloy: brehaut: i actually got all of them into one for! that's why it was so epic

22:17 brehaut: amalloy: when while and let?

22:17 amalloy: https://github.com/flatland/jiraph/blob/502c452e4/src/jiraph/masai_sorted_layer.clj#L83-92 if you want to have a peek

22:17 brehaut: wow

22:17 that is epic

22:18 simard: amalloy: how long has 4clojure been running ?

22:18 amalloy: simard: since april, i think?

22:18 simard: nice initiative

22:18 brehaut: amalloy: what is a masai layer?

22:19 amalloy: brehaut: an implementation of a jiraph backend

22:19 (using masai)

22:19 brehaut: ah so masai is a db ?

22:19 amalloy: masai is another thing ninjudd wrote

22:19 brehaut: right

22:19 amalloy: it's an interface to a k/v datastore

22:20 with a number of actual implementations

22:21 there's backends for redis, tokyocabinet, and memcache, though i don't know how many of them actually work since the only one we use is tokyo

22:21 Raynes: Uh!

22:22 He didn't write that whole thing, ya know.

22:22 brehaut: Raynes: you are too young to be allowed to get credit for things

22:22 its embarassing for the rest of us

22:22 amalloy: Raynes: oh, i didn't know you were involved with masai

22:23 Raynes: amalloy: I did the redis impl. It was my first project at Geni.

22:23 amalloy: nice

22:23 that sounds familiar now but i'd forgotten

22:23 Raynes: It was before you got there.

22:23 I imagine I talked to you about it though.

22:23 amalloy: right

22:24 Raynes: I also rewrote the tests.

22:24 I emphasize that because you say I never write tests.

22:24 :>

22:25 amalloy: brehaut: i was thinking of creating the same value with several different for-expressions. all the odd numbers, maybe? but it's really hard to get the "iterate over N sequences nested-wise" worked into that

22:26 simard: I'd like to do something like that: (and (map contains? (repeat a-map) [map? :type :unit :val]))

22:26 of course, I need to apply and to the map, which won't work

22:26 is there a neat way to do that ?

22:26 amalloy: (every? #(contains? a-map %) [...])

22:27 or if you don't have any nil/false values, you can do (every? a-map [...])

22:28 brehaut: amalloy: i think id still want to split for stuff into two chunks: all the basic mechanics it provides, nested stuff

22:28 some sort of nondeterministic search might be nice

22:28 amalloy: ah, that's nice. then to cover just the nested-ness, my earlier thing about nested maps is good

22:28 brehaut: like what?

22:29 brehaut: amalloy: im trying to think of a suitable small example.

22:29 actually, i think nesting is probably a seperate challenge to nondeterministic search

22:33 ,(for [:let [a [1 2 3]] b a] b)

22:33 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Can't pop empty vector>

22:33 brehaut: ,(for [_ [1] :let [a [1 2 3]] b a] b)

22:33 clojurebot: (1 2 3)

22:33 brehaut: does that seem like a bug to anyone else?

22:34 qbg: Yeah, that seems like a bug

22:35 brehaut: time to brave the jira i guess

22:35 amalloy: huh?

22:35 that seems like obviously-correct behavior

22:35 brehaut: amalloy: that you cant :let at the top of a for?

22:35 amalloy: oh, i missed the exception

22:35 no, i agree, it would be nice if you could :let

22:36 but there's also no particular reason to be able to

22:36 qbg: :let seems a bit weird being first, but whatever

22:36 brehaut: well, no you could just wrap the for in a let

22:36 but never the less

22:36 qbg: Do not look at the implementation of for with remaining mind

22:37 amalloy: yeah, it's...pretty hairy

22:37 even looking at the macroexpansion of a 'for is not for the faint of heart

22:37 brehaut: hehe

22:38 oh well

22:38 amalloy: &(macroexpand-1 '(for [x (range 10) :when (even? x) y [5]] [x y]))

22:38 lazybot: ⇒ (clojure.core/let [iter__4191__auto__ (clojure.core/fn iter__15951 [s__15952] (clojure.core/lazy-seq (clojure.core/loop [s__15952 s__15952] (clojure.core/when-first [x s__15952] (if (even? x) (clojure.core/let [iterys__4187__auto__ (clojure.core/fn iter__15953 [s__... https://gist.github.com/1508809

22:38 brehaut: if i really need it, i know i can fall back on (domonad sequence-m …) ;)

22:38 amalloy: haha

22:40 qbg: Explaining monads is easier than explaining how for is implemented

22:40 brehaut: (= :magic :magic)

22:40 ,(= :magic :magic)

22:40 clojurebot: true

22:41 brehaut: nope, looks equivalent to me

22:41 qbg: dnolan wrote a logic program that derives magic, and ran it backwards to get for.

22:41 brehaut: lol

22:46 amalloy: brehaut: http://www.4clojure.com/problem/145 is my intro-to-for

22:48 brehaut: aha thats nice ;)

22:49 amalloy: aha you also kicked my arse for golfing it too :P

22:49 amalloy: *chuckle*

22:59 brehaut: also approved someone's submission at http://www.4clojure.com/problem/144 while i was at it. solve those dang problems, guys!

23:00 brehaut: amalloy: im sure theres a suitable dice or cards or simple game board search that would be good for an advanced search with for problem but i cant think of one right now

23:08 amalloy: thats a nice problem

23:19 accel: is there a way I can create a timer object that expires when a particular JFrame is closed?

23:20 _how_ can I create a timer object that expires when a particular JFrame is closed? (an answer of "yes" is rather useless :-D )

23:20 minikomi: Hi there

23:21 having a little trouble with vimclojure .. the syntax hilighting is going ok but the nailgun server is giving me a couple of errors

23:22 Unable to resolve symbol: special-form-anchor in this context,

23:23 accel: vimclojure is doing lots of weird things for me too

23:23 minikomi: :)

23:23 accel: like when I hit o to open a new line, it clears my copy/yank buffers

23:23 indenting is also very slow

23:23 minikomi: theres a lot of information but I'm not sure which is the most up to date

23:24 accel: so far; I have found the best way be just keeping another clojure repl open

23:24 it's surprisingly effective

23:24 minikomi: ah

23:24 i have used the slime/screen hack with ruby and python

23:24 or do you just copy paste between?

23:26 accel: i don't copy/paste

23:26 amalloy: accel: add a WindowListener to the frame, that cancels the timer on close?

23:26 accel: I just do (load-file "blahblah.clj")

23:27 minikomi: ah

23:28 accel: then, I use (doc ...) to get documentation in the repl

23:28 use the repl to get the satck traces

23:28 and most imporatntly; when I get stuck; I write long deatiled posts of exactly what I'm trying / waht is working / what is not working

23:28 until someone uch smatter in #clojure decides I'm cluttering up the channel, and helps me out. :-)

23:28 minikomi: haha

23:29 i'm interested in learning a lisp-ish language but getting a working toolchain is a bit of a hassle .. such is the nature with new things I guess!

23:30 accel: the toolchain is overated

23:31 amalloy: http://docs.oracle.com/javase/1.5.0/docs/api/javax/swing/Timer.html <-- interesting; so there is one thread that keeps track of all the timers; but all the timers are eecuted in the Swing TUI thread? I guess it makes sense to allow all the updates to happen; this is knd of cool.

23:32 This is the timer I want to use. http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html . Is there a way to say "kill all existing timers?

23:35 amalloy: brehaut: just finished writing up the problem i proposed earlier: "transform the map {a {x 1 y 2} b {p 3 q 4}} into {[a x] 1 [a y] 2 [b p] 3 [b p] 4}, and btw you might want to use 'for". can't think of a good title for it, though

23:38 hiredman: accel: the cools kids use scheduledthreadpoolexecutors

23:39 http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html has a shutdownNow method

23:40 brehaut: java.util.concurrent is just jammed full of cool classes

23:42 amalloy: thats boggling my brain :P

23:44 accel: hiredman: does ScheduledThreadPoolExecutor have hiredman's seal of approval?

23:45 hiredman: is the difference between FixedRate & FixedDelay that: (1) FixedRate does NOT drift and (2) FixedDelay drifts ?

23:49 hiredman: accel: actually I am not sure, but I believe fixedrate tasks can end up running at the same time if you take longer than the period, while fixed delay tasks wait for the delay after termination for executing again

23:55 accel: hiredman: so I'm reading http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html and I don't see a promise anywhere that says "when this object is GC-ed, shutdown is automatically called on it. Is this implied somewhere, or can I not make this assumptino?"

23:57 hiredman: accel: why would you assume that?

23:58 Raynes: &(reduce #(if ((set %) %2) % (conj % %2)) [] [1 1 2 1 3 2 3 3])

23:58 lazybot: ⇒ [1 2 3]

23:58 accel: In C++, when objects are freed; their desructors are called; I extrapolate it to in Java, when objects are GC-ed, they should "clean up"; it seems like for a thread pool to clean up; it should shutdown all its threads.

Logging service provided by n01se.net