2011-10-08
| 00:27 | no_mind | I am getting this error on using compile "java.lang.ClassNotFoundException: clojure.contrib.json.Read_JSON_From" . Does compile has a dependancy on json ? |
| 00:57 | amalloy | no_mind: the code you're trying to compile does |
| 01:00 | no_mind | amalloy: but the code I am compiling desnt use json |
| 01:02 | amalloy | i think that you are wrong |
| 01:04 | no_mind | amalloy: my code is not using json, maybe some other lib is. But at the same time I have clojure.contrib.json installed |
| 01:04 | no_mind | I am using congomongo, maybe that is using json.;.. |
| 01:09 | no_mind | amalloy: a grep on the source code directory shpws this "Binary file ./classes/clojure/contrib/json/Read_JSON_From.class matches". So Why the error ? |
| 01:09 | amalloy | *shrug* |
| 01:10 | no_mind | clojure community is turning un helpful day by day... |
| 01:10 | amalloy | perhaps you tried to add some new libraries to the classpath without restarting the jvm |
| 01:11 | no_mind | I fired a fresh repl to compile |
| 01:11 | amalloy | no_mind: this is a volunteer helpforce. nobody pays me to know what causes compile errors on your machine, and i simply don't know given the information "compile fails due to json" |
| 01:13 | no_mind | no one pays anyone all over IRC to help anyone... |
| 01:14 | amalloy | yes, indeed. so when nobody jumps out of the bushes with a solution to your problem, complaining that the community is becoming unhelpful is sickening |
| 01:14 | no_mind | what I trying to do is already open sourced and available on github.. No one is paying me to do this... |
| 01:14 | no_mind | I am asking this for couple of days now... |
| 01:15 | amalloy | unlucky. perhaps nobody knows the answer, or you're not giving any information |
| 01:15 | amalloy | s/any/enough |
| 01:15 | lazybot | <amalloy> unlucky. perhaps nobody knows the answer, or you're not giving enough information |
| 01:21 | no_mind | I am using IRC for over a decade now, so I know how to supply enough information for sure |
| 01:24 | rimmjob | the channel is just slow at this time |
| 01:29 | rimmjob | could you post a link to the source? |
| 01:37 | zodiak | no_mind, do a grep -l for contrib.json across the whole project. I assume you have lein dep'd and also have your git clone/source in checkouts so everything related get's searched ;) |
| 06:49 | PleajureSeeker_ | Hey, I'm a noob in Clojure and I'm having troubles with the basics of (gen-class) - can someone help me? |
| 07:09 | eliOcs | hi guys! |
| 07:09 | eliOcs | anyone active around? |
| 07:10 | eliOcs | can someone help me with the swank installation |
| 07:10 | eliOcs | I |
| 07:11 | eliOcs | I've been following the installation instructions: |
| 07:11 | eliOcs | # |
| 07:12 | eliOcs | Install clojure-mode either from Marmalade or from git. |
| 07:12 | eliOcs | lein plugin install swank-clojure 1.3.3 |
| 07:12 | eliOcs | From inside a project, invoke M-x clojure-jack-in |
| 07:14 | khaliG | eliOcs, yup and |
| 07:14 | eliOcs | should I be alble |
| 07:14 | eliOcs | to connect via de SLIME command |
| 07:14 | eliOcs | I dont get de REPL |
| 07:14 | khaliG | no the clojure-jack-in takes care of that |
| 07:14 | khaliG | what happens when you type it? |
| 07:15 | eliOcs | compiles a bunch of files |
| 07:15 | eliOcs | but it doesn't take me to a new buffer |
| 07:15 | eliOcs | or anything |
| 07:16 | khaliG | yea it should split the screen and show a repl on the bottom |
| 07:16 | eliOcs | wow |
| 07:16 | eliOcs | It did it now |
| 07:16 | khaliG | nice :) |
| 07:16 | eliOcs | the first time it only did the compile |
| 07:16 | eliOcs | ok this is odd |
| 07:16 | eliOcs | thansk khaliG |
| 07:16 | khaliG | np |
| 07:16 | eliOcs | feel stupid now |
| 07:16 | eliOcs | hahah |
| 07:25 | eliOcs | when you finally get the emacs with lein to work it seems a great way to develop |
| 07:28 | zilti | eli0cs: Do you have elein installed? |
| 07:32 | eliOcs | yep |
| 07:32 | eliOcs | I've installed lein |
| 07:36 | zilti | No, elein is a script for emacs to use lein with emacs |
| 07:37 | eliOcs | oooh |
| 07:38 | eliOcs | havent installed that yet |
| 07:38 | eliOcs | I'll google it a give it a try |
| 08:20 | eiro | (hello "world") |
| 08:22 | Arafangion | (hello "eiro") |
| 08:52 | daniel___ | whats the equivalent in clojure of x = (1 2 3) ? |
| 08:52 | daniel___ | (define x 1 2 3)? |
| 08:53 | daniel___ | something like that |
| 08:53 | Bronsa | (def x '(1 2 3)) |
| 08:53 | daniel___ | merci |
| 08:54 | daniel___ | and what does the ' mean |
| 08:54 | Bronsa | it's synax macro for quote |
| 08:55 | Bronsa | so that clojure doesnt treat (1 2 3) as a function call |
| 08:55 | daniel___ | i see, but why would it? |
| 08:55 | daniel___ | is 1 a function? |
| 08:55 | Bronsa | indeed it is not |
| 08:56 | Bronsa | but first elements of lists are always treated as if they were a function |
| 08:56 | Bronsa | in all lisps |
| 08:56 | daniel___ | ok |
| 08:56 | Bronsa | if you dont want to syntax quote you either need to construct the list with (list ...) or use a vector |
| 08:57 | Bronsa | daniel___: keep in mind that if you syntax quote, none of the fields of the list will get evalated |
| 08:57 | daniel___ | ok, thats what i want i think |
| 08:58 | Bronsa | then (def x [1 2 3 whatever]) |
| 08:58 | daniel___ | (def ratings '(map rating args)) will give me an 'array' with the ratings of whats in my list |
| 08:58 | Bronsa | no |
| 08:58 | Bronsa | it will bind ratings to a list with three symbols |
| 08:58 | Bronsa | map rating and args |
| 08:58 | daniel___ | ah shit, ofc |
| 08:59 | Bronsa | if you want it to be evaluated you need to remove the quote |
| 08:59 | daniel___ | so in this case i want [] |
| 08:59 | Bronsa | no |
| 08:59 | Bronsa | in this case you want (map rating args) |
| 08:59 | daniel___ | ok right sorry |
| 08:59 | daniel___ | [] is a vector |
| 08:59 | Bronsa | so taht x will be bind to the result of applying map to rating and args |
| 08:59 | daniel___ | and it is equivalent to '() in this scenario? |
| 08:59 | Bronsa | *that |
| 08:59 | Bronsa | well no |
| 08:59 | Bronsa | syntax quoting can be done on vectors too |
| 09:00 | Bronsa | and it prevents every element to be evaluated |
| 09:00 | Bronsa | a vector is different from a list (apart from performance details) in wich it doesnt treat the first element of itself as a function call |
| 09:01 | Bronsa | you can see the difference here |
| 09:01 | Bronsa | ,[map identity 1] |
| 09:01 | clojurebot | [#<core$map clojure.core$map@149e15b> #<core$identity clojure.core$identity@1c81de> 1] |
| 09:01 | Bronsa | ,(map identity 1) |
| 09:01 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 09:01 | Bronsa | fuck |
| 09:01 | Bronsa | ,(map identity [1]) |
| 09:01 | clojurebot | (1) |
| 09:01 | daniel___ | ok, thanks Bronsa |
| 09:01 | Bronsa | np |
| 09:01 | daniel___ | wait, is there a repl in this channel? |
| 09:02 | daniel___ | ,(+ 1 2) |
| 09:02 | clojurebot | 3 |
| 09:02 | daniel___ | :D |
| 09:02 | Bronsa | you can query clojurebot too |
| 09:10 | mbac | i watched stuart halloway's presentation on clojure and simplicity and now i'm confused |
| 09:10 | mbac | maybe it's because i'm a clojure newb |
| 09:12 | mbac | here's what i understood. i have a rigorous definition of simple. clojure is simple. ???. clojure rocks! |
| 09:12 | mbac | did i miss anything else? |
| 09:21 | mbac | https://blip.tv/clojure/stuart-halloway-simplicity-ain-t-easy-4842694 <- this presentation |
| 09:26 | cemerick | mbac: What was confusing to you? |
| 09:28 | mbac | the feeling that i missed something |
| 09:29 | cemerick | it's hard to respond to that |
| 09:29 | mbac | right. so, what if he had done s/clojure/lisp/g |
| 09:29 | mbac | it's still mostly the same talk. yes? |
| 09:30 | mbac | with the exception of vector-bindings |
| 09:30 | mbac | those are EVEN SIMPLER than what other lisps do |
| 09:31 | cemerick | Not really. Lisp doesn't address the same issues Clojure does re: concurrency, state, data structures, etc. |
| 09:31 | cemerick | Lisp, broadly speaking, that is. |
| 09:31 | mbac | maybe i'm having a problem because i'm a lisp newb |
| 09:32 | cemerick | Lisp is good, but homoiconicity doesn't solve everything. |
| 09:33 | mbac | what's novel about clojure wrt. lisp? |
| 09:33 | cemerick | mbac: please read: http://clojure.org/rationale |
| 09:34 | mbac | "Defaults to immutability" |
| 09:34 | mbac | ok that's exciting. i thought all lisps did that |
| 09:34 | cemerick | goodness, no |
| 09:35 | mbac | how do people get off calling lisp a family of functional programming languages when immutability isn't default? |
| 09:35 | cemerick | In very rough terms, all you need to be a lisp is homoiconicity and first-class functions. |
| 09:35 | cemerick | "functional" is a very, very nebulous term |
| 09:36 | mbac | to me it means no side-effects |
| 09:36 | cemerick | Some people would argue that only statically-typed ML-style languages are functional. |
| 09:36 | mbac | and mutability menas programming with side-effecs |
| 09:36 | mbac | strong static typing is orthogonal to functional programming |
| 09:36 | cemerick | some would argue that immutability is orthogonal to FP |
| 09:37 | gtrak`` | i thought functional meant functions |
| 09:37 | cemerick | Right, that's about the only common ground. :-) |
| 09:37 | mbac | pure functions |
| 09:37 | fliebel | I thought functional means "does concurrency well" ;) |
| 09:37 | cemerick | mbac: yeah, zero consensus on that. |
| 09:37 | mbac | pure functions and mutability can't co-exist? |
| 09:38 | mbac | what? really? |
| 09:38 | gtrak`` | mbac, of course not |
| 09:38 | gtrak`` | pure functions have no side effects |
| 09:38 | mbac | yes, i agree |
| 09:38 | cemerick | Insofar as most would want to say that scheme is functional, we have to admit that e.g. Javascript is as well on purely technical terms. A lot of it has to do with accepted idioms. |
| 09:38 | mbac | we have consensus :) |
| 09:38 | gtrak`` | the part that coexists isn't a pure function |
| 09:39 | mbac | In computer science, functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. |
| 09:39 | mbac | no consensus? it's the first line in the wikipedia article! |
| 09:40 | cemerick | Wikipedia being the end-all, be-all, of course. :-) |
| 09:40 | mbac | duh |
| 09:41 | mbac | that's why i'm citing it :) |
| 09:41 | cemerick | mbac: If you look at the 'Type Systems' section in that article, it's clear the whole thing is constructed from an ML perspective. |
| 09:43 | fliebel | Are there any NXT owners here? I'm thinking about writing a compiler, so I wonder if there is any "market". |
| 09:44 | mbac | alright. so, if he had done s/clojure/scheme/g it's mostly the same talk, except again vector-bindings |
| 09:45 | cemerick | except scheme isn't immutable by default, has no unified data structure story, no state abstractions, etc. |
| 09:45 | mbac | OK! unified data structure story. i want that |
| 09:59 | Leeni | hey guys, take a look at this: http://shootout.alioth.debian.org/u64q/performance.php?test=fannkuchredux |
| 09:59 | Leeni | why does clojure solution use only 75% of CPU? |
| 10:02 | fliebel | Leeni: No idea. Have you tried running it yourself? |
| 10:06 | cemerick | gfredericks: Not really a big point of comparison; I'd be surprised if such a hit existed. |
| 10:06 | gfredericks | cemerick: I'd think there'd be plenty of shallow interest though, scheme being one of the two major pre-clojure lisps |
| 10:07 | cemerick | Well, there's *lots* of schemes, which makes things more diffuse. |
| 10:07 | gfredericks | i.e., I think lots of people would google it, whether or not it'd make an existing article. I suppose googlers don't will articles into existence though. |
| 10:07 | gfredericks | oh I did not know that. |
| 10:07 | cemerick | yeah, there's dozens of 'em |
| 10:07 | cemerick | scheme is an idea |
| 10:07 | gfredericks | I guess now there are lots of clojures too huh :/ |
| 10:07 | gfredericks | lots == 3 |
| 10:08 | cemerick | sorta |
| 10:08 | gfredericks | sorta |
| 10:08 | cemerick | They all have the same objectives, as reasonable given their host platforms. |
| 10:08 | gfredericks | right |
| 10:08 | cemerick | Which is not true for the various schemes. |
| 10:09 | gfredericks | s/existing/interesting |
| 10:09 | gfredericks | the phrase "high-level typo" just popped into my head |
| 10:13 | Leeni | fliebel: also what's the deal with slowness. It uses java arrays and runs on clojure 1.3 yet 4 times slower than java |
| 10:14 | gfredericks | Leeni: they're not accidentially including the clojure load time in the measurements are they? |
| 10:15 | Leeni | I don't think so, otherwise java would not get so close to C in terms of time |
| 10:15 | gfredericks | Leeni: I guess I could imagine them accounting for jvm startup time but not clojure |
| 10:18 | bsod1 | gfredericks: what do you mean by `lots of clojures` ? sorry I'm new at clojure.. |
| 10:19 | gfredericks | bsod1: I was just referring to the 3 platforms it has been implemented on: jvm, clr, and javascript |
| 10:19 | zilti | Dynamic languages always are slower than static ones. Especially if they aren't aot compiled. |
| 10:19 | fliebel | It took me a couple of seconds to realize we have an CLR impl too. |
| 10:20 | gfredericks | as cemerick pointed out, they're really a lot more unified than is implied by calling them "lots of clojures", where the differences between them correspond to the differences between the platforms |
| 10:20 | bsod1 | gfredericks: is javascript implementation ClojureScript? |
| 10:20 | gfredericks | bsod1: yes |
| 10:20 | gfredericks | fliebel: yeah I've never really heard of anybody using it :) |
| 10:21 | cemerick | zilti: s/always/often |
| 10:22 | zilti | cemerick: I'd actually like to see a counter-example, never seen any. |
| 10:23 | gfredericks | zilti: well you could certainly construct one just for the sake of a counterexample |
| 10:24 | fliebel | zilti: Counter example to what? |
| 10:24 | gfredericks | fliebel: "dynamic always slower than static" |
| 10:24 | cemerick | zilti: Such comparisons are often flawed because of algorithmic differences enabled/required by the respective languages, and trivial comparisons almost always favor static compilation strategies because of the limited latitude for runtime optimization, etc. |
| 10:24 | cemerick | I've written Clojure that's faster than the corresponding java, tho. |
| 10:25 | gfredericks | I think those performance tests should include development time :) |
| 10:30 | zilti | Of course, since Clojure can be compiled aot it can reach the speed of Java. As for Clojure speed faster than Java speed, I guess that has a lot to do with the involved libraries? Not that I want to say "dynamic is slower, dynamic sucks". It has its technical reasons, e.g. about having to calculate position and length of data in ram |
| 10:31 | gfredericks | once the hardware people stop innovating we can all sit down and take a few decades to make our high-level stuff as fast as is theoretically possible. |
| 10:33 | fliebel | gfredericks: I'd like to hear the hardware people on that. "Once the software people stop mucking around, we can take a few decades to develop super fast hardware. |
| 10:34 | gfredericks | lol. I bet they get peeved that they have to support the same arbitrary instruction set indefinitely |
| 10:35 | zilti | x86 was considered to be outdated almost 20 years ago |
| 10:37 | gfredericks | I wonder what kind of speedup is possible with a fresh redesign |
| 10:37 | gfredericks | also I wonder what the implications on consumer computing would be if FP was moved off-chip |
| 10:40 | gfredericks | I guess that would kick javascript in the gut |
| 10:43 | Leeni | no man, I'm just asking where's the slowup since it's using java arrays and why does it only use 75% of cores. Not asking for instance why is it grotesquely memory inefficient because that's par for the course for clojure |
| 10:52 | Leeni | or this: http://shootout.alioth.debian.org/u64q/benchmark.php?test=knucleotide&lang=all |
| 10:53 | Leeni | clojure always has shitty cpu utilization |
| 10:54 | zilti | Leeni: One could as well ask why Scala is 7 times slower in the benchmark. |
| 10:54 | gfredericks | as someone who's not an expert, I would think that "grotesquely memory inefficient" could lead to "shitty cpu utilization", since the former could reduce the effect of memory caching |
| 10:55 | Leeni | zilti: because it uses only one core |
| 10:55 | fliebel | Leeni: The other run on multiple cores? |
| 10:55 | Leeni | if you are talking about the first benchmark |
| 10:56 | Leeni | or are you talkng about the second one |
| 10:56 | Leeni | look at last column CPU load |
| 10:56 | Leeni | shows cpu load for cores |
| 10:56 | Leeni | clojure is always around 75% load per core and I don't see why... |
| 10:57 | zilti | Second test is funny. g++ 3.86 sec, gcc almost 20 secs, clojure 9 minutes... |
| 10:58 | Leeni | clojure has 60 seconds I believe |
| 10:58 | zilti | And, to be honest, I don't really trust these benchmarks. Look at the different Scala tries. First attempt 37 seconds, fourth attempt "failed". huh? |
| 10:59 | Leeni | different code |
| 10:59 | zilti | Leeni: no, first attempt of closure in the second benchmark is indeed 9 minutes |
| 10:59 | Leeni | those are not attempts |
| 10:59 | zilti | versions? |
| 10:59 | Leeni | different submitted solutions |
| 11:00 | Leeni | generally the best clojure one is ugly as hell with loop-recur, array operations and typehints all over the place |
| 11:00 | Leeni | still takes twice as much RAM and four times as much time as Java in general |
| 11:01 | Leeni | idiomatic clojure code is 9 minutes yes... |
| 11:01 | arohner | emacs masters, what is the name of the feature where comments in your source code get executed by emacs? typically used for formatting and things? |
| 11:05 | Arafangion | arohner: #emacs is awesome. :) |
| 11:06 | Arafangion | I notice that Clojure actually has a respectable position in that benchmarks chart... Particularly #5. |
| 11:06 | Arafangion | Although it does have a lot of hints. |
| 11:07 | pdk | where's this benchmarks chart |
| 11:07 | pdk | language shootout? |
| 11:07 | Arafangion | Yeah, that one. |
| 11:08 | Arafangion | It would be interesting to see that shootout if the startup delay was factored out. |
| 11:08 | Arafangion | Such that the routine itself was compared. |
| 11:09 | Leeni | compare it with java |
| 11:09 | Leeni | same startup |
| 11:10 | Arafangion | Leeni: Notice that the java code has fewer classes needed, it probably doesn't need to load any support used by Clojure or anything. |
| 11:10 | Leeni | and I don't think startup delay is factored in |
| 11:10 | Arafangion | No, I doubt very much that it is. |
| 11:11 | Leeni | or look at regex-dna test |
| 11:12 | Arafangion | Clojure is much closer to Java there. |
| 11:13 | Arafangion | Hmm, no, it's still roughly 10x slower. |
| 11:13 | Arafangion | But that Java code there is horrible. |
| 11:14 | Arafangion | Interesing how C is consistently very high up. |
| 11:16 | Arafangion | Hmm, "all shootouts" and "all languages" gives a /very/ interesting chart. |
| 11:17 | Arafangion | Clojure is /always/ slower than C++. |
| 11:17 | Leeni | no shit lol |
| 11:17 | Leeni | you don't need a shootout to figure that one out |
| 11:17 | Arafangion | Leeni: Well, it's interesting because it's not always slower than C. |
| 11:17 | Arafangion | The best clojure is faster thaan the worst C. |
| 11:18 | gfredericks | the worst C has sleep calls in the inner loop |
| 11:18 | Leeni | I think the negative surprises are: how much slower it is than java, how ugly the code for fastest case is and how low the CPU utilization always is |
| 11:19 | Arafangion | The low CPU utilization would be the only thing that concerns me there. |
| 11:20 | Arafangion | Note that I have yet to actually /use/ clojure. |
| 11:20 | Leeni | :) |
| 11:21 | Arafangion | Unlike the shootout folks, I actually know how to optimise. |
| 11:21 | Leeni | I think the big letdown is that in java I can write idiomatic code and I am pretty sure I am within 30% of speed of hand optimized code, in clojure with idiomatic code you can be pretty certain you are running code three times slower than optimized code |
| 11:22 | Arafangion | Leeni: That's a point, however, that said, my favorite langauge is python. |
| 11:22 | Arafangion | And I'm sure real-world clojure code is probably faster. |
| 11:22 | Leeni | not really |
| 11:23 | Leeni | operations on collections are expensive |
| 11:23 | Arafangion | Unfortunate. :( |
| 11:23 | Leeni | iterating though a sequence is expensive |
| 11:23 | Arafangion | In python, doing a function call is expensive. |
| 11:24 | Leeni | just walking through a sequence and printing results will result in tons of memory allocations |
| 11:24 | Arafangion | That's unfortunate - whose fault is that? Clojure, or the VM? |
| 11:24 | Leeni | clojure |
| 11:25 | Arafangion | Well, someone will just have to optimise clojure a bit more. :) |
| 11:26 | Leeni | this is impossible... you need to allocate an object for each member of a sequence otherwise you'll be breaking the abstraction |
| 11:26 | Arafangion | Perhaps you could reuse objects. |
| 11:27 | Leeni | sequences must support ability to pass tails of sequences around |
| 11:27 | Leeni | thus you need to allocate a sequence object for each element of sequence you realize |
| 11:28 | Arafangion | I'm sure they could still be reused. Perhaps have it copy the iterator on-demand, as well as reusing a shared pool of iterators. |
| 11:28 | Leeni | this is where clojure is very different from java loops or Iterable |
| 11:28 | Arafangion | Well, no, that makes sense. |
| 11:28 | Leeni | bascially imagine a linked list |
| 11:29 | Arafangion | I can imagine it, but even so, I'm sure that there's going to be a typical use case that you can optimise for. |
| 11:29 | Leeni | (range 10) will produce 10 linked list(sequence) nodes |
| 11:29 | Arafangion | You can't produce them lazily? |
| 11:29 | Arafangion | (Which is what I'm getting at) |
| 11:29 | Leeni | yes lazily |
| 11:30 | zilti | They are produced lazily |
| 11:30 | Leeni | but imagine you feed them into a function as a sequence of indexes |
| 11:30 | Leeni | they will all get realized inevitably |
| 11:30 | Arafangion | You can't, say, pre-generate 100 linked lists and reuse them, lazily initialising more if you have the need? |
| 11:30 | zilti | List = single-linked list, Vector = Java-Array |
| 11:30 | zilti | So why is Vector still so much slower? |
| 11:30 | zilti | That should be easy to optimize |
| 11:31 | Leeni | in any case where java would have iterable that returns 10 Integer objects, clojure has 10 sequence objects allocations |
| 11:32 | Leeni | in java ArrayList is faster at adding elements in the front than LinkedList up to I think 10000 or 100000 elements, even though it's O(n) for arraylist and O(1) for linked list. Simply because linked list add results in an allocation for each element added |
| 11:32 | Arafangion | Seems that the obvious solution is to reuse the sequence objects. |
| 11:32 | zilti | I guess that's because all operations on collections are only realized using first and rest functions |
| 11:33 | Leeni | zilti clojure vector is not array, it's a tree with 20 branching |
| 11:33 | Leeni | hence it's really expensive to modify, because you have allocation of nodes again |
| 11:33 | Leeni | (among other things) |
| 11:34 | zilti | Huh, that's strange cause in the screencast he says otherwise (Clojure for Java programmers) |
| 11:35 | Leeni | i;m 100% it's a tree |
| 11:35 | Arafangion | Just looked at the source for sequence. |
| 11:35 | Arafangion | I notice that it's a clojure implementation, not Java. |
| 11:36 | Arafangion | https://github.com/clojure/clojure/blob/f5f827ac9fbb87e770d25007472504403ed3d7a6/src/clj/clojure/core.clj#L2350 |
| 11:36 | Leeni | java doesn't have sequence, only Iterable interface |
| 11:36 | dnolen | Leeni: it's not *that* expensive to modify. plus you get all the safety benefits. |
| 11:36 | dnolen | Leeni: and it's not 20, it's 32 |
| 11:36 | Arafangion | Leeni: That doesn't follow. |
| 11:37 | Arafangion | Leeni: Well, yes, Java doesn't have a sequence type, but that doesn't mean that it can't. |
| 11:37 | Arafangion | Leeni: I'm sure you'd be able to write one in Java? That was the observation I made, that it was Clojure. |
| 11:37 | Leeni | wouldn't change anything |
| 11:37 | Leeni | I mean if it was the same algorith |
| 11:38 | Arafangion | A Java implementation is *unlikely* to use the same algorithm! |
| 11:38 | Leeni | problem is that sequences as they are conceptually produce a ton of allocations on first walkthrough |
| 11:38 | Arafangion | map does even more allocations. |
| 11:39 | Leeni | point being? |
| 11:39 | dnolen | fortunately the JVM is really good at allocations. |
| 11:39 | Leeni | map isn;t known for being fast |
| 11:39 | Leeni | dnolen: still way way way worse than not doing allocations at all |
| 11:40 | dnolen | Leeni: in many applications the allocations hardly matter. Ever. |
| 11:40 | Leeni | it's why arraylist is way faster than linkedlist |
| 11:40 | dnolen | Leeni: it's easy to use a better data structure if the allocations matter. |
| 11:40 | Arafangion | dnolen: You have more or less the same cost for allocations in Java as you do in other environments. |
| 11:41 | Arafangion | dnolen: But deleting the objects is effectively free. |
| 11:41 | Leeni | allocations always matter |
| 11:41 | Leeni | they produce large slowdowns |
| 11:41 | Arafangion | Not if you pre-allocate. |
| 11:42 | Arafangion | Python, for instance, will pre-allocate and share integer objects. |
| 11:42 | Arafangion | (The first hundred or so, anyway) |
| 11:42 | Leeni | java has that too |
| 11:42 | Arafangion | Leeni: I'd be willing to bet it doesn't do that automatically for user-defined classes. |
| 11:42 | Leeni | you are right it doesn't |
| 11:43 | dnolen | Leeni: in anycase "large" slowdowns doesn't really play out much in practice. If you need to write high perf low allocation code in Clojure it can be done w/o much effort. |
| 11:44 | Arafangion | The JVM, can, at least, abstract most of the performance issues of using the native platform allocator. |
| 11:44 | dnolen | in any large code base you need to produce against mutability somewhere - so what are you going to do? deep copy an entire nested structure |
| 11:44 | dnolen | yuck |
| 11:45 | dnolen | expect const to save you? |
| 11:45 | dnolen | yuck |
| 11:45 | dnolen | expect that somebody would cast to a mutable type? |
| 11:45 | dnolen | yuck |
| 11:45 | Arafangion | dnolen: Arguably. The need to do so depends on your application design. |
| 11:45 | Arafangion | There is still, however, a lot of copying going on. :( |
| 11:46 | dnolen | Arafangion: well I'm no expert but I've rarely written code that doesn't need it after certain threshold. |
| 11:47 | Leeni | here's the dealio, if most basic operation (walking through a sequence) is slow then it's gonna affect all programs... |
| 11:47 | Arafangion | dnolen: I tend to restrict such large structures to the module it belongs to. |
| 11:47 | Leeni | still need to solve the mistery of low CPU utilization |
| 11:47 | Arafangion | Leeni: Walking through a sequence is slow in python, too, despite python not needing to pass tails. |
| 11:48 | Leeni | that's weird |
| 11:48 | Arafangion | Leeni: Mostly because function calls are slow. |
| 11:48 | Leeni | I've wrote a java function that returns and Iterable like clojure function range and was much faster |
| 11:49 | Leeni | then again, you couldn't pass it around |
| 11:49 | Leeni | I mean mid-iteration |
| 11:51 | Arafangion | Leeni: I should get to bed, otherwise I"m going to stay up thinking of a nice implementation that would allow you to do that, it doesn't seem to be that hard a problem. |
| 11:51 | Arafangion | Again, speaking of someone who has never done clojure, perhaps there's something I'm missing entirely. :( |
| 11:51 | dnolen | Arafangion: it's hard, you need to consider concurrency, locks, etc. |
| 11:52 | Leeni | gotta figure out how to make the clojure 1.3 work with clojurebox or counterclockwise |
| 11:52 | Arafangion | dnolen: Oh, concurrency, forgot about that, but it'd still be doable, imho. |
| 11:52 | dnolen | Arafangion: of course Clojure has already done the work for you :) and it's hard. |
| 11:53 | Arafangion | dnolen: From what I hear, you're optimising for the worst case, specifically, the assumption that a tail is always passed. |
| 11:53 | dnolen | Arafangion: just working for an Iterable is not enough anyhow, you want array-like, set-like, etc. |
| 11:53 | dnolen | map-like |
| 11:53 | Arafangion | Meh, that makes it a non-trivial amount of code! |
| 11:54 | dnolen | thus be lazy, use Clojure |
| 11:54 | dnolen | work done |
| 11:54 | Arafangion | On that note, G'night. :) |
| 11:54 | Leeni | :D |
| 11:56 | Leeni | dnolen, do you know why on this benchmark http://shootout.alioth.debian.org/u64q/benchmark.php?test=fannkuchredux&lang=all clojure's CPU utilization doesn't exceed 75% per core? |
| 11:56 | Leeni | or any other benchmarks practically |
| 11:56 | Arafangion | Possibly locks. |
| 11:57 | Leeni | then C and java would have same problem too |
| 11:57 | Leeni | these algorythms seem easily paralelizable without locks |
| 11:58 | dnolen | Leeni: no I haven't looked at that code very closely, but that's code based off of 1.2.0, and I see some things that I wouldn't do. |
| 11:59 | Leeni | under notes it says 1.3.0 |
| 11:59 | dnolen | the code itself is written for 1.2.0 |
| 11:59 | Leeni | quite probable |
| 11:59 | Leeni | what wouldnt you do? |
| 11:59 | dnolen | Leeni: I know, I've been writing Clojure for 3 years :) |
| 12:00 | Leeni | well I haven't and I can't find the screwup |
| 12:01 | dnolen | remove all the unnecessary casting, don't use range to allocate contents of array. |
| 12:01 | Leeni | I was thinking pmap was enough to get all the cores running at max |
| 12:02 | Leeni | hehe I use range a lot |
| 12:02 | Leeni | or (iterate inc 0) |
| 12:02 | dnolen | Leeni: as you should, unless you writing silly benchmarks. |
| 12:02 | Leeni | yeah I know range is much slower than a nice loop recur |
| 12:27 | thorwil | i suspect that i have a case where i can't compile a file, because it refers to a class in a required file, in which it's the job of a macro to create that class |
| 12:28 | thorwil | actually, if i require a file, all the macros should get expanded, before anything else happens, or? |
| 12:31 | thorwil | it's appengine-magic's defentity, e.g.: (ds/defentity Article [title, body, created, updated]) |
| 12:31 | thorwil | where i need to refer to Article in another .clj |
| 12:36 | thorwil | defentity expands to a defrecord: https://github.com/gcv/appengine-magic/blob/master/src/appengine_magic/services/datastore.clj#L380 |
| 12:42 | gfredericks | thorwil: what sort of error are you getting? |
| 12:43 | gfredericks | and do you remember to import the class? |
| 12:44 | thorwil | Unable to resolve classname: Article |
| 12:45 | thorwil | gfredericks: i take this needs special handling then. import apparently ;) |
| 12:45 | gfredericks | thorwil: anytime you use a class created with defrecord or deftype you have to import it to refer to it directly |
| 12:48 | thorwil | gfredericks: ah, thanks. given the defrecord is in tlog.models.backing and called Article, what's the right import? |
| 12:52 | thorwil | nm, got things mixed up :) |
| 12:56 | halarnold2000 | does stuart sierra have a nik on this channel? |
| 12:57 | gfredericks | thorwil: your hope looks right to me, which I presume you figured out on your own while I was not replying |
| 12:58 | thorwil | gfredericks: indeed |
| 12:59 | thorwil | i was just juggling too many buffers ... |
| 12:59 | gfredericks | buffer-juggling => buggling |
| 13:01 | zerokarmaleft | buffuggling |
| 13:02 | gfredericks | (inc zerokarmaleft) |
| 13:02 | lazybot | ⟹ 1 |
| 13:02 | gfredericks | HA! Whaddayagonna call yourself now! |
| 13:03 | thorwil | lol |
| 13:11 | halarnold2000 | . |
| 13:19 | zerokarmaleft | gfredericks: i'm immutable :P |
| 13:20 | gfredericks | zerokarmaleft: does that ever change? |
| 13:23 | zerokarmaleft | gfredericks: probably when i get married and have kids |
| 13:31 | mbac | what's the way to represent an association list in clojure? |
| 13:31 | mbac | is a list of vectors appropriate? |
| 13:32 | mbac | ([a b] [x y]) |
| 13:32 | duck1123 | mbac, there's a hash: {a b x y} |
| 13:33 | duck1123 | do you want to be able to find b if you have a? |
| 13:33 | melipone | I need to use the expt function from clojure.contrib.math but the abs function is conflicting with Incanter.core. How do I mix the two? |
| 13:33 | Bronsa | melipone: :as ? |
| 13:34 | bsod1 | is there a better way to reload definitions other than calling (load-file ...) again? |
| 13:34 | melipone | okay, that might work. I was trying (use 'incanter.core :exclude abs) but that didn't work |
| 13:35 | Bronsa | melipone: try with :exclude [abs] |
| 13:35 | mbac | i only want to iterate them. hashes seem overkill |
| 13:35 | duck1123 | melipone: usually it's better to either require with a prefix (:as) or use only the vars you need (:only) |
| 13:35 | melipone | thanks! |
| 13:36 | gfredericks | mbac: hashes are probably more idiomatic. And they're easy to iterate over because they're seqable: ##(seq {:a 3 :b 489 :c 28}) |
| 13:36 | lazybot | ⇒ ([:a 3] [:b 489] [:c 28]) |
| 13:37 | gfredericks | but if you have some tiny piece of code where you feel like it's silly to use a hash, then I don't think anybody will jump out from behind a bush and yell at you |
| 13:37 | mbac | haha |
| 13:38 | duck1123 | it all really depends on what you want to do with them. A seq of vectors might be more appropriate for you |
| 13:38 | gfredericks | mbac: hard to say anything else without more details |
| 13:38 | mbac | that's about it. |
| 13:41 | devn | how DARE YOU, sir! |
| 13:42 | mbac | what's the function that takes an f and a coll and returns the first x where f x is true |
| 13:42 | mbac | (coll means sequence-like thing right?) |
| 13:42 | zerokarmaleft | some |
| 13:44 | mbac | close, i want the x not the truthness |
| 13:44 | Bronsa | mbac: (comp first filter) |
| 13:44 | eanxgeek | ping #clojure anyone here by chance familar with selenium? trying to lein compile some code java.io.FileNotFoundException: Could not locate selenium__init.class and I'm trying to figure out where that would come from. |
| 13:44 | Bronsa | ,((comp first filter) odd? [0 2 4 1 2]) |
| 13:44 | duck1123 | ,(some even? [1 2 3 4]) |
| 13:44 | clojurebot | true |
| 13:44 | clojurebot | 1 |
| 13:45 | zerokarmaleft | Bronsa's then |
| 13:45 | mbac | i only want the first one :) |
| 13:46 | duck1123 | Bronsa was right |
| 13:46 | mbac | and only want to compute all but the first |
| 13:46 | mbac | that seems wordy |
| 13:46 | Bronsa | wait, what |
| 13:46 | mbac | er, wait |
| 13:46 | mbac | and only want to compute the first |
| 13:46 | duck1123 | ,(->> [1 2 3 4] (filter odd?) first) |
| 13:46 | clojurebot | 1 |
| 13:47 | zerokarmaleft | you have to compute on the things that come before it necessarily |
| 13:47 | mbac | sure |
| 13:47 | Bronsa | mbac: then being filter lazy, it will compute until one is true |
| 13:47 | zerokarmaleft | it's lazy though, it stops after the first |
| 13:47 | Bronsa | and returd that |
| 13:47 | Bronsa | *return |
| 13:48 | Bronsa | simply (def ffilter (comp first filter)) |
| 13:48 | Bronsa | and have fun |
| 13:50 | Bronsa | why? |
| 13:50 | clojurebot | why not? |
| 13:50 | devn | because i think it will slow down newcomers |
| 13:51 | mbac | whoa, magic ->> thing |
| 13:51 | Bronsa | mbac: -> too |
| 13:51 | devn | Maybe I'm overstating it, but im working on a tutorial for a meetup group I run and I think the extra step of requiring clojure.repl in all of your projects in order to get (doc) and (source) is annoying |
| 13:52 | duck1123 | those 2 forms are great for turning big complicated fns into simple lists |
| 13:52 | Bronsa | devn: personally i use doc and source only from a repl |
| 13:52 | Bronsa | which is the usecase for them in some code? |
| 13:52 | devn | Bronsa: coincidentally, i only develop when I'm using...a repl |
| 13:53 | mbac | are lists always lazy? |
| 13:53 | devn | Bronsa: I see where you're coming from, but I miss the old days of not needing to (use 'clojure.repl) every single time I start a repl |
| 13:54 | Bronsa | devn: oh |
| 13:54 | devn | it's just extra garbage that new people to the language should not need to do. |
| 13:54 | Bronsa | i always start my repl with lein repl |
| 13:54 | Bronsa | and it uses clojure.repl by default |
| 13:54 | Bronsa | i tought it was the repl, not lein |
| 13:54 | devn | Bronsa: so...that's one way out of how many to start a repl? |
| 13:54 | Bronsa | didn't mean to say that |
| 13:54 | Bronsa | i tought that when starting the repl clojure.repl was automatically :used |
| 13:55 | Bronsa | didnt notice it was lein |
| 13:55 | devn | *nod* -- this is a change as of 1.3 I believe |
| 13:55 | fliebel | Are there any other binary libs for clojure other than Gloss? |
| 13:56 | mbac | oh filter does the lazy |
| 13:57 | chewbranca | is there a form of flatten that allows you to specify depth or type? I've got a list of lists of vectors, and I want to flatten that to be a single list of vectors |
| 13:57 | Bronsa | mbac: most of the core seq fns returns lazy seqs |
| 13:57 | chewbranca | and flatten will flatten the vectors down as well |
| 13:58 | Bronsa | s/ns/n/ |
| 13:58 | lazybot | <Bronsa> mbac: most of the core seq fn return lazy seqs |
| 13:58 | ibdknox | the ones that can will do so :) |
| 13:59 | gfredericks | is there an example of a function that returns a seq that is not lazy? |
| 13:59 | chewbranca | gogo internet: http://stackoverflow.com/questions/5232350/clojure-semi-flattening-a-nested-sequence |
| 13:59 | ibdknox | ,(doc reverse) |
| 14:00 | clojurebot | "([coll]); Returns a seq of the items in coll in reverse order. Not lazy." |
| 14:00 | ibdknox | :) |
| 14:00 | gfredericks | ibdknox: that was certainly easy. :) |
| 14:03 | duck1123 | ,(doc doall) |
| 14:03 | clojurebot | "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the successive nexts of the seq, retains the head and returns it, thus causing the entire seq to reside in memory at one time." |
| 14:04 | gfredericks | obvious exception |
| 14:04 | sritchie | ibdknox, do you have any examples of how to use sandbar for authentication with noir? |
| 14:05 | sritchie | specifically, I'm not sure how to to use server/add-middleware to do something like this: https://github.com/brentonashworth/sandbar/blob/master/src/examples/auth/auth.clj#L130 |
| 14:06 | ibdknox | sritchie: I haven't used it, because it didn't seem to provide anything I needed, to do that, though you just need to add those two middleware separately |
| 14:07 | ibdknox | sritchie: you won't need wrap-file :) |
| 14:07 | ibdknox | sritchie: you could also comp them |
| 14:07 | sritchie | got it, so just add (server/add-middleware with-security authorize) in there |
| 14:07 | ibdknox | yep |
| 14:08 | sritchie | nice, that tossed a few hours, but I'll figure it out from the sandbar side |
| 14:08 | sritchie | s/hours/errors |
| 14:08 | lazybot | <sritchie> nice, that tossed a few errors, but I'll figure it out from the sandbar side |
| 14:08 | sritchie | Key must be integer, etc :) |
| 14:08 | ibdknox | I think you'll need to include his session middleware too, which I'm not sure how way that'll play with mine |
| 14:09 | ibdknox | in theory they shouldn't mess with eachother |
| 14:09 | ibdknox | but I've not tried it |
| 14:10 | sritchie | yeah, you're right, that worked out fine |
| 14:12 | sritchie | so, all I'm looking to do is restrict access to certain pages based on roles -- in noir, I could do the same thing by examining noir's session, right? |
| 14:12 | mbac | can i have fold? |
| 14:12 | mbac | reduce isn't cutting it for me |
| 14:14 | dnolen | foldl foldr considered slightly harmful, http://docs.google.com/viewer?url=http://research.sun.com/projects/plrg/Publications/ICFPAugust2009Steele.pdf&pli=1 |
| 14:14 | ibdknox | sritchie: yeah, it's probably a bit simpler. You would use a pre-route, then check if the person has access, if not, redirect to login or whatever :) |
| 14:15 | ibdknox | sritchie: for example: https://github.com/ibdknox/Noir-blog/blob/master/src/noir_blog/views/admin.clj#L50 |
| 14:15 | mbac | dnolen, i know. i want it anyway. |
| 14:15 | dnolen | mbac: can't help you there :) |
| 14:16 | sritchie | ibdknox: got it, that's great |
| 14:16 | dnolen | and if rhickey #strangeloop talk is any indicator, it's not going to happen. mayhaps as a contrib thing, but I don't hear many people asking for it. |
| 14:18 | mbac | well, what's better then? i want to update state as i consume a list |
| 14:20 | dnolen | mbac: so why not reduce + an atom? |
| 14:20 | mbac | hmm? |
| 14:27 | mbac | there's seriously no fold function because it's not inherently parallelizable? this is better than having thousands of people try write their own buggy versions? |
| 14:27 | mbac | s/try write/try to write/ |
| 14:27 | lazybot | <mbac> there's seriously no fold function because it's not inherently parallelizable? this is better than having thousands of people try to write their own buggy versions? |
| 14:28 | dnolen | mbac: thousands? if you feel so strongly about it bring it up on the mailing list, dev list. |
| 14:28 | mbac | thousands of crappy implementations, at least |
| 14:29 | mbac | i know mine will be |
| 14:29 | dnolen | mbac: I have yet see any implementations of it at all. |
| 14:29 | dnolen | much less thousands. |
| 14:31 | mbac | i'm projecting into the future a little |
| 14:32 | dnolen | people have been using Clojure for a while now, future hasn't arrived. |
| 14:32 | dnolen | but honestly, sounds like something that could find a home in contrib. |
| 14:34 | dnolen | and other people that want it can benefit from a good implementation. same thing w/ pattern matching - rhickey doesn't like that either. |
| 14:34 | dsantiago | dnolen, has he said why he doesn't like pattern matching? |
| 14:34 | dnolen | gotta run |
| 14:35 | mbac | http://pastebin.com/yAS3Fjhe there, i fixed clojure :) |
| 14:36 | gfredericks | mbac: don't you gotta have a 2-arg version? |
| 14:37 | mbac | see? i told you it'd be crappy |
| 14:37 | fliebel | dsantiago: From what I remember he just didn't like the current implementations. |
| 14:37 | dsantiago | Ah. |
| 14:37 | gfredericks | mbac: yeah, no motivation to prove your own point there :P |
| 14:42 | Leeni | isn't fold like reduce? |
| 14:42 | mbac | no |
| 14:42 | mbac | i mean, yes |
| 14:43 | mbac | but if you use a language which discourages mutation, fold is what all of the kids who miss for loops will want |
| 14:43 | mbac | except they don't know they want it, yet |
| 14:44 | gfredericks | foldl === reduce? |
| 14:44 | fliebel | behold the treeduce https://gist.github.com/951553 |
| 14:45 | mbac | it's not. part of the power of fold is the accumulator isn't necessarily the same type as the elements in the collection |
| 14:46 | gfredericks | mbac: well clojure.core/reduce certainly doesn't enforce that. I use it assymetrically all the time. |
| 14:46 | fliebel | mbac: Does reduce require that? |
| 14:48 | mbac | int total=0; for(int i=0;i<a.length;i++) total+=a[i].length; best functional programmingifies to (foldl (fn [acc x] (length x)) 0 a) |
| 14:49 | gfredericks | (reduce + (map count a))? |
| 14:49 | gfredericks | I don't even see where the + happens in your version |
| 14:49 | mbac | yeah, i forgot |
| 14:49 | gfredericks | ah I see where it would go |
| 14:49 | mbac | (foldl (fn [acc x] (+ acc (length x))) 0 a) |
| 14:50 | gfredericks | so you're arguing that because something fits the imperative paradigm better, we ought to have it? |
| 14:52 | mbac | no, i'm arguing the loops that you use to get stuff done are strange |
| 14:52 | mbac | fold explicitly considers the start case |
| 14:53 | mbac | your reduce would have a bug if 0-arity + didn't rescue you |
| 14:54 | Leeni | reduce can take start value |
| 14:54 | mbac | i agree, you can not write bugs |
| 14:54 | mbac | ;) |
| 14:54 | Leeni | it also enables you to accumulate different type than that is the collection |
| 14:55 | gfredericks | mbac: so you consider fold to be a function that requires a start value? |
| 14:55 | Raynes | reduce lets you do anything you want. |
| 14:55 | gfredericks | ,(reduce conj [] #{7 8 4}) |
| 14:55 | clojurebot | [4 7 8] |
| 14:56 | gfredericks | ^ different accumulated type |
| 14:57 | mbac | gfredericks, sort of |
| 14:58 | Leeni | I never know when to use reduce and when to use something like apply vec |
| 14:58 | mbac | fold has a well known form. with reduce i have to look closer |
| 14:58 | gfredericks | ,(doc vec) |
| 14:58 | clojurebot | "([coll]); Creates a new vector containing the contents of coll." |
| 14:58 | gfredericks | Leeni: apply vec sounds pretty useless; and apply vector is equivalent to vec |
| 14:59 | Leeni | yeah that |
| 14:59 | Leeni | I mean I can often do a lot of stuff just with map and reduce |
| 14:59 | gfredericks | Leeni: reduce is a lot more general |
| 14:59 | Leeni | but maybe using specialised function is better |
| 14:59 | mbac | yes, that's it! reduce is too general. it's terrible |
| 14:59 | gfredericks | if all you're doing is trying to make a vector out of something, then you should prefer vec/vector |
| 14:59 | Leeni | perhaps faster |
| 14:59 | gfredericks | mbac: I don't mean it's any more general than fold |
| 15:00 | mbac | :) |
| 15:00 | gfredericks | in fact part of what makes this discussion hazy is that there's not a clear line between the two |
| 15:00 | mbac | there's a very clear line. fold has an explicit required start case |
| 15:01 | mbac | if you use it wrong the system stops you from having a bug |
| 15:01 | gfredericks | mbac: if we like the system to tell us when we have bugs we may as well use static types |
| 15:01 | mbac | hahah |
| 15:01 | mbac | i guess i should stick to ocaml |
| 15:02 | gfredericks | clojure's got flexibility all over the place |
| 15:02 | mbac | i know, it's horrible |
| 15:02 | gfredericks | then don't use clojure. apparently you don't like it. |
| 15:02 | mbac | i don't know how to do anything |
| 15:03 | Leeni | hey, anyone got clojurebox or counterclockwise to run with clojure 1.3? |
| 15:03 | gfredericks | btw, wikipedia doesn't agree with your strict definitions: http://en.wikipedia.org/wiki/Fold_(higher-order_function) |
| 15:03 | gfredericks | mbac: I think most of the people that use clojure appreciate the flexibility |
| 15:04 | gfredericks | I think that can be a personality thing though. Some people like it, some people don't. |
| 15:04 | mbac | i've noticed that |
| 15:04 | toxmeister | leeni: CCW 0.4 works fine w/ 1.3 |
| 15:04 | gfredericks | I have a friend who would be great with clojure except for that one point, so he uses scala |
| 15:04 | mbac | it's not inherently bad, it's simply thwarting my expectations |
| 15:06 | gfredericks | mbac: what other languages do you use/like? |
| 15:09 | Leeni | toxmeister: my CCW feezes my eclipse when I try to connect to 1.3 REPL |
| 15:21 | mbac | gfredericks, besides ocaml? i guess C |
| 15:21 | mbac | python, when i'm doing project euler problems |
| 15:23 | gfredericks | do you find clojure more flexible/surprising than python? |
| 15:23 | mbac | no, they're a lot alike |
| 15:23 | mbac | philosophically, it seems |
| 15:24 | mbac | using python in a large codebase with multiple people drives me nuts though |
| 15:25 | gfredericks | I think immutable data and preferring pure functions can help keep down the chaos |
| 15:25 | mbac | agreed |
| 15:27 | gfredericks | mbac: I sympathize with you some. the dynamic types and stuff are definitely the part of clojure I'm least sure about |
| 15:27 | gfredericks | my personal approach is to use testing |
| 15:28 | gfredericks | my hunch is that could be better than a static language, because you're forced to write lots of tests, which give you confidence not only that you got all the types right, but that the program also does what you want it to |
| 15:28 | Leeni | what's the difference between deftype and defrecord? |
| 15:30 | gfredericks | defrecord gets you a map-compatible data structure. deftype is bare, and can even give you mutable fields if you need them |
| 15:33 | mabes | mbac: another version of foldl for you: https://github.com/amalloy/amalloy-utils/blob/master/src/amalloy/utils.clj#L72-74 |
| 15:33 | mabes | in this case he aliased reduce to be foldl.. which wouldn't get the strict enforcement that you want |
| 15:34 | gfredericks | pretty easy to get it though: (def foldl #(reduce %1 %2 %3)) |
| 15:34 | mabes | yeah |
| 15:35 | gfredericks | I wonder if reverse on vectors is fast |
| 15:35 | mabes | ,(doc reverse) |
| 15:36 | clojurebot | "([coll]); Returns a seq of the items in coll in reverse order. Not lazy." |
| 15:36 | mbac | gfredericks, disciplined coding, almost universally, doesn't work |
| 15:36 | gfredericks | mbac: did I say otherwise? |
| 15:36 | mbac | i don't think so |
| 15:36 | gfredericks | mbac: what does work? |
| 15:36 | mbac | i'm paving the way for why i'd never write unit tests |
| 15:36 | gfredericks | oh I see |
| 15:37 | mbac | the language should make it impossible to push a bad solution |
| 15:37 | gfredericks | oh golly. |
| 15:37 | mabes | mbac: do you use ocaml professionally? |
| 15:37 | mbac | yeah |
| 15:38 | gfredericks | mbac: if the language doesn't let you write incorrect code, I don't think it could be a programming language |
| 15:38 | mbac | no doubt |
| 15:38 | gfredericks | so I guess your statement hinges on what you mean by "bad solution" |
| 15:38 | mbac | there's an interesting proof in there somewhere :) |
| 15:38 | gfredericks | easy: |
| 15:38 | gfredericks | Requirements: push a bad solution |
| 15:39 | mabes | after reading "Ocam for the Masses" and a few tutorials I must say that I am intrigued.. I've never used a language with a decent type system but the benefits sound nice |
| 15:39 | mbac | ideally your developers write unit tests and check their mallocs and do proper mutex locking blah blah |
| 15:39 | mabes | s/Ocam/Ocaml/ |
| 15:39 | lazybot | <mabes> after reading "Ocaml for the Masses" and a few tutorials I must say that I am intrigued.. I've never used a language with a decent type system but the benefits sound nice |
| 15:40 | mabes | (here is the link to the mentioned article: http://queue.acm.org/detail.cfm?id=2038036) |
| 15:40 | mbac | but if they're human beings they're going to forego all that shit if it means they get it out the door faster |
| 15:40 | mabes | mbac: what industry do you work in? |
| 15:41 | mbac | mabes, my boss wrote that article |
| 15:41 | mabes | mbac: awesome! I've been watching some of his presentations too :) |
| 15:42 | mabes | aside from HFT OCaml hasn't really seen much in roads in industry it would seem |
| 15:45 | mabes | mbac: what is your opinion on clojure's approach to concurrency and state? |
| 15:46 | mbac | what's clojure's approach? |
| 15:46 | mabes | :) |
| 15:46 | mabes | http://clojure.org/state |
| 15:47 | gfredericks | piles and piles of mutexes |
| 15:47 | mabes | http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey |
| 15:48 | mabes | gfredericks: under the hood I suppose so, but the overall premise is to remove that complexity from the programmer, right? |
| 15:48 | gfredericks | mabes: yeah, I was kidding. it wasn't very funny. |
| 15:48 | mabes | gfredericks: lol.. okay |
| 15:48 | gfredericks | sometimes I forget whether jokes are supposed to be funny or not. |
| 15:49 | Leeni | btw about reduce |
| 15:49 | Leeni | it does have one weird behaviour |
| 15:49 | mabes | gfredericks: sarcasm can also be lost over IRC as well ;) |
| 15:49 | Leeni | if you hand it an empty sequence it will invoke the function with no arguments |
| 15:49 | gfredericks | mabes: I can get it lost face-to-face if I try hard enough. |
| 15:50 | mbac | everything on irc is sarcastic, unless explicitly noted otherwise |
| 15:50 | Leeni | if you hand it a 2 or more elements it will do a reduce |
| 15:50 | gfredericks | Leeni: not much else for it to do, right? |
| 15:50 | Leeni | and if you hand it sequence of one element it will just return the element |
| 15:50 | Leeni | that's the weird one |
| 15:50 | gfredericks | :/ |
| 15:51 | Leeni | in all other cases function gets called at least once |
| 15:51 | mbac | (defalias foldl reduce) |
| 15:51 | mbac | lulz |
| 15:51 | Leeni | except when sequence has 1 element |
| 15:51 | Leeni | then the function doesn't get called |
| 15:52 | gfredericks | Leeni: I think it makes sense, unless you phrase it specifically so as to make it sound like it doesn't make sense :P would you do it differently? |
| 15:52 | Leeni | perhaps invoke the function with one argument? |
| 15:52 | gfredericks | I think that's even weirder |
| 15:53 | gfredericks | really the exceptional case is the 0-arg case |
| 15:54 | gfredericks | I think if you're going to call fold/reduce, you've got three options: 1), never call it on an empty list, 2) give an initial value that will be returned if you use an empty list, 3) barring the first two, give a reduce function that will accept 0 args |
| 15:54 | gfredericks | case 3 is what you get for rejecting 1 and 2 |
| 15:54 | gfredericks | I think the only other sane thing is to throw an error in case 3 |
| 15:54 | mabes | mbac: have any book recommendations (or other resources) for learning ocaml? From what I've googled, "Introduction to Objective Caml" seems to be well liked: http://caml.inria.fr/cgi-bin/hump.en.cgi?contrib=347 |
| 15:56 | mbac | that's the best ocaml book available |
| 15:56 | mbac | which is to say it sucks the least |
| 15:57 | mabes | of course |
| 16:03 | mbac | have any book recommendations for learning clojure? :) |
| 16:06 | zerokarmaleft | mbac: i enjoyed JoC |
| 16:06 | mabes | mbac: given your background I think you would like Joy Of Clojure |
| 16:08 | mbac | sounds like the winner |
| 16:09 | mabes | which is to say you will hate the book the least |
| 16:09 | mbac | haha |
| 16:13 | ghiu | hi, i'm using intellij idea and leiningen. how can i access the jars imported in the /lib dir of the project from the build-in repl of my die? it seems to have a class path that is different from the one used by lein and the project. thanks |
| 16:16 | ghiu | oh, found it |
| 16:16 | ghiu | i had to add the lib path to the "dependancies" modules in the project settings |
| 16:21 | gfredericks | is it possible to override the clojure reader? |
| 16:26 | duck1123 | gfredericks: if you're asking like reader macros, no |
| 16:34 | gfredericks | duck1123: I was thinking like (binding [clojure.core/read my-silly-reader-fn] (require ...)) |
| 16:34 | gfredericks | it's a stupid idea anyhow. Was just curious if that would work. |
| 16:35 | mbac | does this form (let [foo 1 foo (+ foo 1)] foo) particularly infuriate anyone? |
| 16:36 | gfredericks | mbac: it's a great way to imitate imperative programming! :) |
| 16:37 | Bronsa | s/imperative/procedural/ right? |
| 16:37 | mbac | i don't want to risk re-using the old value by mistake |
| 16:37 | mbac | so... shadow it! |
| 16:37 | gfredericks | I think it certainly has the danger to screw up readability. Sometimes I can't resist using it for getting an argument into a canonical form though. I think clojure.core does that as well. |
| 16:37 | gfredericks | Bronsa: dunno, what's the difference? |
| 16:37 | mbac | of course then you risk much more subtle scoping bugs |
| 16:38 | gfredericks | mbac: I wouldn't go out of your way to hide things like that. If you want isolation, create a separate function to call. |
| 16:39 | Bronsa | gfredericks: as per wikipedia procedural can be used as a synonym for imperative |
| 16:39 | Bronsa | so i think i am wrong |
| 16:39 | gfredericks | Bronsa: nah, you _were_ wrong. Now you're right! |
| 16:39 | gfredericks | probably. |
| 16:39 | Bronsa | gfredericks: lol right |
| 17:04 | michaelr525 | hello! |
| 17:06 | gfredericks | michaelr525: hello! |
| 17:20 | bdb_ | I'm having some trouble getting swank-clojure to work with lein: I've installed the plugin & ~/.lein/bin/ is on my path, but `lein swank` still says "That's not a task." |
| 17:21 | bdb_ | where should I look next to debug this? |
| 17:21 | bdb_ | $ which swank-clojure |
| 17:21 | bdb_ | $ lein swank |
| 17:21 | bdb_ | That's not a task. Use "lein help" to list all tasks. |
| 17:22 | bdb_ | hmm, that didn't render right in my irc client: `which` returns: /Users/brandon/.lein/bin/swank-clojure |
| 17:27 | duck1123 | bdb_: is your lein up to date? |
| 17:28 | bdb_ | yup: leiLeiningen 1.6.1.1 on Java 1.6.0_26 Java HotSpot(TM) 64-Bit Server VM |
| 17:29 | ibdknox | bdb_: ls ~/.lein/plugins |
| 17:29 | ibdknox | is swank actually in there? |
| 17:29 | bsod1 | wow, I got NullPointerException in Clojure! |
| 17:29 | bdb_ | yup |
| 17:29 | gfredericks | bsod1: ##(nil :foo) |
| 17:29 | lazybot | java.lang.IllegalArgumentException: Can't call nil |
| 17:29 | gfredericks | dangit |
| 17:29 | gfredericks | I know there's an easy way to do it... |
| 17:29 | bdb_ | aaaahh two versions were in there |
| 17:30 | bdb_ | i ran uninstall on the older version |
| 17:30 | ibdknox | :) |
| 17:30 | duck1123 | ##(.getFoo nil) |
| 17:30 | bdb_ | and `lein help` shows swank now! |
| 17:30 | lazybot | java.lang.NullPointerException |
| 17:30 | gfredericks | (map nil [1]) |
| 17:30 | gfredericks | ,(map nil [1]) |
| 17:30 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.NullPointerException> |
| 17:30 | bsod1 | heh |
| 17:31 | gfredericks | bsod1: would you prefer clojure defined a NilPointerException? :) |
| 17:31 | bdb_ | thanks idbknox |
| 17:31 | ibdknox | bdb_: leave it to a VIM user to save the day ;) |
| 17:31 | bdb_ | heh -- I'm a vim guy myself |
| 17:32 | ibdknox | haha |
| 17:32 | bsod1 | ,(* 1 nil) |
| 17:32 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 17:32 | bdb_ | been writing clojure in vim for a couple weeks and been using a little macro plus tmux to send forms to the repl |
| 17:32 | bdb_ | and decided it was finally time to bite the bullet and learn some emacs |
| 17:32 | ibdknox | vimclojure would make that much nicer for you |
| 17:33 | bdb_ | yeah, was using that in offline mode |
| 17:35 | Bronsa | ,() |
| 17:35 | clojurebot | () |
| 17:35 | Bronsa | ,(nil) |
| 17:35 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Can't call nil, compiling:(NO_SOURCE_PATH:0)> |
| 17:36 | gtrak`` | ,(println "Clojure is awesome") |
| 17:36 | clojurebot | Clojure is awesome |
| 17:37 | gfredericks | ,(println "&(println \"clojurebot is awesome\")") |
| 17:37 | clojurebot | &(println "clojurebot is awesome") |
| 17:37 | lazybot | ⇒ clojurebot is awesome nil |
| 17:37 | Bronsa | lol |
| 17:37 | bdb_ | so tempting to write an infinite bot loop :-P |
| 17:38 | gfredericks | bdb_: lazybot's arrow prevents it |
| 17:38 | ibdknox | guarded against |
| 17:38 | raek | bdb_: this is why lazybot's output is prefixed with ⇒ |
| 17:38 | bdb_ | ah, nice |
| 17:38 | gfredericks | somebody else say it too! |
| 17:38 | gtrak`` | nerds :-) |
| 17:38 | Bronsa | it's not nice |
| 17:38 | Bronsa | it ruins fun |
| 17:54 | sritchie | you'd just need one more bot that responds to the arrow, I think |
| 18:14 | Leeni | man I can't get swank to work with clojure 1.3 |
| 18:14 | Leeni | it just crashes |
| 18:18 | Raynes | technomancy: Ping. |
| 18:20 | lnostdal_ | works fine here |
| 18:23 | Leeni | changed clojure jar version to 1.3 in lein.bat and now leinigen crashes |
| 18:24 | duck1123 | Leeni: update lein, remove all older versions of swank and install an up to date version |
| 18:24 | raek | Leeni: change the version in your project.clj file, not in leiningen's internals |
| 18:24 | Leeni | raek I did that and it crashed on lein swank |
| 18:25 | raek | leiningen uses two processes: one for build tool stuff and one for your code |
| 18:25 | raek | which version of swank-clojure? |
| 18:25 | Leeni | yes but it ran swank with same version as build tool stuff |
| 18:25 | Leeni | 1.3.3 |
| 18:25 | raek | do you have one as a dev-dependency? do you have one installed as a plugin? |
| 18:25 | Leeni | yes |
| 18:25 | Leeni | both |
| 18:25 | raek | make sure you don't have both |
| 18:26 | raek | if they are different versions, strange things happens |
| 18:26 | Leeni | they are both the same version |
| 18:26 | raek | prefer using it as a plugin |
| 18:27 | Leeni | I downloaded newest version of everything, put clojure 1.3 and swank 1.3.3 in project.clj, ran lein install plugin for swank 1.3.3 |
| 18:27 | Leeni | then lein swank in project folder crashed |
| 18:28 | raek | stacktrace? |
| 18:28 | Leeni | Caused by: java.lang.RuntimeException: Unable to resolve symbol: print-doc in th is context |
| 18:29 | Leeni | then I changed .lein/bin/swank-clojure.bat so it pointed to 1.3 clojure instead 1.2 and nothing changed |
| 18:29 | Leeni | now I changed version used in lein.bat to 1.3 and I get a different error |
| 18:30 | Leeni | Exception in thread "main" java.lang.IllegalStateException: Can't dynamically bi nd non-dynamic var: leiningen.compile/*silently* |
| 18:30 | duck1123 | I don't know what version other people are using, but I've been using 1.4.0-SNAPSHOT with no problems |
| 18:30 | Leeni | so apparently lein swank runs swank with whatever version of clojure it uses for itself |
| 18:30 | Leeni | which was 1.2, now I changed that to 1.3 and now lein doesn't work |
| 18:30 | raek | Leeni: leiningen uses clojure 1.2 for its own process, but that shouldn't interfere with you using clojure 1.3 in your project |
| 18:31 | raek | as I said, lein uses two processes |
| 18:31 | Leeni | well apparently there's no way to tell it to run swank with 1.3 |
| 18:31 | raek | swank runs in your project process |
| 18:31 | duck1123 | and swank should use the project's version |
| 18:31 | raek | which uses the clojure version you choose |
| 18:32 | Leeni | I must be crazy then |
| 18:32 | Leeni | changed lein version back to 1.2 |
| 18:33 | raek | Leeni: if you run "lein repl", you should get a 1.3 repl |
| 18:33 | Leeni | and I get this error when running lein swank |
| 18:33 | Leeni | http://pastebin.com/YTQ8GxsX |
| 18:33 | raek | Leeni: when you get swank to work, it will run in that classpath |
| 18:34 | Leeni | well that's the problem, it clearly doesn't |
| 18:34 | raek | Leeni: maybe clojure 1.3 isn't supported in the stable version of swank-clojure yes. have you tried 1.4.0-SNAPSHOT? |
| 18:34 | raek | *yet |
| 18:35 | raek | after all, clojure 1.3 was released fairly recently |
| 18:36 | duck1123 | raek: I'm pretty sure it worked in swank 1.3.0. The important thing is that he has only 1 version of swank |
| 18:37 | duck1123 | Leeni: delete all your swank plugins, remove it as a dev dependency, delete lib/ and classes, then install 1.4.0-SNAPSHOT as a plugin |
| 18:37 | bdb_ | Is there a naming convention for functions which return a mutated object? "set-foo" just doesn't seem right, since it's not actually changing it's argument… but I guess that would be "set-foo!" right? -- what's the convention? |
| 18:37 | Leeni | duck then how will I run swank with my project in classpath? |
| 18:38 | duck1123 | lein swank, just as normal |
| 18:38 | raek | bdb_: the ! sign is for functions whose side-effects are not safe in transactions |
| 18:38 | bdb_ | fair enough, so here's an example: |
| 18:38 | raek | for example, if you 'swap!' an atom in a transaction, and that transaction is retried, the 'swap!' still happened and is not "rolled back" |
| 18:39 | bdb_ | yup, gotcha |
| 18:39 | bdb_ | let's say I have some immutable hash representing a person |
| 18:39 | raek | Leeni: do you have additional dependencies? sometime a dependency pulls in an old version of swank-clojure... |
| 18:40 | bdb_ | with :first-name and :last-name keys |
| 18:40 | bdb_ | and i want to provide set-name which splits on " " and returns a new person object w/ the first and last names set (yes, i know this is not a real example… you wouldn't every assume people have exactly one space and two names) |
| 18:40 | bdb_ | what do you call that function? |
| 18:40 | bdb_ | set-name ? |
| 18:40 | bdb_ | with-name ? |
| 18:40 | Leeni | raek:seems to be the case |
| 18:41 | bdb_ | name= ? |
| 18:41 | raek | I like with-name |
| 18:42 | bdb_ | so i like that too and with-meta from the std lib seems to say that's a good idea… but i also see the with- prefix for functions which affect lexical bindings, like with-out-str, etc |
| 18:42 | raek | I think that's how Joda-time names their methods |
| 18:42 | raek | yeah, I see the conflict... |
| 18:43 | raek | well, I don't know. names are always hard... |
| 18:43 | Leeni | hm how do I figure out last release on github |
| 18:43 | raek | Leeni: is the dependency incanter? |
| 18:43 | bdb_ | yeah, hence I'm asking for help :-) names are the hardest thing haha |
| 18:44 | amalloy | bdb_: fwiw, with- is mostly for things that affect dynamic scope, not lexical scope. with-out-str is an example of that |
| 18:44 | bdb_ | d'oh yeah, dynamic scope is what i meant |
| 18:44 | raek | Leeni: now you have experience the reason why you should use swank-clojure as a plugin and not as a dev-dep... :-) |
| 18:44 | Leeni | trying to figure out last Enlive version |
| 18:45 | Leeni | well yeah but how do I run it as plugin and will it still let me use my project's classpath |
| 18:45 | duck1123 | Leeni: Network view is always good to see which braches belong where |
| 18:45 | Leeni | I think other dev deps will always pull their versions |
| 18:45 | Leeni | so how to avoid that |
| 18:45 | duck1123 | exclusions |
| 18:46 | duck1123 | you can specify that a dependency should exclude other dependencies |
| 18:46 | raek | Leeni: if you have it as a plugin, it behaves like an invisible :dev-depenencies entry in your project.clj |
| 18:47 | raek | well, in all your project.clj files |
| 18:47 | duck1123 | You can also exclude globally. I recommend that people using 1.3 put a global exclusion on the older contrib libraries |
| 18:47 | raek | duck1123: oh, where do you set that global setting? |
| 18:48 | duck1123 | :exclusions key (ex. https://github.com/duck1123/jiksnu/blob/master/project.clj#L44) |
| 18:49 | FrankL | what's the easiest way to call new clojure code from an existing java project in eclipse? |
| 18:49 | FrankL | i have ccw installed |
| 18:50 | Leeni | thanks |
| 18:50 | Leeni | I got it to run |
| 18:50 | Leeni | successfuly connected from clojurebosx |
| 18:50 | duck1123 | FrankL: If you use :gen-class in the clojure project, you can create a real Class that you can treat just like a Java class |
| 18:51 | FrankL | duck: yup, that's exactly what i want to do |
| 18:51 | Leeni | I'll have to look into exclusions if I wanna get my old projects to run |
| 18:52 | FrankL | but the old project doesn't 'see' the class specified in clojure |
| 18:52 | FrankL | although i added the new project as a requirement |
| 18:53 | duck1123 | I wonder if that has something to do with eclipse. So these are two separate projects? |
| 18:54 | raek | FrankL: https://gist.github.com/1273014 |
| 18:54 | duck1123 | Clojure has to be told to compile those namespaces into classes, I wonder if something about that isn't getting done when eclipse traces the dependencies |
| 18:55 | raek | FrankL: a pretty simple way is to skip gen-class and use clojure.lang.RT to access the clojure stuff |
| 18:55 | raek | might not be the fastest way if you make a lot of java->clojure calls |
| 18:55 | raek | hrm, well, it shouldn't be that slow, actually |
| 18:56 | raek | FrankL: for this to work you need the clojure source and the clojure jars on the classpath |
| 18:56 | FrankL | thanks duck & raek, i'm looking at both options |
| 18:57 | raek | I think the simplest way is to make a new lein project, run lein deps and then add src/ and the jars in lib/* to your eclipse project classpath |
| 18:58 | Leeni | still can't get CCW to connect to repl though |
| 18:58 | Leeni | eclipse just freezes |
| 18:58 | raek | if CCW has some lein integration, disregard my instructions for that part and follow the official docs :) |
| 19:00 | Leeni | when I click Connect to REPL in eclipse should I be connecting to the port "lein repl" gives or the swank server? |
| 19:03 | duck1123 | ccw uses repl, not swank |
| 19:05 | wink | afaik it does not work with "lein repl", it's another repl |
| 19:06 | duck1123 | it works with nrepl |
| 19:13 | FrankL | yay, got it to work |
| 19:13 | FrankL | had to compile the .clj file from the repl myself |
| 19:13 | FrankL | and then i could just use the class methods from a different project |
| 19:13 | FrankL | thanks again duck & raek |
| 19:14 | duck1123 | congrats. Gen-class is good when you don't even want to think about the fact that it's clojure from the java side |
| 19:15 | duck1123 | like when you're implementing some plugin interface |
| 19:15 | FrankL | exactly |
| 19:36 | bdb_ | I'm sure this function is in core, but I can't find it: How do I get some value from a hash, apply a function to it, and return a new hash with that key/value pair replaced? |
| 19:36 | amalloy | &(doc update-in) |
| 19:36 | lazybot | ⇒ "([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created." |
| 19:36 | bdb_ | awesome. thanks! |
| 19:37 | amalloy | bdb_: it probably wouldn't help in this case, but often if there's something you think is in core but don't know what to call it, lazybot can help |
| 19:37 | amalloy | $findfn {:a 1} :b 2 {:a 1 :b 2} |
| 19:37 | lazybot | [clojure.core/assoc] |
| 19:37 | bdb_ | cmd+f in my browser only goes so far :-) |
| 20:05 | duck1123 | there's also clojureatlas.com for when you have an idea what you want, but not what it's called |
| 20:16 | bdb_ | duck: ok that's pretty damn cool :-) |
| 20:17 | amalloy | aw, no "pretty damn cool" for lazybot? |
| 20:17 | gfredericks | duck1123: let's be honest: are those fibonacci numbers? |
| 20:18 | gfredericks | (inc lazybot) |
| 20:18 | lazybot | ⟹ -1 |
| 20:18 | bdb_ | heh, they are both pretty damn cool |
| 20:18 | gfredericks | (inc clojureatlas.com) |
| 20:18 | lazybot | ⟹ 1 |
| 20:18 | duck1123 | gfredericks: yes they are |
| 20:18 | amalloy | hahahaha poor lazybot. gets dec'd when he makes a mistake, and so rarely inc'd |
| 20:18 | amalloy | but you don't mind, do you?? |
| 20:18 | lazybot | amalloy: Uh, no. Why would you even ask? |
| 20:19 | gfredericks | amalloy: it's just too much fun to resist using lazybot to dec lazybot. |
| 20:19 | bdb_ | (inc lazybot) ; just for you amalloy |
| 20:19 | bdb_ | aw, no comment support :-P |
| 20:19 | bdb_ | (inc lazybot) |
| 20:19 | lazybot | ⟹ 0 |
| 20:19 | amalloy | yeah, inc is dumb |
| 20:19 | gfredericks | (dec lazybot) |
| 20:19 | lazybot | ⟹ -1 |
| 20:19 | bdb_ | haha |
| 20:19 | gfredericks | ^ cause of no comment support |
| 20:19 | gfredericks | wanted to put that as a comment, but no... |
| 20:19 | amalloy | nice. fair point |
| 20:20 | gfredericks | (* 3 lazybot) |
| 20:20 | amalloy | i guess it wouldn't be hard to add that, actually, but it hardly seems worth the bother |
| 20:21 | gfredericks | amalloy: I'm on it |
| 20:25 | gfredericks | wtf. I spent 2 minutes agonizing over that regex and github just discarded the change. |
| 20:26 | gfredericks | (dec github.com) |
| 20:26 | lazybot | ⟹ -1 |
| 20:27 | gfredericks | I think github got confused since I had forked sexpbot way back in the day and it's since been renamed and reowned. |
| 20:31 | amalloy | interesting |
| 20:31 | amalloy | we do try to maximize your inconvenience |
| 20:32 | gfredericks | now you know how badly I wanted to create that pull request. |
| 20:33 | amalloy | and instead you created it badly? |
| 20:34 | gfredericks | amalloy: the grammar? |
| 20:34 | gfredericks | or the code? |
| 20:34 | amalloy | no, just that you tried to send it and github failed you |
| 20:35 | gfredericks | oh I think this has been a wordplay. |
| 20:36 | amalloy | (inc gfredericks) ; thanks for pull request |
| 20:36 | lazybot | ⟹ 2 |
| 20:36 | gfredericks | now my evening is complete |
| 20:37 | bdb_ | Sweet! I'm going to give myself credit for supporting the clojure community w/ my awesome inadvertent feature request |
| 20:38 | duck1123 | (inc bdb_) ; you've inadvertently helped us all |
| 20:38 | lazybot | ⟹ 1 |
| 20:38 | gfredericks | amalloy: I thought about converting it to use (read-string) instead of just the regexing |
| 20:39 | gfredericks | in other words I overthought it. |
| 20:39 | amalloy | gfredericks: meh. the goal was for it to be fast, since it's checked every time he sees a message from anyone in any channel |
| 20:40 | gfredericks | ah ha |
| 20:40 | gfredericks | wouldn't want to stress him out |
| 20:40 | amalloy | not that we're short on CPU time on the server, but just as a matter of good practice |
| 20:40 | bdb_ | Oh hey, I've indirectly helped too: I'm brandonbloom -- thanks for pulling my fixes to the links in the lazybot read me |
| 20:40 | gfredericks | of course |
| 20:40 | bdb_ | i mean directly* |
| 20:41 | bdb_ | *sigh* i suck at typing/speaking/etc :-P |
| 20:44 | gfredericks | man now every time I say anything I'm going to imagine poor lazybot churning it through that regex... |
| 20:45 | amalloy | gfredericks: #"^\(" is going to mean he short-circuits pretty fast :P |
| 20:46 | gfredericks | the world is merciful after all |
| 20:46 | gfredericks | (sometimes) |
| 21:17 | duck1123 | Does anyone know which namespace has a *debug* var? this dynamic warning is driving me nuts |
| 21:19 | duck1123 | I really wish the dynamic warnings had shown the fully-qualified vars |
| 21:22 | amalloy | yuck. no qualified name, no filename, no compiler stacktrace? that's tough to fix |
| 21:23 | gfredericks | unzip lib/* and grep? |
| 21:23 | duck1123 | just found it. Yay! one less warning |
| 21:24 | amalloy | gfredericks: well, it could be compiled. you might have to search for _STAR_debug_STAR_ |
| 21:25 | amalloy | duck1123: who was the offender? |
| 21:26 | duck1123 | It was in lamina. I've been maintaining a branch with all the changes to work in 1.3, but I guess I missed one |
| 21:26 | duck1123 | I'm updating all of the dependencies, trying to get rid of the last warnings |
| 21:28 | duck1123 | does anyone know how long it will be before a build of algo.generic is up on the sonatype repo? |
| 21:32 | icefox | Should Clojure documentation end in a period? |
| 21:38 | icefox | Poking around in jira I didn't see anything, does Clojure have something like the Linux Janitor tasks? |
| 22:28 | zakwilson | Congomongo converts string keys to keywords. I do not want this behavior in some cases. Can I turn it off? |
| 22:37 | zakwilson | Never mind. Found it - coerce/*keywordize* |
| 22:43 | amalloy | zakwilson: oh really? i wish i had known that |
| 22:43 | zakwilson | amalloy: well, documentation is a bit lacking, so I had to RTFS. Didn't take too long to find though. |
| 22:44 | zakwilson | It's kind of important too since I'm storing a bunch of maps with string keys and doing compute-intensive things with them. Keyword comparisons are much slower. |
| 22:49 | amalloy | &(let [x (keyword "test") y (keyword "test")] (time (dotimes [_ 1e7] (= x y)))) |
| 22:49 | lazybot | ⇒ "Elapsed time: 63.097127 msecs" nil |
| 22:49 | amalloy | &(let [x (str "te" "st") y (str "te" "st")] (time (dotimes [_ 1e7] (= x y)))) |
| 22:49 | lazybot | ⇒ "Elapsed time: 1080.501377 msecs" nil |
| 22:49 | amalloy | zakwilson: fast comparisons is practically the reason keywords exist |
| 22:51 | zakwilson | amalloy: I don't think I still have my benchmark code around, but keyword lookups in maps were a lot slower under certain circumstances when I tested it last. |
| 22:51 | amalloy | &(let [x "test" y "test"] (time (dotimes [_ 1e7] (= x y)))) |
| 22:51 | lazybot | ⇒ "Elapsed time: 71.512589 msecs" nil |
| 22:52 | amalloy | in this case strings are about the same because they're interned class-constants |
| 22:53 | amalloy | but in general comparing keywords is extremely fast, and comparing strings *might* be extremely fast. if you were seeing bad performance it seems likely you were creating keywords on the fly or something |
| 22:54 | amalloy | (which congomongo does, of course, when it converts strings to keywords) |
| 22:56 | zakwilson | &(time (let [x :foo y (hash-map :foo 4 :bar 8 :qux 2)] (dotimes [_ 1e7] (y x)))) |
| 22:56 | lazybot | ⇒ "Elapsed time: 943.981712 msecs" nil |
| 22:56 | zakwilson | &(time (let [x :foo y (hash-map :foo 4 :bar 8 :qux 2)] (dotimes [_ 1e7] (y x)))) |
| 22:56 | lazybot | ⇒ "Elapsed time: 812.843381 msecs" nil |
| 22:56 | zakwilson | &(time (let [x "foo" y (hash-map "foo" 4 "bar" 8 "qux" 2)] (dotimes [_ 1e7] (y x)))) |
| 22:56 | lazybot | ⇒ "Elapsed time: 442.546335 msecs" nil |
| 22:57 | zakwilson | That code does not, as far as I understand it create keywords on the fly. |
| 22:58 | ibdknox | hm |
| 22:59 | ibdknox | it's nearly 2x on locally for me too |
| 22:59 | ibdknox | -on |
| 22:59 | zakwilson | And it's more on big maps - IIRC something like 5x or 7x. |
| 23:00 | ibdknox | hm |
| 23:01 | amalloy | interesting. i guess i've got some source-reading to do |
| 23:01 | ibdknox | there seems to be a huge difference between using (hashmap...) and just using the literal |
| 23:01 | amalloy | ibdknox: the literal is an array-map |
| 23:01 | ibdknox | ah |
| 23:02 | ibdknox | fwiw |
| 23:02 | ibdknox | in that scenario it's about a 3x diff |
| 23:02 | ibdknox | but the overall number is much lower |
| 23:02 | ibdknox | ,(time (let [x "foo" y {"foo" 4}] (dotimes [_ 1e7] (y x)))) |
| 23:02 | clojurebot | "Elapsed time: 603.974 msecs" |
| 23:02 | ibdknox | ,(time (let [x "foo" y {"foo" 4}] (dotimes [_ 1e7] (y x)))) |
| 23:02 | clojurebot | "Elapsed time: 1031.745 msecs" |
| 23:03 | ibdknox | &(time (let [x "foo" y {"foo" 4}] (dotimes [_ 1e7] (y x)))) |
| 23:03 | lazybot | ⇒ "Elapsed time: 234.443206 msecs" nil |
| 23:03 | ibdknox | there we go |
| 23:04 | zakwilson | Strings are faster than numbers too. |
| 23:04 | zakwilson | &(time (let [x 1 y (hash-map 2 4 1 8 8 2)] (dotimes [_ 1e7] (y x)))) |
| 23:04 | lazybot | ⇒ "Elapsed time: 790.373633 msecs" nil |
| 23:04 | ibdknox | now that doesn't make sense to me at all |
| 23:04 | zakwilson | Nor to me. |
| 23:04 | amalloy | zakwilson: sure, that makes sense |
| 23:04 | ibdknox | lol |
| 23:04 | ibdknox | amalloy: how so? |
| 23:05 | amalloy | because you're comparing interned string literals; they just do a pointer-equality check first, which succeeds |
| 23:05 | hugod | I wonder how long it takes jit to realise that the result of (y x) is not used and turn it into a nop |
| 23:05 | amalloy | numbers have to be checked for type, unboxed, and then compared |
| 23:06 | ibdknox | mm |
| 23:06 | zakwilson | &(time (let [x (int 1) y (hash-map (int 2) (int 4) (int 1) (int 8) (int 8) (int 2))] (dotimes [_ 1e7] (y x)))) |
| 23:06 | lazybot | ⇒ "Elapsed time: 1155.865792 msecs" nil |
| 23:06 | zakwilson | Explain that one? |
| 23:07 | amalloy | you gave the compiler more boxing to do |
| 23:07 | amalloy | you explicitly made x a primitive int, and then to look it up in y you have to box it every time |
| 23:08 | amalloy | &(time (let [x 1 y (hash-map (int 2) (int 4) (int 1) (int 8) (int 8) (int 2))] (dotimes [_ 1e7] (y x)))) |
| 23:08 | lazybot | ⇒ "Elapsed time: 876.695437 msecs" nil |
| 23:08 | zakwilson | Can Clojure maps use a primative as a key? |
| 23:08 | amalloy | the other int calls are immaterial |
| 23:08 | amalloy | no |
| 23:08 | ibdknox | ah, that was the important bit I was missing |
| 23:09 | amalloy | ibdknox: they're Map<Object, Object> and int isn't an Object |
| 23:09 | zakwilson | Right. |
| 23:09 | ibdknox | indeed not |
| 23:09 | ibdknox | wouldn't string always be the fastest possible solution then? |
| 23:10 | amalloy | ibdknox: only if all the strings are known at compile time, or interned later |
| 23:10 | amalloy | which is exactly what keywords do, so i'm sorta puzzled as to why they're not fastest |
| 23:10 | zakwilson | What would cause them to be interned later? |
| 23:12 | amalloy | &(let [x (str "a" "b") y (str "a" "b")] [(identical? x y) (apply identical? (map #(.intern %) [x y]))]) |
| 23:12 | lazybot | java.lang.SecurityException: You tripped the alarm! intern is bad! |
| 23:12 | amalloy | well, i guess that makes sense. but in a repl it works |
| 23:12 | amalloy | that is, returns [true false] |
| 23:12 | amalloy | [false true]. i'm a terrible repl |
| 23:14 | zakwilson | So you'd have to call intern? (read-string (slurp result-of-spitting-a-map-of-strings)) wouldn't do it? |
| 23:16 | amalloy | no |
| 23:16 | amalloy | that is, you would; it wouldn't |
| 23:16 | zakwilson | Strings are still faster than keywords in that scenario. |
| 23:18 | khaliG | hm, trying to get started with clojurescript is dizzying |
| 23:19 | Arafangion | Hmm, clojure depends on libasm-java? |
| 23:19 | Arafangion | What's the libasm for? |
| 23:19 | amalloy | for er. assembling classfiles. the clojure compiler |
| 23:20 | Arafangion | Ah, not asm in the normal sense, then. |
| 23:20 | Arafangion | Hmm, looks like I just installed clojure 1.1, that's a tad out of date. |
| 23:20 | amalloy | i don't understand what "the normal sense" is, if it's not assembling stuff |
| 23:20 | Arafangion | amalloy: Converting assembly to machine code? :) |
| 23:21 | sritchie | has anyone in here generated forms using Enlive? |
| 23:21 | Arafangion | Hmm, yep, 1.1 is very out of date. |
| 23:22 | amalloy | Arafangion: do yourself a favor, don't install any versions of clojure. just install lein and let it get you what you need |
| 23:23 | Arafangion | Hmm, where would lein install it to? /opt/clojure? |
| 23:23 | Arafangion | I just installed 1.1 |
| 23:23 | dnolen | damn Overtone #1 on Hacker News, whodathunk |
| 23:24 | ibdknox | dnolen: Noir was #1 last week, Overtone #1 this week.... :D |
| 23:24 | Arafangion | Clojure 1.1 seems to work very nicely. |
| 23:24 | Arafangion | It manages to print "Hello", at least. :) |
| 23:24 | dnolen | ibdknox: both deserved! |
| 23:24 | ibdknox | Arafangion: that is beyond out of date, don't use it |
| 23:24 | Arafangion | ibdknox: Yeah, I found out after I installed it. |
| 23:25 | Arafangion | Are there newer debian packages, or should I backport it? |
| 23:25 | ibdknox | dnolen: Clojure's getting more and more attention :) |
| 23:25 | amalloy | Arafangion: do not install any versions at all, i'm telling you. clojure doesn't need to be installed |
| 23:26 | amalloy | $google clojure leiningen |
| 23:26 | lazybot | [Building Clojure Projects with Leiningen « I am Zef] http://zef.me/2470/building-clojure-projects-with-leiningen |
| 23:26 | Arafangion | amalloy: You underestimate how easy it is to install with the package manager. |
| 23:26 | zakwilson | I have found cake preferable to leiningen, but they both do about the same thing. |
| 23:27 | zakwilson | Arafangion: the point isn't how easy it is to install. The point is that you're better off using the build tools than installing it. |
| 23:27 | amalloy | Arafangion: you underestimate how irrelevant that is |
| 23:27 | ibdknox | lol |
| 23:27 | Arafangion | amalloy: Yeah, I've just started to realise that clojure is typically used only as part of a regular java build script. |
| 23:27 | amalloy | sudo apt-get install leiningen |
| 23:27 | amalloy | BAM. done |
| 23:27 | Arafangion | amalloy: Even better! |
| 23:28 | Arafangion | Ah, it's not in stable. |
| 23:28 | Arafangion | Well, I'll check out the script. Not interested in using 1.1. |
| 23:28 | Arafangion | One thing I noticed when using 1.1, just now... |
| 23:28 | amalloy | yeah, i'm not sure what versions of debian it's actually released for. my understanding is that phil did get it released for some version somewhere, at least |
| 23:29 | Arafangion | Defining a new function seems to require special syntax, why is the form (defn foo[bar] ...) used, why not: (defn (foo bar) ...) |
| 23:29 | Arafangion | ? |
| 23:29 | amalloy | but downloading a shell script and asking it to install the package itself is not that hard |
| 23:29 | Arafangion | amalloy: Yeah, I'll be doing that. |
| 23:29 | Raynes | That isn't a special syntax. That's consistent throughout Clojure. |
| 23:29 | amalloy | Arafangion: uh, special syntax? |
| 23:29 | Raynes | It's special compared to scheme, maybe. |
| 23:29 | Arafangion | Raynes: Yeah, compared to "other lisps". |
| 23:29 | ibdknox | uh oh |
| 23:30 | zakwilson | Arafangion: the convention in Clojure is that parens are used for things that are evaluated and brackets are used for data. |
| 23:30 | Arafangion | zakwilson: Not a bad convention... But why the m-expr form? |
| 23:30 | zakwilson | So (defn foo [bar] ...), (let [foo bar] ...) |
| 23:30 | zakwilson | Arafangion: it's not m-expr form. It's the same form as Common Lisp (defun foo (bar) ...) |
| 23:30 | mabes | Arafangion: the motivation is that Rich believes that overloading parens for function calls, and parameter lists adds complexity and thinks that complexity is one of the main reasons most people complain about parens in other lisps |
| 23:31 | Arafangion | zakwilson: s-expr form would be (defun (foo bar) ...), right? |
| 23:31 | gregh | don't think of clojure square brackets as m-exprs, since they aren't |
| 23:31 | Arafangion | mabes: Not sure I agree with that... But, making use of square brackets is a nice idea. |
| 23:32 | Arafangion | gregh: I mean, why do we do foo[bar], rather than [foo bar]? |
| 23:32 | zakwilson | Arafangion: both forms are sexps. There's no particular advantage to one form over the other. One is CL-style and the other is Scheme-style. |
| 23:32 | gregh | Arafangion: that's just what defn expects |
| 23:32 | Arafangion | Is there an implied space between ' |
| 23:33 | ibdknox | it's a visual distinction |
| 23:33 | Arafangion | Is there an implied space between 'foo' and '[bar]'? |
| 23:33 | gregh | not sure what that means, since a space there is optional and doesn't affect the meaning |
| 23:33 | ibdknox | hm lol |
| 23:33 | amalloy | Arafangion: no "implied" space is needed - put tokens wherever you want. but usually there is an "actual" space, stylistically, because that's how people write it |
| 23:34 | Arafangion | amalloy: Ah, now the world makes sense again. :) |
| 23:34 | Arafangion | Without the space, it just looked like an m-expr. |
| 23:34 | amalloy | Arafangion: try writing a few lines of clojure before asking why everything is different from...a language you've never actually used? |
| 23:35 | Raynes | There was a stackoverflow thread about this, but damn if I can find it. |
| 23:35 | Arafangion | amalloy: Touche. |
| 23:35 | zakwilson | You could also write (defn foo,[bar] ...) if you wanted. |
| 23:36 | amalloy | (defn, ,foo, ,, ,,,,,[,bar],,, ...) is my preferred style |
| 23:37 | dnolen | ,(,,,,,,,,,,,(fn [a ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, b] (+ a b)) ,,,,,,, 1 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 1) |
| 23:37 | clojurebot | 2 |
| 23:37 | amalloy | hm. i bet i could write a little program to morse-code the commas and spaces in a clojure program |
| 23:37 | amalloy | "take my existing program and rewrite the spacing so that the commas and spaces, in morse code, spell out this shell script" |
| 23:39 | dnolen | Arafangion: reading a lot of Lisp papers w/o using it? that's interesting |
| 23:40 | Arafangion | "Take the existing program and modify it subly so that the commas and spaces are a valid Brain**** program" <-- THAT would make me die inside. |
| 23:42 | Arafangion | dnolen: I had no opportunity to use it, i was struggling enough with crappy C/VB/C#/Java projects in microsoft-shop/uni. |
| 23:42 | Arafangion | dnolen: It's remarkable how lecturers can violate just about every rule and still somehow have a 'working' program. |
| 23:42 | ibdknox | One of my favorite non-functionally-related parts of clojure is that I never have to type commas |
| 23:42 | Arafangion | At work, I use mostly C#, Python, Ruby, and C. |
| 23:43 | Arafangion | And I don't have opportunity to use anything radical there, either. |
| 23:43 | dnolen | Arafangion: gotcha. Well if you're using Ruby/Python, you're not so far from Clojure. |
| 23:43 | duck1123 | ruby was a good gateway to clojure for me |
| 23:44 | dnolen | Clojure is built on the lessons of Ruby/Python/JavaScript. |
| 23:45 | Arafangion | dnolen: Ruby, perhaps, but python? No, I think it's quite different to clojure. |
| 23:45 | dnolen | Arafangion: convenient syntax for data structures |
| 23:45 | zakwilson | I really hate going to other languages where I have to type commas in collection literals. It's a trivial irritation, but I still find it really irritating. |
| 23:45 | ibdknox | zakwilson: me too |
| 23:46 | gregh | especially when you have to omit the last one |
| 23:46 | ibdknox | hah |
| 23:46 | ibdknox | fuck IE |
| 23:46 | ibdknox | that is one of the single most annoying things in all of JS |
| 23:47 | zakwilson | Clojure has list comprehensions. I don't think Ruby does. Python does. |
| 23:47 | ibdknox | You guys might laugh at this, but C# can actually get quite close to Clojure too |
| 23:47 | Arafangion | dnolen: The commas do get in the way. |
| 23:48 | Arafangion | ibdknox: Yeah, how so? (But yeah, C# is a remarkably good language) |
| 23:48 | Arafangion | gregh: What's especially annoying is when a langauge doesn't let you have a trailing comma. Eg, foo = [1, 2, 3,] |
| 23:49 | dnolen | Arafangion: going back a little. I use Scheme/Racket and Clojure. Clojure's take on the number of required parens and syntax around vectors is a real win. |
| 23:49 | ibdknox | Arafangion: depending on which version of C# you're using, with LINQ, var, anonymous functions, and collection initializers you can write very clojure-esque code |
| 23:50 | ibdknox | dnolen: Arafangion: it's a huge win from a cognitive load stand point |
| 23:50 | ibdknox | you can't underestimate the value of conceptual consistency |
| 23:50 | dnolen | ibdknox: I believe that. I think that people focus on Clojure differences, rather than how much it draws in Good Ideas™ from many mainstream languages. |
| 23:50 | Arafangion | ibdknox: Yes - I do use a LOT of C# 4.0 |
| 23:51 | Arafangion | dnolen: Yes, I like the idea of providing convenient data structures via []'s. |
| 23:51 | Arafangion | (Or whatever the syntax is) |
| 23:52 | dnolen | Clojure from one stand point is - Maintstream Good Idea Goldmine™ |
| 23:52 | ibdknox | dnolen: yeah, that makes me sad. I mean even if you just step back and look at it without trying to understand it, it's much easier to section of and group things usefully without even really knowing what it is. |
| 23:52 | ibdknox | off* |
| 23:52 | zakwilson | When will we see atoms and agents in other languages? |
| 23:56 | Arafangion | zakwilson: By what definition? |
| 23:57 | ibdknox | Completely unrelated, but the fact that this can be written in so few lines of code should blow your mind: http://mbostock.github.com/d3/ex/voronoi.html |
| 23:57 | zakwilson | Arafangion: Clojure has constructs called atoms and agents. You can read about them on clojure.org - that explanation will be far better than any I could give. |
| 23:57 | ibdknox | it cheats, but still |
| 23:58 | ibdknox | zakwilson: I thought there was an attempt to do something like the in Scala, but I can't remember what it is called |