#clojure log - Nov 04 2012

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

0:13 hughfdjackson: is it convention to use dynamic scoping only in the case where you have some kind of impure function or state-holding var for testability

0:13 or are there other common uses?

0:13 (elisp style configuration injection via scope? :P)

0:13 bbloom: hughfdjackson: configuration is a pretty common use case

0:14 Raynes: hughfdjackson: Every time I see your name I think I'm reading "hughjackman" and I get all excited.

0:14 hughfdjackson: haha

0:14 I get disappointed

0:14 i don't know if i exist in my own google bubble now, but it used to ask me if i meant hugh jackman whenever i was curious if people could find me by that

0:16 bbloom: that's interesting; for some reason i thought that'd be a 'left behind' practice

0:16 bbloom: hughfdjackson: left behind by what?

0:17 hughfdjackson: the community

0:17 bbloom: hughfdjackson: i mean: replaced by what?

0:17 hughfdjackson: consider a client library for an http api. It would be pretty reasonable to have (def ^:dynamic *api-endpoint* "http://api.example.com")

0:18 you could then pretty easily rebind that for different environments

0:18 hughfdjackson: totally :) it was not a rational thought

0:18 bbloom: (binding [*api-endpoint* "http://api.example-test-server.com"] ...)

0:19 dnolen: hughfdjackson: it's also a useful way to push information deep into a program with the insane tedium of the threading that value everywhere.

0:19 hughfdjackson: in answer to your 'by what' question: configuration injected into higher-order functions was my first guess

0:19 bbloom: for sure! consider *current-user* :-)

0:19 hughfdjackson: :P i can see how writing that way would be a totally PITA though

0:20 bbloom: it's common in web apps to have a *request* var too

0:20 hughfdjackson: that holds? O.o

0:20 bbloom: the current request....

0:20 hughfdjackson: oop, we're in a one-thread spawned per user model?

0:21 * hughfdjackson is very used to the event loop, async, js model

0:21 bbloom: not necessarily

0:21 but there is only one executing piece of code per thread... kinda by the nature of um... threads....

0:21 see bound-fn

0:21 ,(doc bound-fn)

0:21 clojurebot: "([& fntail]); Returns a function defined by the given fntail, which will install the same bindings in effect as in the thread at the time bound-fn was called. This may be used to define a helper function which runs on a different thread, but needs the same bindings in place."

0:23 hughfdjackson: smells like closing over dynamic scope

0:23 :D crazyness

0:23 bbloom: that's what it is

0:25 hughfdjackson: :) thanks for the context, it really helps

0:29 rlb: Raynes: happen to know of anything like refheap for small images, even with a really short lifespan (for example, I have a 10k incanter plot I wanted to show someone)?

0:30 (someone for whome it wouldn't easier for me to just post the source...)

0:30 s/whome/whom/

0:30 Raynes: Is there a reason you've ruled out sites like imgur?

0:31 rlb: Raynes: ignorance?

0:31 Raynes: :p

0:31 imgur is pretty nice. Don't think it requires registration.

0:31 exifhost is something a friend works on, but I think it requires registration. It has the benefit of showing exif data, but I highly doubt you care in this case.

0:31 rlb: yeah -- thanks that might be exactly what I want.

0:32 right -- this is something they're welcome to trash an hour after I post it (and probably should)

0:33 that reminds me I still mean to contact the incanter author about ssh -X/Y being broken -- see if it's something that can be fixed...

0:34 bbloom: rlb: imgur preserves images only if they get traffic

0:35 rlb: which the FAQ apparently says 1 view per six months is all that's needed, heh

0:35 rlb: saw that

0:40 hughfdjackson: cron job? :D

0:41 jyu: does anybody use the vimclojure, how to arrow up the prvious expression and it seems the C-CR does not work.

1:16 bbloom: jyu: the vimclojure maintainer is very responsive on his google group

1:15 amalloy: Raynes: i think for an image host, showing exif data is an anti-feature

1:15 Raynes: amalloy: I'm not sure what you mean.

1:16 amalloy: Raynes: if you upload a picture to the web with exif data, your chance of being murdered by a stranger goes up by at least 300%

1:16 because it has location and all kinds of stuff

1:17 Raynes: amalloy: There is more than just location data there. Data about the camera is what is important, and the site was authored by a guy interested in high profile photography (who knows other people interested in it as well).

1:18 Also, people tweet with locations, put it on their facebook statuses, etc.

1:18 Nobody seems to care about privacy anymore.

1:33 notsonerdysunny: why does clojure.core.Vec (created by doing (vector-of :long 0) ) not implement IEditableCollection which would enable transient on the vector ? or am I missing something?

1:53 amalloy: my guess: because transients require work, and primitive vectors are mostly ignored

1:57 Sgeo: amalloy, what's the best way to learn about how the data structures in Clojure work, reading the source or reading some sort of documentation?

1:57 amalloy: $google higher order persistent clojure vector

1:57 lazybot: [Understanding Clojure's PersistentVector ... - Higher-Order] http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/

1:57 Sgeo: Cool, thanks

1:58 amalloy: any more detail than that, probably you want to look for anything about array-mapped hash tries, especially by phil bagwell

3:40 _francis: I need to use LaTeX in a seesaw (swing application) - does anyone know of a good starting point/have any useful information on the matter?

4:21 Anonny: A clojurescript vector is cljs.core/PersistentVector, a lists is cljs.core/List... any idea what a string is?

4:22 For defmethod purposes.

4:27 TEttinger: is there a list of companies that have announced that they use clojure?

4:29 Anonny: Don't think it's up to date but http://dev.clojure.org/display/community/Clojure+Success+Stories

4:31 Raynes: Not so much that it isn't up-to-date as much as it isn't all inclusive. If companies haven't added themselves to it, they're not going to be listed. It's still a big resource.

4:33 TEttinger: thanks

4:34 I love Clojure, but I am really pretty early in the learning process still

4:34 haven't written a macro yet

4:34 Anonny: It's amazing what you can do with only functions.. :)

4:34 TEttinger: it's a very powerful/succinct language.

4:35 lpvb: TEttinger: there's also clojure job listings to tell you what companies use clojure: http://www.indeed.com/q-Clojure-jobs.html

4:37 Anonny: This CLJS is driving me nuts, though. I can catch vectors with (defmethod xxx cljs.core/PersistentVector [etc] (etc)).. But I have no ideas how to make a defmethod for cljs strings.

4:38 Feels like I'm missing something obvious.

4:47 Aaaand the answer was js/String

5:17 wingy: TEttinger: will you go with clj?

5:22 TEttinger: wingy: I haven't programmed very much lately, but when I write little things it usually seems to be in clj

5:23 wingy: its the perfect language

5:24 Raynes: "I don't always program, but when I do, I prefer ClojuresScript."

5:25 Anonny: That's what I was thinking too.. :D

5:26 wingy: yeah love cljs

5:26 but its so heavy

5:27 isn't it compiled to js like coffeescript so it won't load other stuff to the browser?

5:28 Anonny: I don't understand that question. Could you clarify?

5:28 wingy: it seems to load a lot of code into the browser

5:29 it compiles to a big js file

5:29 Anonny: It is compiled to JS. But if you compile it correctly (advanced mode) the closure compiler should trim out everything you don't use.

5:29 That makes it significantly smaller.

5:30 wingy: if i use advanced mode, can i still use third party libs in my code?

5:30 or will the variable names be changed

5:31 Anonny: I'm fuzzy on that part honestly. Yes, they'll be changed unless you mark them not to be changed or some such.

5:31 This might answer.

5:31 http://lukevanderhart.com/2011/09/30/using-javascript-and-clojurescript.html

5:32 wingy: yeah i remember that one

5:38 Anonny: Might also take a look at how jayq wraps jquery since Chris had to figure out how to mix advanced comp and an external library for that.

6:15 yarn: Hi everyone, how do I correctly use a google closure aware library from clojurescript? I tried :libs ["resources/public/js/boob-moog-google-doodle/deps.js"] in my project.clj file, to no avail

6:15 (trying to require the Moog Google Doodle: http://code.google.com/p/bob-moog-google-doodle/

6:16 I get an exception "goog.require could not find: doodle.moog.Moog"

6:16 joro: if I do (reduce clojure.set/intersection a b c) do I gain perforamnce if I order a b, and c increasingly by size

6:24 ambrosebs: Is there a high res Clojure logo around?

6:25 Actually, I think the one I found might just be enough.

6:25 nvm :)

6:26 wingy: ambrosebs: what are you going to do with it?

6:26 ambrosebs: Put in on a poster advertising Typed Clojure for uni. Rich already gave the thumbs up thankfully.

6:28 Is there an official source for a large version?

6:29 wingy: ambrosebs: what is _typed_ clojure?

6:29 ambrosebs: https://github.com/frenchy64/typed-clojure

6:30 Clojure + optional type system

6:30 WIP, but has been my honours project.

6:32 wingy: looks cool

6:33 ambrosebs: :)

6:34 wingy: can typing reduce bugs?

6:35 but on the other hand the code grows

6:35 Iceland_jack: Does it wingy?

6:35 That depends on a lot of things

6:36 ambrosebs: wingy: IMO it helps the most when you've got higher-order code. Fns taking Fns taking...

6:39 wingy: but I think the benefits of static typing speak for themself. Whether Typed Clojure can bring most of the benefits is yet to be seen.

6:39 Bodil: ambrosebs: I don't remember where I found it originally, but I've got an SVG logo here if you don't mind inkscaping off the opacity etc: https://raw.github.com/bodil/catnip/master/resources/catnip/m/clojure-glyph.svg

6:41 ambrosebs: Bodil: I googled the name of the file and found the original, cheers!

6:50 ejackson: ambrosebs: how did the seminar go ?

6:51 ambrosebs: ejackson: went a bit too fast and had some extra time. Except I realised afterward it was because I forgot my last 2 slides :P

6:51 Oh well, good experience.

6:51 Snuck in a quick demo too.

6:51 ejackson: nice one!

6:51 good validation for your work

6:52 ambrosebs: ejackson: planning to do more demoing at the conj.

6:53 ejackson: yeah - demos are the key to drive adoption, and hence contributions

6:56 ambrosebs: ejackson: could I send you this poster once it's done to check?

7:02 ejackson: ambrosebs: sure thing

7:09 meredydd: What do I need to do to make (run-tests) notice my tests?

7:10 I'm in a namespace, I've just done:

7:10 (deftest x (is (= 0 1)))

7:10 (run-tests)

7:10 ...and it says "Ran 0 tests containing 0 assertions"

7:11 Oh, God, never mind.

7:11 <-- fool.

7:55 flying_rhino: hello

7:56 I would like to know what IDE solutions do we have for Clojure? I tried enclojure (netbeans version) but it is only available for clojure 1.2. What is there for 1.4 version?

7:57 developing without IDE is PITA.

7:58 rodnaph: most ppl use emacs i think flying_rhino. i use vim. i've heard intellij has some decent integration if u need an IDE.

7:58 IDE's won't give you any more integration than emacs though, it's pretty complete.

7:59 _ulises: +1 for emacs

7:59 flying_rhino: okay is there 'batteries included' emacs or vim packaged with newest clojure?

7:59 rodnaph: u can try an emacs starter kit like - https://github.com/technomancy/emacs-starter-kit

8:02 flying_rhino: this 'starter-kit-lisp' thing will make it possible to work with Clojure?

8:03 rodnaph: not used it myself but i think so, should include this somewhere - https://github.com/technomancy/swank-clojure

8:10 flying_rhino: I think you guys really need better getting started page

8:12 Scriptor: there's been a lot of discussion on that, but I think the concensus is that clojure.org is terrible for beginners

8:12 antares_: flying_rhino: see http://clojure-doc.org

8:12 flying_rhino: Scriptor: you are a guy that buit pharen?

8:13 Scriptor: flying_rhino: yep

8:13 flying_rhino: Scriptor: big fan

8:13 Scriptor: thanks :)

