#clojure log - Sep 08 2012

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

0:42 basicsensei: hi, I'm new to clojure and leiningen and counterclockwise, I am using eclipse+ccw and imported a github project, I'm failing to figure out how to export a .jar from a Leiningen project in eclipse, the ccw doc says to use classic Eclipse export as Jar wizard, but that seems to ignore project.clj settings(?) like :aot and :manifest

0:42 this is the project: https://github.com/jonnay/Watership-Down and you may see the project.clj there

0:47 my question is, how should I correctly export .jar if I'm using eclipse+ccw ?

0:48 tomoj: any reason to use eclipse to export a jar instead of just running `lein uberjar`?

0:48 basicsensei: okay, apparently I've stumbled upon something, loading the main .clj file in repl generated a bunch of classes inside the classes folder

0:49 tomoj, I wouldn't know where to run that

0:49 tomoj, that sounds like I need more stuff installed than eclipse+ccw ?

0:49 tomoj: well, leiningen

0:51 basicsensei: tomoj, there seems to be leiningen already existing in ccw

0:56 Sgeo: So you should be able to use it from there (not sure how convenient it is). Open a command prompt

1:01 basicsensei: windows command prompt? not repl?

1:03 I could get lein.bat but this seems like doing it wrong, I mean, there must be a way to do it with eclipse+ccw considering that ccw has lein support(as I see it)

1:04 tomoj: ccw cannot support all the features of lein, so it makes sense to get lein.bat anyway

1:04 I don't know specifically about ccw's support of uberjar

1:05 basicsensei: running lein uberjar, what tomoj said, seems to work in that it creates a 'classes' folder in 'target' folder which means I don't have to load the main .clj in repl inside eclipse to do that; but should that also yield me a .jar ?

1:06 tomoj: yes, it should put it in target

1:07 basicsensei: it's nothing there (or anywhere else inside the project) except a bunch of .class files, I'm wondering if this is maybe how the project.clj intended it (no jar , only classes) maybe?

1:08 Raynes: $mail xeqi I'm not sure you caused it. Looks like a threadpool died and that causes very weird things to happen. Anyways, feel free to mess with it tomorrow and see if you can get it happening again.

1:08 lazybot: Message saved.

1:09 Sgeo: Is there a way to extend-type an interface such that, if an interface or protocol is implemeneted, I can say that XYZ code is used to implement another interface or protocol?

1:10 That is, let's say, I want to say that all IFns are IMonadValues

1:10 basicsensei: tomoj, i tried it on an new empty project and it works, the .jar are there, thank you for that command; I'll try and see what's the difference between the two to detect why the .jar isn't generated

1:11 tomoj: you can extend IMonadValue to IFn because IFn is an interface on the jvm, but you probably shouldn't...

1:12 basicsensei: tomoj, I didn't realize that this was actually an error: http://pastebin.com/amSb94DR I thought it's more like a warning, but that is why the .jar wasn't generated

1:13 tomoj: yeah, either add -SNAPSHOT to your project's version in project.clj, or find a stable version of the snapshot dep you have

1:13 Sgeo: tomoj, clarify?

1:14 tomoj: if IFn were a protocol, like it should be (it is in cljs), you couldn't do that

1:14 basicsensei: tomoj, sweet thanks

1:14 tomoj: you can't extend a protocol to another protocol, at least not now

1:14 Sgeo: I thought all protocols make interfaces?

1:14 tomoj: (never, I suspect..)

1:14 yeah

1:15 I guess you could extend a protocol to another protocol's interface, but it seems wrong

1:15 the interface hatch is there for java interop

1:16 basicsensei: this is awesome, 'lein uberjar' did the job which I somewhat expected to be able to do with eclipse+ccw, I'll be using a combination of these then:)

1:16 scode: Getting http://pastebin.com/hbGWdhGC trying to use swank w/ leinigen. Assuming I'm looking at matching soure (1.2.1), it looks like baseLoader() is probably returning null causing the NPE. THis is on a fairly clean ubuntu. Same with both JDK6 and JDK7. Anyone recognize this?

1:17 tomoj: Sgeo: so e.g. if you extend to both IFn and IPersistentSet, you've got multiple inheritance and it's undefined which implementation gets called

1:19 huh, the doc for extend says both "extend an interface to a protocol" and "extend a protocol"

1:23 Sgeo: tomoj, erm, I guess I don't quite understand extend

1:25 I want all IFns to be IMonadValues but not all IMonadValues to be IFns. If I also want IPersistentSet to be IMonadValues, wouldn't that be a separate thing? (Unless all IPersistentSets are IFns, which I guess they are. Is that what you mean?)

1:26 abp: Is it possible to traverse through the whole source code of an expression(resolving all calls to forms etc) in a macro?

1:26 tomoj: that's what I meant, but I guess just the IPersistentSets we run into are always IFn

1:27 Sgeo: abp, possible, but may or may not be easy

1:27 ,(doc macroexpand-all)

1:27 clojurebot: I don't understand.

1:27 Sgeo: http://richhickey.github.com/clojure/clojure.walk-api.html#clojure.walk/macroexpand-all

1:27 lazybot: Nooooo, that's so out of date! Please see instead http://clojure.github.com/clojure/clojure.walk-api.html#clojure.walk/macroexpand-all and try to stop linking to rich's repo.

1:28 Sgeo: I blame Google.

1:28 tomoj: what else do you think might be a monad value besides IFns?

1:28 er, an IMonadValue I mean

1:29 arohner: I have a ref. I also have quartzite https://github.com/michaelklishin/quartzite. Quartz can only schedule jobs with serializable arguments. Is there a way to get a "pointer" to the ref, so I can look up the ref by its id later?

1:30 Sgeo: :/ sequences

1:30 arohner: basically, my goal is to call (f ref), a minute from now

1:31 abp: Ok, now let's assume I've written that macro and use it to traverse the whole program to find calls to some other macros. Would that be a good solution..? I need to build meta-data on things that get not eval'ed due to if's etc. so theres no other way, I think.

1:31 Sgeo: Wait, whole program?

1:32 It can only see calls that are inside of it... hmm, I may have misunderstood you

1:32 (my-macro (f a b c))

1:32 my-macro will see (f a b c), and if f is a macro, it can see the expansion... but if f is a function, I think it's opaque to the macro.

1:32 abp: Sgeo: Err, yes. That's what I meant, resolve calls to fns to their forms, so I can traverse those and so on.

1:32 Sgeo: Damn.

1:33 casion: I think I'm about ready to give up on clojure :| I've spent all day trying to figure out IO, and I still have no clue

1:33 abp: So I have to wait for _zach|away to work on https://github.com/ztellman/sleight ? :)

1:33 Sgeo: casion, hmm?

1:33 abp: casion: What are you trying?

1:33 * Sgeo has a feeling that that sentiment is more ... existent among newbie Haskellers

1:34 casion: I want to tokenize a very large file based on specific byte-arrays

1:35 as far as I can figure, I have to use line-seq and parse… except everything I try just seems ridiculously slow

1:36 since the files have no 'lines' per se, and the tokens often get split across what .readLine decides is a line

1:37 it seems like I have to parse the entire read up til that point for every iteration of line-seq

1:37 tomoj: don't use line-seq

1:38 abp: casion: You don't have to use line-seq, you can use clojure.java.io/reader for example

1:38 Sgeo: Hmm, will the reducers library have some alternative to line-seq that's clean? Because the post mentions Iteratees, and I think this sort of thing is right up Iteratee's alley

1:39 tomoj: I don't know if it will go into the reducers library or a separate library, but I expect it's coming

1:39 casion: abp: I've been trying with reader, and I haven't come up with a solution

1:39 well, I have… but it's slow as molasses

1:39 abp: casion: So, that's what you got then: http://docs.oracle.com/javase/6/docs/api/java/io/Reader.html

1:40 Sgeo: Wait, why does read() read in as an ... int?

1:40 What.

1:41 casion: abp: but how do I efficiantly tokenize on a 4 byte array?

1:41 efficiently*

