#clojure log - Jan 25 2012

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

0:00 skelternet: Thank you, dnolen

0:00 dnolen: as you can see it can get complicated, easier to see if you use an editor that has pretty-printed macroexpansion

0:00 skelternet: lack of pretty-printing was what killed my interest in lisp in college

0:01 they had us using some sort of environment that ate up white-space, too. was terrible.

0:02 clj_newb: println is kinda like cout; does clojure have osmething like cerr? (I hate it when my debugging print statements gets interleaved with the java stack trace exception) = hard to read

0:02 skelternet: ,(macroexpand '(doseq [i [1 2 3 4]] (print i)))

0:02 clojurebot: (loop* [seq_67 (clojure.core/seq [1 2 3 4]) chunk_68 nil count_69 ...] (if (clojure.core/< i_70 count_69) (clojure.core/let [i (.nth chunk_68 i_70)] (do (print i)) (recur seq_67 chunk_68 count_69 (clojure.core/unchecked-inc i_70))) (clojure.core/when-let [seq_67 (clojure.core/seq seq_67)] (if (clojure.core/chunked-seq? seq_67) (clojure.core/let [c__3921__auto__ (clojure.core/chunk-first seq_67)] (...

0:03 jayunit100: dnolen i tried to make the clojure meetup in ny last wk but got busy ---- any chance of another one on the east coast soon where we do some intermediate lisp thinking / clojure programming .

0:03 adam_: jayunit100, nice blog, i have read a couple of your entries!

0:03 jayunit100: cool thanks adam :]

0:03 adam_: no problem, I'm trying to use clojure for some bioinformatics stuff myself

0:04 dnolen: jayunit100: definitely! I try to go everytime but I had to miss the last one as well

0:04 jayunit100: yeah. what are the odds that we schedule to do one in new haven. ... how many people you think would come ?

0:04 Raynes: clj_newb: (binding [*out* *err*] (println "some message"))

0:05 jayunit100: adam_ you should contribute to RudolF with us.

0:05 https://github.com/jayunit100/RudolF

0:05 clj_newb: Raynes: nice

0:07 adam_: okay, that sounds good, I have been trying to get involved in a project

0:07 clj_newb: Raynes: nice; thanks

0:07 jayunit100: u on github?

0:07 @adam_

0:08 adam_: yeah, adamwespiser is my username

0:08 * Raynes twitches

0:08 jayunit100: @adam_ what type of bioinformatics do you do ?

0:09 adam_: i am working in structural biology

0:09 mostly on protein-protein interaction site prediction methods

0:09 jayunit100: aweseome well you'll love the examples in RudolF. Integration with the PDB structural utilities.

0:09 skelternet: flashbacks to my summer at ciba-geigy

0:09 adam_: yeah, check out the code base I am working on:

0:10 jayunit100: check this out : http://writequit.org/papers/files/RudolF.pdf

0:10 dnolen: so is anyone offended by the inclusion of IFn to ClojureScript? It's now fully baked - https://github.com/clojure/clojurescript/compare/master...96-ifn

0:10 adam_: http://pfaat.sourceforge.net/ is my boss's project that I contribute to

0:12 jayunit100: has this paper been submitted anywhere?

0:12 amalloy: dnolen: what would be the reason for being offended? because js already has first-class functions and it's silly to invent our own, or what?

0:13 jayunit100: yeah itng

0:13 adam_: nice, good luck, i think its a great idea

0:14 dnolen: amalloy: heh, no reason really, IFn inclusion moves some ugliness into the compiler so people don't have to write yucky stuff by hand when adding fn capability to their custom types.

0:15 jayunit100: adam_: BioClojure has been replaced by RudolF --- just saw you were following it .

0:16 adam_: yeah, I am going to take a look at it, I'm sure there are features I can add

0:17 jayunit100: in any case adam_ I have a publication idea i can write up if you want to help add some code. I'll ping you about it offline.

0:18 oh nevermind you have no email : email me at jayunit100@gmail.com

0:18 and ill add you to RudolF as a commiter also .

0:20 looking at pfaat this would be great for venn. that would be awesome if you could add some lispy alignment examples

0:21 adam_: okay

0:24 dnolen: bunch 'o goodies just landed in CLJS

0:33 adam_: jay, can I download the venn source code and run it locally?

0:47 chouser: dnolen: are you still around?

0:48 trying to figure out native deps via lein, using your plugin.

0:49 dnolen: chouser: off I haven't messed w/ that in ages

0:49 oof I mean

0:49 chouser: yeah, I guessed.

0:49 dnolen: chouser: it was a convention more than anything else really

0:49 chouser: your plugin looks helpful, and I've got to close.

0:50 dnolen: chouser: it never solved the packaging problem ever

0:50 chouser: I don't expect you to work through anything with me, but thought if you recognized my issue off the top of your head...

0:50 dnolen: it was just about making it easy to pull down native deps off clojars and expand them into the project folder

0:50 chouser: if I use -Djava.library.path on a manual java command line, I can load the native lib

0:51 dnolen: k

0:51 chouser: and I have :native set right in project.clj, I think, and can see a -Djava.l.p that looks right in a ps of the repl process

0:52 dnolen: and you ran- lein deps, lein native deps -in that order?

0:52 lein native-deps rather

0:52 chouser: maybe not. let me try again.

0:54 UnsatisfiedLinkError

0:54 I don't get it. Using ps I definitely see -Djava-library-path=/home/chouser/shadowfax/native/linux/x86_64

0:54 amalloy: chouser: i think the flatland projects tokyocabinet and jiraph show how to bundle and use a native dependency, if i understand what you mean by the term. they work in lein (used to be cake), but Raynes is probably the guy to ask about how to do the native-specific stuff

0:55 dnolen: hmm, sounds like the path isn't right

0:55 Raynes: For native deps to work properly, you need to be using leiningen off of the 1.x branch.

0:55 chouser: ls at that path shows my .so's

0:55 Raynes: Otherwise it wont set java.library.path

0:55 chouser: this is lein 1.6.2

0:56 (System/getProperty "java.library.path") does *not* show my path

0:57 oh

0:57 Raynes: You don't need to run 'lein native-deps' at all.

0:57 It just works.

0:57 And you don't have to set :native either.

0:57 technomancy: jkkramer: did you evaluate neo4j for clojuresphere at all?

0:57 chouser: lein is using -Djava-library-path. Running java manually with -Djava.library.path works

0:58 Raynes: chouser: Yes, that's what I fixed in the 1.x branch of Leiningen.

0:58 Which is what I just told you, BUT YOU DON'T LISTEN TO ME!

0:58 Bah!

0:58 dnolen: chouser: perhaps native-deps is getting in the way :)

0:58 chouser: dashes simply don't work. dots do.

0:59 Raynes: I'm running 1.6.2. How is that not 1.x?

0:59 Raynes: It has to be specifically from the git repo 1.x branch.

0:59 And a relatively recent commit on said branch.

0:59 chouser: oh

1:00 Raynes: It will be in the 1.7.0 release.

1:00 jkkramer: technomancy: i did not. does heroku support it?

1:00 Raynes: jkkramer: Yep.

1:00 technomancy: chouser: this is something I broke in 1.6.mumble

1:01 chouser: ok

1:01 * Raynes shakes his fist at technomancy

1:01 technomancy: jkkramer: specifically asking because of http://neo4j-challenge.herokuapp.com/

1:02 chouser: so my plan is to git clone lein and symlink ~/bin/lein to something in the git repo. Is that a sane plan?

1:02 I'm a lein newb and don't understand how it installs itself

1:02 technomancy: chouser: absolutely respectable

1:03 chouser: also acceptable would be to fall back to 1.6.1 stable or 1.5.2, I can't remember which version introduced the bug

1:03 Raynes: technomancy: I don't support that.

1:03 jkkramer: technomancy: interesting. been meaning to play with neo4j

1:03 Raynes: technomancy: No version behind 1.6.2 works with lein-newnew for some reason.

1:03 technomancy: o_O

1:03 odd

1:03 Raynes: Never did figure out why.

1:03 technomancy: maybe InsufficientUnicodeException?

1:04 Raynes: I don't think so. Look at the closed issues for lein-newnew.

1:04 technomancy: joke ruined!

1:04 Raynes: Oh. I didn't catch it.

1:05 technomancy: referring to the lack of © in newnew skeletons

1:05 Raynes: I assume that even the most ridiculous exceptions are plausible with any Clojure code using Java code.

1:05 technomancy: the readmes thereof

1:05 Raynes: Yeah, I'm going to get to work on all of those issues and such soon. Probably tomorrow.

1:07 technomancy: hah; no rush

1:10 chouser: heh. where'd rlwrap go?

1:10 brehaut: a circle of hell?

1:10 or am i thinking of jline

1:11 hiredman: jline

1:11 rlwrap is the one that works with unicode

1:12 brehaut: i'll rescind that joke then

1:15 chouser: so this snapshot lein seems to set the native lib path correctly, but doesn't use rlwrap

1:18 the jar I built has a 'native' dir that seems to be unpacked correctly, but it has a 'lib' dir with jars in it that are not on the classpath in lein repl

1:19 do my java .jars belong somewhere else besides in the 'lib' dir next to the 'native' dir?

1:20 hiredman: what does lein classpath say?

1:23 chouser: it includes my native-deps.jar but not the .jars inside it.

1:23 technomancy: http://p.hagelb.org/lein-os.png

1:23 hiredman: oh

1:23 I see you have one of those weird things that is like an uberjar but not

1:24 chouser: I made my native-deps.jar according to the instructions for dnolan's native-deps plugin

1:24 technomancy: jars-inside-jars isn't supported; it's just the native .so-and-friends extraction that leiningen does

1:25 chouser: so I need separate deps for the .jars and the .so's they depend on?

1:25 hiredman: chouser: I think dnolen's plugin might have been from before lein got it's own native deps handling

1:25 chouser: hiredman: yes, I'm getting that impression. So I'm trying to learn how I ought to do it now.

1:25 technomancy: chouser: not necessarily; you could put the .so's in the same jars as the .class files

1:26 chouser: ah. hm.

1:26 technomancy: I didn't realize the old jars-in-jars was actually documented somewhere.

1:26 brehaut: technomancy: i was expecting a screenshot of a lein based distro

1:26 technomancy: chouser: where were you when I was trying to get testers when I was implementing this? =)

1:29 chouser: heh. The last time I touched any native deps was when writing clojure-jna.

1:29 technomancy: chouser: improved native-deps creation and documentation has been on the roadmap for a while; it's just a bit hard to find people interested in giving feedback. so expect a few pings down the line.

1:30 native-deps consumption should make it into lein2-preview; creation might be a bit further off.

1:30 anyway, off to bed

1:30 feel free to ask on the mailing list if you get lost

1:30 chouser: that was about 6 months before your initial commit to lein. :-)

1:30 technomancy: hah

1:31 chouser: technomancy: if we end up using this for work, it's likely I'll be able to pitch in for docs, testing, etc.

1:53 unlink: Is there a function like this in the stdlib? (defn tails [xs] (when-let [s (seq xs)] (cons xs (lazy-seq (tails (next xs))))))

1:54 hiredman: ,(doc iterate)

1:54 clojurebot: "([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects"

1:59 unlink: True, it could have been written (defn tails [xs] (take-while identity (iterate next xs))).

3:01 clj_newb: Is there a way to have clojure compile errors (resulting rom load-file) to report the _full_ name, relative to `pwd`, rather than just the filename

3:33 Blkt: good morning everyone

3:37 casperc: good morning

3:55 kral: morning pals

4:02 muhoo: is there a way to tell the lein repl which port to listen on?

4:03 raek: muhoo: yes, check out sample.project.clj in the Leiningen docs

4:04 muhoo: ah, cool :repl-port, thanks

4:17 using the jdbc stuff. it seems like everything is wrapped in with-connection.

4:17 is there a way to store a connection somewhere globally, and then use it multiple times, instead of having to open and close connections with with-connection all the time?

4:18 or, alternately, wrapping the whole program inside with-connection?

4:27 casperc: Is there a good way to set up a thread or daemon to perform a task at certain intervals?

4:29 in my specific case i want to check an event queue for new events to react to, but that's not important. Could be any task

4:40 llasram: muhoo: That's the sort of thing people tend to use ^:dynamic *vars* for

4:42 casperc: java.util.Timer?

4:48 casperc: llasram: hmm, might be a good option

4:50 Raynes: casperc: Would a thread that loops and sleeps for a certain amount of time be too simplistic?

4:51 llasram: casperc: If you need complicated stuff there's http://quartz-scheduler.org/ for which there's even https://github.com/pingles/clj-quartz, but I've never used either

4:52 casperc: Well, I would want a way to pause it and generally inspect its state (not quite sure yet what this would entail)

4:54 llasram: i hadn't thought of quartz actually. That might be a good option.

4:55 In essence we have a bunch of things which we will want to do a regular intervals. We want to be able to pause these tasks and inspect the state

4:56 I'll probably end up making a dashboard for it.

4:58 llasram & Raynes: thanks for the input. I'll have a look at quartz so see if it fits our needs :)

4:59 Raynes: 'our'. We are legion!

5:00 bluezenix2: Are there methods to inspect a deftype? Say i have (deftype Dude [name, age]) ; is there a way to get a vector of [:name :age] or something simlar?

5:01 (props-or-whatever Dude) ; => ["name" "age"]

5:03 llasram: bluezenix2: defrecords will implement the map interface for you by default, but deftypes are barebones, so you'll need to implement anything like that yourself

5:05 bluezenix2: right

5:15 morphling: bluezenix2: deftype (on the jvm at least) creates a class, so you should be able to get this information through reflection

5:31 student1: test

5:32 you don't have to register nowadays, to be able to speak in #clojure?

5:32 raek: yeah

5:32 student1: ok

5:54 bluezenix2: when using (defrecord Dude [name age]) ; i can use (keys (Dude. "blue" 12))

5:55 but what I want is to find the properties a Dude is allowed to have

5:55 like (keys Dude)

5:55 i can't construct a temporary Dude

5:55 so i guess i'll have to dig into java reflection?

7:59 samaaron: /

8:03 Raynes: howdy

8:15 TimMc: bluezenix: You can create a map, and once it has all the attributes, convert it into the record. (I think...)

9:07 aidanf: Hi all,

9:07 Can anyone tell me why this doesn't work as I was expecting?

9:07 http://pastie.org/3249922

9:08 I was expecting the output from the two threads to be mixed up.

9:08 But it seems to run all the way through f1 before starting f2 i.e. the threads are not running concurrently

9:10 TimMc: aidanf: That'll happen. Try a longer run e.g. 1e5, or just add some .sleeps in there.

9:12 aidanf: Thanks TimMc

9:13 clgv: aidanf: it works over here with my dualcore cpu

9:13 TimMc: To test concurrency stuff, you often have to simulate it with sleeps. :-/

9:14 aidanf: cljv: Thanks, works for me now after adding Thread/sleep

9:14 TimMc: or long-running processes with lots of jittery computations.

9:14 clgv: TimMc: I never tested - does thread creation consume a decent amount of time?

9:15 looking at my run I'd say that shouldnt be the problem

9:16 TimMc: aidanf: Even running your original one several more times should get you some interleaving occasionally.

9:21 aidanf: TimMc: I tried it several times without sleep and got the same every time. Playing with it now - for small (range n) and no sleep I never see interleaving. If I add sleep or make n really big I see the results interleaving.

9:23 AWizzArd: clgv: Creating threads can be expensive. Typically I follow the rule of thumb that a calculation should take at least one msec for it to be outsourced into its own future or agent.

9:25 clgv: AWizzArd: yeah thats true. although 1ms isnt enough. in one of my experiment I parallel tasks with 20ms and the overhead ruined the performance

9:31 AWizzArd: clgv: I tried this:

9:31 ,(time (count (map (fn [_] (Thread/sleep 1)) (range 1000))))

9:31 clojurebot: "Elapsed time: 2206.241 msecs"

9:31 1000

9:31 AWizzArd: vs

9:31 ,(time (count (pmap (fn [_] (Thread/sleep 1)) (range 1000))))

9:31 clojurebot: "Elapsed time: 322.43 msecs"

9:31 1000

9:31 AWizzArd: The example with map took just a bit over one second on my machine, as expected.

9:32 The second one runs here in 60 msecs.

9:32 clgv: ok. I had an algorithm with lots of double operations

9:35 AWizzard: btw. pmap has its "lazy problem" that it in fact does not do good cpu utilization since it tries to be lazy and the last task of a batch can prevent moving pmaps sliding window further.

9:35 thats almst only a problem when parallelizing tasks with different runtimes.

9:40 AWizzArd: clgv: but my example from above is flawed anyway, because when one Thread is sent to sleep then that thread becomes free for other jobs. This way I can have pmap running 25 threads that each sleep for one second within around one second, on 4 cores.

9:41 clgv: Awizzard: yes thats true. you need an active waiting loop ;)

9:43 jsabeaudry: dakrone, Is there any facility in clj-http to access the streams directly as available in the apache httpcomponents? (I'm working with responses too big to fit in memory)

9:45 * clgv lobbying for the RAM industry: "buy more memory ;)"

9:46 AWizzArd: clgv: For example (time (count (map #(dotimes [i 10000] %) (range 1000000)))) runs in 2,8 seconds on my machine, and in 1,9 seconds with pmap. So on my system it seems that even for sub-msec tasks it is already worthwhile to run parallel.

9:47 clgv: But for a dotimes 1000 finally map is much faster than pmap, because of the threading overhead.

9:47 clgv: AWizzard: you should calc the parallel efficiency value. its not even half the time with 4 cores - that does not seem good

9:50 jsabeaudry: dakrone, Found the answer right in the doc, "Note that where Ring uses InputStreams for the request and response bodies, the clj-http uses ByteArrays for the bodies." Too bad...

9:51 dakrone: jsabeaudry: I'd like to be able to provide a stream as a response, hopefully in the future

9:54 *near future

10:15 jsabeaudry: Netty is so incredibly heavy I wonder how anyone can tolerate it

10:16 All that cpu spent in SelectorUtil.select...

10:17 lucian: jsabeaudry: are you joking?

10:19 jsabeaudry: lucian, Not at all, I'm cpu bound serving a file with netty. I do the same thing with Jetty and I get more than 10x the transfer rate

10:19 lucian, So I profiled Netty and more than 50% of the cpu time is spec in SelectorUtil.select

10:19 s/spec/spent

10:20 lucian: jsabeaudry: that sounds like a bug. select is the system call

10:20 although i'd expect netty to use epoll or something. what os?

10:21 jsabeaudry: linux, I tried both on Ubuntu and Angstrom with the same results

10:21 On the openjdk and on oracle's

10:22 lucian: it seems odd to me. i don't have experience with netty in particular, but it should behave like twisted

10:22 and use epoll when available, no cpu on I/O, etc

10:23 it sounds like a bug in netty, either in its select binding or in its sniffing of native async APIs

10:30 TimMc: jsabeaudry: Is this still on the little constrained platform?

10:31 jsabeaudry: TimMc, Yes and no, I tried on both, with the same results. The profiling was done on a regular ubuntu

10:34 gtrak``: jsabeaudry: it's odd, but any particular reason to prefer netty? jetty uses NIO, too

10:38 jsabeaudry: gtrak``, Simply because aleph is built on netty

10:39 gtrak``: I remember there being a perf issue with aleph and netty

10:40 romain_p: Hi everyone, could anyone help me understand functional programming with an example ? I am trying to represent NFAs in Clojure

10:40 gtrak``: anyone recall what that was about?

10:40 romain_p: So my initial idea was:

10:40 (defrecord NfaState [final char_transitions empty_transitions])

10:40 Using this or something else, how do I represent two nodes that point at each other?

10:41 (for instance, two nodes transitioning to one another on the character 'a', char_transistion being a map<char, nfastate> in my mind)

10:41 gtrak``: jsabeaudry: take a look at this hackernews: http://news.ycombinator.com/item?id=3135662 it might explain the discrepancy, specifically the post by prospero

10:55 jsabeaudry: Just tested it again, the only thing that changed in my code is switching from aleph/start-http-server vs noir.server/start, all the handlers are the same. Transfer rate with aleph/netty 330KB/s, transfer rate with noir/jetty 10.5 MB/s (maximum because 100Mbps ethernet)

10:57 gtrak``: on the arm?

10:57 jsabeaudry: gtrak``, yes

10:57 gtrak``: might be worth asking ##java if netty on arm sucks

10:58 jsabeaudry: gtrak``, good idea

11:10 clgv: romain_p: with immutable data you cant build direct referencing cycles. but you can build them by indirection like having edge ids and looking them up in a hash-map or such

11:11 romain_p: clgv: yup, so my graph would be a set of states, each one having a name (atom)...

11:11 gtrak``: or atoms/refs?

11:12 clgv: gtrak: you often dont want to use them if you have no real concurrency scenario there. but they might be an option if suited

11:12 romain_p: clgv: well actually, not an atom

11:13 gtrak``: clgv: if not concurrent, then they're quite fast

11:13 clgv: romain_p: you can have nodes and edges immutable if you do not insist to link them directly by reference

11:14 gtrak``: an atom's just a java AtomicReference, a loop and a CAS, so mutating one is just a CAS in single-threaded code

11:14 clgv: gtrak``: but why should I make my data representation more complicate by using them? I think it really depends on what you are doing.

11:15 romain_p: Okay, bear with me (newbie and all): why does this throw an exception?

11:15 clgv: I think you'll have to discuss "indirection vs. atoms" for your concrete problem

11:15 romain_p: (defrecord NfaState [name final char_transitions empty_transitions])

11:15 (def my-graph {(NfaState. :a false {} {:b})})

11:15 user=> java.lang.ArrayIndexOutOfBoundsException: 1

11:16 llasram: gtrak``: If you're going to use atoms that way, you might as well use `deftype' with mutable fields -- it'll be faster and the intent will be clearer

11:16 (IMHO)

11:16 Somelauw: Does clojure allow importing classes? This is probably a bad idea but sometimes convenient. For example when using Math.

11:16 clgv: romain_p: because of {:b} since you have a hash map with only the key and not the value

11:16 romain_p: clgv: OK so that's a map. How do I represent a set?

11:16 clgv: romain_p: #{:b

11:17 oops. #{:b}

11:17 romain_p: clgv: thanks!

11:17 seancorf`: anyone know if cascalog can be used with amazon's elastic map/reduce? or should i go ask on the cascalog ML?

11:17 Somelauw: So I can use sin, cos, tan directly?

11:18 llasram: Somelauw: Oh, you mean import static methods of a class? There isn't a builtin way to do that, but here

11:18 clgv: Somelauw: you can use whatever class you like by specifying it completely like java.util.Math/sin or importing it via (:import java.util.Math) within the ns statement and use it like Math/sin

11:19 llasram: s,here,there, used to be an 'import-static' in contrib, which you could rip off

11:19 romain_p: clgv: so given my previous definition, that would be a sensible method of representing graphs in clojure? : {(NfaState. :a false {} #{:b}) (NfaState. :b false {} #{:a})}

11:20 TimMc: llasram: It would also be lovely to be able to rename imports, like Math :as M

11:20 M/sin would be acceptable.

11:21 or Point2D$Double :as P2D !

11:22 clgv: romain_p: "sensible" depends how you are using them. I went with nodes and edges as deftype but both referencing with IDs

11:22 dnolen: Somelauw: make a lib (defn sin ^double [^double n] (Math/sin n))

11:25 llasram: TimMc: I've wanted that a few times, and it seems like it shouldn't be too hard, since normal importing works by interning the short name as a reference in the namespace to the class anyway

11:25 TimMc: clgv: I guess transients are no help here either, since they hide their mutability somewhat.

11:25 Somelauw: clgv: I tried (ns hello.hi (:import (java.util.Math))) on a repl and it didn't give an error, but I couldn't use sin directly. Maybe I did it wrong since I am still a bit new to clojure.

11:26 TimMc: llasram: Ooh, that would be a good group project at a meetup.

11:26 Somelauw: You'll have to do Math/sin

11:26 dnolen: Somelauw: you can't use it "directly", it's not first class

11:26 Somelauw: make a lib and then you're all set and you have something first class

11:26 Somelauw: no overhead it will inline

11:26 clgv: Somelauw: like I wrote and the others told you, it's Math/sin you can use then

11:27 TimMc: dnolen: It doesn't even need an :inline clause?

11:27 dnolen: TimMc: nope

11:27 TimMc: Because of HotSpot, or the Clojure compiler?

11:27 dnolen: TimMc: HotSpot

11:28 TimMc: OK, cool.

11:28 <3 HotSpot

11:28 Somelauw: okay, Math.sin works

11:28 * clgv tried definline before and noticed it had no real use due to HotSpot

11:28 TimMc: Somelauw: Math.sin or Math/sin?

11:29 Somelauw: Math/sin

11:29 dnolen: clgv: not true

11:29 clgv: the expansion has to be something inlineable by HotSpot

11:31 Somelauw: Math/sin probably works anyway even if nothing is included

11:32 TimMc: Somelauw: Right, java.lang.* are automatically imported.

11:33 gtrak``: Math's not a package, it's a class

12:01 chouser: dnolen: thanks for the help last night. Got some native deps working in the end.

12:03 dnolen: chouser: sorry I couldn't be of more help :) I've pretty much forgotten everything I learned as far as native-deps :)

12:12 phil_: why is (for [x (range) :when (< x 100)]) not terminating?

12:13 ah cause :when is a filter not a stop condition

12:13 sry :D

12:13 TimMc: phil_: :while

12:13 phil_: TimMc: thx

12:14 semperos: way to see docs for fn's at cljs repl?

12:14 TimMc: or [x (range 100)], but I assume that was a simplified example

12:14 dnolen: semperos: nope, I created a ticket for that in JIRA today.

12:14 semperos: dnolen: sweet

12:15 any metadata-querying abilities?

12:15 phil_: TimMc: yeah i need to go through some seqs lazily while some condition holds

12:15 semperos: I saw meta in the source, but not sure on status of things

12:15 dnolen: semperos: metadata on the actually source is not available from the JS side,

12:16 semperos: open question on how to best provide access to that stuff

12:16 semperos: dnolen: understood; happy to have it done right vs. fast

12:16 dnolen: it exists, it's just a matter of how to get to it

12:16 currently hooking into the analyzer from CLJS REPL means a macro

12:17 but it's a macro that can never work in your actual source

12:17 semperos: :)

12:17 dnolen: oh rather a macro is one way, not sure if it's the best

12:18 another interesting way might be a reflection system, where the JS communicates back w/ the compiler/analyzer

12:19 then we can avoid the macro goofiness. perhaps a special reflect namespace or something ...

12:19 semperos: right

12:24 llasram: How reasonable would it be to try to get '_' added as an "internal whitespace character" (for lack of a better term) in numeric literals, like in Ruby? Ex: (= 50_000 50000)

12:25 dnolen: llasram: low I imagine

12:25 llasram: Oh?

12:25 dnolen: i mean the likelihood is low

12:25 llasram: Why so?

12:28 dnolen: llasram: it's a cosmetic enhancement - those get pretty very low priority.

12:28 hiredman: and it seems of questionable utility

12:28 llasram: Even with a patch? (Not that I've submitted a CA yet, although it is on my todolist)

12:29 hiredman: I find it pretty useful myself

12:29 dnolen: llasram: even with a patch, just based on my experience with patches like this

12:29 llasram: Ok. Fair enough

12:33 TimMc: llasram: 5e4 in that particular example. :-)

12:34 llasram: TimMc: But then it's floating-point :-p

12:34 TimMc: Oh man, you're right. I learned that at some point and totally forgot it again.

12:36 samaaron: dnolen: is there any documentation describing how the cljs repl works? It's all voodoo to me - particularly given the absence of eval

12:37 TimMc: I tried to reverse-engineer the cljs repl for try-cljs and totally failed.

12:37 If there's documentation, it's not in the source.

12:38 dnolen: samaaron: TimMc: I know of no docs beyond the source, but it's not that complicated from what I've seen.

12:39 samaaron: dnolen: ok cool - i'll tackle it when i get some spare cycles

12:39 my main issue is that i know no js

12:39 dnolen: I have a half-baked Node.js CLJS REPL that shows the basics, though it has some real issues.

12:39 samaaron: and i know nothign about how browsers present a js execution env

12:39 TimMc: dnolen: I never did figure out how to get cljs.core referred.

12:39 dnolen: samaaron: so how long before we get to run Overtone in the browser, Chrome Audio API is pretty cool :D

12:40 TimMc: there's no magic, you just need to push the whole thing to get eval'ed

12:40 samaaron: dnolen: well, you'd have to build your own 'mini-supercollider' implementation

12:40 and then use the standard Overtone stuff on top of that

12:41 dnolen: samaaron: heh, yeah i know, just day dreaming :)

12:41 samaaron: :-)

12:41 dnolen: TimMc: samaaron: https://github.com/swannodette/clojurescript/tree/node-repl

12:41 https://github.com/swannodette/clojurescript/blob/node-repl/bin/repl.js

12:41 samaaron: we've been talking about building protocols for defining and controlling synths

12:41 dnolen: https://github.com/swannodette/clojurescript/blob/node-repl/src/clj/cljs/repl/node.clj

12:41 those are the relevant files for a minimal hacky REPL, at least for Node.js

12:41 samaaron: so then it would "simply" be a matter of implementing them on top of the Audio API ;)

12:41 dnolen: samaaron: neat :)

12:42 samaaron: yeah, Overtone seriously needs a good looking at from a protocol perspective

12:42 we really need to make more stuff modular and pluggable

12:42 and much less monolithic

12:43 TimMc: dnolen: THanks, I'll try to figure out why that works and mine doesn't.

12:55 jaley: hey guys. I'm using Clojure 1.3 for some java interop which used to work with 1.2. The problem is all numbers are now java.lang.Long and that won't cast to Integer. How do I force Clojure to use an Integer? I've tried (int x), (.intValue x), nothing seems to work...

12:59 TimMc: (Integer. ...)

13:00 You need to produce an Integer object, since an int will get turned into a Long. :-/

13:00 semperos: jaley: ^^^ what TimMc said

13:00 AimHere: jaley: ^^^ what semperos said

13:01 * AimHere practices recursive thinking

13:01 jaley: semperos: but Integer has no constructor that takes a Long?

13:01 & (class (Integer. 1)) ;; appears to work

13:01 lazybot: ⇒ java.lang.Integer

13:01 gtrak``: Integer.valueOf?

13:01 &(class (Integer.valueOf 1))

13:01 lazybot: java.lang.ClassNotFoundException: Integer.valueOf

13:02 TimMc: THat's a static and it takes a string.

13:02 jaley: but once compiled, I get a runtime error that it can't find the constructor

13:02 muhoo: jsabeaudry: isn't there an async package in clojure? "aleph", IIRC? , instaead of natty/jboss?

13:02 TimMc: &(Integer. 50L)

13:02 lazybot: java.lang.NumberFormatException: Invalid number: 50L

13:02 TimMc: oops

13:03 gtrak``: ah, so you can't use the integer cache without having to convert to string? lame

13:03 TimMc: &(let [l 50] [(class l) (Integer. l)])

13:03 lazybot: ⇒ [java.lang.Long 50]

13:03 TimMc: gtrak``: No, it turns out it will take a long.

13:03 Not sure why, looking at the docs.

13:04 gtrak``: hmmmmmm

13:04 TimMc: &(let [l (Long. 50)] [(class l) (Integer. l)]) ; just to be sure

13:04 lazybot: ⇒ [java.lang.Long 50]

13:04 gtrak``: TimMc: http://docs.oracle.com/javase/6/docs/api/java/lang/Long.html

13:04 looks like it was added in 1.6

13:05 &(class (Integer/valueOf 1L))

13:05 lazybot: java.lang.NumberFormatException: Invalid number: 1L

13:05 TimMc: gtrak``: Oh, good. But that doesn't resolve my confusion over Integer's constructor.

13:05 gtrak``: &(class (Integer/valueOf 1))

13:05 lazybot: ⇒ java.lang.Integer

13:05 gtrak``: what's the confusion?

13:06 TimMc: gtrak``: Integer's constructors in Java v1.6 take String or int, not long

13:07 jaley: TimMc: yeah, that's exactly what's messing me up[

13:07 gtrak``: ah, you're right, I gave you the Long html page

13:07 jaley: TimMc: it works at my repl - i'm guessing clojure is detecting I need something other than a long and passing the right object appropriately?

13:07 gtrak``: maybe it gets cast automatically

13:08 jaley: TimMc: but it won't work after compilation for some reason

13:08 gtrak``: really? now that's odd

13:08 jaley: No matching ctor found for class java.lang.Integer

13:08 my mind is full of **** :p

13:08 TimMc: Well, I thought at first that (Integer. 50) was getting an int 50 because the compiler saw that it didn't need to promote it to long, but... nope, works with (Long. 50) input.

13:09 jaley: TimMc: yeah I just tried that too. it's bizarre

13:10 jaimef: anyone run clojure apps on embedded hardware?

13:10 TimMc: jaimef: jsabeaudry is doing some work on an arm7 device or whatever it is

13:16 jaimef: ok. just wondering if 256 megs of ram is sufficient for lein deps/jar on compojure

13:18 technomancy: best not to run lein itself on the device

13:18 just prep an uberjar

13:19 jaimef: k

13:20 jaley: i think i'm going to have to revert to 1.2 :(

13:20 there's just no way i can find to prevent it from using Long

13:21 TimMc: jaley: Of course there is.

13:22 ...and I'm not even getting the compilation error that you were. WTF?

13:22 jaley: TimMc: well... I think the problem is that I'm adding them to a collection, then the java app expects Integer to come up

13:22 TimMc: jaley: (Integer. (int ...)), does that work?

13:23 jaley: TimMc: nope. wait let me see if i can give an isolated example...

13:25 Somelauw: jaley: please describe the error you are getting

13:26 I mean the console output

13:26 jaley: Somelauw: for which method of creating an integer? the constructor call one?

13:27 dnolen: jaley: (Integer. (int n))

13:28 Somelauw: Or I can just wait for the isolated example

13:28 pandeiro: are <_include>s in clojurescript one's templating lib supposed to show up in development mode?

13:29 jaley: dnolen: that works!

13:29 Somelauw: I was just wondering if it just said RuntimeError or if there was further info

13:30 jaley: Somelauw: so for some reason, if I do (Integer. 1), I get an integer in my repl, but then putting that in a java object collection, then passing that collection to a java library that casted it back to Integer was giving a cast error, claiming the object was a Long

13:31 dnolen: jaley: (Integer. 1) won't work, 1 is primitive long

13:31 ,(Integer. 1)

13:31 clojurebot: 1

13:32 Somelauw: And (Integer. (int 1)) does work instead?

13:32 dnolen: ,*clojure-version*

13:32 clojurebot: {:major 1, :minor 3, :incremental 0, :qualifier nil}

13:32 jaley: dnolen: should (int 1) without the Integer constructor call work?

13:33 dnolen: huh weird oh well

13:35 oh ok, prim long can cast to prim int

13:35 jaley: you were seeing something like this

13:35 ,(Integer. (fn [] 1))

13:35 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching ctor found for class java.lang.Integer>

13:35 dnolen: ,(Integer. (int (fn [] 1)))

13:35 clojurebot: #<ClassCastException java.lang.ClassCastException: sandbox$eval105$fn__106 cannot be cast to java.lang.Character>

13:35 dnolen: ,(Integer. (int ((fn [] 1))))

13:35 clojurebot: 1

13:35 dnolen: ,(Integer. ((fn [] 1)))

13:36 clojurebot: 1

13:36 hiredman: I was gonna say

13:36 jaley: dnolen: I was... when I was calling the constructor with a long, yes

13:36 dnolen: huh, I give up, don't know why that wasn't working

13:36 jaley: I can't get it to break like you did

13:37 jaley: dnolen: well, (Integer. (int x)) seems to work

13:37 dnolen: so thanks for that guys - my head hurts now. i need beer. :-)

13:37 TimMc: dnolen: Any idea why (Integer. (Long. 50)) *does* work?

13:38 dnolen: TimMc: not really

13:38 TimMc: eep

13:38 dnolen: but the rule is simple, if Java interop wants prim int, prim to cast int

13:39 cast to prim int

13:39 TimMc: I don't think that's true.

13:39 dnolen: TimMc: in what way?

13:40 TimMc: I've seen (Integer.) be required, (int) didn't work,

13:40 although that may have been due to some overloading with Object or Long or something.

13:41 sr71-blackbird: what's a good way to do write a typed validation system/ err recommended in Clojure, defprotocol, defrecord?

13:41 dnolen: TimMc: that doesn't make any sense, if Integer is required, that pass Integer

13:41 if prim int is required pass prim int

13:42 sr71-blackbird: defprotocol deftype/record don't do validation

13:42 sr71-blackbird: you could contribute to the analyzer

13:42 sr71-blackbird: analyzer?

13:42 dnolen: sr71-blackbird: https://github.com/frenchy64/analyze

13:43 sr71-blackbird: dnolen, I know, I was writing validate and convert methods to defprotocol and using that with records

13:43 dnolen, analyzer actually looks sweet

13:45 dnolen: sr71-blackbird: it is, hopefully more people contribute

13:46 dakrone: sea

13:46 sr71-blackbird: dnolen, any quick easy issues to get my feet wet? or features needed?

13:49 dnolen: sr71-blackbird: you should message the maintainer, nice fellow

13:50 TimMc: dnolen: Checked the logs -- I misremembered re: Integer.

13:50 dnolen: sr71-blackbird: also https://github.com/frenchy64/typed-clojure

13:51 TimMc: Hmm, javac bails on new Integer(new Long(50))

13:58 phil_: why is this running out of memory?

13:58 https://gist.github.com/1677918

13:58 it is an attempted solution to problem #108 on 4clojure: https://www.4clojure.com/problem/108

14:00 gtrak``: 4clojure looks to be hung

14:00 phil_: desc: Given any number of sequences, each sorted from smallest to largest, find the smallest number which appears in each sequence. The sequences may be infinite, so be careful to search lazily.

14:01 llasram: phil_: I believe the problem is `:when' vs `:while' in `for'

14:01 (or if not versus, you do need some terminating condition)

14:01 gtrak``: Raynes: I get a 504 gateway time-out on 4clojure

14:02 phil_: llasram: doesnt for return a lazy seq?

14:02 Raynes: Damn. And Alan isn't here. Guess that means I have to *gasp* restart it myself.

14:02 llasram: phil_: Oh, it does. I missed that `first' should be being applied to it

14:03 apwalk: gtrak``: glad you see it too. i thought my solution was just *that* good.

14:03 Raynes: apwalk: It probably was. ;)

14:03 Alex is bringing it back up.

14:03 phil_: yea, for small ranges it terminates and if there are no matching numbers then its gonna hang but its not part of the requirements :)

14:04 however it bombs out with an outofmemoryexception actually

14:04 llasram: Oh, wait

14:04 Actually, nm. :-)

14:05 phil_: can it be because lazy seqs are cached?

14:05 but shouldnt they be garbage collected whenever they go out of scope?

14:05 gtrak``: they're not?

14:06 phil_: gtrak``: theyre not?

14:06 Raynes: gtrak``, apwalk: It's back up.

14:06 gtrak``: lazy seqs aren't cached, if you hold on to a reference as you iterate though, they'll never be freed

14:06 TimMc: Without looking at the code, I'm gonna say you're holding onto the head of some seq.

14:06 Raynes: Thanks for reporting it.

14:06 gtrak``: Raynes: thankyousir

14:08 phil_: ok im a little confused now... if they arent cached, holding on to the head shouldnt cause any additional memory consumtion?

14:08 TimMc: phil_: THey aren't so much *cached* as nonexistent before they are realized and... existent... after they are realized.

14:08 gtrak``: if you have an infinite seq, you can realize it, you'll get an oom if you hold on to the head and an infinite loop otherwise

14:10 &(range)

14:10 lazybot: java.lang.OutOfMemoryError: Java heap space

14:10 phil_: ok, just to have a clear concept, what is cached then? i read somewhere that some type of seq was cached, i.e. elements arent recomputed on subsequent queries

14:10 gtrak``: it's not cached, you've realized it

14:10 TimMc: phil_: Would you say that the elements of [1 2 3 4 5] are cached?

14:11 gtrak``: if you can access a prior value, that means you've held on to the head of a seq

14:11 if you discard it, then the GC can collect it

14:12 llasram: phil_: I for some reason can't see why, but if add a :while condition to terminate the `for' when y exceeds x, the function generates no results. So some logic error is causing you to walk all of (range)

14:12 gtrak``: if you can only care about 'first' and 'rest' in your iteration then you're fine

14:12 phil_: from clojure.org/lazy: (talking about lazy-seq): returns a logical collection that implements seq by calling the body

14:12 invokes the body only the first time seq is called on it, caches result

14:12 will call seq on the body's return value if not already a seq or nil

14:13 gtrak``: and?

14:13 phil_: well here they talk about caching

14:13 tavis: dnolen: jumping back to what you were talking about earlier, re the cljs metadata open question: is metadata something that is definitely on the roadmap?

14:14 phil_: or is "realizing" a seq and "caching" a seq the same thing?

14:14 TimMc: phil_: And I'm encouraging you to think about it differently.

14:14 gtrak``: the function caches its value so it doesn't have to compute it again, it's up to you to hold on to that cache by holding on to a reference and preventing the GC from doing its job, there's no global seq cache

14:15 phil_: TimMc: yes, i just wanted to understand if those two things are different concepts or not

14:15 TimMc: They are confusingly similar in this instance.

14:15 phil_: gtrak``: yes, i wasnt implying that there was a global cache

14:16 TimMc: but still different? then, when is a seq cached and when realized?

14:16 gtrak``: well, so if there was a cache, you'd have to be holding a reference to it for it to matter

14:17 TimMc: phil_: "cache" implies an eviction algorithm or timeouts

14:17 at least to me

14:17 gtrak``: phil_: it's really an implementation detail that shouldn't affect how you use seqs

14:17 cemerick: "never" isn't an eviction strategy? :-P

14:17 TimMc: heh

14:18 phil_: I'll say this, then get back to work: An infinite lazy seq is always only partially constructed, there's always a dangly bit at the end that's just an IOU promising to construct some more as needed, a.k.a. lazily. The more you ask for, the more gets constructed (realized), and the bigger it gets.

14:19 phil_: when i say cache i mean that the body isnt recomputed again on subsequent calls, whenever the ref to the seq goes out of scope then the "cache" is garbage collected

14:19 TimMc: phil_: Since it is a linked list, you can drop stuff off the beginning by dropping your references to it.

14:19 phil_: There is *no cache*.

14:19 gtrak``: phil_: there are other details like chunking that are also irrelevant

14:19 TimMc: The seq *is the cache*.

14:20 phil_: TimMc: "cache" in this context meaning the head

14:20 llasram: phil_: AH! It's the order of iteration in the for. The recursive call is lazy, but generates over a potentially lazy list. Since there's no terminating condition in the `for', the penultimate recursive call waits forever for the ultimate recursive call to generate more values

14:20 phil_: If you swap to [y (apply ! more), x a], then it works

14:20 TimMc: phil_: "cache" in this context meaning you're going about this all wrong.

14:20 phil_: llasram: but if you swap the arguments? is it gonna work as well? :/

14:21 * TimMc ragequits

14:21 llasram: phil_: Er, why wouldn't it?

14:21 phil_: TimMc: i think i understand the whole concept, it just seems the word "cache" is the wrong one

14:22 TimMc: sry if i made you rage :)

14:23 llasram: well try it, [1 2 100] (range) [3 5 100]

14:24 llasram: Oh. If you need it to work in that case, you need a :while condition in your `for'. Otherwise you'll always be iterating over a potentially infinite list (which never actually generates more than one result)

14:24 gtrak``: &(println (range))

14:24 lazybot: java.lang.OutOfMemoryError: Java heap space

14:25 gtrak``: it's odd that it actually tries to print in my cmd repl, I wonder how that works

14:26 phil_: gtrak``: maybe print just iterates over the seq if the argument is a seq

14:26 lazily

14:27 TimMc: phil_: Reading the source of LazySeq.java is quite illuminating, actually. (Even though there are no docs...)

14:28 gtrak``: phil_: hmm, I don't see it yet

14:29 phil_: llasram: well for returns a lazy seq and i access the first element, so it shouldnt iterate over the whole infinite seq, i.e. [100 101] (range) and (range) [100 101] both wok

14:30 work*

14:32 TimMc: yes, and what else is sval() if not a one-value cache?

14:32 i.e. if you already know the value of fn.invoke() dont recompute it again

14:33 amalloy: are we asking why lazybot doesn't "try" to print (range)?

14:33 llasram: phil_: Without a termination condition, the ultimate (deepest) call to `for' returns a lazy infinite sequence. Then the penultimate `for' (the one containing the recursive function call which makes the depeest `for') iterates over that sequence. If it can't generate any results from the values the deepest `for' generates, then it iterates over the deepest lazy sequence forever

14:33 phil_: The solution is to add a :while to your `for' so that it terminates

14:34 gtrak``: amalloy: well I think I get why lazybot doesn't try, I'm just not sure why the real repl does try

14:34 amalloy: gtrak``: print just walks the sequence streaming to *out*

14:35 lazybot has *out* bound to a StringWriter, so it just chews up memory until it runs out; it doesn't stream like the built-in output stream

14:35 Raynes: It'd get a little hairy streaming to IRC. ;)

14:35 phil_: llasram: but why shouldnt it be able to generate values from the values of the deepest for? this is what i dont understand

14:36 TimMc: Raynes: I do it all the time!

14:36 A user, after all, is just a slow, buggy I/O device.

14:36 amalloy: Raynes: clojurebot actually does something fairly close to that, i think

14:36 Raynes: amalloy: I'm pretty sure it sets *print-length*.

14:36 amalloy: for sure

14:36 Raynes: And it prints a new message per newline.

14:36 But I don't think streaming is the right word for either of those things.

14:37 We should probably set *print-length* too, just for fun.

14:37 phil_: llasram: the probelm is that i dont see a valid :while condition in this case, but it should terminate in any case :/

14:37 amalloy: ,(dotimes [x 3] (Thread/sleep 1000) (println x))

14:37 clojurebot: 0

14:37 1

14:37 2

14:38 amalloy: Raynes: he prints those as they arrive, rather than bundling them up: streaming

14:38 he flushes the stream at each newline

14:38 TimMc: amalloy: Hard to tell with that slowpoke.

14:39 Raynes: amalloy: Okay, sure, but he isn't streaming character by character to IRC. It has to be a single message per.

14:39 llasram: phil_: why not?: :while (>= x y)

14:39 TimMc: I get the same timing with sleep 1.

14:39 amalloy: Raynes: no argument there

14:39 ,(dotimes [x 3] (Thread/sleep 4000) (println x))

14:39 clojurebot: Execution Timed Out

14:39 amalloy: okay, maybe you win this time, TimMc

14:40 TimMc: I think it's a rate limiter between messages.

14:40 ,(dotimes [x 3] (println x)) ; no sleep, ma!

14:40 clojurebot: 0

14:40 1

14:40 2

14:40 amalloy: yeah. i seem to have misinterpreted it as a streaming thing

14:41 Raynes: Even Einstein was wrong a couple of times.

14:41 phil_: llasram: still bad, try it on (map #(* % % %) (range)) (filter #(zero? (bit-and % (dec %))) (range)) (iterate inc 20)

14:43 llasram: phil_: wfm

14:43 phil_: llasram: and while (>= x y) is still gonna produce an infinite seq if both are infinite

14:44 llasram: really? what is the result?

14:44 llasram: 64

14:44 phil_: can you paste the soure somewhere?

14:46 llasram: Hmm.

14:46 phil_: llasram: nvm

14:46 i got it

14:46 now i must understand it :)

14:47 llasram: thanks a lot for the help!

14:48 llasram: phil_: np! It was a fun puzzle. It can be hard debugging these sorts of problems

14:48 phil_: llasram: yea, it definately can :) did you some tracing macro or just the old good brain? :D

14:49 geef: what do clojurers use instead of cadr,cdadr and caaar?

14:50 TimMc: geef: get-in

14:50 and less reliance on lists of lists of lists of lists...

14:50 Raynes: Logical sentences.

14:50 llasram: phil_: Tracing is hard when the problem is getting infinite list somewhere :-) I do wish there were better tooling for such issues, but I'm not sure what it would look like

14:50 Raynes: Words with definitions. Etc.

14:52 phil_: llasram: yea, functional debugging is a lot harder it seems... unfortunately :while doesnt work either: [1 2 3 4 5 6 7] [0.5 3/2 4 19]

14:52 it returns 1 instead of 4

14:52 cemerick: FYI: use couchdb like it was a clojure collection: http://groups.google.com/group/clojure-clutch/browse_frm/thread/4520716eb37a90cc

14:52 feedback on the API, etc. most welcome

14:54 brehaut: cemerick: thers no magic for views yet with that new api right?

14:54 Raynes: cemerick: I want to use couchdb like a couch. And sit on it.

14:54 llasram: phil_: Like this? https://gist.github.com/1678269

14:55 cemerick: brehaut: aside from _all_docs via seq, no

14:55 coming, coming :-)

14:55 views are tricky bastards

14:55 amalloy: geef: fewer cons cells

14:55 brehaut: cemerick: dont mean to sound pushy. i've not updated all my code to the 0.3.0 stuff yet :P

14:56 Raynes: cemerick: Wow, that's pretty awesome.

14:56 amalloy: I bet he is writing down all of our clever responses so that he can worship them later.

14:57 amalloy: heh

14:57 llasram: cemerick: OOC, does clutch support lazily generating results from couch's 'Transfer-encoding: chunked'?

14:58 phil_: llasram: perfect, thanks a lot again :)

14:59 Raynes: cemerick: We plan to add proper Github-like rendering of markdown to refheap. You should add asciidoc support.

15:01 cemerick: I'm basically throwing that off to you in order to avoid grumbling about not supporting it in the future. I can just say "well, I told you to do it ages ago".

15:01 TimMc: I'm not actually a fan of GitHub-flavored Markdown. Specifically, I wish single line breaks were ignored so I could write super-ragged (SCM-friendly) docs.

15:11 cemerick: f'n macbook BSOD'd on me. :-X

15:11 llasram: you asked something?

15:11 gtrak``: is it blue on a macbook?

15:12 cemerick: gtrak``: it actually a very well-styled gray, logoed screen with antialiased text indicating that you're SOL.

15:12 llasram: Oh, sorry. I was just wondering if clutch can allow lazy processing of results as couch streams them via chunked-encoding

15:12 gtrak``: ha, it's good to bomb out in the most aesthetically pleasing way

15:13 cemerick: My problem is actually not that — every now and then, the whole business freezes, with the screen frozen with odd animated artifacts. I think it's either an overheating video card, or bad memory.

15:13 llasram: I don't know my underlying Java well enough to tell if the HTTP facilities support that...

15:13 cemerick: llasram: Yes, absolutley

15:13 llasram: Awesome!

15:13 brehaut: cemerick: is that the multiligual F U bezel ?

15:13 cemerick: brehaut: yeah, something like that!

15:14 brehaut: mac os x has a more dire error mode; kernel panic text just slowly rights down the screen over everything

15:14 cemerick: I'm lucky enough to have never seen that.

15:14 brehaut: you need to seriously damage the mobo i think

15:14 cemerick: I'm salivating at the next upgrade.

15:14 brehaut: (or have it ship with a dodgy nvidia card)

15:15 oh yeah?

15:15 sritchie: do you guys know how to use the multi-arity version of aset?

15:15 ,(doto (int-array 10) (aset 1 10))

15:15 clojurebot: #<int[] [I@1449b2b>

15:15 sritchie: ,(seq (doto (int-array 10) (aset 1 10)))

15:15 clojurebot: (0 10 0 0 0 ...)

15:15 cemerick: mmm, maybe I should switch to use the on-chip video…

15:16 sritchie: not sure how to use this version: [array idx idx2 & idxv]

15:16 cemerick: sritchie: that's for N-dimensional arrays

15:16 brehaut: cemerick: i get the occasional f u bezel from sshing into VBox bridged vms

15:16 sritchie: cemerick: I see, so setting a corner of 2d array would be (aset arr 0 0 10)

15:18 cemerick: sritchie: yeah, although, you should never really use it: it uses apply, so boxes like mad. You want to use deep-aset from http://clj-me.cgrand.net/2009/10/15/multidim-arrays or the much-enhanced version that's in the book.

15:18 (we should put that out in a separate project…)

15:18 sritchie: I'm going through clojure.core w/ Anki

15:18 cemerick: awesome, thanks for the reference

15:18 brehaut: cemerick: have they told you when to expect the next revision of the pdf to occur?

15:19 cemerick: brehaut: Any minute now?

15:19 sritchie: Love cgrand's blog heading: »When the pupil is ready to learn, a teacher will appear

15:19 brehaut: cemerick: awesome :)

15:19 cemerick: It's like trying to choose the right pipe out of 100 into which one can drop a message, and hope it hits the right person in the head.

15:28 chouser: cemerick: congrats, btw. feeling the relief yet?

15:29 cemerick: chouser: Thanks :-)

15:29 To some degree. It's a bit odd — the days are so much longer all of a sudden!

15:31 chouser: :-)

15:32 does anyone know how to declare a dep on a particular version of a snapshot dep?

15:32 the jar I want is in me ~/.m2, but I can't figure out how to tell lein that's the one I want (vs. the newer broken version it's trying to use)

15:33 cemerick: chouser: that's called "locking snapshots" in maven-land

15:33 replace SNAPSHOT with the timestamp from the particular rev you want

15:37 sritchie: technomancy: quick question on dependency resolution

15:37 chouser: I tried that, but I screwed it up. Trying again...

15:37 jsabeaudry: what exactly is reported when clojurebot says "recently on clojars.org..." Is is that a new version was uploaded?

15:38 sritchie: I'm pulling from an artifactory repo where some dependencies are <packaging>jar</packaging> and some are <packaging>pom</packaging>

15:38 TimMc: yeah

15:38 sritchie: technomancy: the pom packages are just bundles of jar dependencies

15:38 TimMc: jsabeaudry: I think it's a different message when something new is added.

15:38 sritchie: leiningen doesn't seem to be able to handle these properly, though everything works fine if I manually include everything

15:38 chouser: cemerick: thanks, that did it. I was repeating the package name in the version string. for some reason *that* didn't work. :-P

15:39 jsabeaudry: TimMc, So what does this one mean exactly? Someone downloaded a library?

15:39 TimMc: jsabeaudry: Nah, someone uploaded a new version of something.

15:40 jsabeaudry: TimMc, Ah ok! Thanks!

15:40 cemerick: sritchie: what if you specify packaging of "pom" in your relevant :dependencies?

15:40 chouser: Good; something to automate that really should be in lein.

15:40 sritchie: cemerick: interesting, like :packaging "pom" ?

15:41 I know the exclusions key

15:41 cemerick: the problem is when some jar pulls in a dependency that's packaged like this

15:41 I can explicitly include it in project.clj, but that doesn't feel right, really

15:42 cemerick: sritchie: looks like it's :type "pom"

15:42 sritchie: do you have an example (publicly-accessible) dep that has this issue?

15:43 It's been a while since I messed with pom deps.

15:43 sritchie: me too, I don't know where I can find one of these guys

15:43 or how to deploy one to clojars, for that matter

15:44 cemerick: Why would you want to deploy one to clojars?

15:44 sritchie: that's the only public maven repo I know of that I can push an example to

15:44 cemerick: oh, I see :-)

15:44 There's plenty of pom deps in central, I just don't know of one off the top of my head

15:45 Probably gobs of 'em in spring, etc.

15:45 brehaut: they are seasonal?

15:46 sritchie: :type "pom" works

15:46 cemerick: but not if some other dependency pulls in a pom packaged dep

15:46 even if I override it, it'll still fail

15:46 let me check central

15:47 [org.kohsuke/pom "2" :type "pom"] works, [org.kohsuke/pom "2"] fails

15:53 cemerick: https://github.com/sritchie/Example-Deps-Issue

16:05 jodaro: huh

16:05 sritchie: technomancy: issue here: https://github.com/technomancy/leiningen/issues/380

16:05 jodaro: i don't seem to be getting any google group digests

16:06 Raynes: jodaro: You're a blessed man.

16:06 jodaro: i know

16:07 except there are a couple i kinda like

16:07 for example

16:07 clojure

16:07 cemerick: sritchie: that's expected behaviour AFAIK

16:07 sritchie: cemerick: the question is how I can deal with dependencies that haven't formatted their poms in the way that lein expects

16:09 cemerick: sritchie: a pom dependency that doesn't declare a <type> is broken

16:09 jsabeaudry: Anyone has some experience with clj-time? (No matter if I use (from-time-zone or not the time is always printed in UTC)

16:09 cemerick: <type> defaults to "jar", and shouldn't ever resolve to a .pom AFAIK

16:10 although, presumably, they *are* working, so…

16:12 sritchie: adding the <type>-less dep on org.kohsuke/pom to a maven project yield a dependency resolution error (Could not find artifact org.kohsuke:pom:jar:2 in central)

16:13 sritchie: I'll see if I can track down this issue on the twitter side and make them fix it

16:13 jsabeaudry: Ah all is well, from-time-zone was erroneous I was supposed to use .withZone on the formatter

16:23 cemerick: sritchie: It'd be interesting to hear what would make that succeed, if you ever find out. :-)

16:27 technomancy: so it sounds like the problem is with the dependency?

16:28 sritchie: technomancy: yeah, and with my maven understanding, I guess

16:28 I had thought there was some way to look at the deps in the pom to figure out the type

16:28 technomancy: ok.

16:28 sritchie: if that's missing from the pom (the type), then there's nothing we can do

16:29 except fix it up inside twitter, which I'll do

16:29 technomancy: sritchie: btw, I think the user-level repos thing you mentioned earlier is something you get for free with profiles in lein 2

16:29 sritchie: technomancy: nice

16:29 the profile isn't project-based?

16:29 technomancy: except it's basically repeatability-poison, so it will probably emit a big ol' warning

16:30 profiles are read from the project and the user config

16:30 sritchie: I think it'd be nice to be able to have an internal config for leiningen

16:30 so you could use lein in a closed environment

16:30 technomancy: yeah, cemerick has sketched some of that out; shared project middleware

16:31 sritchie: https://github.com/technomancy/leiningen/wiki/Project-Middleware

16:31 feedback welcome

16:31 cemerick: that was actually ninjudd

16:31 technomancy: oh?

16:31 cemerick: well, I was instigating something, I'm sure :-P

16:31 technomancy: oh right; he wrote it up, but I thought that it addressed a number of use cases you were pining for

16:32 cemerick: yeah

16:32 I think my initial email to the lein ML described a couple of scenarios that profiles and middleware will address

16:32 technomancy: readability is only going to get more important; viz. chouser wanting to lock snapshots earlier

16:32 stuff like that can and should be automated.

16:34 technomancy: I agree, but giving up the ability to comment your project is a ridiculously high cost.

16:35 cemerick: I think a formatting- and comment-preserving alternative reader impl would be a perfectly fine idea.

16:35 technomancy: absolutely

16:35 just don't want to be the one to write it

16:35 cemerick: it's not like requirements like this are going to get less common

16:35 :-D

16:35 technomancy: heh

16:35 I'd consider it a prerequisite to automated project.clj modification

16:35 brehaut: i could throw out so much code if there was a preserving reader that i could use in clojurescript

16:35 cemerick: technomancy: don't talk the task down!

16:36 * cemerick is waiting for chouser to start on it ;-)

16:36 chouser: a preserving reader would be great in so many contexts

16:36 cemerick: gah! crossed posts! I wasn't volunteering!

16:36 cemerick: LOL

16:36 chouser: it's so great that it worked out that way, though!

16:36 technomancy: hiredman: you spiked out a lossless reader, right?

16:37 that'd make a great demo at the next seajure

16:39 chouser: if everything that could be read could hold metadata, that'd be an intruiging option. But without that, I'm not even sure what such a reader should return.

16:42 TimMc: How does Eclipse handle refactoring Java code?

16:42 gtrak``: TimMc: it has its own compiler

16:42 TimMc: That sort of thing might be a good research starting point.

16:43 gtrak``: in other words, they have control of the AST

16:43 technomancy: this is actually the one interesting thing about Go IMO; the AST is actually an explicit part of the language spec

16:44 cemerick: it seems like comments and contiguous whitespace just turn into instances of some other type; no reason why a lossless reader wouldn't return (mostly) the same as what the current reader does

16:44 And then 1:1 correspondence is a postwalk away

16:45 * cemerick is trolling himself now :-P

16:45 TimMc: There are some tough questions about insertion of forms and preserving indentation, etc. Eclipse has a configurable formatter built in, which is probably what they fall back to.

16:46 gtrak``: the formatter's not terribly smart

16:53 arohner: cemerick: I just started using bandalore. it looks good. Great docs too

16:54 cemerick: arohner: oh, cool. :-) I haven't touched it in a while, glad it's still up to snuff.

16:54 well, great docs if github wasn't so bloody broken these days :-X

16:55 arohner: cemerick: so far, I've only done the 'send' side of hello world. I'll you know about the rest soon :-)

16:55 yeah, but the docstrings are good too

16:55 cemerick: glad it's clear for you

16:56 I really have no idea why markdown holds such sway with programmers.

16:56 brehaut: historical accident i think

16:56 technomancy: least-common denominator

16:57 just be glad textile seems to have withered; it was king of '06-era rubyland

16:57 brehaut: gruber wrote good docs and a solid implementation for it back when tools of its ilk were rare. the php port that everyone used with wordpress was also pretty good

16:58 Raynes: cemerick: I know markdown. I do not know asciidoc.

16:58 Is that not good enough?

16:58 technomancy: he forgot to write a spec, unfortunately

16:58 brehaut: indeed

16:58 and its a big bag of regexps to bash against the input, so good luck reverse engineering that

16:58 cemerick: Raynes: insofar as markdown is an impoverished format, no.

16:59 Raynes: $dict impoverished

16:59 lazybot: Raynes: adjective: Reduced to poverty; poverty-stricken. See Synonyms at poor.

16:59 Raynes: cemerick: Everything you say to me makes me feel like an illiterate hick. Just FYI.

16:59 jsabeaudry: Typically does version "0.0.1-SNAPSHOT" come before or after version "0.0.1" ?

16:59 Raynes: Way, way before.

17:00 technomancy: (as well as immediately before)

17:00 brehaut: jsabeaudry: -SNAPSHOT is the untrustworthy imposter release of the version.

17:00 Raynes: I never use snapshots.

17:01 jsabeaudry: Alrighty, thanks, I guess I can see snapshot as some kind of RC0

17:01 cemerick: Raynes: You're plenty erudite, don't worry. :-P

17:01 Raynes: If I need to release something before a stable release, I release alphas and betas.

17:01 0.1.0-alpha1.

17:01 $dict erudite

17:01 lazybot: Raynes: adjective: Characterized by erudition; learned. See Synonyms at learned.

17:01 Raynes: cemerick: I'm learned!

17:01 gtrak``: maven tends to always check for new snapshot releases upstream, is this true for lein as well?

17:01 jodaro: nice

17:02 technomancy: gtrak``: once a day

17:02 gtrak``: actually, no with the latest lein it's only whenever your :dependencies list changes

17:02 or when you explicitly run "lein deps"

17:02 gtrak``: ah

17:02 TimMc: so if deps doesn't run, the daily SNAPSHOT check doesn't run

17:03 gtrak``: that makes sense

17:03 TimMc: Raynes: Wait, I thought 1.0.0-SNAPSHOT came after 1.0.0 because it's not known what the next version will be.

17:04 gtrak``: WRONG

17:04 :-D

17:04 Raynes: TimMc: I thought that the chicken came before the egg, but even that is cloudy these days.

17:04 brehaut: actually the chicken came from asia and is a domesticated red jungle fowl

17:05 hiredman: sounds correct to me

17:05 just don't check wikipedia

17:06 TimMc: gtrak``: This is terrible. I thought it was such a cool thing!

17:06 jodaro: $know chicken

17:06 lazybot: jodaro: chicken (the domesticated bird)

17:06 jodaro: vague but not incorrect

17:07 Raynes: $know leiningen

17:07 lazybot: Raynes: "Leiningen Versus the Ants" by Carl Stephenson, the classic short story published in the December 1938 edition of Esquire Magazine

17:07 TimMc: Raynes: The egg came first, because the genetics are what matters, and the egg has the same genetics as the chicken it turns into, not its parents. Whereever you draw the line across the lineage, it will be between an egg and its parents.

17:07 Raynes: technomancy: ^ lazybot knows. It *knows*.

17:08 TimMc: You and aren't friends anymore.

17:08 TimMc: me and some invisible username?

17:08 Raynes: Yes.

17:08 TimMc: I'm pedantic for your benefit, Raynes.

17:09 jodaro: i think we all benefit from said pedantry

17:10 TimMc: I know *I* do.

17:19 So, is there any way to version something as v.Next?

17:21 LATEST, is that it?

17:22 Never mind, that's instead of a version range.

17:24 technomancy: holy smokes, do you really need to set the JAVA_HOME environment variable to use Oracle's JDK on windows?

17:25 Raynes: technomancy: I've just given up on supporting Windows in anything I do ever.

17:25 I'm mostly a "patches welcome if you need windows support" kind of guy, though the Windows patches I get tend to be completely insane and unformatted by people who don't really know Clojure.

17:26 technomancy: oh man, this guy is telling people to manually download libssl in order to do curl in order to do lein self-install.

17:26 Raynes: Haha

17:27 technomancy: I don't even know; that could be a reasonable thing to tell people to do on Windows?

17:29 TimMc: technomancy: Is that with Cygwin?

17:30 technomancy: TimMc: nah

17:30 TimMc: I mean, if you're doing anything outside of Cygwin, it's going to be that nmuch worse.

17:31 technomancy: "disable your antivirus to allow lein plugin install to work" =(

17:31 is this the price of enterprise domination?

17:31 the-kenny: Also, try to reboot if M-x clojure-jack-in doesn't work.

17:31 brehaut: lets just let the enterprise use F#

17:32 technomancy: brehaut: tempting!

17:32 I wonder if relevance's sponsorship of CCW was a strategic move in that direction

17:33 brehaut: a reasonably hypothesis

17:33 and a more approachable enviroment than emacs

17:33 * brehaut ducks

17:34 the-kenny: Well, if I had to use windows, I'd use emacs.

17:34 So I have at least some kind of abstraction between me and Windows :)

17:34 technomancy: brehaut: what; that's a reasonable thing to say.

17:34 TimMc: brehaut: Emacs is in no way approachable... and you'll have to pry it from my cold, dead RSI-riddled hands.

17:34 brehaut: technomancy: yes, but i fear jihad nontheless

17:34 gtrak``: the-kenny: then all you'd need is a decent text editor

17:35 TimMc: I'm sure you canload vim in a buffer.

17:35 the-kenny: gtrak``: I can use vim inside emacs for that.

17:35 technomancy: brehaut: the objections come when people value approachability over other good things

17:35 brehaut: the-kenny: visual studio + F# is actually a pretty good buffer too

17:35 technomancy: fortunately you have to already understand that familiarity is orthogonal to elegance and power to even want to use Clojure in the first place

17:36 Scriptor: +

17:36 technomancy: so we don't get too many of those types

17:36 (the mailing list being the exception that proves the rule I guess?)

17:36 brehaut: totally

17:36 * brehaut avoids the ML

17:36 AimHere: I always thought of emacs as RMS's method of having some kind of usable abstraction between him and Unix ;)

17:37 technomancy: AimHere: for a long time it was the only thing keeping the dream of the Lisp Machine alive

17:37 AimHere: Yup

17:38 brehaut: actually, i think i avoid the ML because of google groups more than any personalities

17:39 technomancy: ugh; the stupid new hashbang UI

17:39 brehaut: it has a nice email interface too, you know =)

17:39 brehaut: brehaut: haha nah they broke that for me with my apps for domains accoutn

17:40 i gave up trying to fix it

17:40 TimMc: I used to have my domain email hosted with Google but now I use Cotse -- much less sketchy.

17:40 although I do miss the UI

17:40 brehaut: TimMc: yeah thats why ive stayed with gmail; my family also have email addresses at my domain

17:41 TimMc: aha

17:41 brehaut: gmail and reader are the only things i use google for these days

17:41 technomancy: not jabber?

17:41 brehaut: oh

17:41 maybe i do actually

17:41 that'd be trivialy to switch out though

17:41 llasram: technomancy, brehaut: And a usenet interface via gmane!

17:42 technomancy: llasram: hm; I should check that out

17:42 probably not as sluggish as gnus+imap

17:43 * TimMc still has not used usenet

17:44 brehaut: TimMc: you havent lived till you've tried to read comp.lang.lisp

17:45 TimMc: heh, I bet

17:45 fhd_: Can't seem to find something equivalent to seq-utils/find-first (from contrib) in 1.3, any leads?

17:45 jodaro: wouldn't that make it unusednet?

17:45 AimHere: If you ever go on Usenet, TimMc, just type the word 'Kibo' in there somewhere, as a test

17:45 TimMc: AimHere: Oh, I've browsed around his site.

17:46 AimHere: I'm just curious as to if he still greps all of Usenet

17:46 Kibo was the Candyman of the internet back in the day

17:46 TimMc: fhd_: You mean (first (filter ...)) ?

17:46 fhd_: TimMc: No, I don't want to filter the whole seq, only up to the first match

17:46 TimMc: But filter is lazy, eh?

17:47 TimMc: OK, thanks :)

17:47 brehaut: fhd_: thanks to the magic of lazy seqs, thats mostly true (except for chunked seqs)

17:56 TimMc: &(first (filter #(do (println %) true) (range)))

17:56 lazybot: ⇒ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 0

17:56 TimMc: I guess filter is chunked!

17:57 brehaut: range and vector produce chunked seqs, rather than filter being chunked isnt it?

17:57 TimMc: Hmm...

17:57 technomancy: brehaut: yes

17:57 brehaut: TimMc: have a look at (source filter); its got a bunch of extra code to handle chunked seqs though

17:57 TimMc: filter isn't in control of what its predicate gets applied to?

17:58 &(first (filter #(do (println %) true) (iterate inc 0)))

17:58 lazybot: ⇒ 0 0

17:58 franks: technomancy: the 1.7.0-SNAPSHOT code for lein still doesn't seem to use rlwrap - you mentioned before that you may have accidently deleted it... should I submit an open issue for that?

17:58 brehaut: TimMc: it does maintain a chunked-seq if it gets one, buti it doesnt generate one otherwise

17:58 TimMc: ANd now I see the purpose of unchunk.

17:58 brehaut: ,(apropos 'chunk)

17:59 clojurebot: (chunked-seq? chunk-buffer chunk-cons chunk-append chunk-rest ...)

17:59 TimMc: brehaut: It's not a standard fn.

17:59 amalloy: brehaut: i believe that describes all chunked-seq functions (those that take a seq as input, anyway; i'm not including range here)

17:59 brehaut: amalloy: yes i think you are right; i was just using it as an example

17:59 technomancy: franks: hmm; I thought I had fixed that

18:00 apparently not! feel free to open an issue and/or pull request

18:00 franks: technomancy: maybe i'm looking in the wrong branch...

18:00 technomancy: nope; it's gone

18:00 franks: ok

19:13 technomancy: is the "-XX:+TieredCompilation" option for the jvm valid in general or only for the trampoline case?

19:26 technomancy: franks: no, it should always be active

19:54 pickles: anyone have any tips on general optimization?

19:54 any functions to avoid?

19:54 I rewrote part of a program, and what would take a few seconds before in the old, ugly code on my netbook's Atom now takes over 15 on my dual-core athlon

19:55 (granted I'll have to review the algorithms I'm using now, but any tips would be appreciated)

19:55 dnolen: pickles: look at test.benchmark for ideas when perforamnce is actually critical

19:56 pickles: mmk, I'll take a look

19:56 (I'm still new to clojure so I'm not that familiar with things yet)

19:56 dnolen: pickles: common pitfalls including trying to do operations like nth and count on seqs

19:56 pickles: mm... I am doing a couple of count calls

19:56 dnolen: including -> include

19:56 pickles: []s are seqs, right?

19:57 dnolen: pickles: vectors are random access, but not if you put them through seq operations like map/filter/etc

19:57 pickles: yup, using map and mapcat alot

19:58 on vectors

19:58 dnolen: pickles: there's nothing wrong with those use well, but expect operations like nth and count to be linear after those have been applied, you longer have a vector but a seq

19:58 used well

19:58 pickles: hm

19:58 so if i wrap it in a vect cal will it ease that a bit?

19:59 i was using that alot more in my earlier code

19:59 dnolen: pickles: 1.4.0 alphas have mapv / filterv as well

19:59 pickles: i'm still on 1.2 atm

19:59 dnolen: pickles: but yes you could put them back into vectors (into [] ...)

20:00 pickles: ok, would you recommend that before counts, or just generally after maps?

20:00 dnolen: anything that would be linear otherwise

20:00 pickles: mm

20:01 technomancy: pickles: my advice would be don't optimize before you profile

20:01 dnolen: pickles: and I'm not recommending that in general, just depends on what you're doing

20:01 pickles: right (to both)

20:01 technomancy: a common cause of slowdown is reflection, but until you've confirmed that's a problem you don't want to waste your time with type hints

20:01 pickles: right

20:01 technomancy: especially considering it's likely you only need a handful of them in a few strategic locations

20:02 pickles: was just reading something to that effect

20:02 dnolen: pickles: best to assess your changes since an order of magnitude slowdown sounds weird

20:02 pickles: yeah

20:03 sadly that'll have to wait till another nite, when my brain isn't so fried

20:03 brehaut: re:type hinting and global *warn-on-reflection*, if you set w-o-r to true in lein, do all the dependancies also warn?

20:03 pickles: thx for the help guys

20:04 time for some profiling

20:04 technomancy: brehaut: they should, possibly except for the ones that have been AOTd?

20:04 I actually have no idea; I never profile or AOT personally.

20:04 brehaut: technomancy: right. so if you were to release a library, would you type hint it so that it had no reflection warnings ?

20:04 (ie, to prevent it being noise in someone elses codebase)

20:05 technomancy: I would release it with reflection and wait till someone yelled at me, then I would accept a pull request from them. =)

20:05 brehaut: lol :)

20:05 fair enough :)

20:05 technomancy: it depends on the lib and its likelihood to be used in a tight loop I guess

20:05 brehaut: ie, its a complete waste of time in an xml-rpc lib ;)

20:06 and i shouldnt have bothered

20:06 technomancy: the problem tooling-wise is that there's no way to say "I don't care about reflection warnings from these namespaces; they are all I/O bound anyway"

20:06 I don't think you can fix that outside the compiler

20:06 brehaut: right

20:06 franks: technomancy: just checked-in a pull-request for that rlwrap fix for the 1.7.0-SNAPSHOT branch...

20:07 technomancy: brehaut: so someone could have a legitimate need for warn-on-reflection but have the useful info they need buried by my crap, and that would make me feel at least marginally bad even if it's not necessary for my code

20:07 but really I would shift most of the blame to clojure itself =)

20:07 franks: great; thanks!

20:10 amalloy: mapv, interesting. i guess that avoids creating as many temporary seqs?

20:10 brehaut: and can use a transient ?

20:10 technomancy: hmm; I smell a doall/map replacement =)

20:11 franks: technomancy: ...just one other issue that I noticed - you only enable rlwrap for options of repl/interactive, which doesn't allow a plugin to enable rlwrap... I kind of hardcoded my plugin in there for now - you should be able to enable rlwrap always and still pipe input in thru stdin without rlwrap getting in the way - otherwise maybe enable for any plugin starting with "repl*" ;-)

20:11 technomancy: franks: yeah, I do feel a bit bad about special-casing the built-in tasks. it's probably fine to enable in unconditionally.

20:12 brehaut: answering my own question: yes

20:13 franks: technomancy: you could still test whether there is a terminal connected to enable rlwrap...

20:13 brehaut: whoa. the definition for *clojure-version* is way more complicated than i expected

20:13 technomancy: franks: should already be doing that actually

20:17 franks: technomancy: correct - and that test alone should suffice

20:26 technomancy: modified the pull-request to include a change that would remove the tests for internal tasks.

20:44 jedahu: trying to get lein to start a rhino repl

20:44 no joy: http://paste.lisp.org/display/127304

20:45 dgrnbrg: Is there a good way to report an error from inside a macro and get a stacktrace?

20:45 Can I just (throw (RuntimeException. msg))?

20:45 Can I integrate with clojure's compiler errors?

20:46 jedahu: you know macros don't create stack frames right?

20:46 technomancy: franks: sorry if I was unclear; the removal of the check for the trampoline task was intentional

20:46 amalloy: jedahu: that's an overstatement that assumes something about what he means

20:46 technomancy: since with the addition of :plugins we need to be able to trampoline from arbitrary tasks

20:47 jedahu: amalloy: just trying to clarify exactly that :-)

20:47 dgrnbrg: I am writing some code that does very complex tasks within macros

20:47 and they can fail

20:47 amalloy: an error occuring during macroexpansion will certainly result in a stacktrace in the compile phase

20:47 dgrnbrg: I want the line number where they fail

20:47 amalloy, that's what I'm wondering

20:47 I feel like i've seen my environment not give me stacktraces

20:47 sometimes, but other times I see them

20:49 Is there a shortcut to throw a runtime exception? Like, a utility function or the like?

20:49 brehaut: throw ?

20:49 dgrnbrg: But I want to write (throw "problem is this var" the-var)

20:50 Write my own?

20:50 amalloy: dgrnbrg: so write a function for that, problem solved

20:50 technomancy: slingshot sorta does that

20:50 dgrnbrg: I like to not maintain my system

20:50 and to integrate with the best solutions

20:51 so that I can just focus on my actual problem, instead of the solved problem

20:51 is slingshot the conditions lib?

20:51 technomancy: yeah, its successor

20:51 brehaut: a one line function isnt really that onerous is it?

20:51 dgrnbrg: right, i've read about that

20:52 brehaut, ;)

20:52 jedahu: technomancy: any ideas?

20:52 clojurebot: Gabh mo leithscéal?

20:54 technomancy: jedahu: weird... I haven't done any clojurescript beyond hello world, so it's hard to say

20:55 the task function looks legit though

20:56 I tend to use fully-qualified references + require instead of require :as in eval-in-project, but that's just a style thing

20:57 jedahu: technomancy: thanks for looking

20:57 dgrnbrg: what is a better way of doing (flatten (partition 1 2 [1 2 3 4]))?

20:58 ,(flatten (partition 1 2 [1 2 3 4]))

20:58 clojurebot: (1 3)

20:58 jedahu: there isn't a channel where clojurescript gurus hang out is there?

20:58 dgrnbrg: rather, is that idiomatic?

20:59 technomancy: clojurebot: flatten?

20:59 clojurebot: flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.

20:59 amalloy: &(take-nth 2 [1 2 3 4])

20:59 lazybot: ⇒ (1 3)

20:59 amalloy: jedahu: #clojure

21:00 dgrnbrg: amalloy, take-nth is exactly the function. And thanks for telling me about concat--I forgot about it

21:03 phil: is it considered cleaner style to work with defprocols/records or with just maps of functions when polymorphism isnt needed?

21:33 jeremyheiler: Is it conventional to have an ! at the end of a function name that does IO?

21:35 apwalk: "Use the bang! only for things not safe in an STM transaction."

21:35 http://dev.clojure.org/display/design/Library+Coding+Standards

21:40 dgrnbrg: How do I diff data structures?

21:40 ahh, clojure.daat

21:41 jeremyheiler: apwalk: What is considered not safe? I suppose if I'm not touching the transaction, then it's safe.

21:42 Well, by "touching" I mean not changing a var/ref/agent/atom etc.

21:45 apwalk: I'm new, but I'd say yes, that and using transients.

21:46 I'm looking through the source of *! functions on clojuredocs and looking for patterns.

21:48 Pretty looks like anything that's expected to have side-effects, unless protected by STM.

21:48 jeremyheiler: Nice, yeah, I would agree.

21:48 Thanks

21:49 brehaut: functions whose name end in a ! are not safe for use within an STM transaction

21:49 (rather than side effects in general like in other lisps)

21:50 apwalk: Ah, so replace my "unless" with "and can't be" ...

21:51 jeremyheiler: brehaut: Yeah, I was thinking the definition could also include other side-effecty things, but now that we've talked about it, it makes sense to keep it STM related stuff.

21:52 Given that STM is essential here

21:52 brehaut: send is a good example: its side effecting, but the STM holds all agent sends till after the transaction succeeds

21:52 contrast with atoms that have swap!

21:53 im pretty sure this is _somewhere_ on the dev.clojure.org site, but i can never find it

21:53 jeremyheiler: apwalk provided the link to the one-liner, but that doesn't explain much. unless you're thinking of something else?

21:54 brehaut: maybe ive confused two articles then

21:54 because thats the article i was thinking of, but not not the right exposition

21:56 im curious how dosync and send actually coordinate the holding back of the agent message

21:57 send itself is rather brief

21:57 jeremyheiler: http://clojure.org/refs explains it very well, but doesn't mention the formality of the bang

21:57 brehaut: sorry, i mean the implementation details

21:58 dgrnbrg: I'm trying to test out a macro, and I'm noticing that if I use macroexpand-1 in a deftest, it doesn't seem to expand the macro

21:58 jeremyheiler: brehaut: no, my bad, I was replying to your message about the article

21:59 brehaut: ah i see. clojure.lang.Agent dispatchAction explicitly looks for the running transaction https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Agent.java#L248-258

21:59 jeremyheiler: was just loading that file on github myself haha

22:01 so basically then it just queues it up into the transaction. but that doesn't mean it waits until the end, or does it?

22:01 dgrnbrg: Hmm, the tests work if I namespace-qualify the quoted macro form I want to expand

22:01 but I don't need to on the repl

22:01 brehaut: jeremyheiler: looking at LockingTransaction it does

22:01 jeremyheiler: oh nevermind, i see iterate over the actions in the finall block

22:02 i see it*

22:02 finally*

22:02 brehaut: i wonder why its specific to agents

22:02 and not just arbitrary ifns

22:03 it seems like it would useful to package up all sideeffecting, non transactional stuff like that

22:05 jeremyheiler: it seems like you could by referencing all your side effecty objects with an agent?

22:05 brehaut: i guess so

22:06 that does make them asyncronous, i wonder if thats a problem

22:06 this is all well above my pay grade

22:06 jeremyheiler: im not sure what the bounds of a transaction are yet, though. but i can imagine you may not want... yeah, asynchronous.

22:06 lol

22:08 it'

22:08 it's cool to think about, though.

22:08 amalloy: dgrnbrg: deftest has all kinds of weird and crazy behaviors, especially related to macros

22:10 brehaut: jeremyheiler: definately is. ive learnt a lot by spelunking like that

22:11 amalloy: i believe this is because (deftest foo (blah)) expands to something like (defn ^{:test (fn [] (blah))} foo []), and there's something weird about metadata that i don't entirely understand

22:13 jeremyheiler: brehaut: do you know what the bounds of a transaction are?

22:14 brehaut: jeremyheiler: well, the body of a transaction is wrapped in a thunk fn and passed to LockingTransaction.runInTransaction

22:14 so i presume that the thunk defines the bounds

22:14 (unless it happens to be within an existing transaction)

22:15 jeremyheiler: thunk?

22:15 brehaut: function of zero arguments

22:15 (fn [] :foo)

22:15 jeremyheiler: ah ok

22:16 brehaut: clojure's transactions have a very simple nesting model: if you are in a transaction already, just run the thunk with that, otherwise, create a new transaction. If any of the transactions fail for some reason, then it rolls back the entire thing

22:17 the details however, are a little more involved ;)

22:19 jeremyheiler: Yeah, i'm fully aware of the complexity of concurrency :-P but that sounds like the transactions work like java reentranlocks

22:19 brehaut: last time i really looked at java's concurrency primatives was 2003 ;)

22:20 jeremyheiler: nice, i did some stuff a couple years ago with jsr166 before it was released into java 7, but i haven't done much since :-P

22:20 brehaut: jeremyheiler: a lot of the magic is actually in tracking what refs have been touched

22:21 part of what appealed to me about clojure was that id done threaded stuff in python and it hurt a lot

22:21 even with blocking queues

22:24 jeremyheiler: yeah, i know what you mean. there are some interesting and cool agorithms, like non-blocking queues that leave messes, but the next guy to come through knows how to clean it up. i got a chance to learn form doug lea himself, and it's crazy all the little tiny details that need to be taken care of in order to implement something seemingly simple.

22:25 because of that, is why I started to learn clojure

22:26 with clojure, you can still learn the nitty gritty details, but not have to worry about it if you don't want :-P

22:26 adam_: i concur, the transaction system is why i'm learning clojure now

22:26 brehaut: ironically, most of the code ive written with clojure hasnt used the concurrency features :P

22:26 (at least, not explicitly)

22:26 adam_: yeah, Purely Functional Data Structures by Okasaki has a lot to teach you about data struts

22:27 jeremyheiler: brehaut: i know what you mean, it's been the same here, but it's ok because I plan on getting into it more as clojure takes over my projects.

22:28 adadm_: I read his "follow" up article to that book a few weeks ago. good stuff.

22:28 adam_: **

22:29 but, i'll have to put the actual book at the end of my very long book queue

22:29 adam_: it does a pretty good job explaining how lazy evaulation

22:29 yeah, i got it with some christmas money, i've only read the first couple chapter, its been time well spent

22:29 the only downside is that it's written in ML and Haskell, so understanding those languages is a must

22:30 brehaut: thats not a downside :P

22:30 jeremyheiler: adam_: nice that's good to hear.

22:30 brehaut: its an opportunity

22:30 jeremyheiler: adam_: any excuse to learn haskell is probably a good one :-P

22:30 adam_: because we all know nothing useful can be done with it (jk jk)

22:30 phil: is it considered cleaner style to work with defprocols/records or with just maps of functions when polymorphism isnt needed?

22:30 adam_: yeah, i went thought Learn You a Haskell for Great Good

22:30 its free online

22:31 the problem with Haskell is everything is so damn hard to do

22:31 Raynes: Meh.

22:31 Not really.

22:31 Everything is hard to do until you know the language

22:31 adiabatic: For someone who's already fluent in functional style, how different are, say, Clojure, ML, and Haskell? I know the latter two are statically, strongly typed, but how big of a deal is that?

22:31 Raynes: You have to understand that everything is input to something.

22:31 adam_: yeah, and get your phD in functional languages

22:32 jeremyheiler: meh, it's good to learn to think abstractly anyway. syntax should be moot

22:32 (well, for any reasonable language)

22:32 brehaut: adiabatic: it depends what you are building. if you are just building websites, haskell is going to hurt a lot more than clojure

22:32 TimMc: phil: Work with maps. You can still get polymorphism with multimethods dispatching on some key in the map.

22:32 Raynes: adam_: Those are mostly tired jokes.

22:32 adiabatic: brehaut: Why?

22:32 Raynes: adam_: I started learning Haskell at 13-14. I managed better in it than any other language I used at the time.

22:33 I don't buy into the "it's so hard mathy and academic" stuff.

22:33 brehaut: adiabatic: because websites are programs that take some semi-structured goop from DBs, Forms, Ajax briefly mashing them around and push them out as differently semi-structured goop

22:33 Raynes: No, it isn't what you're used to. But neither was programming in the first place when you started.

22:33 adiabatic: Raynes: You're probably very good at hard, mathy things :)

22:33 phil: TimMc: thx

22:33 brehaut: if you have to satisfy a typechecker you have a bunch more work that has very little reward

22:33 Raynes: You get more done by doing and much less done by worrying about how hard something might be.

22:34 phil: bradwright: why? you still have to get the "types" right in a dynamic langugage and haskells type checker doesnt get in your way

22:34 Raynes: adiabatic: Absolutely. I'm a child genius. Chip off of the ol' block. I've had papers written about me, I have.

22:35 brehaut: phil: i presume you misaddressed that?

22:35 phil: brehaut: yes, sorry

22:36 brehaut: phil: im entirely aware how nice haskells type checker is

22:37 phil: brehaut: what i mean is that when the type checker complains about something thant its likely a bug (more often than not)

22:37 brehaut: phil: on the other hand, the points where data comes into a web app typically already do the transformations to correct types for you

22:38 adam_: Raynes, haskell is a really beautiful langauage, but for what I'm trying to accomplish clojure is much better

22:39 phil: Raynes: i think the language itself is not that hard, but one has to rather adjust to the constructs around it, like if you want state you need the state monad and you need to know what monads, applicative functors etc etc are in the first place

22:39 Raynes: adam_: I'm not trying to argue Haskell vs Clojure.

22:39 brehaut: phil: thats incorrect

22:39 phil: Raynes: in a tradition language you just say a = 4, done

22:39 brehaut: the state monad is just one approach

22:39 Raynes: I'm trying to make you look stupid for saying things like "[21:34:31] <adam_> yeah, and get your phD in functional languages"

22:39 phil: brehaut: i was oversymplyfing

22:39 brehaut: io, ST, STM monads all provide very simple approaches to state

22:39 phil: brehaut: but you need *some* monad in any case

22:40 brehaut: phil: so?

22:40 its only hard if you want it to be

22:40 Raynes: phil: You just described functional programming.

22:40 brehaut: if you just use IO

22:40 adam_: yeah, Rich's article on state in clojure is what really got me into it

22:40 brehaut: then you are writing slightly quirky C code

22:40 Raynes: $he let x = 1 in x + 1

22:40 lazybot: ⇒ 2

22:40 Raynes: Done.

22:40 brehaut: Raynes: OMG head asplode. warn me next time and i'll get my PhD ready!

22:41 Raynes: :)

22:41 jeremyheiler: i always thought haskell's syntax was driven by being somewhat notational.

22:41 and not something so terse it's hard to understand ( although it could get crazy)

22:42 Raynes: They have a Perlish fetish of symbols.

22:42 brehaut: jeremyheiler: i think the trickiest thing is grasping how pervasive partial application is

22:42 and how operator binding interacts with parenless application

22:42 jeremyheiler: brehaut: yeah, i think i'll agree with you on that point

22:42 phil: Raynes: come on... but what happens if you want to manage a widget hiearchy for example? to add a subwidget to a widget you have to first know the path to that widget or use some other construct like a zipper, than replace it, then update some state monad holding the widget hierarchy you have to pass in to the add-subwidget function etc etc etc

22:42 as opposed to just addWidget(widget);

22:43 brehaut: jeremyheiler: i think the hardest thing about typical stateM tutorials is that they brush over that they are using a partially applied type constructor ;)

22:43 Raynes: phil: Learning to program.

22:44 phil: Raynes: so if you dont use a state monad + tree zipper for managing a widget hierarchy you cant program?

22:44 brehaut: wait. not type constructor, field accessor

22:44 Raynes: No, not what I'm saying.

22:44 TimMc: brehaut: I got a taste of the partials stuff when I dabbled in OCaml.

22:44 brehaut: TimMc: its pretty addictive eh

22:44 TimMc: Hard to read when you're just coming from a sexp language.

22:44 * brehaut is slightly embarassed about his 4clojure solutions

22:45 TimMc: I had trouble with it, but mostly for visual/syntactic reasons.

22:45 Raynes: When you learn to program, both of those sets of concepts are equally unapproachable. Once you've learned to program in x way, y starts to look insane because you know how to do the same thing in the x way.

22:45 brehaut: phil: why do you keep insisting that state monad is hard to use?

22:46 phil: Raynes: but would you say that approach A may be better suited to some problems while approach B to others, or is one approach always better?

22:46 brehaut: phil: learning how the machinary works can be difficult, but then, its no different than learning how the interpreter for an imperative language works

22:46 Raynes: My approach in life has been to learn things as I go. When I need something that I don't understand, I just learn it. I don't waste time comparing it to other things.

22:46 Sure.

22:46 phil: brehaut: im not saying it is "hard" to use, its just a lot of extra work for something very simple in an imperative mutable langugae

22:46 Raynes: I'll reiterate that I am not arguing Clojure vs Haskell.

22:47 I'm arguing that it is only hard if you compare it to what you already know.

22:47 When I first drove a stick, I was terrified and frustrated because it was so easy to drive an automatic.

22:48 Are manual transmissions worse than automatic transmissions because I learned on an automatic?

22:48 phil: Raynes: im not arguing a > b either, im also constantly questioning things... just at the moment i cant say im convinced pure fn programming is the answer to everything

22:48 Raynes: I can't say I am either.

22:48 On that we agree.

22:49 adam_: Raynes, we're just trying to compare languages, and you're making arguments for argument sake

22:50 Raynes: Actually, I've pointed out at least twice that I am not comparing languages and phil still responded to me, indicating to me that he wasn't just comparing languages. *shrug*

22:50 I thought it was a worthwhile discussion. But you're the one who brought it up. :)

22:51 * TimMc invents the argument monad

22:51 Raynes: I'd use that monad.

22:51 TimMc: You just did, without knowing it!

22:51 Raynes: Bang!

22:51 adam_: that should be the first monad you learn

22:51 phil: i just wanna hear other points of view, doesnt matter if they are "a > b" or "a != b", they open up new perspectives to think about things

22:52 :D

22:52 how would one define >>= on that monad :/

22:55 brehaut: TimMc: jsut as long as you implement an instance of MonadPlus so we can fail in style

22:56 adam_: is anyone here using monads in their clojure program? and if so, what for?

22:56 brehaut: adam_: i use them for error handling, nondeterminism, and parsing

22:56 TimMc: adam_: They're just not called monads.

22:57 adam_: what would you call them then?

22:57 Raynes: I call them code.

22:57 TimMc: s I understand it, there are a bunch of common functional programming design patterns that Haskellers instantly recognize as monads. :-)

22:58 brehaut: (variations of maybe-m, seq-m, seq-m and for, parser-m (aka state-t seq-m))

22:58 TimMc: I assume brehaut uses formalized versions of them.

22:58 adam_: yeah, i mean the clojure.contrib.monads library

22:58 brehaut: clojure.algo.monads

22:58 TimMc: Ah, well that's the extent of my knowledge on monads,

22:58 brehaut: TimMc: yes

22:59 scottj: adam_: the monads library is not used very much in open source clojure code.

22:59 brehaut: TimMc: (i use the formal ones as well as the informal ideas)

22:59 TimMc: and goddamnit why does the comma have to be next to the period.

22:59 brehaut: TimMc: to increase mistakes

23:00 seancorf`: i'm looking forward to the next "Monads Made Easy" talk at a Clojure conference ;)

23:00 jeremyheiler: brehaut: maybe to minimize more serious errors.

23:00 adam_: i'll have to go then!

23:00 i just started a monad tutorial in clojure

23:00 brehaut: seancorf`: lol

23:01 adam_: following or writing?

23:01 adam_: note taking

23:01 phil: brehaut: i read about cdelim this morgning

23:01 adam_: i learn best by taking copious amounts of notes

23:01 phil: dunno what id use it for but ill think of something for sure :D

23:01 adam_: so i guess following would be the category

23:03 brehaut: adam_: i found doing the reductions by hand made each individual monad make more sense

23:04 (especially complicated ones like state-m)

23:05 adam_: nice, i'm actually working through state-m right now

23:51 clj_newb: is the following correct? clojure is so amazingly smart, it forces me to use agents ... then automatically, behind my back, executeds functions went to agents, and watchers sent on agents, in separate threads -- and it can do so safely due to clojure's concurrency constructs?

Logging service provided by n01se.net