8:13 flying_rhino: Scriptor: didn't have chance to use it much, but I like the idea

8:14 Scriptor: no worries, I'm still not sure whether it will every see much serious use

8:14 but it's fun to play around with, at the very least

8:14 joro: do you use unit tests, or TDD while writing clojure?

8:14 flying_rhino: but seriously, Clojure needs some sort of one click install

8:15 rodnaph: Scriptor: that looks neat, i was playing around with the same idea myself a while ago - https://github.com/rodnaph/clj-php

8:15 flying_rhino: Python has it and the only obstacle for clojure is that it builds on top of Java. But that's not a reason enough

8:16 rodnaph: flying_rhino: the "one click install" for clojure is installing leiningen - http://leiningen.org/

8:16 Scriptor: rodnaph: nice, I started it before I knew clojure well at all, so it's far from a clojure -> php compiler

8:16 so that niche is still open :)

8:17 rodnaph: yah same here, it was very much to learn the ideas.

8:17 i stopped though because i think the idea has really been superseded by clojurescript (which will have pluggable backends soon i think)

8:18 Scriptor: didn't know about the pluggable backends

8:18 rodnaph: don't think it's landed yet, but it's defo in the works. might be part of the clojure-in-clojure effort.

8:18 Scriptor: I think someone here mentioned that semantically, you'll never have a "true" clojure to php compiler, since php has mutable strings

8:18 so that guarantee that strings will never change isn't there

8:19 which messes up equality, and so on

8:19 pau|c: Hi, I've spent a few hours fighting with NoClassDefFound and ClassNotFound exceptions. I've been playing with various combinations of noir, clj-http, monger and chesire.

8:19 Any idea whether there are incompatibilites between those libs, or whether there's something wrong with my setup (I've cleared out ~/.m2 a few times)

8:20 flying_rhino: well php has mutable *everything*

8:20 antares_: pau|c: please post full stack trace and your project.clj

8:20 flying_rhino: so I don't really see why strings are the problem

8:20 antares_: pau|c: that exception cannot be caused by "incompatibilities"

8:21 Scriptor: flying_rhino: it's somewhat theoretical

8:21 rodnaph: i don't think the mutable part of php will cause any problems, it'll just be a detail of the host. ie. you can mutate java stuffs in clojure.

8:21 flying_rhino: if you don't give people means to change strings from withing implementation, I don't get why would it matter that strings are mutable

8:21 *within

8:21 Scriptor: but essentially, it means that if you compare two strings that *should* be the same, they might not actually be the same

8:21 rodnaph: (not that i really think anyone should invest much time in trying to get a good clj to php compiler)

8:22 Scriptor: strings can be changed by other php functions that you can't control

8:23 pau|c: antares:_ http://pastebin.com/QTgxg0ws

8:25 I get the same stack trace with noir 1.3.0-beta10

8:34 antares_: updated version, where I'm certain everything is 'clean' https://gist.github.com/4011912

8:35 antares_: pau|c: are you using Monger 1.3.2 or earlier?

8:35 pau|c: 1.3.1

8:35 antares_: pau|c: then upgrade to 1.3.3: https://github.com/michaelklishin/monger/blob/1.3.x-stable/ChangeLog.md

8:36 pau|c: http://blog.clojurewerkz.org/blog/2012/10/31/monger-1-dot-3-3-is-released/

8:37 pau|c: antares_: bah, not sure why I was on 1.3.1. will upgrade, thanks.

8:37 antares_: the problem is that if data.json not available, extending its protocols is tricky and before 1.3.2 it wasn't done correctly

8:37 but 1.3.3 will use cheshire, data.json 0.1.x or data.json 0.2.x, whichever is available

8:37 pau|c: ok

8:46 flying_rhino: rodnaph: from what I understand Lenanigen is build tool for clojure, it is not one click install

8:48 rodnaph: flying_rhino: it's kind of more than just a build tool, aside from java it's all you need to get started with clojure, which is why i suggested it. there is also lighttable which you might find interesting as a complete solution http://app.kodowa.com/playground

8:49 Scriptor: it's not a gui installer, but it can knock out two birds with one stone

8:49 since you'll likely need it for any serious projects later on, in addition to getting clojure

8:50 raek: flying_rhino: Leiningen is for clojure what the 'python' and the 'virtualenv' commands are for Python

8:50 Clojure is distributed as a library

8:50 so you need more stuff to actually use it

8:51 it's too bad Leiningen hasn't been officially endorsed as a part of Clojure

8:51 95% of all clojure programmers use Leiningen

8:51 flying_rhino: okay now that I have Lein, what now?

8:52 rodnaph: and the other 5% probably don't have keyboards.

8:52 raek: you create a project (yes, even for trivial stuff) and declare which version of clojure you want to use

8:52 and any libraries you want to use

8:53 then you can run "lein repl" in the project dir to start playing around

8:54 flying_rhino: also: https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md

9:05 mammoth: my connection died

9:06 okay, one more thing: is there command prompt for windows that doesn't completely and absolutely sucks?

9:06 callen: I think I'm close to being able to put to words what I don't like about enlive.

9:07 classcast: mammoth: there is the Windows PowerShell

9:07 mammoth: I don't think they have Windows 7 64 bit version

9:07 mdaines: I'm trying to invoke a function four times. What's the idiomatic way to do that?

9:07 mammoth: ah they do

9:08 classcast: it's .Net - I dont think it would be that limited

9:08 mammoth: nevermind found it

9:08 rodnaph: mdaines: dotimes maybe? depends exactly what ur doing though probably.

9:08 mammoth: thanks

9:08 thanks, classcast

9:10 mdaines: Using a DataInputStream and want to read 4 bytes. I want each to be an element in the returned seq

9:10 classcast: mdaines: (repeatedly 4 (.readByte dis))

9:11 needs to be a function thus: (repeatedly 4 #(.readByte dis))

9:13 mdaines: excellent, thanks classcast

9:17 leoncame`: how can I check if a symbol is a macro or not?

9:21 classcast: leoncame`: you can resolve the symbol to its variable and check its metadata for :macro true

9:21 goracio: hi there is there any with fluent english and good clojure knowledge i wrote some articles about clojur and need an reviewer :)

9:22 snake-john: Hi I'm trying to use the reducers library .