1:42 abp: Sgeo: I suppose because Reader can take different encodings in different impls, so you can get at UTF-8 chars with it for example.. But I don't know for sure.

1:42 jkkramer: readers are character-oriented. if you're reading byte arrays you may want to be using input streams

1:42 casion: jkkramer: that's what I was doing, but I was told earlier today to use readers :(

1:43 Sgeo: casion, are you reading text or bytes?

1:43 casion: Sgeo: bytes

1:43 abp: jkkramer: casion: So readers use streams under the hood I think..

1:44 Sgeo: abp, but readers might make assumptions about what those bytes mean

1:44 casion: this evening I've been using readers with :encoding "UTF-8" to read per byte

1:44 jkkramer: that sounds silly

1:44 Sgeo: casion, if the data is not UTF-8 text, don't do that. Otherwise you may end up with several bytes ending up as one value

1:45 Because in UTF-8, several bytes can make up one codepoint.

1:45 casion: Sgeo: I'm aware.. and this is part of the issues I've encountered in this attempt

1:46 I did try with InputStreams, and I have't been able to figure out how to find a byte-array in a byte stream

1:47 abp: casion: casion You could use FileInputStream, wrapped in a BufferedInputStream directly, Readers seem to add encoding all the time

1:48 casion: abp: and then how do I tokenize?

1:48 since the separator can occur at any byte boundary

1:48 tomoj: commons-lang has ArrayUtils/indexOf

1:49 Sgeo: If I were thinking imperatively, I might take in a chunk at a time, check if the seperator's in it, and if not, keep adding to the chuck

1:49 When I find the seperator, then do whatever at that point

1:49 casion: Sgeo: that's the only way I managed to get it working… and it was really slow

1:51 Sgeo: Well, hmm. The size of the chunks is a tradeoff. Too small, and you keep reading from disk too often, too large, and it takes up a lot of memory.

1:51 abp: casion: Could you show how you did it? I must admit I'm not a good programmer when it comes to functional algorithms by now..

1:51 Sgeo: No, that's what BufferedInputStream is for

1:51 Sgeo: abp, oh

1:51 abp: Sgeo: Read a chunk into a buffer once, pass to reader in sizes he takes

1:51 Sgeo: I'm not really too familiar with the JVM ecosystem

1:51 casion: abp: I don't have the code available, been writing over it

1:51 abp: casion: Ok

1:52 casion: Then how much data do you process?

1:52 casion: abp: 4gb-10gb or so

1:52 per file

1:53 if these were small files, I think I could handle it

1:53 abp: casion: Neat. What do you do with the processed data? Do you have reference implementation you can compare to in terms of performance or why do you think it's slow?

1:54 casion: abp: data is RIFF64 wav files, right now I'm just trying to parse the header (which can be of arbitrarily large size)

1:55 and as reference I'm comparing to javax.sound.sampled's RIFF header parsing

1:55 it doesn't handle RIFF64, but the headers are nearly identical besides some extra feilds

1:56 so I'd think I could get this performing nearly identically

1:58 abp: casion: Probably.. But that's a java lib, so why don't you just wrap javax.sound.sampled or use it directly?

1:58 casion: oh ok

1:58 casion: abp: because I'm trying to support file types it does not

1:58 abp: casion: Just saw doesn't handle, sorry

1:58 casion: I've already written half a wrapper for it though (read only atm)

2:00 abp: casion: Yes then writing Clojure that matches the performance of a Java lib isn't easy but quite doable in many cases. It's probably a bit of work to get your head around programming performant code..

2:01 jkkramer: if you're dealing with individual bytes, arrays, large files, and want speed, your code will probably be heavily imperative and interop-y

2:01 abp: jkkramer: Indeed

2:02 casion: in that case, I will go back to that concept

2:02 abp: casion: you can look at http://stackoverflow.com/questions/12176832/quicksort-in-clojure (dnolens answer), also he suggests looking at http://github.com/clojure/test.benchmark to archieve java perf

2:03 casion: is there a clojure way to compare byte-arrays, or is it proper to use java.util.Arrays.equals()

2:05 abp: casion: http://docs.oracle.com/javase/6/docs/api/java/util/Arrays.html#deepEquals(java.lang.Object[], java.lang.Object[]) don't know of a clojure way

2:05 casion: ok

2:06 I was using java.util.Arrays/equals before, which seemed to work correct

2:07 thanks for the help, I'm going to see if I can get input streams working again so I have some code to show if it's still slow

2:07 abp: casion: should be shallow comparison. :x

2:07 casion: You're welcome

2:08 casion: apologies for the 'I'm going to quit clojure' drama… getting frustrated trying to do stuff I can do/have done in another language

2:11 tomoj: casion: you might consider looking at gloss sometime

2:11 not sure if netty makes sense, or how fast it would be, but your code would almost certainly be simpler :)

2:12 casion: tomoj: ok, I will do so once I at least conoquer this basic bit on my own :) thank oyu

2:12 conoquer… lol

2:12 abp: casion: I was frustrated some times with banging my head into fp-thinking but never enough to start a drama. Perhaps I'm to stubborn. ;)

2:15 casion: ok, I have the 'working' input-stream code

2:16 https://www.refheap.com/paste/4936

2:17 that takes 5ms to just 'pull' the header, where the java equiv pulls and parses the header in 0.002ms

2:17 so obviously something is broken with my code I would think

2:18 and I checked, seems comparing seqs is faster than java.util.Arrays/equals

2:18 abp: casion: first this, don't call (byte-array) in every step, one array instance is enough

2:18 this=thing

2:19 casion: abp: where do I bind it then?

2:19 if I put it outside the loop, I end up with an array of whatever the last read was N times

2:19 abp: casion: let around loop, carry throug loop/recur, as you prefer I think

2:20 ah I see

2:20 casion: you conj array-refs into vec

2:22 casion: use (into coll ba)

2:22 casion: ok, let me try

2:24 abp: ,(into [] (byte-array 4))

2:24 clojurebot: [0 0 0 0]

2:24 abp: ,(into [] (byte-array 4))

2:24 clojurebot: [0 0 0 0]

2:24 abp: ,(conj [] (byte-array 4))

2:24 clojurebot: [#<byte[] [B@2b41bb40>]

2:24 abp: I need to start using the bot for explanations. :)

2:26 casion: heh, just that emacs instance

2:27 does this look like what you were suggesting? https://www.refheap.com/paste/4937

