#clojure log - Oct 13 2012

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

0:17 Sgeo: ivan, I think something like that already happened. So few new programmers capable of programming COBOL.

0:20 tomoj: I hope fn-> and fn->> appear along with cond->

0:20 Sgeo: What would fn-> and fn->> do?

0:21 Also, I still want the thing that I called let->

0:21 tomoj: well

0:22 (defmacro fn-> [& forms] `#(-> % ~@forms))

0:22 but

0:22 I guess #(-> %) is is OK

0:22 Sgeo: Ah

0:23 So, a macro that essentially does what comp does?

0:23 In reverse?

0:23 Except works with macros and never needing #() I guess

0:23 I guess it's the thrust vs -> debate again

0:24 tomoj: (fn-> (rename-keys kmap))

0:25 I went with #(rename-keys % kmap) instead

0:25 for some reason #,% seem like eyesores to me

0:25 Sgeo: I don't know if your definition of fn-> might conflict with using #() inside the form, but that's easy to fix by using fn and an autogensym

0:26 ivan: gah Java has no NullOutputStream built in?

0:26 Sgeo: (defmacro fn-> [& forms] `(fn [arg#] arg# ~@forms))

0:26 Erm, oops deleted the ->

0:27 (defmacro fn-> [& forms] `(fn [arg#] (-> arg# ~@forms)))

0:27 tomoj: yeah, it seems to break otherwise

0:28 strangely it doesn't cause an error

0:29 wait, no, it seems to work

0:53 aperiodic: what? it totally breaks without the gensym

0:53 you can't have fully-qualified symbols as parameters

0:57 Sgeo: I think I'm beginning to see a rationale behind the behavior of symbols in Clojure: It's slightly creepy for symbols to have magic information added to them on read

1:08 amalloy: ivan: welcome to the glory of java.io

1:09 classes instead of interfaces, inheritance instead of composition, and no useful primitives

1:10 Sgeo: using #() in a macro won't affect users of the macro, because #() is a reader macro

1:10 tomoj: aperiodic: hmm

1:10 ivan: anyone have some sort of Clojure thing to black-hole *out*?

1:10 tomoj: ,(defmacro fn-> [& forms] `#(-> % ~@forms))

1:10 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

1:11 Sgeo: amalloy, ah, ok

1:11 tomoj: well, (= (macroexpand-1 '(fn-> inc)) (fn* [p1__5906__5907__auto__] (clojure.core/-> p1__5906__5907__auto__ inc)))

1:11 ivan: I guess I have to write a proxy if I want it in Clojure

1:11 Sgeo: black-hole?

1:12 tomoj: hmm

1:12 (= (macroexpand-1 '(fn-> #(%))) (fn* [p1__5906__5907__auto__] (clojure.core/-> p1__5906__5907__auto__ (fn* [p1__5923#] (p1__5923#)))))

1:16 Sgeo: Um.

1:16 Does ClojureScript not have promises?

1:17 amalloy: Sgeo: who would deliver to them while you block the only thread waiting?

1:17 Sgeo: Could wait for one after it's delivered. e.g. using a promise to give an event handler the key to unregistering it

1:19 tomoj: in (let [a 3 b 4]), are the bindings ([a 3] [b 4]) or (a b)? what's the other one called?

1:19 amalloy: so? if you never block on it, a promise is just an atom that you only write to once; easily implementable yourself without language support

1:20 Raynes: ivan: https://www.refheap.com/paste/5065 something like this

1:20 Not sure what class you have to proxy, but this is what it would look like.

1:20 Sgeo: I guess promises seem more semantically accurate somehow, or I'm used to thinking about the answer to that question in terms of promises

1:21 tomoj: you have to cps

1:24 hmm

1:24 so you would prefer (cps (let [x @async-promise] (+ x 3))) ?

1:25 to, say, (cps (let [x async-promise] (+ x 3)))

1:25 ivan: Raynes: cool, thanks a lot

1:25 tomoj: I was looking at http://taskjs.org/

1:26 you have to explicitly yield (is that the opposite of deref?) for an async value

1:26 can't decide whether that's good or bad

1:26 ivan: explict yields reveal switch points which is good if you want your programs to work

1:26 tomoj: switch points?

1:26 ivan: some mutable state could change between yields

1:27 bad #python terminology I'm reusing

1:27 tomoj: mutable state? :P

1:27 ivan: =)

1:27 tomoj: the point is to get rid of that..

1:27 Sgeo: I think, as long as I can call some function that itself does yields, and expect it to work from within my own generator, I'm happy

1:28 tomoj: I haven't figured out yet whether task.js is sufficiently composable

1:28 Sgeo: I don't like the non-composibility I've been exposed to, where I can't abstract some lines that use yield into a function

1:31 Hmm, I don't have access to defmacro in Himera.... darn

1:31 Well, that makes sense, because there's no defmacro in ClojureScript

1:31 But that means I don't see a way to get the server to run arbitrary code >:(

1:42 shachaf: ivan: You're alive?

1:49 tomoj: if Named were a protocol, should java.util.UUID satisfy it?

1:50 ivan: shachaf: I'm alive

1:50 shachaf: Weird.

1:50 * ivan checks for hitmen

1:52 shachaf: Are you still in that place which isn't the bay area?

1:52 ivan: yep

1:53 shachaf: You should instead try being in that place which is the bay area.

1:53 You should go to edwardk's talk next week!

1:54 * ivan tries to locate this edwardk

1:54 tomoj: the incanter one?

2:25 bfreis: Hello, I've just posted a question on SO, I'd be glad if anyone could take a look and give a hand! http://stackoverflow.com/questions/12870437/override-drop-for-a-custom-sequence

2:26 In short, I'm writing a custom seq that could be slow because it reads data (lazily) from disk, and I want to reimplement drop in a way that would avoid unecessary reads.

2:30 brainproxy: one of my deps is pulling in an older version of clj-stacktrace, but I can't figure out which one :/

2:31 is there a way to have `lein deps` spit out more verbose info, i.e. so you can figure out which dep is responsible for triggering a download/install

2:34 tomoj: bfreis: strange, my implementation of drop seems to call more

2:36 bfreis: tomoj: indeed, I've just checked core.clj and (drop) does call (rest), which calls (more). But I'm not sure I understand what you mean.

2:36 tomoj: I mean, my implementation of (more) calls (next), which will cause unecessary reads.

2:37 tomoj: yeah

2:37 bfreis: Oh, I see your point.

2:37 tomoj: the answer is "no"

2:37 bfreis: I could reimplement more in a way that it does not call next

2:38 more would just drop cached items and increment the counter

2:38 brilliant

2:38 thanks!

2:38 tomoj: oh

2:38 but it still will be O(n), yes?

2:38 bfreis: Yes

2:39 Could be better, but this is already way better than the first workaround I could figure out.

2:39 I will update the question

2:39 tomoj: isn't that what your next already does?

2:40 bfreis: My next reads data into the cache if necessary

2:40 Oh, crap

2:40 It won't work!

2:40 If I (first (drop dataseq)), there would need to be some data available in the cache

2:41 Damn, back to the original problem of my first workaround: I'd need some mutable state: a mutable cache to be populated by the first call to (first)

2:41 tomoj: well, you can return a lazy-seq ?

2:42 bfreis: Hmmm, would that help? How would that be different?

2:42 tomoj: ,(doc lazy-seq)

2:42 bfreis: You mean, replace load-data by something like (defn load-data [id] (lazy-seq .....))

2:42 clojurebot: "([& body]); Takes a body of expressions that returns an ISeq or nil, and yields a Seqable object that will invoke the body only the first time seq is called, and will cache the result and return it on all subsequent seq calls. See also - realized?"

2:42 tomoj: no, put the next impl in more but wrap it in lazy-seq

2:43 then make next (seq (.more this))

2:43 I think

2:43 but really, you should be building an IChunkedSeq I think

2:43 (if a seq at all..)

2:44 bfreis: But wouldn't that still have the same problem? A call to drop would just call more many times, reaching the "end" of the cache and causing a new read from the disk.

2:44 tomoj: the body of the (lazy-seq) is only evaluated when needed

2:44 bfreis: An IChunkedSeq? Hmmm, I think that could be worse: it could potentially cause unecessary reads

2:45 (I'm trying to avoid reads because: if I read too little data, it is fast, but many small reads is much much slower than a big read; therefore I'm doing big reads, which are slow, and I'd like to avoid if not needed)

2:45 tomoj: I don't see why, you're already chunking

2:46 bfreis: Yes, but I'm controlling very precisely how I chunk my data

2:46 tomoj: that's what the IChunkedSeq interface would let you do

2:46 maybe I'm confused

2:46 bfreis: Hmmm, I will take a look at it

2:47 You said "if a seq at all", do you have another suggestion?

2:47 I like it being a seq because I'm processing it with map, filter, partition-by, etc

2:47 tomoj: I was thinking of reducers

2:47 but I don't think partition-by has been implemented

2:47 bfreis: reducers? o.O

2:47 tomoj: and might not fit

2:47 bfreis: What is that?

2:48 I don't think I've ever read about it!

2:48 tomoj: http://clojure.com/blog/2012/05/08/reducers-a-library-and-model-for-collection-processing.html

2:48 http://clojure.com/blog/2012/05/15/anatomy-of-reducer.html

2:48 what are you doing with the seq?

2:49 bfreis: interesting! but I'm not sure it fits

2:50 I'm filtering the data, I'm producing derived data by partitioning the original sequence and reducing the partitions

2:50 tomoj: well

2:50 sounds like a good fit for reducers to me

2:50 except http://dev.clojure.org/jira/browse/CLJ-991

2:50 bfreis: :)

2:50 damn

2:51 I see that reducers do things with fork/join

2:51 ie, in parallel

2:51 tomoj: those are called folders

2:51 bfreis: Would that help? I mean, I'm mostly IO bound

2:51 oh

2:52 tomoj: but "reducers" I guess can mean "reducers and folders"

2:52 bfreis: oh, I see

2:52 tomoj: a reducer can be a good fit for IO because (unlike folders) it's a one-shot thing

2:53 you make one reduce call to the reducer you built up with the IO reducer at the bottom, and it can e.g. open a file, make a pass through the data, then close it, then your reduce returns

2:54 if you really want a seq, maybe seque could make your impl easier?

2:54 bfreis: hmmm, looks interesting, I will certainly take a look at reducers

2:54 seque? never heard of it!

2:54 ,(doc seque)

2:54 clojurebot: "([s] [n-or-q s]); Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer."

2:55 tomoj: not sure that helps, but it sounds vaguely similar to what you're doing

2:55 bfreis: indeed, good to know it exists, but I still think it wouldn't solve everything

2:56 As I understand it, it would still need to read all the file

2:56 tomoj: your IndexedSeq has to read all the file, right?

2:57 bfreis: So, the reading would either: fill up my memory, or block until I read from que BlockingQueue to free some space

2:57 Not necessarily, depends on how I will process it. Sometimes, yes, I need to fully read the file. Sometimes, no, I just want to drop a lot of data, process some data, drop more data, etc

2:58 tomoj: but doesn't your drop impl read everything as it goes?

2:58 bfreis: No, it would jump right to the position it would need to read

2:59 (note that I'm not using an InputStream to read data, but a memory mapped file)

3:00 tomoj: how? more only steps through one at a time

3:00 bfreis: I mean, *if* I could override the default implementation of drop

3:00 tomoj: right, you can't :)

3:00 bfreis: damn :)

3:02 well, I've got only two options left: to provide a (fast-drop [dataseq]) function, or to make my DataSeq even lazier, as I wrote on SO

3:02 but I'd need to deal with mutable state, which I've never done in clojure

3:02 (actually, I've tried it a bit, but in other contexts)

3:03 tomoj, do you know if there's a reason we can't override drop?

3:03 I mean, it is obvious that it can't be overriden, just by looking at core.clj

3:04 But do you have an idea why this has been implemented that way, and not like (seq), (first), (next), etc?

3:04 Is what I'm looking for *THAT* unusual?

3:04 tomoj: would you rather there be an IDrop interface?

3:04 bfreis: Exactly!

3:05 Just like there's clojure.lang.Counted, which provides count()

3:09 tomoj: I don't think I can explain why that isn't the case

3:09 bfreis: There could be an IDrop interface, then drop (in clojure.core) would call RT.drop, which would check if the instance implements IDrop then call that method, otherwise would fallback to the default implementation that calls more n times

3:09 tomoj: except with a slippery slope argument :/

3:09 bfreis: :P

3:10 tomoj: it looks like IChunkedSeq won't work in place of IndexedSeq either

3:10 since drop isn't chunk-aware

3:10 seems like it should be

3:10 if it were you could have a chunked seq of counted chunks

3:11 bfreis: indeed

3:11 tomoj: and drop could just skip over chunks and they'd never be read

3:11 bfreis: but the thing is:

3:11 I could have a chunked sequence built from "iterate". In this case, the intermediate, thrown away, elements, might need to be built

3:12 Imagine a chunked version of the canonical implementation of fibonacci sequence using iterate

3:12 (or something similar, but in which chunks make more sense)

3:13 (map first (iterate (fn [[a b]] [b (+ a b)] [0 1]))

3:13 (drop 1000000 fibs), that would need to calculate all the dropped fibs

3:14 tomoj: some chunked seqs might behave that way, but not all

3:14 bfreis: yes

3:15 The one that started this discussion would tremendously benefit from drop being chunk-aware

3:17 tomoj: anyway I think reducers would be a good fit, but you'd need to copy the partition-by from the patch above. and defcurried and rfn from clojure probably, since they're private >:[. oh and reducers are only in 1.5.0-alpha4

3:17 er, alpha6 is the latest

3:20 well, drop might still be problematic with reducers

3:21 yeah, I think r/drop still would force reading everything

3:21 bfreis: :/

3:22 Do you think Rich would consider adding IDrop, RT.drop and modifying (drop), so that it would be similar to how (count) is implemented?

3:22 *Rick

3:22 RichHickey

3:22 damn

3:22 tomoj: I would bet $50 he wouldn't

3:23 bfreis: :P

3:23 tomoj: (and I make $20K)

3:23 bfreis: lol

3:23 tomoj: but I think a patch to make drop chunk-aware could happen

3:24 bfreis: hmmmm

3:25 And what's the standard way to suggest this?

3:25 Is there any official "wish list"?

3:29 brainproxy: bfreis: the google discussion group

3:30 bfreis: brainproxy: thanks!

3:30 brainproxy: np

4:18 amalloy: it sounds like bfreis doesn't want to implement a seq, but something that's Indexed and just call nth on it for items he decides he actually wants

4:18 bfreis: amalloy: I usually do want a seq -- I process the data sequentially

4:19 amalloy: no you don't. you skip over it with drop

4:20 bfreis: sorry, amalloy, it is not you who is processing the data, it is me.

4:20 Trust me: I'm telling you I process the data as a whole some times, and parts of it other times.

4:21 I experimented with nth, but opening a file, reading 3 bytes and closing it becomes very slow when you need more than a few entries -- especially if I need sequential entries, which, again, believe me, is what I need.

4:22 (and to be clear, when I say "parts of it" I mean: long runs of sequential data, not necessarily in the beginning of the file)

4:25 Seriously, I hate when people act as they know what I'm doing more then I know what I'm doing.

4:38 samrat: I need to store username/password in a Noir session. What is the most secure way to do this?

4:38 just to be clear, the password is for another application's APi

4:41 bfreis: samrat: the decision on how to store that credentials depends on what you are trying to protect from.

4:42 For instance, you could have a hardcoded "master key" to encrypt the credentials, and store that in a database. Then you read and decrypt it whenever you need.

4:42 That way, if someone hacks into your database, the password won't be readable.

4:42 However, if they have access to the source code (or the compiled code as well), they can obtain the master password.

4:43 You could store that master key it into a file, but again, if they have access to the file, security is gone.

4:44 You could have your application ask for the password at startup, so it would only be stored on your head. But I doubt you would like to type it everytime you launch your application

4:44 (and, to be clear, there's still the possibility to read the password from memory)

4:45 Anyways, the decision depends on what you are trying to protect from.

4:46 samrat: bfreis: I'd like to have a hardcoded master key, what are my options?

4:47 noir does provide noir.util.crypt but that just provides an option to compare against a raw password, and not fully decrypt it

4:47 bfreis: samrat: (def master-key "my-m4st3r-k3y")

4:47 oh, I don't know noir.util.crypt

4:47 I'm talking about general approachs to this kind of problem

4:47 samrat: bfreis: ok

4:48 do tell about the general approach

4:49 bfreis: Another option is to have a different key per user: you generate a random key and store it along with the user information. But again, if this key is stolen, the encryption is useless.

4:49 You could encrypt the passwords with a combination of a master-key (either hardcoded, or typed on startup) and this random key.

4:50 You could also avoid saving this user-key by deriving the key from the user data.

4:50 samrat: bfreis: any recommendations on encrypting libraries?

4:50 bfreis: Well, you have tons of options there, the decision really depends on the threats.

4:50 samrat: javax.crypto already has a lot of useful classes

4:51 samrat: if you need something else which is not provided in the standard distribution (for instance, GCM), you could try BouncyCastle

4:53 http://www.bouncycastle.org/java.html

4:53 http://www.bouncycastle.org/java.html

4:53 But usually javax.crypto is enough

4:55 samrat: bfreis: is javax.crypto included in the standard distribution?

4:56 bfreis: samrat: yes

4:57 In the book Programming Clojure, the authors use it to create a "crypto vault"

4:57 someone published a lib based on that: https://github.com/midpeter444/crypto-vault

5:02 samrat: bfreis: I think I'll try using this https://github.com/macourtney/clj-crypto. crypto-vault seems to be specific to file encrypting

5:03 bfreis: Didn't know clj-crypto, looks interesting.

5:04 It is a wrapper around on javax.crypto, using the BouncyCastle provider (I don't know why, apparently it could use the standard, built-in JCE) -- but I might have missed something

5:05 samrat: bfreis: I'll try it... but there's absolutely no docs, so might be a pain

5:07 bfreis: Oh

5:07 be careful, though

5:07 You will be doing symmetric encryption for this

5:08 And that library uses DES as the standard algorithm

5:08 But DES is considered very insecure nowadays

5:10 Furthermore, he doesn't specify the mode and padding, therefore it should be DES/ECB/PCKS5Padding, which means: it is weak.

5:11 samrat: bfreis: yeah... I think it breaks with 1.4 or something, not working for me(it depends on 1.2)

5:12 any other wrappers for javax.crypto? I don't want to have to deal with java

5:14 bfreis: Sorry, I don't know. I haven't done much crypto in clojure, and when I did, I just used javax.crypto.

5:34 tomoj: just posted the version of DataSeq using a mutable local cache updated by first to stop drop from reading from the disk!

5:34 http://stackoverflow.com/a/12871794/150339

5:40 samrat: how do I find the data type of something in clojurescript? (class ...) doesn't seem to work

5:48 bfreis: samrat: it looks like you'd profit from reading this http://blogs.msdn.com/b/ericlippert/archive/2011/09/27/keep-it-secret-keep-it-safe.aspx

5:48 (I just came across that article and thought about what you are trying to do)

5:49 it is a little bit long, but worth the time, from Eric Lipert

5:54 samrat: bfreis: thanks, will go through it

8:26 uvtc: ,(apply + 1 2 3)

8:26 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

8:26 uvtc: ,(apply + 1 2 3 nil)

8:26 clojurebot: 6

8:26 uvtc: Why does that second one work?

8:26 There's still no seq to unpack (the contents of which `+` is applied to).

8:34 terom: ,(apply + 1 2 3 '())

8:34 clojurebot: 6

8:35 ssideris: hello. In clojurescript, do we throw exceptions as normal?

8:35 I guess one has to stick to the Exception class

8:36 because IllegalArgumentException does not exist

8:36 correct?

8:36 andrewmcveigh: uvtc: because apply calls 'seq', and (seq nil) => nil ?

8:36 ,(seq nil)

8:36 clojurebot: nil

8:37 terom: uvtc: only the last arg to apply should be a seq, other args before it are "added" to that seq: http://clojuredocs.org/clojure_core/clojure.core/apply#example_520

8:38 uvtc: terom: right, I understand that. But I was under the impression that the last arg must be a coll.

8:39 AdmiralBumbleBee: uvtc: as far as I understand it, nil can be used anywhere a collection can (with obvious exceptions)

8:39 ,(concat [1 2 3] nil)

8:39 clojurebot: (1 2 3)

8:39 uvtc: In the source for `apply`, I see that call to `list*`.

8:40 ,(list* 1 nil)

8:40 clojurebot: (1)

8:40 uvtc: So, that's it I suppose.

8:41 ...since `list*` calls `cons`, and `cons` seems happy to cons onto `nil`.

8:41 ,(cons 1 [1 2 3])

8:41 clojurebot: (1 1 2 3)

8:41 uvtc: ,(cons 1 nil)

8:41 clojurebot: (1)

8:42 uvtc: AdmiralBumbleBee: That sounds odd. If it's the case, I wonder why that is.

8:44 AdmiralBumbleBee: uvtc: I'm not sure why at all, but I noticed it and so I tried lots of permutations of it and it seems to be practically correct… if not technically correct

9:13 nonrecursive: I'm trying to use weavejester's ragtime library but I keep getting this error: Exception in thread "main" java.lang.RuntimeException: java.lang.NoClassDefFoundError: clojure/lang/ILookupHost

9:13 has anyone seen that? know how to fix it?

9:23 wting: Hi, can someone explain how this returns the last element of a list? reduce #(-> %2)

9:25 babilen: wting: It always returns the second argument to the function that is reduced with. That argument is the current element (the first is the accumulator/result) to which "f" is applied

9:26 wting: I would use (last coll) though ;)

9:27 wting: babilen: Thanks, doing 4clojure koans and last isn't allowed. :p

9:27 The goal was to recreate last.

9:27 babilen: wting: Ah, sure. In that case: Have fun!

9:28 nonrecursive: How would I modify my project's dependencies so that I can debug an issue? For example, I'm using ragtime and would like to throw some println statements in it, but I don't know where the code is actually located

9:29 babilen: nonrecursive: You mean "throw some println statements [into ragtime]" ?

9:30 nonrecursive: yeah

9:30 exactly :)

9:32 babilen: nonrecursive: If you use leiningen 1 you'll find dependencies in PROJECT/lib and if you use leiningen 2 you would find it in ~/.m2/repository/ -- You cannot edit those directly though. I would personalyl recommend to just get hold of ragtime, make your changes and "install" it with "lein install" to ~/.m2/ (if you use lein2)

9:32 nonrecursive: That assumes that ragtime doesn't provide any debug/loggin facilities itself that you can enable (e.g. by setting a dynamic variable somewhere in its namespace)

9:32 nonrecursive: babilen: thanks, that helps a lot. I'm using leiningen 2 - I'll try what you described

9:33 babilen: nonrecursive: ragtime is probably on github ... create a new local branch (e.g. dev/debug or whatev) so you can hack away. You might even want to change the version so you don't (by mistake) pick up the original.

9:34 nonrecursive: babilen: yeah it's on github - thanks for the tips

11:35 ticking: I was wondering what is the best way to append elements to a seq?

11:37 dnolen: ticking: concat, which is lazy.

11:37 ,(concat '(1 2 3) '(4 5 6))

11:37 clojurebot: (1 2 3 4 5 ...)

11:44 ticking: dnolen, thanks :) still kinda meh that one has to wrap the value first ;)

11:45 ddeaguiar: ticking: use cons if appending single value? Though that won't return a lazy seq.

11:46 dnolen: ddeaguiar: cons on a seq will add to the front

11:46 ticking: ddeaguiar, and conj will add to the front or back depending on the collection type

11:46 ddeaguiar: dnolen: ah yes,

11:46 ticking: (which drove me almost mad during debugging)

11:46 dnolen: ticking: or something else entirely.

11:46 ticking: dnolen, right ^^

11:47 dnolen: ticking: since you conj on a set or a hash map too

11:49 ticking: thanks and see you :D

12:34 Bronsa: https://github.com/Bronsa/blind a complete clojure reader implemented in clojure

12:34 based on clojure's implementation and clojurescript's

13:14 lynaghk: ping: alex_baranosky

13:15 alex_baranosky: pong: lynaghk

13:15 :)

13:16 lynaghk: alex_baranosky: have any tips on how to speed up midje? I'm using 1.4.0 under lein2 with the lein-midje 2.0.0-SNAPSHOT

13:16 alex_baranosky: I'm getting the sense that it loads every dep in every namespace rather than just what's required by stuff in the test/ dir

13:17 alex_baranosky: speed up Midje on a per assertion basis?

13:17 lynaghk: alex_baranosky: nah, just the startup. I just threw it into this project and have two assertions

13:17 alex_baranosky: or speed up the load time?

13:18 your sense is correct: https://github.com/marick/lein-midje/blob/master/src/leiningen/midje.clj#L119

13:19 the reason is, I think, that some users put assertions in their source???

13:19 lazybot: alex_baranosky: How could that be wrong?

13:19 lynaghk: alex_baranosky: okay, fair enough. I'll look into the lazytest solution then---is that still what's what? Sierra's project looks very unmaintained

13:20 alex_baranosky: the issue could be resolved by adding a option to only load the test-path

13:21 lynaghk: regarding lazy test…. not sure what's going on with that . I don't use it myself

13:21 lynaghk: alex_baranosky: you just run "lein midje" manually?

13:22 alex_baranosky: lynaghk: there's a midge mode that could probably help your situation too

13:22 lynaghk: alex_baranosky: yeah, I was thinking maybe I'd just primarily run tests from within emacs/swank

13:23 alex_baranosky: thanks for the info!

13:24 alex_baranosky: lynaghk: yeah try that, and if it doesn't work out, a pull request to lein-midje to narrow the namespaces loaded could be good

13:24 lynaghk: alex_baranosky: okay, can do.

13:26 alex_baranosky: lynaghk: it also looks like if you specify a namespace wilcdcard you'll avoid the issue

13:26 lynaghk: try this `lein midje my.project.test.*` (see: https://github.com/marick/lein-midje/blob/master/src/leiningen/midje.clj#L133)

13:27 Bronsa: http://sprunge.us/KXEe?clj is this expected behaviour or is it a bug?

13:28 lynaghk: alex_baranosky: yeah, that's the first thing I tried but it didn't pick up my test

13:28 alex_baranosky: test is in /test/ccplot/t_compile.clj; namespace is ccplot.t-compile

13:28 alex_baranosky: lynaghk: dang. I wonder if there's a bug in it. The lein-midje stuff isn't tested (which I hate)

13:28 lynaghk: alex_baranosky: running "lein midje ccplot.*" doesn't find any facts

13:29 alex_baranosky: what about `lein midje ccplot.t_compile` ?

13:30 lynaghk: alex_baranosky: yep, that works

13:31 alex_baranosky: lynaghk: ….. so something's a-rye with the wildcard code

13:32 lynaghk: it should be getting the namespace-on-classpath, using multitude. (https://github.com/marick/lein-midje/blob/master/src/leiningen/midje.clj#L88)

13:32 ok have to go. Let me know if you have any more questions. Take it easy.

13:32 lynaghk: alex_baranosky: okay. thanks

13:33 alex_baranosky: I'll open a ticket.

13:33 alex_baranosky: lynaghk: oh, and any fixes or improvements are welcome

13:50 rhickey: draft of the results from yesterday's cond-> discussion: https://gist.github.com/3885504

14:54 zerokarmaleft: rhickey: in let->, expr and forms needs to match ~init and steps

15:07 tgoossens: if i have two lists. Is there a "built-in" way to check if those two lists have overlapping elements?

15:09 egghead: tgoossens: if they are sets you can use intersection

15:09 frozenlock: If you don't mind using sets, there's quite a few interesting functions.

15:09 Aww

15:09 tgoossens: they are sets. But i'm also interested in the "general" way for a list

15:11 frozenlock: I was sure that 'if' would not evalutate before it needed to, but I have an 'if' function that lookups in a database even if it only needs to go to the else statement.

15:11 How can I avoid evaluation?

15:12 ChongLi: you can't do it with a function

15:13 you need a macro

15:13 egghead: (if true (println true) (println false)) <-- in that you're saying the 'println false' is evaluating?

15:13 frozenlock: yeah

15:14 More precisely: (if login (query-database-for-stuff) (print-some-msg))

15:14 And in my case even if login is false, the database is queried. (and throws an error)

15:16 egghead: weird, according to the clojure docs if shouldn't evaluate the "then" form if the value of the test is falsy

15:18 frozenlock: That was my original impression too.

15:19 egghead: also tgoossens you can filter down any one list by whether or not each member is within the other list using filter and contains? -- probably not super effecient tho :p

15:20 ChongLi: he's talking about an 'if' function

15:20 egghead: err wait

15:20 raek: frozenlock: are you sure 'login' really is false?

15:20 ChongLi: that presumably he wrote

15:20 egghead: contains wouldn't work

15:20 ChongLi: the real 'if' is not a function

15:21 rhickey: zerokarmaleft: thanks, hasty rename before gifting - fixed

15:21 gisting

15:21 frozenlock: raek: I am, I've hardwritten false in it. Let me try to get a minimum working example...

15:23 KaOSoFt: rhickey, sorry to hijack, but any reason there a “reduce1” function? Sorry, I’m new to Clojure, but found it weird to find a “reduce1” function inside +, -, etc.

15:24 there is*

15:25 ChongLi: it's used internally before protocols are up and running

15:25 rhickey: KaOSoFt: reduce gets redefined mid bootstrap

15:27 frozenlock: Damnit. I'm such an idiot.

15:27 Let see if you can see it too :P https://www.refheap.com/paste/5826

15:28 ChongLi: I will probably have to make a macro as you suggested

15:30 Cubic: Why is [] true and (seq []) false? I find this somewhat confusing.

15:31 ChongLi: everything is true except nil or false

15:31 seq returns false

15:32 Cubic: ,(println (seq []))

15:32 clojurebot: nil

15:32 ChongLi: ah yeah

15:32 Cubic: Oh. Well that makes sense

15:32 ChongLi: anyway, it makes easier to use it as part of a control structure for operation on seqables

15:33 Cubic: ,(for [x nil] true)

15:33 clojurebot: ()

15:53 tgoossens: egghead: thanks

16:50 yedi: /join #economics

17:02 wingy: hi

17:03 how do you create mobile and tablet apps?

17:06 Cubic: For what mobile and for what tablets?

17:07 wingy: all of them

17:08 Cubic: Then deploy it as a web application

17:09 wingy: Cubic: i mean you do YOU do

17:09 i know there are different solutions

17:10 part of me things that native apps is an evolution and we will move away from HTML as native apps

17:10 thinks

17:10 Cubic: wingy: Isn't it pretty much the other way round?

17:11 wingy: after doing some research i found that native apps are really much more mature than html5 .. we always find a lot of inconsistencies using html5

17:11 all those frameworks abstracting away the bad parts

17:11 perhaps the foundation is wrong? just like mutable states

17:12 reminds me about why we love OOP .. since it hides the complexity

17:12 Cubic: wingy: I don't understand your problem

17:12 AdmiralBumbleBee: his problem is that he talks in here about this stuff rather than #programming

17:13 wingy: it was on purpose since i wanted to know how clojure people do it .. here people tend to focus on simplicity

17:13 Cubic: wingy: So your question isn't about Clojure then?

17:14 wingy: you could say it is if you look at it from a higher perspective where clojure is part of it

17:14 Sgeo: Always writing native apps means needing to write several times for each platform

17:14 Even things like Java are abstracting away the annoyances of writing code for multiple platforms

17:15 And a lot of the reason for inconsistencies with HTML5 is that not everything supports it yet

17:15 Well, at least some of the reason

17:15 clojurebot: the reason to use the immutable types is that it saves you from all that stuff; if you don't use them you don't get the benefit.

17:16 Cubic: What's wrong with clojurebot?

17:18 wingy: Sgeo: you have a point

17:18 Sgeo: I wouldn't say that HTML5 is in fact "good", but relative to the alternative of developing native apps for everything...

17:19 wingy: Sgeo: there is a point in whaty ou way

17:19 say

17:20 that would be like developing for different platforms on server side

17:26 antares_: ivan: are you gsnewmark on github?

17:26 TimMc: Cubic: clojurebot treats random messages as being addressed to it.

17:26 antares_: man, the progress on CDS makes me all warn and fuzzy inside

17:27 in just a week we have like more than half of the guides in decent shape

17:27 and a dozen of contributors

17:36 oich: Do I simply ignore the throws clause of interfaces/classes when creating a proxy? Or, how does one specify a throws clause?

17:36 antares_: oich: Clojure compiler ignores checked exceptions

17:38 oich: thanks

17:47 Raynes: antares_: ping

17:48 antares_: Raynes: pong

17:49 Raynes: antares_: The Emacs tutorial on clojure-doc.org uses lein-clojars. If I want to point that out but not fix it right now myself, should I open an issue?

17:50 I'm also a little bugged that it focuses on SLIME instead of nrepl.el just because of clojure-test-mode, but to a lesser extent.

17:50 antares_: Raynes: yes, please. Just mention why you think it is a bad idea and what's a better way.

17:50 Raynes: nrepl.el does not support clojure-test-mode

17:50 that's discussed in the pull request, take a look

17:50 well, that's exactly why I still use SLIME, for example

17:51 Raynes: I guess I don't know what clojure-test-mode is.

17:51 antares_: when you hit C-c C-, in a test namespace and it runs your tests instantly

17:52 Raynes: I'm tempted to think most new users aren't going to care either and would rather have something more future-proof than SLIME. Especially common lisp users who would almost certainly rather trade clojure-test-mode for keeping their SLIME installation working for CL.

17:52 antares_: Raynes: it very much depends on their background

17:52 Raynes: what % of people come from CL vs Ruby?

17:52 Ruby developers coming to clojure will certainly ask "how do I run tests quickly without JVM restarts"

17:52 Raynes: I'd be more interested in what percentage actually use clojure-test-mode though.

17:53 antares_: Raynes: almost every person coming from Ruby, I think

17:53 Raynes: I find that hard to believe.

17:54 antares_: people who don't use clojure-test-mode typically don't know about it

17:54 Raynes: Anyways, I'm not going to argue against it. I just hope people get clojure-test-mode going with nrepl fast, because I die a little inside every time we recommend SLIME to a new user.

17:54 antares_: because nothing in the Clojure ecosystem is documented for noobs or visible

17:54 Raynes: Nobody likes providing support for that crap.

17:54 antares_: me and Gareth hope so too :)

18:01 Raynes: please do file issues for everything you don't like on CDS. I absolutely do not think that what we have right now is great.

18:02 Raynes: also, we need a new ground for arguing

18:02 Raynes: Hah

18:02 AdmiralBumbleBee: wait, is CDS meant to be general documentation?

18:02 Raynes: Yeah, I figure the clojure-test-mode stuff is too subjective to make an issue for.

18:03 AdmiralBumbleBee: or is it an introduction to clojure for a certain population of people

18:03 Raynes: It's an easy fix -- someone just needs to care enough to make clojure-test-mode work with nrepl.

18:06 antares_: AdmiralBumbleBee: it is primarily for newcomers but yes, it will cover most or even all expertise levels

18:06 and not just the language

18:06 there is value in simply centralizing and maintaining docs in one place

18:08 AdmiralBumbleBee: antares_: I'm somewhat perplexed why you'd consider someone's background when writing documentation. Certainly there's some pre-requisite knowledge required

18:08 but I would think that well written documentation would not need to cater to someone who knew python v ruby v C v CL etc..

18:09 I do understand that there's a place for such targeted information, but in context of emacs+clojure it sounds weird to me for that to be a consideration

18:10 antares_: AdmiralBumbleBee: well, you develop using some kind of tools, right?

18:10 AdmiralBumbleBee: of course

18:10 antares_: Emacs is a popular choice when it comes to Clojure

18:10 AdmiralBumbleBee: yes, and I'm an emacs user for a long time

18:12 antares_: I'm just a bit perplexed as to why a reader's background should be considered when writing general documentation

18:13 antares_: AdmiralBumbleBee: not sure I am following

18:13 you cannot please everybody with a single approach to docs

18:13 AdmiralBumbleBee: ok, I'm probably explaining myself badly

18:13 antares_: but that's why we are grouping things into Tutorials, Language Guides, Ecosystem and Cookbooks

18:15 AdmiralBumbleBee: antares_: I think lust I'm sensitive to you bringing up what a Ruby user would want to see in documentation :) I've brought that up before, so I'm restating myself I suppose.

18:15 just*

18:15 Raynes: antares_: I think he is referring to your response to my questions regarding clojure-test-mode that indicated a believe that everyone from Ruby uses it and most people probably come from Ruby so /thread. :p

18:15 belief*

18:21 oich: can you invoke more than one constructor with proxy, i.e. the class a proxy is proxying for has more than one constructor

18:23 yedi: anyone have suggestions for a great clojure dev environment on osx?

18:23 AdmiralBumbleBee: yedi: emacs

18:23 lpvb: or CCW

18:23 antares_: Raynes: everybody who comes from Ruby will expect it, that's what I really mean

18:23 Raynes: and The State of survey suggests a good third of people come from ruby or python

18:24 yedi: Emacs, Vim, Eclipse and IDEA are all pretty good

18:24 lpvb: vim doesn't have autocomplete :(

18:25 AdmiralBumbleBee: vim is a pain to setup on OS X in my experience

18:25 for clojure ^

18:28 oich: to answer my question about multiple constructors, I think I can't use proxy and have to use gen-class

18:30 JonasH_: AdmiralBumbleBee: true, I'm was just trying to get VimClojure working

18:30 only semisuccessful so far

18:31 can't get the key mappings to work

18:31 AdmiralBumbleBee: CCW or emacs can be setup on os x in about 3-4 minutes on a standard OS X install

18:31 vimclojure… eh :)

18:31 Sgeo: What's this about Ruby?

18:31 I've had some interest in it, but I could never shake the impression that, if I'm using Ruby, I should really be using Smalltalk instead

18:32 AdmiralBumbleBee: Sgeo: not talking about ruby… talking about documentation

18:37 ivaraasen: strange, clojure-doc.org doesn't seem to be working here

18:44 aperiodic: i'm using vim for clojure on os x w/slimv and bits of vimclojure

18:44 had a few stumbles setting it up, but works great now

18:44 i've also heard good things about vimclojure + lein-tarsier to handle the nailgun stuff

18:58 antares_: ivaraasen: can you ping and dig it? where you located?

19:10 ivaraasen: antares_: getting req timeouts. situated in Norway

19:11 antares_: ivaraasen: surprising, it is hosted in Germany

19:11 ivaraasen: for dig, too?

19:11 (ping's ICMP packets may be filtered out, actually)

19:15 ivaraasen: antares_: gives me back as the IP address.

19:15 antares_: ivaraasen: that's the correct answer

19:15 ivaraasen: try traceroute-ing that IP?

19:16 ivaraasen: no route to host

19:16 this is extremely weird

19:16 antares_: ok, something must be up with one of the routing tables between your ISP and the hoster I use

19:17 ivaraasen: my ISP is notorious for screwing things up, so you're probably correct

19:18 I'll give them a call tomorrow to see what's up

19:21 Urthwhyte: Any recommendations for a CSV processing lib?

19:23 amalloy: oich: proxy doesn't create a named class, it creates an instance of an anonymous class. you can only ever call one constructor at a time, so why would there be two?

19:29 frozenlo`: Urthwhyte: clojure-csv? :p

19:31 Urthwhyte: frozenlo`: Thanks :) I've spent enough time dealing with horrible ruby/python libraries that happened to rank well for search terms that I usually ask first now :)

19:43 mint`: hello :) question: I just ran lein for the first time on a live linux installation (which supports persistence) and jack-in is not an available task. what should i do differently?

19:43 technomancy: mint`: you need the lein-swank plugin

19:43 or nrepl.el

19:43 mint`: ah

19:47 technomancy: what do i need to do after i install the nrepl emacs package?

19:48 technomancy: M-x nrepl-jack-in should do it

19:49 mint`: cool thanks!

20:06 ticking: lol, I wanted to implement partition-between, which is similar to partition-by but allows for arbitrary splits instead for value changes, turns out my slightly optimized implementation can do more than partition-by and is still faster

20:14 amalloy: ticking: https://github.com/flatland/useful/blob/develop/src/useful/seq.clj#L222

20:15 ticking: amalloy ah cool, I asked a few days ago nobody pointed me to that :D I be mine is till faster though ;] I'll do a benchmark

20:16 amalloy: *shrug* it probably is. i don't see that it matters much either way

20:16 AdmiralBumbleBee: amalloy: what is this magic!? this need to be in core

20:16 everything here

20:16 ticking: amalloy, yeah but for core functions speed is significant

20:31 Sgeo: Should I rely on two different (Object.)s not being = in my programs?

20:32 Come to think of it, I could probably just use a symbol

20:32 technomancy: yeah, gensym is usually nicer IMO

20:33 amalloy: i usually use (Object.)

20:33 Sgeo: Good point, but I don't even need a unique object, not sure why I thought I did

20:48 ticking: so if anybody is interested, suggestions are welcome :)

20:48 https://gist.github.com/3886665

20:49 clj_newb_234: dumb question ... in clojre, how do I turn an character to a integer? i.e. \a -> 65

20:49 ticking: clj_newb_234 int

20:49 clj_newb_234: , (int \a)

20:49 clojurebot: 97

20:49 clj_newb_234: , (int \A)

20:49 clojurebot: 65

20:50 clj_newb_234: ah, cool; thanks :-)

20:50 ticking: np :)

20:57 Sgeo: ,(char 65)

20:57 clojurebot: \A

20:58 clj_newb_234: is ther a clojure builtin (extract-hashmap hashmap keys) <-- it takes hashmap, but only the [k v ] pairs where k \in keys ?

20:59 Sgeo: ,(for [i (range 1000) :when (not= ((comp int char) i) i)] i)

20:59 clojurebot: ()

20:59 Sgeo: Hmm, should probably have written that in terms of maps and filters

20:59 meh

21:00 uvtc: But how do you turn a one-character string into a char? I see that this ##(first (seq "a")) works ...

21:00 lazybot: ⇒ \a

21:00 Sgeo: ,(.charAt "a" 0)

21:00 clojurebot: \a

21:01 Sgeo: ,(first "a")

21:01 clojurebot: \a

21:01 Sgeo: ,(nth "a" 0)

21:01 clojurebot: \a

21:01 uvtc: Oh, of course, Sgeo. Right. :)

21:01 Sgeo: ,("a" 0)]

21:01 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>

21:01 uvtc: ,(last "a")

21:01 clojurebot: \a

21:01 Sgeo: ,(get "a" 0)

21:01 clojurebot: \a

21:01 Sgeo: ,(get "a" 1 :oops)

21:01 clojurebot: :oops

21:02 Sgeo: ,(get "a" 1)

21:02 clojurebot: nil

21:02 uvtc: I'd figured that `char` would do it, but `char` only takes an int.

21:02 Sgeo: ,(nth "a" 1)

21:02 clojurebot: #<StringIndexOutOfBoundsException java.lang.StringIndexOutOfBoundsException: String index out of range: 1>

21:02 Sgeo: ,(nth "a" 1 :oops)

21:02 clojurebot: :oops

21:02 Sgeo: Hrm.

21:02 ,(nth {:a 1} :a)

21:02 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.Number>

21:02 AtKaaZ: how do you turn a string into a list of chars?

21:03 uvtc: ,(seq "hello")

21:03 clojurebot: (\h \e \l \l \o)

21:03 AtKaaZ: lol i was afraid of that, thanks

21:03 Sgeo: ,((comp type seq) "hello")

21:03 clojurebot: clojure.lang.StringSeq

21:03 Sgeo: ,((comp class seq) "hello")

21:03 clojurebot: clojure.lang.StringSeq

21:03 * Sgeo still has no idea what the difference between class and type is

21:03 AtKaaZ: I remember hickey saying strings are sequences

21:03 AdmiralBumbleBee: afraid of that?

21:04 AtKaaZ: not afraid, but more like guessing/hoping

21:04 AdmiralBumbleBee: ah

21:05 Sgeo: ,(((partial partial apply) concat) [[1 2 3] [4 5 6]])

21:05 clojurebot: (1 2 3 4 5 ...)

21:06 AdmiralBumbleBee: Sgeo: ?

21:06 uvtc: He's partial to `partial`.

21:07 (er, sorry -- just guessed gender there, Sgeo)

21:08 AdmiralBumbleBee: uvtc: maybe just as insulting to say you couldn't tell he was male ;)

21:08 (assuming 'he' is of course… heh)

21:08 quick, we need a gender abstraction!

21:08 xeqi: they

21:09 uvtc: s/he is in the `s` namespace...

21:09 Sgeo: e

21:09 amalloy: Sgeo: type is mostly obsolete now

21:09 (the clojure function, not the concept, of course)

21:09 Sgeo: I'm partial to Spivak pronouns, because nomics tend to use them a lot, and I grew up interested in nomic

21:10 I am a guy

21:10 uvtc: amalloy: do you mean the concept of "type", or the function `type`? Or both?

21:10 amalloy: and if either, why is it (or they) obsolete?

21:10 amalloy: uvtc: BAM! ninja'd

21:11 Sgeo: (partial apply blah) returns a version of blah that accepts a seq instead of a variable number of arguments

21:11 * uvtc thinks he must've missed something ...

21:11 amalloy: <amalloy> (the clojure function, not the concept, of course)

21:11 Sgeo: So, if I want a general function to turn functions that accept varargs into functions that accept seqs, I want (partial partial apply)

21:11 uvtc: amalloy: why is the Clojure function `type` mostly obselete?

21:12 Sgeo: amalloy, am I insane for liking partial partial stuff?

21:12 amalloy: it's a holdover from the days before deftype and defrecord, when the only way to introduce new types was the convention of putting :type :mytype in the metadata of your object

21:13 Sgeo: no, i like partial partial apply myself. i had convinced ninjudd to add it to useful but then he changed his mind

21:13 Sgeo: ,(type ^{:type :foobar} 5)

21:13 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>

21:13 amalloy: (def ap (partial partial apply)) (map (ap concat) coll)

21:13 uvtc: amalloy: thanks!

21:13 Sgeo: ,(type ^{:type :foobar} 'foo)

21:13 clojurebot: clojure.lang.Symbol

21:14 amalloy: ,(type (with-meta 'foo {:type :foobar}))

21:14 clojurebot: :foobar

21:14 Bronsa: wow

21:14 amalloy: ,(type '^{:type :foobar} foo)

21:14 clojurebot: :foobar

21:15 Sgeo: Wait, what's with the '^

21:16 uvtc: amalloy: Heh, I see. Missed your comment ("ninja comment"). :)

21:16 Bronsa: I'm guessing the reader that way is quoting the symbol foo after metadata has been attached to it

21:16 whether using ^{}' the metadata is being attached to the form (quote ..)

21:16 amalloy: indeed, Bronsa

21:31 AtKaaZ: what should I look into if I wanted to read/process binary files into structs or something like that ?

21:33 this seems to be it right? https://github.com/ztellman/gloss/wiki/Introduction

21:33 amalloy: yes

22:27 AtKaaZ: CompilerException java.lang.RuntimeException: Unable to resolve symbol:  in this context, compiling:(quil/core.clj:1)

22:28 how can I track down what's happening?

22:31 this is the file: https://github.com/quil/quil/blob/master/src/quil/core.clj

22:34 ,(seq "  ")

22:34 clojurebot: (\space \ \space)

22:34 AtKaaZ: ,(seq " ")

22:34 clojurebot: (\space \)

22:35 AtKaaZ: ,,(int \)

22:35 clojurebot: 65279

22:37 AtKaaZ: wow seriously, this is how that file begins: (ns

22:41 antares_: AtKaaZ: this is UTF-8 BOM

22:42 most likely that file was saved from a weirdly configured editor, possibly on Windows

22:42 AtKaaZ: that makes sense, but still not even github diff can show that char

22:43 look how it (doesn't look: https://github.com/quil/quil/commit/d0312f0f119db066a8d613dec8803571b92bea39

22:43 :)

22:44 my concern is how to prevent that in the future?

23:25 ChongLi: ok I'm really confused

23:25 I have 2 different projects

23:25 with nearly identical project.clj

23:25 (same dependencies)

23:26 one of them can import a class at the repl

23:26 and the other gets UnsatisfiedLinkError

23:26 > (import org.lwjgl.opengl.Display)

23:26 org.lwjgl.opengl.Display

23:27 > (import org.lwjgl.opengl.Display)

23:27 UnsatisfiedLinkError no lwjgl in java.library.path...

23:33 when I print the classpath for both with (pprint (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader)))

23:33 it is virtually identical between the two (only the local project stuff differs)

23:41 ahh, hmm

23:41 target is different (native stuff in one but not the other)

Logging service provided by n01se.net