9:22 (require '[clojure.core.reducers :as r])

9:22 Hodapp: goracio: PM me.

9:22 snake-john: (into [] (r/mapcat my-fn coll)

9:24 classcast: snake-john: I guess `into` will have to do with your question ;)

9:24 leoncame`: classcast: Cool.

9:25 snake-john: sorry I'v got code like (into [] (r/mapcat my-fn coll) working sequently. I now want to make it parrellel. But my col has only 15 elements.

9:26 I see that fold which is used by r/map uses a default of 512 to decide if fork-join is going to be used

9:27 ejackson: that's right

9:27 snake-john: How do get map to use a splitting factor of 1

9:28 ejackson: dunno actually ;)

9:28 are you sure fork-join is what you want ? Perhaps pmap or agents are better ?

9:29 classcast: snake-john: do your 15 tasks use up enough time so that this is really worth it?

9:30 snake-john: Well I just playing around and want to experiment…. but each collection element transform is doing quite some work...

9:30 classcast: snake-john: I just wanted to save you some time in case they might be pretty quick anyway ;)

9:31 snake-john: I am working just on a chess program and each item in the collection is a chess piece and the map fns calc the possible moves

9:33 so far the reducers have helped me a lot because I do not need to create in-between vectors

9:36 classcast: snake-john: humm I wonder why they have `n` on the low-level anyway if they just default it to 512 and do not expose it to the highlevel functions

9:38 snake-john: I think one is supposed to right a custom map function. but unfornatlly all helper functions are private so its a lot of work

9:45 classcast: snake-john: I guess that it's due to the alpha status ;)

9:50 snake-john: @classcast I think your right…. anyway its a great library ! do you have any idea when clojure 1.5 will officially come out?

9:53 classcast: 1.4 had 7 betas after the alphas

9:55 snake-john: oh so it could take another year...

9:56 classcast: snake-john: maybe not that long but probably several months. there is hardly any info on deadline if there are any

9:56 Deston: Can someone tell me what I'm doing wrong with this exercise from the clojure koans? Why does the output contain "street-address, city, state" and not the values? http://pastebin.com/w69Squev

9:58 classcast: Deston: your quoted list expression is wrong. you want the values of the symbols in the list and not the unevaluated symbols

10:01 Deston: Interesting. It works if it's a vector instead of a list.

10:01 classcast: Deston: try that one http://pastebin.com/G1miy9R5

10:02 &(let [a 1 b 2 c "hello"] '[a b c])

10:02 lazybot: ⇒ [a b c]

10:02 classcast: Deston: as you can see above it wont work with the vector either

10:03 Scriptor: you don't need to quote the vector

10:03 Deston: yeah, I didn't quote the vector and it did work.

10:03 classcast: well thats something different ;)

10:03 Scriptor: lists need to be quoted to prevent them from getting evaluated as a function call

10:03 classcast: [a b c] = (vector a b c), '(a b c) = (list 'a 'b 'c)

10:04 lesson: a quoted list works only for constant lists as abbreviation ;)

10:05 Deston: but as you can see in my example, your code was too complicated anyway

10:06 Deston: yeah. I'm just working with what I've seen in previous koans exercises.

10:08 Thanks for the assistance.

10:16 duck1123: Is there an easy way to expose the "/META-INF/resources/webjars/" directory of any of the jars on my classpath as static resources with compojure?

10:16 I haven't been able to get it right yet

10:17 weavejester: duck1123: Anything on the classpath can be exposed using route/resources

10:17 duck1123: But I'm not sure that /META-INF/resources is on the classpath

10:18 duck1123: So would specifying that in lein make it work? Or would that only be for that project?

10:19 weavejester: Specifying what in Lein?

10:19 duck1123: I'm wondering if there's something I can specify to make sure that that path is added to the cp

10:19 let me try some thigss first

10:20 weavejester: This is in a war file, right?

10:20 duck1123: yeah, from http://www.webjars.org/

10:21 actually wait. I'm not deploying a war

10:21 I'm running an aleph server started from lein run

10:22 weavejester: So why is there anything in META-INF?

10:23 duck1123: All these jars have a different js lib in META-INF (for the benefit of setups that ARE packaged as wars)

10:23 I'm trying to see if I can make use of it from compojure

10:23 weavejester: Okay, so these are jars designed for use with Java servlets

10:23 And not Clojure

10:23 duck1123: right

10:24 weavejester: Try loading up a REPL

10:24 and using the clojure.java.io/resource function

10:24 To see if "META-INF/resources/webjars/some/file/you/know/exists" returns a URL or nil

10:25 duck1123: ah ha! I've been trying with an initial /

10:53 snake-john: @classcast I think I found out how-to override the 512 default. Instead of using reduce I just have to use fold with which I can supply an n. But as you thought my code runs actually slower. because n probably needs to be pretty large to overcome the Thread overhead

10:54 joro: if I do an intersection of two sorted sets, does the core algorithm utilize the fact that, you can do the intersection by choosing a subset of a larger set using min and max of the smallest set?

10:55 classcast: snake-john: ah nice.

11:30 Hodapp: goracio: 'They are fine frameworks and languges but all of them praise OOP paradigm. I have no big experience with programming but i can say that this concept is overcomplicated from my point of view. I even think that people just didn’t understand objects concept and started using it in another way, mostly wrong way. I could say that nowadays it’s Class programming.'

11:30 yeah, that's pretty much true...

11:35 joro: Hadapp: who wrote that quote?

11:55 Hodapp: joro: goracio did :)

11:58 joro: clojure-experience has been very interesting. I'm still a newbie yet, but when the codebase has increased, I find to reuse much more than in any other language.

11:59 goracio: well i'am wrting series of articles about clojure and clojurescript will anounce it soon on clojure forum

11:59 antares_: goracio: make sure your blog is aggregated by planet.clojure.in

12:00 joro: I've not used statically typed FP-lanugages for any serious things, though. I do not know how clojure compares to them.

12:00 goracio: antares_: ok will check that - now it's on tumblr

12:12 mdaines: Any recommendations for dealing with byte constants? Writing a chain of (cond) seems clunkier than it does in Java.

12:16 bbloom: mdaines: dealing with them in what way?

12:16 mdaines: Parsing in binary data. First byte indicates what to do with the next few bytes.

12:17 antoineB: hello, what is the most efficient (distinct (sort a)) or (sort (distinct a)) ?

12:18 rlb: mdaines: do you mean cond or case?

12:19 http://clojuredocs.org/clojure_core/clojure.core/case

12:19 mdaines: Actually, I didn't see there was a case.

12:19 rlb: might be more what you want

12:19 mdaines: Thanks.

12:19 rlb: certainly

13:35 dnolen: ambrosebs: poster looks good to me!

13:36 ambrosebs: dnolen: thanks!

13:40 callen: dnolen: liked your talk on "Clojure for Schemers"

13:40 dnolen: the audience seemed like they were being a little defensive though.

13:45 jonasen: What's the difference between VarExpr and TheVarExpr in the Clojure compiler?

13:45 ambrosebs: ^^ maybe you know that one :)

13:47 ambrosebs: Isn't TheVarExpr (var a)

13:47 But what is VarExpr... :)

13:48 Possibly (foo ...) vs. (var foo)

13:48 dnolen: callen: that was sound long ago, I forget what about?

13:48 that was so long ago I mean

13:49 jonasen: ambrosebs: That's probably it. Thanks

13:49 ambrosebs: jonasen: np

13:49 jonasen: what are you doing so deep?

13:50 jonasen: ambrosebs: Just playing around... I'd like to port http://github.com/jonase/scape to jvm clojure instead of just clojurescript

13:52 ambrosebs: is `analyze` useful?

13:56 jonasen: ambrosebs: it is, I have created an "lite" version of analyze for this project.. just to understand the underpinnings better

13:56 ambrosebs: jonasen: sweet

13:57 jonasen: I really wanted to enhance the analysis phase for codeq.. but that turned out to be much harder then anticipated

13:58 ForSpareParts: Could someone help me debug this? http://pastebin.com/m4dGy11f

13:58 ambrosebs: how does it work?

13:59 ForSpareParts: It's supposed to create a class using the bundled java hooks and a function that's been passed in

13:59 but when you call it from another namespace, there are collision problems.

13:59 dnolen: jonasen: what was so challenging?

14:08 jonasen: dnolen: the short version: macros get in the way

14:11 tomoj: (fn [part] (memoize (fn [& args] (d/tempid part))))

14:12 or (fn [] (memoize (fn [part & args] (d/tempid part)))) ?

14:15 jonasen: I tried to use the clojurescript analyzer to add codeq support for clojurescript (with a more advanced analysis phase than the clojure version)... The codeq Analyzer protocol works on one source file at a time calling "git cat sha ..." and passing the source text to the Analyzer protocol functions. This doesn't play nice with e.g., https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/analyzer.clj#L669 and https://github.com/clojure/cloj

14:16 dnolen: jonasen: that line in the CLJS analyzer an optimization thing, we could probably make that optional.

14:16 is an

14:18 Sgeo_: ,(let [-> inc] (-> 5)) ; ##(let [-> inc] (-> 5))

14:18 lazybot: ⇒ 5

14:18 clojurebot: 6

14:19 jonasen: dnolen: but the problem is pretty fundamental I think. If you want to figure out which var's are in use you pretty much have to macroexpand. If you are handed source code for one file at a time there is no way to find do the macroexpansion.

14:20 As long as you don

14:22 As long as you don't have access to all the source code you have no choice but to resort to "guess work" (which the codeq analyzer does, i.e., (.startsWith (name sym) "def") etc.)

14:22 dnolen: jonasen: I guess I don't see why codeq can't be modified to make doing the right thing possible? or are you saying you might as well continue with scape? :)

14:22 Sgeo_: I guess one advantage Clojure has over Tcl is that it's actually possible to analayze Clojure code

14:22 Pretty sure it's actually impossible with Tcl

14:25 ForSpareParts: Is there anyway to create an abstract class with gen-class?

14:25 jonasen: dnolen: There is good reason to not do any macroexpansion too as that means eval-ing (possibly untrusted) code, especially if you intend to index every clojure github project (which would be awesome).

14:26 Sgeo_: Run it in a VM?

14:26 (Not suggesting Clojail, it has some issues that might make code intended to not be run in Clojail break)

14:27 jonasen: one idea is to only macroexpand clojure.core macros. That would probably get you 95% of the way to correctness

14:29 Sgeo_: Write a macroexpander where only pure non-I/Oy functions run?

14:29 And any macro that tries to execute an impure function gets marked as well as places that rely on that macro?

14:29 (e.g. all uses of Noir's defpage, I think)

14:32 tomoj: I always imagined an lxc per project. is there a way to avoid needing a new jvm for every commit?

14:32 dnolen: jonasen: right

14:34 Sgeo_: lxc?

14:44 callen: Sgeo_: since nobody else piped up: http://en.wikipedia.org/wiki/LXC

14:45 Sgeo_: Ah, cool

14:45 jonasen: dnolen: Anytime you wan't to statically analyze lisp programs, macros get (by definition) in the way since there is no way to know what they do with your s-expressions. On the other hand, If you do macroexpansion you are 1. no longer doing _static_ analysis, 2. lose valuable information as all "macro call sites" are lost. I have come to the conclusion that analysing lisp programs is a hard problem.. and therfor interesting :)

14:48 dnolen: jonasen: aren't there some assumptions here about the macro system at play? If Clojure offered something more akin to Scheme syntax-rules - simple rewriting - I think this would be less problematic.

14:49 jonasen: dnolen: I'm not familiar with schemes hygienic macro system

14:50 dnolen: jonasen: arbitrary code not allowed - pattern matching, rewriting only

14:50 jonasen: dnolen: ok

14:51 dnolen: jonasen: sufficient for many macros - and insane for sophisticated ones like pattern matching

14:52 jonasen: dnolen: I learned scheme once but never got as far as creating my own macros.. But I do remember they looked scary

14:53 dnolen: jonasen: they are actually quite nice - Scheme's problem is that syntax-rules really is awful for more complex macros. syntax-rules really is pretty simple to understand.

14:53 I haven't ventured into syntax-case or the macro features of Racket

15:41 bbloom: jonasen: is there any reason you can't do *dynamic* analysis too?

15:41 jonasen: i.e. run the macro expansions inside a security context and with a timeout?

15:47 the static vs dynamic divide always seemed strange to me.... most static type systems have "soundness" (ie. termination) as a built in quality. but that severely limits what you can have them represent. seems like "terminates within 3 seconds" is a reasonable requirement to enforce externally :-P

15:48 jonasen: bbloom: sure, that's possible. But the problem with using the clojurescript analyzer (or ambrosebs 'analyze') for codeq still stands.

15:49 bbloom: jonasen: you're referring to the need to recurse into files you depend on?

15:50 jonasen: yes

15:50 bbloom: dnolen: this brings up the idea of a protocol for the module system....

15:51 Sgeo_: There's a language extension to Haskell that allows some cases in which type checking might not terminate, I think

15:51 bbloom: Sgeo_: i think i saw that. and lots of other work too on proving more dynamic properties with termination. see: dependent types

15:52 jonasen: would you be interested in helping decouple the clojurescript compiler from gclosure and to make the module system more pluggable? i'm imagining supplying/finding/loading/whatever a module out of codeq

15:53 jonasen: no idea what that looks like yet.... needs a lot of thought

15:54 dnolen: bbloom: termination is not enough in a system in which macroexpansion can fully interact w/ the runtime. sandboxing might help but given the freedom Clojure programmers have I think there are probably a lot of wacky macros out there.

15:55 to which I've contributed my share

15:55 bbloom: dnolen: yeah, of course there will be things that are simply too difficult to analyze statically. but expanding most macros has got to beat heuristics like startsWith "def"

15:56 s/analyze statically/analyze

15:56 dnolen: bbloom: thus my earlier point about syntax-rules. The Scheme people already thought about this. syntax-rules is reasonable default if you want the most of the corpus to be analyzeable w/o jumping through hoops.

15:57 bbloom: dnolen: oh yeah, that makes sense to me, but it's too late to change all the macros out there now :-P

15:57 dnolen: yep

15:57 jonasen: bbloom: that's exactly what I meant when I said that expanding clojure.core macros would get you 95% there

15:58 bbloom: jonasen: being that i haven't memorized core yet.... are there any macros in core who's execution could be a security or stability risk?

15:59 jonasen: maybe i'm paranoid, but i wouldn't even run those outside of a security context & timeout :-) at which point you can get 98% of the way there by also expanding user macros... .assuming you solve the dependency/module problem

16:00 jonasen: The problem is: is a symbol (without a ns-part) in an s-expression a local or a var? With that information it would be easy to substantially enhance the codeq clojure analyzer

16:01 tomoj: will a security context prevent d/connect + d/transact?

16:02 bbloom: jonasen: doesn't the analyzer's :var form include a :name property? can't you just check for (namespace (:name vast-ast-node)) ? non-nil means it's a var

16:03 jonasen: bbloom: you can't run the available analyzers in codeq (as things are now)

16:03 bbloom: jonasen: right, because of the module system.... i think we're going in circles :-)

16:04 jonasen: I'd love to be able to participate in the codeq unsession at clojure-conj.. Any and all notes from that session would be much appreciated. Video would be even better :)

16:06 Sgeo_: Am I the only one who thinks Clojure/Tcl communication would be fun?

16:07 Iceland_jack: Heh.. possibly

16:11 Sgeo_: They're both very flexible languages, they both have notions of immutability

16:12 clj_newb_2345: how do I write a clojure structure out ot file

16:12 bbloom: spit

16:12 clj_newb_2345: (spit f _structure_) ends up printing out "lazy sequence"

16:12 bbloom: ,(doc spit)

16:12 clojurebot: "([f content & options]); Opposite of slurp. Opens f with writer, writes content, then closes f. Options passed to clojure.java.io/writer."

16:12 clj_newb_2345: i need to convert the structure to a string first

16:12 perferably a string that I can read back using "read"

16:13 bbloom: clj_newb_2345: are you sure you haven't already got a string?

16:13 clj_newb_2345: try (class _structure_)

16:13 (println (class _your_thing_)) and report back what you get

16:14 clj_newb_2345: got it working with with-out-str println

16:15 bbloom: clj_newb_2345: ah, yeah, spit uses str, not pr

16:16 jonasen: bbloom: I'm not sure what you mean with a module system, but if cljs.analyzer/get-expander was customizeable it might be possible to use the clojurescript analyzer with codeq.

16:16 But enhancing the codeq _clojure_ analyzer would be more useful as there is much more clojure code out there than clojurescript

16:17 bbloom: jonasen: there are a few things that you need knowledge of namespaces and vars to do. get-expander is one example of resolution

16:18 jonasen: another example is that analyze-deps you pointed out

16:18 jonasen: it calls io/resource and then analyze-file

16:18 in theory, there are several related functions that differ depending on where you're looking up files to satisfy dependencies, resolve vars, etc

16:19 the implementation that is there now loads up files using the java class path

16:19 dnolen: bbloom: analyze-deps is not necessary - the analyzer would work just fine w/o it - that's just for optimization like said before.

16:20 bbloom: dnolen: right, but that's not true for macros nor is it true for :use without :only

16:21 dnolen: bbloom: yes but analyze-deps doesn't look at macros.

16:22 bbloom: er sorry didn't read closely enough. right.

16:22 bbloom: jonasen: does codeq use the "real" jam clojure analyzer? or is it ad-hoc?

16:23 jam -> jvm

16:23 dammit Textual, how do i forcibly turn off autocorrect?

16:24 * bbloom unchecks that damn box

16:25 jonasen: bbloom: the codeq analyzer doesn't do much (clojure specific) analysis: https://github.com/Datomic/codeq/blob/master/src/datomic/codeq/analyzers/clj.clj#L29

16:26 bbloom: jonasen: yeah, pretty ad-hoc

16:26 would be nice to use the clojurescript analyzer there... despite the fact that it needs some work to support big boy clojure

16:27 jonasen: bbloom: that was my idea too.. but it was more difficult than I initially thought :)

16:28 dnolen: bbloom: jonasen: rhickey said he'd like to see bits of the CLJS analyzer integrated too. My understanding is that codeq in it's current is a proof of concept and it's up to the community to push it along further. like ClojureScript was/is to a large degree.

16:28 bbloom: jonasen: yup, now that we're on the same page, let me reiterate: i think the module system needs to be decoupled :-)

16:29 jonasen: it should be able to look up a namespace in datomic, rather than on the file system

16:29 this way you can go back and run the analyzer on an older version of the code

16:29 without relying on the java classpath

16:33 jonasen: dnolen: bbloom: It's getting really late here. Thanks for an interesting discussion, hopefully we can continue another day.. these are all interesting problems

16:39 lpvb: cljsc takes a very long to compile

16:39 dnolen: lpvb: yeah you shouldn't use it, I recommend lein-cljsbuild

16:40 lpvb: it has auto mode so you don't pay for JVM boot + CLJS self compile every time you change somehting.

16:45 Sgeo_: An explicit compile step for a Lisp seems ... counterintuitive

16:47 dnolen: Sgeo_: I guess you haven't looked at many Lisps - there quite a few compilers that do whole program optimization

16:47 S11001001: Sgeo_: ANSI Smalltalk is a variant of smalltalk with enough late-binding features removed such that building an AOT build infrastructure for it is feasible.

16:48 Sgeo_: But you could still change code around at runtime, I'd assume?

16:49 dnolen: Sgeo_: probably greatly depends on the implementation

16:52 lpvb: dnolen: thanks

16:52 dnolen: lpvb: np

16:53 lpvb: still, I agree we definitely need to improve compile times ;)

17:16 matt444: Hello, I am unable to find a function that lets you replace a substring by position, does not exist?

17:16 clojure.string/replace replaces by a pattern.

17:21 AimHere: matt444, you could probably patch things together with subs

17:22 Sgeo_: Is there a Java method that could do it, perhaps?

17:23 unlink: Why does `lein ring server' on OS X start a new focus-stealing Java application when I run it?

17:23 Said application appears in Command-Tab as `clojure.main'.

17:28 Apage43: unlink: if you ever actually import any swing or awt classes that will probably happen

17:28 regardless of whether they are instantiated

17:32 unlink: That's heinous.

17:32 Is it possible to suppress that?

17:34 S11001001: matt444: All String methods are also available. Just remember that there's even odds you'll screw up an index if you do index-based string manipulation directly, hence the preference for patterns

17:37 Apage43: unlink: I believe it's part of static {} blocks in the class, so if the classloader loads them, that's going to happen.

17:38 S11001001: ~(do (require 'clojure.string) [(clojure.string/replace "z" #"z" "\\\\") (clojure.string/replace "z" #"z" (constantly "\\\\"))])

17:38 clojurebot: clojure euler is http://clojure-euler.wikispaces.com/

17:38 S11001001: ,(do (require 'clojure.string) [(clojure.string/replace "z" #"z" "\\\\") (clojure.string/replace "z" #"z" (constantly "\\\\"))])

17:38 clojurebot: ["\\" "\\"]

17:38 S11001001: yummy

17:39 ,(clojure.string/replace "z" #"z" "\\") ;my favorite feature of replace

17:39 clojurebot: #<StringIndexOutOfBoundsException java.lang.StringIndexOutOfBoundsException: String index out of range: 1>

17:39 S11001001: ,(clojure.string/replace "z" "z" "\\")

17:39 clojurebot: "\\"

17:40 S11001001: ,(clojure.string/replace "z" #"z" (java.util.regex.Pattern/quoteReplacement "\\"))

17:40 clojurebot: #<CompilerException java.lang.IllegalArgumentException: No matching method: quoteReplacement, compiling:(NO_SOURCE_PATH:0)>

17:40 S11001001: ugh

18:09 alex_baranosky: seems to be something tricky about using type hints on java method calls that have vararg signatures

18:10 this is giving me reflection warnings, any suggestions?: https://gist.github.com/4014270

18:17 dnolen: alex_baranosky: into-array doesn't have a return type-hint

18:17 alex_baranosky: I didn't know how to type hint a array of Strings.., so that's the issue, thanks

18:18 dnolen: ,(class (into-array String []))

18:18 clojurebot: [Ljava.lang.String;

18:18 dnolen: ^"[Ljava.lang.String;"

18:18 alex_baranosky: ^

18:18 bbloom: dnolen: isn't there a special case for primitive arrays?

18:18 alex_baranosky: dnolen: thanks: nice and esoteric

18:18 dnolen: alex_baranosky: but really all you care about is ^objects

18:18 alex_baranosky: ^objects should work I think.

18:19 bbloom: isn't there ^strings too ?

18:19 and ^ints, floats, etc

18:19 alex_baranosky: I tried ^strings, that one doesn't work

18:19 dnolen: bbloom: don't think there is one for strings, only primitives, and ^objects

18:19 amalloy: ^objects shouldn't work if he has an array of strings. afaik String[] isn't a subclass of Object[]

18:20 dnolen: amalloy: but isn't varargs always ^objects?

18:22 alex_baranosky: amalloy: correct, ^objects didn't work but ^"[Ljava.lang.String;" did

18:22 ^strings might not be a bad addition to Clojure

18:22 amalloy: dnolen: no

18:23 bbloom: alex_baranosky: make a patch :-) src/clj/clojure/genclass.clj, search for prim->class

18:24 alex_baranosky: bbloom: thanks, I may just do that

18:24 dnolen: amalloy: gotcha

18:25 amalloy: alex_baranosky: from reading the jodatime and jollyday docs, i don't think that ^Interval hint is buying you anything, btw

18:25 oh no, silly me, of course it is

18:26 alex_baranosky: amalloy: yeah getHolidays is overloaded so needs the hint

18:32 Sgeo_: I really don't understand the [Ljava.lang.String thing

18:33 What's going on that that shows up like that?

18:33 amalloy: $google jvm array class name

18:33 lazybot: [How does array class work in Java? - Stack Overflow] http://stackoverflow.com/questions/2910774/how-does-array-class-work-in-java

18:33 Sgeo_: ty

18:34 bbloom: i always forget that strings aren't considered "primitives"

18:35 trying to write some java after clojure (or even just c#) and the number of string == bugs that a linter finds and warns me to use .equals is astronomical :-P

18:58 callen: bbloom: strings are an abstraction.

18:58 Sgeo_: Is there any circumstance where Clojail is used in such a way that malicious code is not supposed to be able to detect that Clojail is in use?

18:59 bbloom: callen: primitives are an optimization ;-)

18:59 Sgeo_: Haskell doesn't have that concept of reference identity

18:59 Much simpler to think about

18:59 callen: bbloom: not really, they're data that doesn't require abstraction or intermediate translation to represent in the hardware.

19:00 bbloom: an array of integers is a pretty straightforward thing to represent at the machine level.

19:00 bbloom: callen: how is that not an optimization?

19:01 callen: bbloom: what you call an optimization, I call an unburdened and simple representation of data that comes naturally to the hardware.

19:02 bbloom: eliding potentially unnecessary operations is a more obvious case of an optimization. Or vectorization.

19:03 bbloom: callen: i'm not interested in arguing semantics -- all i said was that i forget to use .equals on strings b/c im used to languages that have either operator overloading or stronger notions of equivalence

19:04 Sgeo_: "Primitives" in some languages such as Java might be more directly representable, but can be annoying if they don't play nice with the general abstraction that the language uses.

19:05 An int is not a java.lang.Object, which seems bizarre to me

19:05 dnolen: Sgeo_: I thought Haskell also has escape hatches to get to low level mutable reps

19:05 representations

19:05 Sgeo_: dnolen, yes, but at least those are escape hatches, not things you tend to need to interact with on a regular basis.

19:05 *directly interact with

19:06 Although, I think things like Int# are not Haskell itself but GHC stuff, not sure

19:07 dnolen: Sgeo_: so the store is more or less the same. Reality sets in.

19:07 story

19:08 40 years of FP research and sometime you still need to get to a primitive mutable thing.

19:08 50 years sorry.

19:08 callen: I think it's impossible to ever overcome that need for some subset of things.

19:09 as long as practical limitations reign.

19:09 Sgeo_: dnolen, to implement a language on an imperative machine?

19:10 dnolen: Sgeo_: I didn't say anything about implementing a language on imperative machine.

19:10 Sgeo_: The bigger problem is I/O which seems to be naturally imperative. In Haskell it's fairly simple to interact with the outside world in an imperative-style way, but it would be nice with more functional-style approach

19:10 callen: I/O isn't that big of a problem.

19:11 I'm not trying to be contradictory, I'm serious.

19:12 the sometimes-necessity of mutable state/imperativeness doesn't need I/O to be a problem.

19:21 Sgeo_: in particular, monads and arrows have provided a lot of insight into how to encapsulate I/O. FRP is an alternative to typically callback-driven interactive global state.

19:22 The deeper issue is that any declarative programming style is never going to escape directly to a set of instructions that are more optimal/faster than what a human operating with a lower level set of primitives could accomplish. There are fundamental limitations preventing that from happening.

19:25 shachaf: Not if the lower-level primitives are complicated enough that no human could hope to reason about them. :-)

19:25 Sgeo_: But at what point is that gap small enough that working non-declaratively is about as much use as working in assembly?

19:25 callen: shachaf: thus, C.

19:25 shachaf: callen: "thus, CPUs"

19:25 callen: why do people think everything is a totality?

19:25 shachaf: Because they hate the halting problem?

19:25 KirinDave: Ha

19:25 callen: Why not work at a higher-level with the understanding that you might run into a brick wall that requires stepping down the ladder of abstraction?

19:26 Python/Ruby people are perfectly comfortable accepting that sometimes they need to use the C FFI.

19:26 shachaf: Who said not to?

19:26 KirinDave: callen: Actually, they're comfortable wedging everything they can into C.

19:26 Sgeo_: When are those sometimes?

19:26 callen: because a lot of people seem to act as if everything can be done in their language of choice.

19:26 KirinDave: callen: because their interpreters are pretty bad.

19:26 callen: KirinDave: keenly aware of that.

19:26 Sgeo_: Interacting directly with hardware, drivers etc., but when else?

19:27 Need for speed at cost of programmer sanity?

19:27 KirinDave: Also: "abstraction" means something entirely different int he OO, imperative world.

19:27 callen: KirinDave: actually, you're a good person to ask. Does Haskell ever stop feeling like I'm solving unnecessary puzzles?

19:27 KirinDave: In the functional world it usually means something very broad and optimizable. In the OO world it's about stacking ontologies ever higher into specific cases.

19:27 callen: because I'm getting pretty tired of taking 2 hours to do something that takes 5 minutes in Python or Clojure.

19:27 KirinDave: drop the strawman, nobody's interested in bashing OO here.

19:27 KirinDave: callen: Trying to build a Scala project? ;)

19:28 callen: Is neither a straw man nor did I bring up that world. You did with Ruby+Python.

19:28 Sgeo_: callen, are you counting debugging time in those 5 minutes?

19:28 KirinDave: Even comparing them is to have an impedance mismatch.

19:28 callen: Sgeo_: debugging my python code is a pleasure and not often necessary outside of the experimental REPL phase.

19:29 I'm not super interesting in comparisons or dick-waving.

19:29 Sgeo_: I should try to learn and understand clojure-test-mode at some point

19:29 callen: It's a serious question

19:29 does Haskell ever stop feeling like a chore?

19:29 KirinDave: callen: I'm not sure what you are interested in.

19:29 callen: Yes.

19:29 callen: because I've talked to other people who've invested between 2-5 years into it

19:29 bbloom: callen: most of your comments in the last few minutes certainly seem like dick waving

19:29 callen: and it never started being more productive than Brand X

19:30 so I'd like to know if I should cut my losses or not.

19:30 KirinDave: callen: If not constantly learning is a problem for you, you might want to cut your losses on the entire profession of programming.

19:30 Because no toolchain eliminates that requirement.

19:30 callen: I should've expected as much.

19:30 It's not about the learning, it's about the productivity.

19:30 wkelly: callen: how much time have you put in?

19:30 KirinDave: It's a fundamental feature of the medium at this stage of its lifecycle.

19:31 callen: I love learning, that's why I'm learning Haskell. It's benefited my Python code a *LOT*

19:31 more than Lisp or Clojure ever did

19:31 however, I'm having trouble seeing that I'll ever become *more* productive in Haskell *than* Python or Clojure.

19:31 and I'm not the only one with this concern.

19:31 KirinDave: For some things you won't.

19:31 For some things you will.

19:31 callen: wkelly: a very casual 1-1.5 years

19:31 KirinDave: Not every tool is uniformly better.

19:31 Iceland_jack: callen: productivity is a broad term

19:31 callen: wkelly: not serious time though. Lots of fiddling.

19:31 KirinDave: Why is this conversation in #clojure and not #haskell?

19:31 dnolen: KirinDave: +1

19:31 callen: KirinDave: because #haskell people are hateful as fuck.

19:32 KirinDave: and you were already insulting a moment ago

19:32 KirinDave: callen: You have a bad attitude and they smell that

19:32 callen: KirinDave: I don't need a whole channel of that.

19:32 KirinDave: callen: I was?

19:32 * callen sighs

19:32 KirinDave: callen: Where?

19:32 callen: KirinDave: you suggested I should quit programming

19:32 KirinDave: Oh

19:32 callen: for reasons I never stated I had.

19:32 * dnolen thought we having a technical discussion

19:32 KirinDave: No, I made a generalizatoin.

19:32 It's not specific to haskell or you.

19:32 callen: don't make excuses.

19:33 own up to it, and try to stay on topic.

19:33 KirinDave: callen: Well you've scared me off. Good luck.

19:33 callen: is the answer: "Haskell is great for some things, awkward for others"?

19:33 bbloom: dnolen: no, callen is trolling

19:33 callen: Because I'll accept that as an answer.

19:33 is it really that unreasonable to ask a well known Haskeller if it ever stops feeling awkward to write code in?

19:34 I came through the other side, so to speak, in terms of comfort level a lot quicker in Common Lisp, Python, Clojure, etc.

19:34 Iceland_jack: For some people it probably never feels awkward, that's a subjective call

19:34 bbloom: callen: no, your tone, intentional or not, is extremely adversarial

19:34 callen: it just seems like a lot more people struggle and struggle harder with Haskell. I'm just trying to get some anecdote on the matter.

19:34 bbloom: callen: if you don't intend to troll, know that you are doing so

19:35 callen: and choose your words more carefully

19:35 callen: it would've satisfied me to know that some people feel maximally comfortable in Haskell above all others.

19:35 bbloom: cut the meta conversation. If you have alternatives to me, suggest them via private chat rather than passing on dictates in public chat.

19:36 KirinDave: Batten down the hatches

19:36 bbloom: callen: that would be a perfect example right there...

19:36 KirinDave: Deploy the /ignore! Trollicane a'comin!

19:36 callen: you keep complaining about my trolling, when I'm trying to get answers to the original question

19:36 is there a "safe space" for asking comparative questions about programming languages?

19:36 I wanted to ask in #yfl, but there are some serious haskell haters there

19:36 dubz: lol

19:36 callen: and I wanted to talk to haskell users.

19:37 KirinDave: callen: We've already answered your question. Twice actually.

19:37 callen: You're just really busy being defensive.

19:37 callen: KirinDave: was your answer, "productivity is a broad term"?

19:37 Sgeo_: Considering my constant language switching, I would like a channel where I could talk about various languages

19:37 KirinDave: callen: I am not going to read your history for you.

19:37 Sgeo_: And how interesting a Clojure-Tcl bridge could be.

19:37 callen: Sgeo_: #yfl is one. They're pretty prolog/erlang centric AFAICT. They've used many though.

19:37 dnolen: Sgeo_: :P

19:37 KirinDave: Sgeo_: here is a good place, I suppose. Very few clojure hackers are exclusive.

19:38 callen: Sgeo_: just don't mention haskell there and you'll probably be okay.

19:38 KirinDave: Erlang is another great example of a language with specific talents.

19:38 callen: KirinDave: what are the specific talents of Haskell?

19:38 KirinDave: callen: Correctness, performance, succinct code.

19:39 Iceland_jack: This is just a flamewar waiting to happen.. come on, know better than to ask subjective questions like this on a crowded channel

19:39 KirinDave: callen: Haskell's price is that it's from an entirely different universe of coding that only a few other languages bear relation to.

19:39 callen: KirinDave: that seems reasonable.

19:39 KirinDave: I think one problem is that my priorities are a bit different. I care more about shipping the 80/20 ASAP than I do correctness.

19:39 KirinDave: For contrast, Erlang is incredibly good at making distributed systems. God help you doing string processing in it though. The resulting code is at best "not natural" and at worst an exercise in patience.

19:39 jcromartie: so this post on /r/clojure makes me think: could mapcat be improved?

19:39 http://clojurian.blogspot.ca/2012/11/beware-of-mapcat.html

19:39 KirinDave: callen: For some products that is the right call.

19:39 callen: KirinDave: that combined with my untrained-ness in the heavily recursive and type-driven style leaves me a bit...lost.

19:40 and rather slow at making progress.

19:40 KirinDave: callen: Very few people have training in type-inferenced languages.

19:40 callen: It's not really the type *inference* that's the hold-up.

19:40 bbloom: KirinDave: stop feeding the troll :-P if you want to discuss this with him go to a private channel. jcromartie actually has an interesting discussion :-)

19:40 callen: it's learning to satisfy the type system and make it happy that takes time for me.

19:40 Iceland_jack: Wait until he tries languages with undecidable type systems..

19:40 KirinDave: callen: There is no difference.

19:41 bbloom: jcromartie: yeah, i saw that too. seems like mapcat could be considered bugged

19:41 callen: KirinDave: I find the incredibly powerful type system incredibly appealing though. Some of my little hacking phases with Haskell have been incredibly enlightening as a result.

19:41 KirinDave: bbloom: That's actually salient to the blog post I am writing.

19:41 callen: s/incredibly//g

19:41 KirinDave: bbloom: It's no surprise lazy-seq comes into play.

19:42 bbloom: KirinDave: cool. I'd like to see space guarantees make their way into the clojure.core doc strings

19:42 KirinDave: Tough to do correctly.

19:42 callen: KirinDave: what's the blog post about? Also, I liked your fizz-buzz post that transitions into macros a lot.

19:43 KirinDave: callen: monoids, you mean?

19:43 callen: sorry, sure.

19:43 I'm still fuzzy on the category theory. Quite so.

19:43 I don't really understand the monad laws or how the different categories relate to the code.

19:43 KirinDave: 'sokay. So is SPJ.

19:44 callen: huh?

19:44 how could he be?

19:44 KirinDave: You should ask those questions elsewhere. They're way offtopic.

19:44 brehaut: KirinDave: lol

19:44 callen: monads are off-topic in Clojure?

19:44 KirinDave: callen: Yes.

19:44 callen: they have monadic libraries in Clojure.

19:44 KirinDave: Yes.

19:44 brehaut: and they arent especially idiomatic

19:44 KirinDave: For anyone.

19:44 They're sort of a "look what i can do!"

19:44 callen: er...then why does Haskell use them?

19:44 brehaut: KirinDave: not entirely true; they are useful as macro plumbing

19:45 KirinDave: brehaut: Eehhhhhhhh.

19:45 callen: Because Haskell has strong static typing with a very powerful inference engine and also probably one of the worlds 3 most sophisticated compilers for functional programming (and also a host of hard-won rewriting rules for making that work)

19:46 callen: I've yet to see a good implementation of monadic code in dynamically typed languages.

19:46 callen: what about Haskell necessitates them, as opposed to Clojure, though? The purity?

19:46 KirinDave: You usually have to explicitly annotate which monad you want, and that sort of spoils the exercise.

19:46 The non-strictness.

19:46 callen: oh that explains a lot actually. Cf. OCaml.

19:47 KirinDave: want to take it to #haskell-overflow?

19:48 KirinDave: Nope. I want to go fold laundry and rest my brain after writing a 3k word blog post in one sitting.

19:48 callen: I figured as much. Well I learned something anyway.

19:48 KirinDave: Good luck.

19:48 callen: I'd forgotten how incredibly unpleasant IRC can be for the simplest conversations. This was a good reminder.

19:48 AdmiralBumbleBee: I was enjoying reading the discussion :(

19:49 callen: AdmiralBumbleBee: I'd be happy to talk to you somewhere people won't complain.

19:49 brehaut: hi AdmiralBumbleBee

19:49 shachaf: You don't need to understand category theory to understand the monad laws.

19:49 bbloom: callen: is english your first language?

19:49 KirinDave: The monad laws are sort of obvious, once you realize the intent.

19:49 callen: shachaf: doesn't really matter. All of it gets rubber-stamped with *MATH!*

19:49 AdmiralBumbleBee: callen: I'm usually the guy who whines about offtopic… and that discussion seemed totally on topic to me

19:50 callen: AdmiralBumbleBee: are you familiar with Haskell at all?

19:50 AdmiralBumbleBee: callen: yes

19:50 I started learning it relatively recently, but I've been very busy

19:50 shachaf: Uh oh, looks like I missed a long discussion in here.

19:50 AdmiralBumbleBee: hi brehaut :)

19:51 callen: AdmiralBumbleBee: story of my life. I've been tinkering with it off and on for over a year.

19:51 AdmiralBumbleBee: callen: oddly enough, I keep running into road blocks with haskell… and what gets me by is understanding the concept applied in clojure

19:51 so any discussion of haskell in a remotely clojure context is super cool for me

19:52 I still have issues understanding monads honestly

19:52 everytime I think I get it, someone tells me that I don't

19:53 then someone tells that person that they're wrong too

19:53 and I go back to square one

19:53 shachaf: AdmiralBumbleBee: You don't need to worry about "underading monads" that much.

19:53 "monad" is a pretty generic API for a lot of concrete types.

19:53 AdmiralBumbleBee: understanding :P

19:54 it's what I want

19:54 shachaf: Er, yes. That word.

19:54 Understanding the concrete types is useful.

19:54 Once you understand all the "prerequisites", "understanding monads" will come pretty naturally.

19:54 Before that, it's just trying to understand an abstraction for its own sake.

19:54 AdmiralBumbleBee: I always want to know implementation details

19:54 I can't stand just knowing how to use things

19:54 shachaf: OK. Monads aren't implementation details. :-)

19:55 AdmiralBumbleBee: I want to know how they work, what they do, what they should do etc..

19:55 shachaf: Monad is entirely "how to use things"

19:55 AdmiralBumbleBee: hmm

19:55 callen: AdmiralBumbleBee: I do the same thing sometimes (translate between Haskell and Clojure) but I find it doesn't help for the truly haskell-specific parts.

19:55 shachaf: Well, OK, I'm exaggerating.

19:55 callen: I don't think it helps with the stuff specific to recursion either.

19:55 AdmiralBumbleBee: this is where I'm conflicting with what I've read and been explained before shachaf :(

19:56 shachaf: AdmiralBumbleBee: Did you see the FAQ?

19:56 http://www.haskell.org/haskellwiki/FAQ

19:56 http://www.haskell.org/haskellwiki/FAQ#The_M-word in particular.

19:56 AdmiralBumbleBee: yes shachaf

19:56 shachaf: This uses a lot of features: first-class functions: the second argument to (>>=) is a function; type constructors (here m); type class polymorphism; type class polymorphism over type constructors (which few other languages have); parametric (not type class) polymorphism, over a and b. Each of these features is more fundamental than the specific idea of monads. If you understand each feature, then Monad is a small example of how they fit together

19:56 AdmiralBumbleBee: I really think the core issue is that I don't understand type classes, at all

19:57 it seems very strange to me

19:57 callen: oddly, I found the typeclasses part easier to understand. Perhaps because that's largely how I use Python's inheritance.

19:57 amalloy: type classes are not far off from clojure protocols or java interfaces

19:57 shachaf: OK, so that's an important thing to understand before you can understand a specific type class.

19:57 callen: I get stuck on modeling code in terms of recursion more often.

19:57 shachaf: amalloy: They are in how they're used!

19:58 AdmiralBumbleBee: callen: clojure is the first 'high level' language I've used, let alone functional

19:58 I really don't have anything to fall back on for understanding such things

19:59 amalloy: shachaf: really? i'm conversant in the basics of monad use, and the only difference that's obvious to me is that haskell functions/typeclasses can dispatch on return type

19:59 callen: AdmiralBumbleBee: ah, I'm kinda the opposite. I spent most of my years in clisp or Python.

19:59 AdmiralBumbleBee: my only low-level is C.

19:59 amalloy: i would love to hear what else is different

19:59 AdmiralBumbleBee: callen: I've tried python a bit… never used CL

20:00 * callen sighs wistfully

20:00 callen: AdmiralBumbleBee: CL was great if you wanted to write code like a cabin-dwelling unabomber.

20:00 AdmiralBumbleBee: honestly, I've not spent any time in an OO language other than understanding enough objc so I can just write straight C for everything :)

20:00 brehaut: amalloy: *handwaving* there kinds and ranks stuff makes typeclasses slightly more complicated

20:01 KirinDave: amalloy: " the only difference that's obvious to me is that haskell functions/typeclasses can dispatch on return type" there are more things, but this is a pretty important thing.

20:01 shachaf: It's less "return type" and more "type".

20:02 "return-type polymorphism" isn't special.

20:02 You have minBound :: Bounded a => a, which isn't a function at all.

20:02 KirinDave: shachaf: Tell this to scala? ;)

20:02 callen: my primary experience of Scala was seeing sbt run out of memory and crash, and being so disgusted that I couldn't even be bothered to continue.

20:03 shachaf: Anyway, many places where you might use interfaces and types in Java, the thing you'd use in Haskell is just types and regular old values.

20:03 callen: shachaf: regular old values? you mean in the context of pattern-matching or something else?

20:04 shachaf: Talking about this in the abstract probably isn't much use. :-)

20:04 KirinDave: shachaf: That is why i am trying to write a series of more concrete posts

20:04 shachaf: Type classes and Java interfaces have different enough uses that thinking of them as "the same thing" is misleading.

20:04 callen: I'm just trying to understand where and what regular old values suffice in Haskell for something else in Java.

20:04 shachaf: They also work differently.

20:05 dnolen: shachaf: I don't think that typeclasses are that different from protocols. The ad-hoc polymorphism of typeclasses was introduced to surmount the special case of equality in SML as far as I understand it.

20:05 AdmiralBumbleBee: so, what is the purpose of a type class?

20:05 is there a simple explanation of that?

20:05 shachaf: callen: Hmm. Well, for example, a list might be sufficient for something which would be Iterable in Java? I don't actually know java, mind you. :-)

20:05 dnolen: Type classes aren't really for ad-hoc polymorphism, the name of that paper notwithstanding.

20:05 KirinDave: AdmiralBumbleBee: Well one purpose is to provide a solution to the so-called "expression" problem.

20:05 callen: shachaf: that gives something to chew on at the least.

20:06 shachaf: KirinDave: Huh? Type classes have nothing to do with the expression problem!

20:06 dnolen: shachaf: that's is not my understanding from the literature.

20:06 callen: ogod.jpg

20:06 KirinDave: shachaf: Untrue. :)

20:06 shachaf: callen: See also section 5.4 in the Haskell FAQ I linked to before.

20:06 AdmiralBumbleBee: KirinDave: if that's true… then I get it

20:06 that's what I thought in fact

20:06 but I've been told thats' wrong a few times :(

20:06 callen: shachaf: eggscellent. Thank you!

20:06 KirinDave: It's just one thing.

20:06 Like a specific thing.

20:07 I mean, at the end of the day they don't serve a purpose totally dissimilar from protocols for the workaday programmer.

20:07 callen: shachaf: the veering away from excessive typeclassing/existential-ness makes a lot of sense to me.

20:07 KirinDave: "I know how to fmap this"

20:07 "I know how to show this"

20:07 "Tell me how to treat this as a Num"

20:08 dnolen: shachaf: I'm looking at the Wadler paper right now and your interpretation of type classes make no sense to me.

20:08 shachaf: equality in SML was a special case - the only function that worked differently for different types - SML only had parametric polymorphism outside of that.

20:09 shachaf: Right.

20:09 KirinDave: Personally I feel like Haskell is just hitting its stride as a workaday programmer's language.

20:09 A lot of really key libraries have fallen into place. The build system is getting to where it needs to be.

20:09 There is actually a LOT of free code for Haskell out there.

20:09 shachaf: But would you really call (==) "ad-hoc"?

20:09 OK, that's just an argument over words. Let's don't have that.

20:10 dnolen: shachaf: yes because it is open world, implicitly defined when you create a new datatype.

20:10 KirinDave: Oh, and I'm trying to hire infrastructure devs with haskell experience. By the by.

20:10 For a pretty different project.

20:10 shachaf: Are you actually using Haskell?

20:10 callen: KirinDave: Haskell seems to be really popular in infrastructure/SRE/devops work. Is there a particular reason for that?

20:10 KirinDave: callen: I would not say it is yet.

20:10 shachaf: yes.

20:10 shachaf: Two components have very high correctness requirements.

20:11 callen: KirinDave: really popular relative to its overall popularity as a ratio of how much people use most languages for such things.

20:11 KirinDave: Haskell's primary use at google in infrastructure. Berkeley too IIRC

20:11 KirinDave: shachaf: I am writing a free-monad based interpreter of a financial algorithm simulator for work. I imported Kan-extensions _like a boss._ ;)

20:12 shachaf: You may have seen me bugging #haskell for help getting that sorted in my head.

20:12 Cuz i've never done it via Free before.

20:12 Oh also Clojure.

20:12 So like.

20:12 Hit me up, peeps who want work.

20:13 callen: definitely not my bag, I'm supposed to quit programming soon so I can be a janitor.

20:14 KirinDave: Or just, you know, cowboy up. :)

20:14 callen: KirinDave: psh, if only you'd seen the reader macros I'd written in CL. Your free monads would wilt.

20:14 KirinDave: Perhaps so.

20:14 callen: gensym ALL THE THINGS

20:15 KirinDave: Nothing scares me after finishing LoL.

20:15 Cannot be frightened.

20:15 Actually check that.

20:15 One time I had a bug in a haskell program due to whitespace.

20:15 callen: I still think BoS type error -> delete file bug for GHC was pretty choice.

20:15 KirinDave: I'm surprised you've done LoL.

20:16 shachaf: It's an unfortunate flaw in GHC that it only typechecks non-whitespace characters. :-(

20:16 KirinDave: callen: I've done a lot of regrettable things in my life.

20:16 callen: KirinDave: IIRC, LoL spends a decent amount of time making fun of purity-fascists.

20:16 KirinDave: callen: I do too.

20:16 Purity is a tool. Just like non-strictness.

20:16 AdmiralBumbleBee: lol?

20:16 callen: AdmiralBumbleBee: Land of Lisp.

20:16 AdmiralBumbleBee: ah

20:17 callen: AdmiralBumbleBee: a silly world for silly people. You should visit sometime.

20:17 KirinDave: AdmiralBumbleBee: http://www.amazon.com/Let-Over-Lambda-Doug-Hoyte/dp/1435712757/ref=sr_1_1?ie=UTF8&qid=1352078173&sr=8-1&keywords=let+over+lambda

20:17 AdmiralBumbleBee: yeah… I"ve thought about it

20:17 KirinDave: No no

20:17 Let over Lambda.

20:17 AdmiralBumbleBee: wait

20:17 KirinDave: Land of List is baby talk.

20:17 AdmiralBumbleBee: which is which

20:17 KirinDave: err, Lisp.

20:17 Let over Lambda is abbreviated "LoL" for a reason.

20:18 callen: KirinDave: what about AMOP?

20:18 shachaf: «eLet Over Lambda (ISBN 978-1-4357-1275-1, 376+iv pp.) is one of the most hardcore computer programming books out there. Starting with the fundamentals, it describes the most advanced features of the most advanced language: COMMON LISP.»

20:18 KirinDave: callen: What about it?

20:18 shachaf: Poe's law applies to Lisp people, I think.

20:18 KirinDave: shachaf: Uh, in this case I concur. It's a fairly insane book.

20:18 shachaf: "hardcore" meaning "I love lisp. Oh god I love lisp so much. Take me, lisp!"

20:19 But once you've seen (defmacro … (let (x …) (lambda (y) …))) a few times you begin to go mad and it all becomes easier.

20:26 jcromartie: I think the LoL guy is a bit full of himself.

20:27 but maybe it's only because I don't understand his genius :)

20:27 AdmiralBumbleBee: he must be _really_ good with lisp then

20:28 callen: AdmiralBumbleBee: http://letoverlambda.com/index.cl/toc just take a look for yourself.

20:29 AdmiralBumbleBee: callen: Im already there :)

20:29 this seems like a decent book to me

20:30 AimHere: Well that book has some neat ideas

20:30 The 'Common Lisp Uber Alles' tone of the book is a bit obnoxious

20:31 * callen chokes laughing

20:31 bbloom: dnolen: i see a yourkit notice on the core.logic project. what's the deal with open source licenses for that? can i get one if i want to profile some clojure stuff?

20:32 dnolen: bbloom: yeah just ask, you just need to send them a link to your project, give 'em a couple of days is all.

20:32 amalloy: bbloom: their licensing page has a pretty clear statement

20:32 AdmiralBumbleBee: I like opionated books

20:32 bbloom: dnolen: amalloy: thanks

20:33 dnolen: speaking of Common Lisp, I looked at a bit ACL2 today - pretty cool stuff.

20:38 bbloom: dnolen: have you found it to be generally useful? my experience with jvisualvm is pretty lackluster

20:38 dnolen: bbloom: jvisualvm sucks IMO.

20:38 bbloom: "oh? lots of object[] were allocated? thanks...."

20:38 dnolen: bbloom: YourKit is much better and much much faster.

20:39 xeqi: dnolen: acl2 is pretty neat

20:39 bbloom: dnolen: sadly, their email system isn't all that fast.... trail key hasn't come :-P

20:39 dnolen: bbloom: yes it takes a couple days

20:39 bbloom: dnolen: it say "less than 5 minutes" after i filled out the trail form lol

20:39 trial*

20:40 dnolen: xeqi: yeah was playing around w/ it in Racket today, it has graphical support for it via Dracula.

20:40 well more like interface support I mean

20:40 bbloom: hah yeah, no, it took a couple of days for me.

20:41 bbloom: dnolen: probably old copy from when the CTO was nervously refreshing his inbox all day :-)

20:42 jcromartie: so, java.awt.Rectangle is a useful class… why didn't I just use this all along

20:44 should just make a protocol around it

20:58 bbloom: dnolen: heh so the license just came

20:58 dnolen: bbloom: cool

20:58 bbloom: dnolen: first glance at the cljs compiler... i'm surprised to see that emit and analyze are both almost exactly equal in terms of time...

20:59 dnolen: bbloom: makes sense to me, surprised by which part?

20:59 bbloom: dnolen: i'd have expected analyze to be a tad slower, since it's doing lots more allocations

20:59 i expected printing strings to be faster :-P

20:59 dnolen: bbloom: analyzer is fast, I keep saying that. No one believes me ;)

21:00 bbloom: dnolen: i believe you

21:00 i just want to get my iteration times on the test suite from 30 seconds to 3 seconds

21:00 step 1 might be to buy that new 13 macbook pro ... mmmm

21:00 dnolen: bbloom: heh, 24-25 seconds for me on 2.66 ghz, good luck w/ that.

21:01 bbloom: one big problem is Fogus's time literal test, adds 10 seconds.

21:01 bbloom: it be nice if we could have that test be optional.

21:01 bbloom: well 10 seconds on the slower JS engines.

21:01 bbloom: i'm consistently impressed by rhino's slowness

21:02 i might just be forced to do a node repl impl :-)

21:02 dnolen: bbloom: it's epic, I dream about Nashorn

21:02 bbloom: dnolen: just googled that... heh "available for java 8 in late 2013"

21:03 oh and 30 seconds was for the repljs start

21:03 my test times are more like 2 minutes

21:04 * callen gawks from afar at the ghetto

21:04 dnolen: bbloom: yeah it used be 30 seconds for me for all 3 engines.

21:05 bbloom: but that was like a 8 months ago when CLJS was considerably simpler.

21:05 bbloom: hrm, actually maybe 30 seconds for V8

21:05 bbloom: dnolen: I think we could recapture some of that simplicity :-)

21:06 dnolen: much of the complexity comes from too much stuff happening in a single pass

21:07 dnolen: llvm has dozens....

21:08 http://llvm.org/docs/Passes.html

21:10 wingy: i am following the nr 1 rule of using macros .. don't

21:14 dnolen: bbloom: I meant simpler as in the core.cljs

21:14 bbloom: core.cljs is more than 2X larger

21:15 bbloom: but sure

21:15 bbloom: dnolen: is core.cljs really all that complicated? i mean, there's lots of stuff, but it's all pretty straightforward, right? are you referring to the various optimizations?

21:17 dnolen: bbloom: it's all relative :)

21:39 tmciver: exit

21:46 bbloom: what's the quickiest/easiest way to call a private java constructor ? (yes, i know bad idea, etc etc, i just want to test something in the repl real quick)

21:47 brainproxy: wingy: macros are a good tool, you just have to learn when to use them and when to favor solutions that in the long run are / will be simpler to understand and maintain

21:48 wingy: one thing they can do for you that functions can't is give you a way to work around eager argument evaluation

21:49 you may not need that often, but when you do, you pretty much have to use a macro

21:59 amalloy: bbloom: reflection

22:00 bbloom: amalloy: yeah, i'm muddling around with getConstructor, etc... is there a popular clj lib to make this trivial?

22:00 amalloy: *shrug*

22:01 clojure.lang.Reflector has a lot of relevant stuff

22:11 bbloom: amalloy: grep setAccessible yields no results, so probably not useful :-)

22:11 amalloy: thanks tho

22:15 wingy: brainproxy: yeah

22:24 mudge: does anyone know what clojure book covers building clojure projects the most or best?

22:28 xeqi: building as in build systems, or building as in growing a code base?

22:29 mudge: xeqi: about using clojure build systems like lancet or leiningen

22:29 I think I want to learn more about how to use ant in clojure

22:49 scottj: mudge: the first edition halloway book covers lancet, not sure about second. in general I think clojurebook.com is the best overall book currently.

22:49 mudge: thansk scottj

22:50 i'm checking out if the second halloway book covers lancet

22:50 scottj: mudge: but I don't think clojurebook.com talks about ant or lancet, I imagine it focuses on lein

22:52 mudge: thanks scottj: I wonder what book covers lein the best

22:55 i wish there was a book just on leiningen

23:01 xeqi: all the cool stuff in lein2 was created within the past year, so I doubt any book covers it much

23:01 mudge: is there something in particular you're trying to do?

23:11 mudge: xeqi: well i have an unusual build process I need to implement where I need to build several projects together and package them together. Actually I'm thinking that maybe what I should do is make each project a seperate lein project

23:11 and make a project for the build that packages together the jars of the other projects

23:12 callen: mudge: I'm going to venture a guess and say..."yes"

23:12 technomancy: ^^ ?

23:12 mudge: xeqi: is there a way to call lein tasks from within a clojure program?

23:13 So that in my build project I'd like to call lein jar on my other projects and then get those jars and package them together and deploy

23:13 callen: mudge: that seems reasonable to me.

23:13 lynaghk: I'm giving a talk on Clojure + data visualization next week and just put together this handout: http://keminglabs.com/oredev_handout.pdf I'd love feedback.

23:13 mudge: thanks callen

23:13 lynaghk: It's way more data visualization than Clojure, at the moment.

23:14 xeqi: mudge: you don't want the sub projects in a repo?

23:15 usually I'd see each seperate project get built, and then a top level one that includes them

23:15 like ring

23:15 mudge: xeqi: i'm new to building with leiningen, I don't see the advantage of putting things in repos other than being able to access them remotely if I had a computer somewhere else or was going to share something

23:15 lpvb: is there a way to get lein repl to watch for changes in files and reload namespaces?

23:16 lynaghk: lpvb: not natively as far as I'm aware, but you might want to check out: https://github.com/clojure/tools.namespace

23:18 mudge: xeqi: all my build project does it take the jars of the other project, add a configuration file, and zip them together and them deploy the zipped file. Does ring do something like this?

23:19 jars of the other projects*

23:23 xeqi: similar, but different as it's a library; including ring/ring, brings in ring/ring-devel, ring/ring-core, etc

23:43 mudge: xeqi: thanks

23:43 I noticed that the lein jar task includes the clojure source code files. What if I just want the class files?

23:47 I found out on my own: putting this in the project.clr: :omit-source true

23:50 just curious: what's everyone's favorite editor for Clojure programming?

23:58 ivan: mudge: Emacs. Though I often read code in IDEA.

23:59 mudge: ivan: cool, i use Emacs for clojure too

Logging service provided by n01se.net