2:32 abp: casion: Yes, now let ,(byte-array 4 (map byte [100 97 116 97])) in the outer let too and do ,(java.util.Arrays/equals (byte-array 4 (map byte [100 97 116 97])) (byte-array 4 (map byte [100 97 116 97]))) insted of (= (seq ba) ...

2:32 casion: just did that… it's 4x slower

2:32 abp: casion: Sorry, just setting up an account for refheap so I can edit there..

2:33 casion: no prob, the help is greatly appreciated

2:33 abp: casion: java.util.Arrays.deepEquals is for objects, equals for primitives, so that's ok here, said something wrong earlier

2:35 casion: Oh, that's weird, paste the code again?

2:36 casion: sure

2:36 https://www.refheap.com/paste/4938

2:39 abp: casion: wow, that's slower than (= (seq...? Wouldn't assume that

2:40 casion: yeah… I don't get it either

2:40 I had this code this morning and stumbled on using (seq) because I didn't know about java.util.Arrays/equals, and I was naively using (= )

2:41 when I tried equals after learning of it… it was quite plainly slower

2:41 abp: casion: Hm, do you benchmark properly, ie multiple runs, taking the mean, for the jvm to warm up?

2:43 casion: abp: yep

2:45 hmm, with another file they're benching about equal

2:46 I'm so confused :|

2:46 equals isn't better at all yet though

2:51 tomoj: must a reducer never call reducef after returning from reduce?

3:14 devn: casion: "another file"?

3:14 casion: devn: one with a shorter header

3:14 devn: so you're trying to seq on the contents of a file?

3:15 casion: no, only on a 4 byte-array

3:16 this https://www.refheap.com/paste/4937 compared to this https://www.refheap.com/paste/4938

3:16 there's a mising parens in the second one

3:17 devn: which is faster?

3:17 2?

3:17 clojurebot: 2 is mark

3:17 casion: 1 is faster for me

3:18 devn: and that's surprising?

3:19 casion: I would think java.util.Arrays/equals would be faster

3:19 but I have little to base that on

3:19 devn: yeah but it's sort of pleasant that it isn't, no?

3:19 casion: yes

3:20 tomoj: reflection?

3:20 devn: haha

3:20 man, this channel

3:21 "Do you have *warn-on-refle..."

3:21 tomoj swoops in

3:22 casion: warn-on-reflection is off

3:23 Sgeo: What is it about reflection that's slow?

3:23 Is it just -reflection on the JVM- or -reflection in general-?

3:24 If the latter, do things such as Ruby's pervasive use of reflection for metaprogramming in various frameworks make things slow?

3:36 amro: Sgeo: reflection in general

3:42 abp: So, I ran casion's byte-array comparisons without IO etc, measuring with criterium

3:43 (seq (= .. Evaluation count : 1144172760 in 60 samples of 19069546 calls. Execution time mean : 52,665007 ns

3:44 java.util.Arrays/equal Evaluation count : 1220332860 in 60 samples of 20338881 calls. Execution time mean : 49,670757 ns

3:45 At least not much of a difference..

3:48 Sgeo: Is Clojure suitable for making proprietary applications? In terms of legality/licenses, I mean

3:49 abp: https://www.refheap.com/paste/4940

4:11 Sgeo: https://github.com/rplevy/swiss-arrows

4:12 The example of the diamond wand with two maps seems like it might be a compelling use-case

4:14 muhoo: happy (reduce #(assoc %1 %2 (get-tag %2 j)) {} [:id :title :city :url])

4:15 that one line leaves me going to sleep with a smile on my face

4:41 _KY_: I used "doseq" to evaluate something, but it still seems to be lazy... is that normal?

4:42 But if I add a "print" to debug it, it evaluates fully

4:42 This laziness is driving me nuts....

5:01 Sgeo: Use for a macro-writing macro: A macro to make a macro that's merely an alias of another macro

5:21 callen: okay, what'd you change this time?

5:21 plugin is gone, swank-clojure is gone, how do I make clojure-jack-in work?

5:21 what are user profiles and why can't I install a plugin without creating a project or a profile?

5:26 I seem to have gotten it to behave, but a lot has changed o_o

5:26 Raynes: I'd suggest abandoning swank and slime and trying out nrepl.el. You don't need any extra plugins for it, just nrepl.el and leiningen 2.

5:26 If you install it, you can do nrepl-jack-in

6:01 tsdh: Given a namespace and a symbol, how do I get the qualified name of the var the symbol refers to in the namespace?

6:01 Basically, I want (ns-resolve ns 'var) but as symbol, not as var.

6:02 callen: Raynes: I ended up doing that right around the same time you suggested it (Ritz and NRepl are recommended in swank clojure's readme)

6:02 Raynes: it worked great, thanks.

6:03 also light table seems neat, but where's the source? I want to turn live-eval on in table mode.

6:06 tsdh: Hm, seems there's no clean way. Even clojure.repl/doc uses str for that task...

6:14 leafw: just posted on clojure monads: albert.rierol.net/clojure-monads.html -- I hope you find it interesting, and I would appreciate comments.

10:20 ro_st: datomic question: how do i update schemas? i'm getting a ":transact/bad-data Unique conflict: :db/ident, value: :my/ident already held by 62" error

10:39 Sweden_jack: Hey, what's the easiest way to find the {min,max}imum of a list by some “key” function? Let's say that I want to find the shortest list in a list of lists: (? [[1 2 3] [-2] [3 2] :key count) → [-2]

10:39 In Python you'd use: min(..., key=len) and in Haskell you'd use minimumBy (comparing length)

10:40 dhm: Sweden_jack: reduce + min/max i think

10:40 raek: Sweden_jack: check out min-key and max-key

10:40 ,(apply min-key count [:a :aa :aaa])

10:40 clojurebot: #<UnsupportedOperationException java.lang.UnsupportedOperationException: count not supported on this type: Keyword>

10:41 Sweden_jack: ,(apply min-key count [[1 2 3] [-2] [3 2]])

10:41 clojurebot: [-2]

10:41 Sweden_jack: OK fantastic :)

10:41 raek: ,(apply min-key (comp count name) [:a :aa :aaa])

10:41 clojurebot: :a

10:41 Sweden_jack: Thanks a bunch

10:42 raek: inga problem

10:42 Sweden_jack: haha, I'm not really Swedish ;) up until 2 weeks ago I was Iceland_jack

10:44 hyPiRion: $findfn [:a :aa :aaa] :a

10:44 lazybot: java.lang.ClassCastException: clojure.lang.PersistentStructMap$Def cannot be cast to clojure.lang.IFn

12:24 deeplloyd: exit

12:25 exit

12:25 Frozenlo`: enter

12:39 ro_st: can anyone tell me how to handle schema migrations with datomic?

12:45 gfredericks: abedra told me the other day that maybe it was somehow even simpler than renaming everything

12:46 but I haven't even used datomic so I really can't speculate about what he meant.

12:47 rhickey was asked the question at a talk here recently and gave some incomprehensible "what schema!?" response

12:47 ro_st: i thought i could just transact schemas over and over and it'd all just sort itself out. but i'm getting Unique conflict exceptions (unless i _delete_ the database), which leads me to wonder how one can safely update the schema

12:48 i'm sure it's dead simple. docs don't talk about it at all, though

12:55 looks like the answer is boils down to 'only define new schemas'

12:56 gfredericks: is that limiting?

12:57 ro_st: only in the sense that i have to construct a migrations sytem, now

12:57 system*

12:59 Bronsa: OlegYch|h:

13:35 Sgeo: What happens if a library provides an atom but I want to modify it in a transaction only if the transaction succeeds?

13:42 raek: Sgeo: one way could be to let the transaction extression return everything you need when you update the atom, and then do the update outside the transaction

13:43 Sgeo: Would it even be that inconvenient if atoms didn't exist?

13:43 raek: (but maybe that's not possible in your data flow)

13:46 (let [delta (dosync ...)] (swap! a + delta))

14:02 solussd_: can I not have a namespace with hyphens in it? my namespace is some-words.server and I'm getting java.lang.ClassNotFoundException: some-words.server. I have a path in my project of src/some_words/server.clj. ?

14:04 llasram: solussd_: You can have '-' in your namespace name just fine, but there are occasional issues with inconsistent munging. What's the context in which you're getting the error?

14:05 solussd_: 'lein run'

14:05 and i think it's my project.clj :main section

14:05 :)

14:06 nope..

14:06 now I'm getting java.lang.ClassNotFoundException: some_words.server

14:08 llasram: Both of those should work without problem, so I think there's another issue

14:14 solussd_: hmm.

14:41 arohner_: Sgeo: you can send to the atom, in the transaction

14:41 i.e. using an agent

14:42 agent sends inside a transaction only fire on success, after the transaction completes

14:42 that will be async btw

15:04 djanatyn: ...hmm. how possible would it be to have a clojure library similar to lispbuilder-sdl?

15:04 is it possible for us to create clojure bindings to SDL, on the JVM?

15:05 emezeske: djanatyn: Possibly, through the use of JNI

15:05 djanatyn: I think that many people on the JVM use lwjgl as an alternative to SDL though

15:06 djanatyn: E.g. see https://github.com/ztellman/penumbra

15:10 ro_st: emezeske: so happy cljsbuild is working 100% on lein 2. thanks for your effort!

15:10 we're using lein2 end to end, now. yay

15:10 djanatyn: emezeske: I've tried using penumbra, but opengl is a little difficult to wrap my head around :\

15:11 emezeske: ro_st: That's great!

15:12 ro_st: it's so much simpler using lein2

15:12 profiles.clj is a big help

15:12 emezeske: djanatyn: If you don't need opengl, can you just use Swing?

15:12 ro_st: Yeah, profiles are really nice

15:12 djanatyn: I guess though

15:13 *so. Is Seesaw appropriate for writing little simulations and games?

15:13 emezeske: djanatyn: If that's your goal, have you looked at quil?

15:13 djanatyn: Yeah, I have. I should probably take a closer look at quil

15:14 emezeske: I've done a couple simple physics simulations with quil

15:14 It's good if you just need a super quick way to display something

15:14 djanatyn: I had trouble figuring out how to manipulate state using quil

15:14 emezeske: Using quil's built-in state stuff?

15:14 I dropped that immediately and just manage my own state with an atom

15:15 djanatyn: could you elaborate? how do you manage your state with an atom?

15:16 emezeske: djanatyn: Would it be helpful if I just put my little physics demo up on github?

15:16 djanatyn: yeah, it would! that would be great.

15:16 emezeske: djanatyn: cool, it's pretty ugly code, but I'll put it up in a sec

15:16 ro_st: emezeske: did you see the cljsbuild enfocus shoreleave demo i put up?

15:17 https://github.com/robert-stuttaford/demo-enfocus-pubsub-remote/

15:18 emezeske: djanatyn: In no way do I represent this as good code: https://github.com/emezeske/germ

15:18 djanatyn: :)

15:18 ro_st: taking a look

15:18 ro_st: just as a sort of a starter kit for projects that want to use cljsbuild crossovers + enfocus for ui + shoreleave for remotes and client-side pubsub

15:19 emezeske: ro_st: That looks really cool! I need to read more about shoreleave

15:20 ro_st: it's nice. the remotes stuff is pretty much just fetch but with csrf protection baked in

15:20 the pubsub is nice. declaratively bind ui and model

15:22 emezeske: Nice, built-in csrf protection is cool. Also, not depending on noir is cool.

15:23 ro_st: cemerick just released a nice redo of the server side of shoreleave remotes

15:23 https://github.com/cemerick/shoreleave-remote-ring

15:23 we're using noir anyway :-)

15:24 emezeske: hah :)

16:13 Sgeo: If it's possible to make cyclic immutable data structures in Haskell, why shouldn't it be possible in Clojure?

16:14 * Sgeo is vaguely aware that Haskell's pervasive non-strictness is probably an/the answer

16:15 seancorfield: You can certainly construct lazy sequences that are cyclic in Clojure...

16:16 Sgeo: How about trees or other graphs

16:16 seancorfield: Sure, as long as you can specify the cycle points... (he says blithely without trying it)

16:17 * seancorfield wonders why you would want to?

16:17 hiredman: ,(doc cycle)

16:17 clojurebot: "([coll]); Returns a lazy (infinite!) sequence of repetitions of the items in coll."

16:18 hiredman: depends what you mean by cycle

16:18 emezeske: Sgeo: You are talking about referential cycles, right? Like a circular linked list

16:18 seancorfield: That's not really quite the same tho' hiredman - not as a general cyclic graph

16:18 hiredman: the tail of the seq contains the whole seq

16:18 seancorfield: A has children B C D and C has children E F and A, for example

16:19 emezeske: seancorfield: Can you really make an immutable datastructure with a referential cycle? It seems like there's a chicken and egg problem there.

16:19 ivan: can one do http://en.literateprograms.org/Fibonacci_numbers_%28Haskell%29#Infinite_Lists in Clojure?

16:19 emezeske: seancorfield: You could roll your own reference system, like storing the lookup key for a cyclic structure

16:19 Sgeo: emezeske, you can if there's sufficient non-strictness

16:19 ToxicFrog: ivan: yes; clojure has lazy data structures

16:20 ivan: ToxicFrog: yeah, but I tried porting it directly and got a terrible algorithmic complexity explosion, because it wasn't reusing the outer lazy-seq

16:20 rlb: http://stackoverflow.com/questions/4580865/how-can-one-create-cyclic-and-immutable-data-structures-in-clojure-without-ext

16:20 hiredman: emezeske: you can definitely do it with laziness

16:20 seancorfield: emezeske: sure if the lazy expansion of the tree resolves to nodes you've already generated

16:21 emezeske: hiredman, seancorfield: I see. That makes sense.

16:21 * hiredman has a sweet letfn implementation using delays

16:22 Sgeo: The thing with delays is that they need to be explicitely forced

16:22 hiredman: recursive functions, recursive data, whats the difference?

16:23 https://gist.github.com/1179073

16:24 rlb: I imagine people used to traditional lisps may be likely to reach for direct graph representations by default (via set-cdr! or similar)...

16:43 konr: Do you remember the name of that JS library that implements ClojureScript functions in vanilla JS?

16:44 Bronsa: mori?

16:44 konr: yes! thank you

16:50 ro_st: anyone modelled tags with datomic yet?

16:51 nbeloglazov: Does nrepl have feature to search in history with prefix? I think swank has it.

16:52 I mean nrepl.el

16:58 callen: so does anyone use anything other than the code-heavy hiccup for templating for web dev in Clojure?

16:58 ro_st: YES

16:58 callen: I'd like my frontend guy to be able to wrangle the templates.

16:58 ro_st: enlive.

16:58 callen: okay, enlive is equally guilty of what I'm talking about.

16:58 ro_st: https://github.com/robert-stuttaford/demo-enfocus-pubsub-remote/blob/master/resources/public/templates/templates.html + https://github.com/robert-stuttaford/demo-enfocus-pubsub-remote/blob/master/src-cljs/depr/view.cljs

16:58 callen: I need plain-text templates he can understand.

16:59 ro_st: let him do the html and you do the clj

16:59 that code is enfocus (cljs port-ish of enlive) but the principle applies

17:00 callen: looks a little complicated for what's generally a simple problem.

17:00 ro_st: that scales incredibly well.

17:01 callen: ...right.

17:01 what scales well is something more people than just me can understand.

17:01 emezeske: callen: There's like at least 42 mustache implementations in Clojure

17:01 duck1123: when you edit your templates, are they automatically picked up?

17:01 Frozenlock: I've yet to understand what's the point of templating... isn't there HTML (from clj) and the rest is CSS?

17:01 ro_st: duck1123: yup. you can optionally have em compiled in at compile time

17:01 callen: emezeske: aha, thank you.

17:01 ro_st: but i prefer not to

17:02 Frozenlock: hiccup doesn't scale all that well. nice for simple stuff but big projects it gets sticky on

17:02 emezeske: callen: You might have to poke around a bit to find the most current/maintained one

17:02 callen: I figured

17:03 duck1123: I looked into using closure template, but It didn't automatically pick up the changes, and I went back to hiccup

17:03 ro_st: duck1123: for cljs?

17:03 duck1123: Now that I'm using Knockout, I'm trying to get as much of the logic out of my templates as possible

17:03 I was only using the server-side at that point

17:04 ro_st: gclosure's soy templates are not a fun experience

17:04 duck1123: Now I send a blank template and my page fetches a viewmodel on load and then loads any other missing models

17:05 I was hoping I could just pass it my record, but the soy compiler was way too picky about types

17:05 ro_st: yup

17:06 duck1123: I have a series of multimethods where I have common names for types of display (index-section, show-section, etc) and it dispatches on the type of records passed to it and the format being used. Works well for me

17:07 ro_st: nice

17:07 xeqi: emezeske, callen: https://github.com/davidsantiago/stencil for mustache

17:07 mr_rm: '(clojure.string/join "," #{1 2})

17:07 `(clojure.string/join "," #{1 2})

17:07 hmmm how do you talk to the bot again?

17:08 nbeloglazov: ,

17:08 ro_st: ,

17:08 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

17:08 #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

17:08 Bronsa: lol

17:08 mr_rm: ,(clojure.string/join "," #{1 2})

17:08 clojurebot: "1,2"

17:08 nbeloglazov: Or &(clojure.string/join "," #{1 2})

17:08 Frozenlock: and iirc, # is for when you want to mess around

17:08 mr_rm: interesting... this is blowing up on my clojure 1.4 in eclipse

17:08 nbeloglazov: &(+ 1 1)

17:08 lazybot: java.lang.ClassCastException: clojure.lang.PersistentStructMap$Def cannot be cast to clojure.lang.IFn

17:08 Bronsa: &+

17:08 lazybot: java.lang.ClassCastException: clojure.lang.PersistentStructMap$Def cannot be cast to clojure.lang.IFn

17:08 nbeloglazov: о_О

17:08 Bronsa: wtf.

17:09 mr_rm: oh... no. ccw is using 1.3 i think

17:09 Sgeo: &(meta #'+)

17:09 lazybot: java.lang.ClassCastException: clojure.lang.PersistentStructMap$Def cannot be cast to clojure.lang.IFn

17:09 Bronsa: who broke lazybot

17:09 Sgeo: &(class +)

17:09 lazybot: java.lang.ClassCastException: clojure.lang.PersistentStructMap$Def cannot be cast to clojure.lang.IFn

17:09 duck1123: if you know you're going to be messing with the bot a lot, it'll respond to /query

17:09 xeqi: I might have yesterday

17:14 nbeloglazov: $javadoc Thread

17:14 lazybot: http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html

17:14 Sgeo: Isn't one of the bots a self-wiping thing?

17:16 hyPiRion: Sgeo: clojurebot is, afaik.

17:16 Sgeo: Ah

17:16 ethanis: has anyone ever seen an exception of this sort?

17:16 lnostdal: i figured i'd try nrepl.el since swank is on its way out, but it doesn't seem to be listed as a package to install via marmalade? (i've tried M-x package-refresh-contents)

17:16 ethanis: Exception in thread "main" java.lang.IllegalArgumentException: Parameter declaration if should be a vector

17:16 I've been slamming my head on it for a while

17:16 the stack trace is… opaque

17:17 https://gist.github.com/3679797

17:17 hyPiRion: lnostdal: nrepl should be there

17:17 ethanis: this is a web application, my namespace is startlabs, the .server is noir's standard server setup

17:17 ro_st: ethanis: remove all your view clj files

17:18 Bronsa: ethanis: you're doing (defn foo (args) ..)

17:18 ro_st: and put em back one at a time

17:18 Bronsa: instead of (defn foo [args] ..)

17:18 ro_st: or ignore me and listen to Bronsa

17:18 ethanis: very good tip

17:18 Bronsa: ro_st: haha

17:18 ethanis: Bronsa: I may have made a typo, I'll look into that

17:18 thank you very much for the advice, folks

17:18 Bronsa: ethanis: defn or defmacro, that is

17:18 ro_st: Bronsa speaks as one with personal experience -grin-

17:22 ethanis: you were right Bronsa, I accidentally snipped the [] from a defn by copy-pasting

17:22 nice call

17:22 Bronsa: happy to be of help

17:25 ro_st: datomic is lots of fun but the lack of people to pester for help is annoying

17:25 #datomic might as well be called #tumbleweed

17:27 you guys need to get cracking so i have someone to talk to about it :-)

17:28 lnostdal: hyPiRion: odd .. i'm not seeing it .. packages like slime etc. are missing too .. strange

17:28 duck1123: ahh the burdens of being into fringe topics

17:29 ro_st: yeah

17:29 first world problem!

17:29 my favourite first world problem: "I'm bored, but I don't want to do anything"

17:31 djanatyn: emezeske: thanks, I'm having much more fun with quil now that I read up on atoms

17:31 I assumed that they were the same as atoms in scheme, which led to a lot of confusion :)

17:33 lnostdal: hyPiRion: never mind .. i'm an idiot .. i thought emacs 24.x already had the marmalade repo. included by default

17:42 emezeske: djanatyn: Great!

17:44 djanatyn: The state stuff in quil probably has certain advantages, but I found using an atom to be just very straightforward.

17:47 djanatyn: emezeske: Yeah. I'm trying to get overtone set up now, to play with both of them together.

17:50 mmitchell: In this example, How do I create an instance of Geometry in clojure? https://github.com/neo4j/spatial/blob/master/src/test/java/org/neo4j/gis/spatial/TestSpatialQueries.java#L60

17:50 I just don't know how you translate "new Geometry[] {...}" to clojure?

17:58 thoughtmanifest: mmitchell: it's just an array of that object which the for loop iterates over. Is that what you're asking? http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html

18:24 mindbender1: Is there a way of knowing which library is requesting for a particular dependency

18:25 something keeps requesting for thneed SNAPSHOT each time I try starting a repl

18:28 emezeske: mindbender1: "lein deps :tree" might help

18:29 konr: I've managed to run a 'hello world' project in clojurescript, yet I don't know what to do next. What APIs can I use? How can I manipulate things? In my main .cljs file, there are no uses or includes, for example

18:30 emezeske: konr: You can use any JS library, for instance the Google Closure Library is available

18:30 konr: There's also jayq if you want to go down the jQuery route

18:30 konr: Or enfocus or domina

18:33 gfredericks: emezeske: does cljsbuild determine the require-order for namespaces just once?

18:33 (when running auto)

18:33 * gfredericks is just speculating about how his namespaces end up out-of-order

18:33 emezeske: gfredericks: I think that may be the case

18:33 Oh that? It's a bug in the ClojureScript compiler

18:33 * emezeske digs up a link

18:34 gfredericks: oh cool

18:34 emezeske: http://dev.clojure.org/jira/browse/CLJS-282

18:34 gfredericks: it always gets fixed by restarting cljsbuild though

18:34 emezeske: Yeah, the first time will work

18:35 I gotta run; if that bug seems to be what you're encountering, please vote or comment

18:36 Maybe at some point I'll have a chance to look at it

18:36 * gfredericks didn't know voting was an option

18:36 emezeske: :)

18:36 * gfredericks voted

18:37 konr: In an example cljs application, there is a (js/alert) call without any require. Is 'js' an automatically available namespace? If so, is it documented somewhere?

18:46 xeqi: mindbender1: its coming from trammel, which is used by leinjacker.. which is used by some lein plugins, for example lein-ring

18:46 casion: how can I improve this, or what concepts could I apply to make it more idiomatic? (besides checking for file end) https://www.refheap.com/paste/4956

18:46 xeqi: lein deps :tree doesn't help with finding out plugins deps :/

18:51 basicsensei: hey guys, is it possible to have *use-context-classloader* set to false before clojure loads itself ? as to avoid this error: http://pastebin.com/atUEgBQL

18:51 without having to recompile clojure

18:52 gfredericks: konr: js/foo gets compiled directly to "foo"

18:52 so I guess it's a way to refer to global stuff in the js runtime

18:52 I don't know if that's the permanent solution for doing things like that

18:52 but it works for now

18:53 mmitchell: oops, i posted this a while ago but lost my connection... my question was: how do you translate this (java) "new Geometry[] {...}" to clojure?

18:53 an example: https://github.com/neo4j/spatial/blob/master/src/test/java/org/neo4j/gis/spatial/TestSpatialQueries.java#L60

18:54 gfredericks: mmitchell: http://clojure-log.n01se.net/#17:50

18:54 xeqi: mmitchell: (into-array Geometry [...})

18:55 mmitchell: awesome thank you!

18:55 xeqi: * ])

18:59 gfredericks: does clojurescript have with-redefs?

18:59 TimMc: mmitchell: Are you converting that Java code?

19:00 basicsensei: TimMc: is there a better way ?

19:00 to convert that java code

19:01 mmitchell: TimMc: yes, converting it to clojure

19:04 gfredericks: basicsensei: depends on how strictly he needs to preserve what the code does

19:05 e.g., does he really need an array?

19:05 * gfredericks assumes "he"

19:06 TimMc: Right, mmitchell doesn't need an array -- [shortLineString longLineString] is sufficient for iterating over, if you want to iterate over it.

19:06 basicsensei: I was thinking maybe there's some kind of automation that does java to clojure, and that's why he asked; or that he wanted to suggest a different project which already had neo4j converted or simply use clojure java interop, or a project that uses that existed already

19:07 mmitchell: actually, i just had no idea how to make that code work in clojure (not a java programmer)

19:11 basicsensei: regarding my first question for this session, I was hoping leiningen had an option in project.clj like ':warn-on-reflection true' which (if that's even possible at that stage, before clojure loads that is) would allow setting *use-context-classloader* to false to void this error: http://pastebin.com/atUEgBQL

19:12 avoid*

19:48 shouldn't leiningen yell when invalid options are encountered in project.clj ? ie. I had :java-source-path "javasrc" but for 2.x should've been :java-source-paths ["javasrc"] (notice the extra "s")

19:54 gfredericks: I don't think lein could reasonably determine what an invalid option is, given plugins can use arbitrary options

19:59 basicsensei: plugins for lein? maybe each plugin can "register" every valid option so that lein can check that and detect if it's valid? I mean, it would seem better than assuming your option is handled but at the same time not knowing if it is or isn't

20:00 S11001001: basicsensei: ah, the old typed versus untyped problem :]

20:00 basicsensei: java vs clojure ? :)

20:01 that's actually what I am afraid of with clojure, that errors are simply ignored and you wouldn't even know there would be one

20:01 well I mean, in cases like above

20:02 it's not that it cannot be programmed to handle those cases, it's that it allows those to go unnoticed by default; well at least that's my first impression

20:03 S11001001: basicsensei: java is a typed straw man, doesn't even have higher kinds

20:04 basicsensei: but yes, asking for options to be registered explicitly is just asking for types, so it is a philosophical black hole when it comes to clojure

20:05 seancorfield: project.clj is just a map - it can have arbitrary key/value pairs in it

20:05 basicsensei: seancorfield: I understand that, but there are no checks being done by lein to see if those keys are valid "options", and coming from java let's say, I would've expected that

20:06 seancorfield: for example it could have options for a plugin that you are not using - is it then still a valid project.clj file? yes - if the plugin is not used, the option is ignored, if the plugin is in use then the option is used

20:07 basicsensei: that makes sense, but in that cause I would want to see maybe a warning if not an error

20:07 seancorfield: java doesn't validate that every entry in a configuration file is valid / used

20:07 shaunxcode: duck1123: added the jsedn bin you requested on latest version so you can pipe edn forms to it and us -s "x y z" path style to explore

20:08 seancorfield: if i develop a library and use a custom plugin locally for some development task, i should be able to ship that library - still containing options for that plugin - and have people use it regardless of whether they have that plugin installed or not

20:08 otherwise my library will break for users without that plugin - which would be silly

20:10 basicsensei: seancorfield: but what if that plugin being installed and used is a requirement to compile that library (btw, I noticed that project.clj is included inside the uberjar , am I to understand that the options inside it are used also after the jar is compiled, like at runtime?)

20:11 seancorfield: if the plugin is a _requirement_ i'd list it in the :plugins section and lein would automatically download it :)

20:11 i'm talking about _optional_ plugin usage

20:11 and, yes, it's possible that options apply at runtime if you do, say lein run on that project

20:12 basicsensei: ok, but look in my case above, i had an obsolete option :java-source-path in project.clj which while it existed lein uberjar would still work, but it wouldn't also include a .java class, and it took me a while to realize, but if a warning for that option would've been issues, so much time would've been saved

20:13 seancorfield: if you think lein 2 should give a warning if it sees the lein 1 java source path option, open an issue on lein's github repo

20:14 but remember that some projects are actually set up to run with both lein 1 and lein 2 (not many, admittedly)

20:15 so it isn't necessarily an error to see lein 1 options in project.clj when running lein 2 (unless, i guess you've explicitly specified the minimum lein version as an option as well?)

20:16 but i'm pretty sure an application can pull options out of project.clj at runtime if it is run via lein, so the options in there don't necessarily relate just to plugins...

20:16 basicsensei: I hear you, :min-lein-version "2.0.0" ? I'll add that too, thanks

20:17 seancorfield: ok, dinner time... curry is calling!

20:17 basicsensei: that's good to know

20:17 djanatyn: say I have a map, {:foo nil :bar nil}. how can I return a new map which is the same but with :bar being 100?

20:18 I'm doing this because I have maps that contain the state of Things, and I want to modify just a certain part of a Thing usually

20:19 gfredericks: assoc

20:19 ,(let [ihaveamap {:foo nil :bar nil}] (assoc ihaveamap :bar 100))

20:19 clojurebot: {:foo nil, :bar 100}

20:19 basicsensei: ,(assoc {:foo nil :bar nil} :bar 100)

20:19 clojurebot: {:foo nil, :bar 100}

20:19 djanatyn: sweet, thank you!

20:20 hey, can we do the same thing with records?

20:21 gfredericks: totes

20:21 djanatyn: omg it worked

20:21 that's so excellent

20:22 gfredericks: I think the community consensus is that records are rather advanced though; so without knowing what you're doing, if you just learned about assoc then you probably don't need records

20:22 djanatyn: (defrecord Foo [bar]) (assoc (Foo. nil) :bar 100) ;=> Foo{:bar 100}

20:23 gfredericks: djanatyn: you can also assoc extra keys onto a record

20:23 djanatyn: well, I've used records in haskell before, and clojure records seem pretty similar

20:23 gfredericks: if you want to really have a wild time

20:23 djanatyn: the protocols remind me of java interfaces, like they said in a blog post I read

20:24 in haskell the record syntax was prett funky; if I understand correctly, there's been a lot of campaigns to clean it up

20:24 but this is really cool, just using assoc to mess with records!

20:24 gfredericks: djanatyn: it depends on how concerned you are about what "idiomatic clojure" is; I don't want to imply that you _ought_ to be concerned about that

20:25 hiredman: djanatyn: protocols are more like typeclasses in that they are open ended

20:25 (compared to java interfaces)

20:26 djanatyn: now that you mention it, I can think of places I've used records where simple maps would have been sufficient

20:27 gfredericks: djanatyn: it's probably somewhat of a static vs dynamic aspect as well

20:27 djanatyn: when should you use a regular map, and when should you use a record? is it appropriate to use records if you're not going to make any protocols?

20:27 Sgeo: djanatyn, keep in mind though that using Clojure maps for stuff is not type safe the way using Haskell records is.

20:27 Haskell does have Data.Map which you could use but it's ugly because it's not type-safe

20:28 To assume that, say, you have a key "mykey"

20:28 gfredericks: I'm curious how much people use records. I've seen a lot more uses for protocols and deftype together

20:28 usually for libraries or bootstrapping the language

20:28 tomoj: records have faster access to defined fields

20:28 so _after_ you profile, you might make some defrecords for performance

20:29 gfredericks: good point

20:29 more like structs I guess :/

20:29 what about defrecords with protocols?

20:30 Sgeo: Clojure maps are less painful than Haskell records, but keep in mind that you're losing typesafety.

20:30 tomoj: I don't think I've done that yet..

20:30 gfredericks: I feel like people are inclined at first to see defrecord as a solution for business objects

20:30 tomoj: seems wrong

20:30 nodename: Hi, I just posted a problem to the Clojure Google group: "Can't start Rhino repl for ClojureScript". Would love it if someon can help

20:31 tomoj: if it's data, it shouldn't be a business object, if it's not data, why is it a defrecord?

20:31 wish I could run a query to find all examples of defrecord w/ protocols on github

20:32 gfredericks: tomoj: I don't understand "if it's data, it shouldn't be a business object"; I must be missing at least one of your definitions

20:33 hiredman: NoBusinessObjects

20:33 tomoj: I only have a vague idea what 'business object' means

20:33 hiredman: it'sa dual of NoSQL

20:33 gfredericks: yes me too

20:33 what I meant by it (since I used it first)

20:34 is maybe "domain objects" but not using the word "object" in any kind of programming language sense

20:34 hiredman: domain data

20:34 gfredericks: you know the typical user and account and client and etc

20:34 sure

20:34 domain data

20:35 so tomoj your first phrase was just that domain data should be in maps and not custom types?

20:35 tomoj: well, either maybe

20:35 as an example my domain right now is neural networks, and I have a (defrecord Node ...) for performance

20:35 duck1123: I use a lot of defrecords for that purpose. I find it's useful to have a type you can dispatch on

20:35 tomoj: but the Node doesn't know how to activate itself

20:36 that logic is agnostic to the type, just takes any associative

20:36 gfredericks: duck1123: you have protocols for your domain data?

20:36 duck1123: I haven't used too many protocols. A lot of the design was done with multimethods

20:37 some of it predates protocols

20:37 hiredman: :(

20:37 gfredericks: satisfies? is not a function in cljs?

20:37 Sgeo: You could dispatch on the value of a key in the map

20:37 Rather than dispatching on type

20:38 hiredman: duck1123: if you are using multimethods using records for "performance" is just silly

20:38 duck1123: originally, way back, I used metadata on the maps

20:38 gfredericks: hiredman: duck1123 didn't mention perf I don't think

20:38 duck1123: hiredman: it's not for perf

20:39 hiredman: multimethods are slow, and until 1.5 goes out they have locking overhead

20:39 gfredericks: tomoj likes perf, duck1123 likes type dispatch

20:39 FIGHT!

20:39 Sgeo: I still want to bring lenses into the picture

20:40 (Composable thingies that conceptually know how to "get" and "modify" (not really modify but like what assoc does) a location)

20:40 duck1123: I'm actually dispatching on more than just the type of a record, so while protocols may be able to replace some of it, I'd still need multimethods for the rest

20:41 solussd_: is there a clojure reader macro that repeats the last evaluated form in the repl? Also, is there a reader macro for the last result?

20:42 tomoj: I guess you might sensibly implement IComparable or IPrintable or the like in a defrecord?

20:42 gfredericks: solussd_: *1 isn't a reader macro, but holds the last result

20:42 solussd_: cool

20:43 gfredericks: doubt there's anything for "replay last form"

20:44 tomoj: er, IPrintWithWriter

20:46 Sgeo: Hmm, I guess I should make the "throw two functions together" form of lenses be a deftype rather than a defrecord?

20:48 gfredericks: Sgeo: are lenses some kind of abstract nonsense?

20:48 Sgeo: They might be somewhat abstract but how are they nonsense?

20:49 Are monads "abstract nonsense"?

20:49 http://hackage.haskell.org/packages/archive/data-lens/2.10.2/doc/html/Data-Lens-Common.html

20:49 casion: monads are abstract nonsense :P

20:50 gfredericks: oh this is starting to sound familiar

20:50 tomoj: try e-prime

20:51 gfredericks: is it reasonable to aim to spend my time around strange loop finally learning the heck out of some haskell?

20:51 I would need something non-trivial to do with it

20:51 casion: write a file handling library in it then

20:52 Sgeo: There's an e-prime form, but it seems abandoned

20:53 *forum

20:54 hiredman: lens are years of researchers trying to write update-in and get-in

20:55 xeqi: my goto non-trivial programs is a calculator

20:55 mmitchell: TimMc: Hey there, so the java interop, iterate thingy... I'm still not understanding this syntax: "new Geometry[] { shortLineString, longLineString }" and how you convert that into clojure?

20:55 xeqi: "1 + 1" -> 2

20:55 etc

20:56 Sgeo: With update-in and get-in can you use a smart selector, let's say, one that ... reverses stuff

20:56 xeqi: mmitchell: that says make an array of two elements, shortLineString and longLineString

20:57 if I remember the java example you're porting, its put directly into a for loop

20:57 gfredericks: [short-line-string long-line-string]

20:57 xeqi: so the clojure equiv might be (for [x [short-line-string long-line-string]] ....)

20:57 Sgeo: In order for get-in and update-in to work, the strucuture needs to recognize the keys. Lenses do not need to be recognized by the structure being retrieved from or modified.

21:02 mmitchell: xeqi: ok, so isn't it creating an instance of Geometry?

21:03 gfredericks: mmitchell: it's creating an instance of Geometry[] which is an array of Geometrys

21:03 mmitchell: gfredericks: ahh! I get it now, thanks.

21:05 gfredericks: ~hurray

21:05 clojurebot: \o/

21:09 gfredericks: single-bit probabilistic circuits are fascinatingly trivial

21:09 Sgeo: I think maybe the idea of monads should be modified a bit to work better in a Clojure environment

21:10 There are a lot of Clojure macros and concepts that are similar to various monads, but easier to use.

21:10 If using monads could result in similar simple macros, that would be ideal.

21:28 xeqi: maybe they augmented ones should be called marshmellows

21:40 Sgeo: xeqi, marshmellow burritos?

21:46 xeqi: sattvik: leinjacker 0.2.0 -> trammel 0.7.0 -> thneed 1.0.0-SNAPSHOT = sadness

21:46 gfredericks: a thneed is a thing that everyone needs

21:48 thneed must be fogus's useful

21:49 Sgeo: # thneed

21:49 FIXME: write description

21:49 ## Usage

21:49 FIXME: write

21:50 https://github.com/fogus/thneed/blob/master/src/fogus/thneed/cps.clj

21:50 This could be written to use a function and then the macro just puts its body into a ... hmm, n/m

21:50 * Sgeo would need to rethink that a bit

21:55 cark: ah technomancy, now you're nitpicking for the sake of it

21:55 case in point : look at the update-val function at https://github.com/clojure/algo.monads/blob/master/src/main/clojure/clojure/algo/monads.clj

21:56 it uses (get s key) and really couldn't do it any other way without CL's setf =)

21:58 S11001001: cark: I think you mean to be talking to me

21:58 cark: oh !

21:58 well you ! with the number name !

21:59 i wouldn't cry bug if my case wasn't well researched

22:00 and have no fear for double negation =(

22:00 S11001001: and instead of setf, you use a lens

22:01 cark: i don't know much about these

22:01 S11001001: cark: essentially it is the pair of getter and updater functions

22:02 cark: here's a quick hack that uses the idea with algo.monads a bit: https://bazaar.launchpad.net/~scompall/+junk/clojure-stuff/view/head:/src/com/nocandysw/cloj_dummy/punch.clj#L13

22:03 cark: and edwardk wrote a tutorial: https://github.com/ekmett/lens/wiki/Tutorial

22:04 cark: i'll be looking at it

22:04 S11001001: cark: indeed, scalaz has lots of functions for working with lenses directly in combination with states

22:06 cark: i hape reading scala code =( that's one language i never really tried

22:08 Sgeo: Oh hey so there's already a lenses library for Clojure?

22:08 S11001001: Sgeo: not that I'm aware of

22:08 Sgeo: Oh, so what's fetch-val?

22:08 cark: S11001001: I'm wondering why you are so bent on refusing a fix for set-val ?

22:09 S11001001: Sgeo: a simple function for working with states in algo.monads

22:09 Sgeo: erm, focus

22:09 Ah... hmm

22:09 S11001001, oh, btw, I officially hate m-lift

22:09 cark: Sgeo: haha yes, it's always doing almost what i want too !

22:09 Sgeo: Although I shouldn't say anything until I actually _test_ my replacement

22:09 cark: but not quite

22:09 S11001001: cark: you mean fetch-val? For one, I *like* its current behavior, and use it with arbitrary functions in the file I linked above

22:09 Sgeo: https://github.com/Sgeo/algo.monads/blob/master/src/main/clojure/clojure/algo/monads.clj#L270

22:10 cark: S11001001: well then, why not write an additional function that does what you want

22:10 and keep this one as is

22:10 as should be i mean !

22:11 S11001001: cark: because writing your fetch-val as a specialization of the current fetch-val is easier than the other way around, which means that fetch-val as-is is more primitive

22:11 cark: you have to admit that there is a logical problem when you consider the rest of the -val functions

22:12 Sgeo: I think a lens library should be independent of a monad library, and provide things to make working with the monad library easier, but not require it

22:12 Also, that last line I feel like I'm talking in the style of someone I know in a different channel

22:12 S11001001: maybe, but consistency isn't a good enough reason to lose primacy

22:13 and resolving things with doc updates has a proud history in the clojure community

22:13 cark: S11001001: I'm sorry, I can't go and use it as it is, because it will be fixed some day. And then the code calling it to work around that bug will need to be rewritten

22:13 S11001001: cark: I doubt it

22:14 ,(let [x (to-array [42]) xv (vec x)] [(xv 0) (do (aset x 0 33333) (xv 0))])

22:14 clojurebot: [42 33333]

22:14 S11001001: ^^^ solved with a doc change

22:16 cark: I think your function (the one currently there) should also exist, but it should have another name, or all the -val functions should change name i don't care, it is very possible to both have consistency and what you want

22:16 S11001001: a more useful enhancement would be to update the other state primitives to work with lenses

22:18 cark: you've been using this function in a non documented way, taken advantage of a bug, and now you want to block a fix.

22:19 S11001001: no, I think the docstring was just wrong, and the fix should be made to the docstring

22:19 that's not "block[ing] a fix"

22:20 anyway I have no such powers; unlike technomancy, I have no position in the clojure community, just an interested programmer

22:20 cark: i don't know how i thought you were him =)

22:20 anyways !

22:20 S11001001: sometimes I report things that I think are bugs but get fixed with doc updates instead; sometimes I disagree with that resolution, but such is as it is

22:21 cark: when i look at this function as it is right now, i feel like the guy who wrote it didn't think about all implications not only with this bug, but also with the efficiency thing, and coding standard

22:22 S11001001: Like technomancy, I have contributed code to lein; there is a significant difference of degree though :)

22:25 cark: notice also the with-state-field function, it also works with keys of any type

22:26 but really, i feel that this whole bunch of functions does not belong in the monad library itself

22:26 S11001001: probably not

22:27 they aren't terribly useful as-is

22:27 cark: i need to find some tutorial on lenses and check that out .... with haskell rather than ugly scalla =)

22:29 S11001001: true; edwardk's tutorial linked above is for his relatively new and popular lens library for haskell

22:29 as for algo.monads problems, I find http://dev.clojure.org/jira/browse/TMACRO-1 more pressing

22:30 Sgeo: Oh hey maybe I can complain about m-lift there

22:34 seancorfield: Bugs rarely get fixed without patches, in my experience, unless the library maintainer themselves runs into the same bug repeatedly...

22:34 (of course, to submit a patch, you have to be a signed up contributor)

22:35 Sgeo: I have a replacement for m-lift

22:35 Just need to actually test it somehow

22:35 seancorfield: but, hey, if a bug is annoying enough that should be incentive to sign & mail the CA :)

22:35 S11001001: Sgeo: btw the new lens library is "lens", which will probably deprecate "data-lens" at some point

22:36 * seancorfield wonders how many people are actually using algo.monads?

22:36 cark: hum i won't go the trouble for a 3 line correction...

22:36 either a maintainer maintains, or a glaring bug stays in the algo.monad !

22:36 Sgeo: seancorfield, jimduey has a separate monad library using protocols

22:39 casion: how can I improve this, or what concepts could I apply to make it more idiomatic? (besides checking for file end) https://www.refheap.com/paste/4956

22:40 S11001001: casion: use map and into instead of reduce

22:41 casion: S11001001: why?

22:41 S11001001: casion: it's more idiomatic than using reduce, and easier to read

22:42 casion: hmm ok

22:42 all the examples of doing I/O I found used reduce, that's why I ended up with that

22:43 S11001001: casion: probably because they didn't have the forcing guarantee that into will give you

22:43 tomoj: into is just a shortcut for a particular reduce

22:43 S11001001: tomoj: a non-obvious shortcut, though

22:43 tomoj: basically reduce conj but sometimes faster

22:43 S11001001: casion: the order of preference is pretty much loop/recur last when nothing else works, then reduce, then all the other HOFs or `for' if you're into `for' for whatever reason

22:46 seancorfield: cark: i'll bring up ALGOM-4 on clojure-dev and see if anyone objects to me fixing it...

22:46 cark: seancorfield: thanks !

22:46 casion: S11001001: would there perhaps be a better way to approach creating a map from an input-stream?

22:46 cark: hum jduey's protocol based monads has a strange treatment about return

22:47 can't write generic monadic code with that

22:47 Sgeo: I should look at it again

22:48 cark: basically he says that return is just the constructor for a type, and he's right about it

22:48 S11001001: casion: your code seems fairly reasonable to me

22:48 cark: but then you need to tie your code to a specific monadic value

22:49 *but then you need to tie your code to a specific type of monadic value

22:49 casion: S11001001: ok, thank you for the advice

22:49 Sgeo: Return-type-based polymorphism would be nice (is that the right terminology?)

22:49 cark: yes

22:50 S11001001: cark: you should look at semigroupoids too sometime; they're like applicative functors that lack a natural return, so monad without return is called "bind"

22:50 cark: but really i don't feel like algo.monad is slow

22:51 Sgeo: cark, I'd imagine the problem with algo.monad is that it's excessively macroic

22:51 cark: thos you can't go around it

22:51 tho*

22:52 how do you invent a do notation without macros ?

22:52 Sgeo: cark, m-lift does not need to be a macro

22:52 cark: there is a non-macro version floating around

22:52 Sgeo: The one I wrote or a different one?

22:52 seancorfield: functions > macros :)

22:53 Sgeo: Although maybe I should make mine be curried automatically

22:53 seancorfield: (i.e., more composable and generally more usable)

22:53 Sgeo: So ((m-lift-fn foo) (m-result bar) (m-result baz))

22:53 Also, I need to test it.

22:55 cark: seancorfield: we all agree about that i think, but the do notation is really new syntax, that's a good fit for a macro

22:55 Sgeo: I think m-lift is a good example of what happens if you try to translate from Haskell and see that Haskell can't do something and assume that that means the solution is to use a macro.

22:57 Haskell does not have apply.

23:14 michaelr525: good morning

23:15 tolstoy: Is there a way to write a plugin that's inside my project for lein2, like you used to be able to do for lein1?

23:19 Hm. Maybe you can add a hook in project.clj?

23:31 Raynes: Sgeo: Is apply even possible in Haskell? With type magic?

23:32 Sgeo: apply seems like it would be non-type-safe in Haskell

23:32 Although, it is possible to have variadic functions with type magic

23:33 Raynes: Haskell is fun.

23:38 S11001001: cark: haskell "do" doesn't imply return anywhere

23:39 cark: i didn't say that

23:39 S11001001: cark: oh, I read "without macros" as "without monads", sorry :]

23:39 cark: =)

23:41 i watched Edward Kmett's talk about lenses (lots of scala to read =( )

23:41 looks like it can solve a problem of mine

23:42 i'm trying to have a very large data structur and maintain it in a purely functional way

23:43 but there are points where some collection has to have the same values that are in other collections

23:43 so i need to make some of these values, references to others

23:44 but in a purely functional way

23:44 it looks like lenses are all about that

23:49 S11001001: lenses must be applied in relation to some context

23:50 cark: right, stick eveery entity in an id-map, and provide lenses into the id-map to all entities that refer to other entities

23:50 sounds right ?

23:51 S11001001: seems okay, but at that point, what's wrong with just putting the ids in the colls?

23:52 (I haven't done anything more sophisticated than safe update-in replacement with them at this point, so can't be much help with things above that)

23:52 casion: S11001001: I have it implemented and your suggestion was fantastic. thank you again.

23:52 S11001001: casion: no prob

23:53 cark: I am currently putting id in those collections, but i like the idea of having a kind of reference there instead of just an integer

23:54 S11001001: well, as it happens, anything that is a map key also qualifies as a map lens :)

23:54 cark: indeed

23:56 see my problem is kind of like this : i have a country which is a map from social security number to people, then i have a list of houses, each house has a list of name to people ... how do i go about updating a person's hair color

23:56 each house could also have a country

23:57 so now it gets quite hairy

23:57 if working in a purely functional way

23:57 so i decided to stick everything in a map from id to entity

23:58 but 2 things are bothering me

23:58 S11001001: you also have sequence item lenses, and lenses are morphisms so can be composed end-to-end

23:59 indeed update-in is just map map-lens followed by a composition fold, then using that lens for the update

23:59 cark: right, i watched the talk, it looks great to go down the tree

Logging service provided by n01se.net