#clojure log - Feb 16 2011

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

0:00 ihodes: and you make sure all arithmetic is mod N

0:00 simard: cool

0:01 I might try that tomorrow... after sleeping a lot

0:01 ihodes: haha it's pretty fun in clojure. i'm going to push to github a simple rsa-clj libe soon, i think.

0:02 simard: nice

0:02 fun and efficient ?

0:02 ihodes: yep, else it wouln't work for RSA using large enough primes. you're looking at numbers with 200 digits or more

0:03 thought we'll see if i get to all the necessary speed-ups.

0:03 simard: how do you enforce modulo N for all your arithmetic ?

0:03 manually ?

0:04 amalloy: simard: mod n after every iteration

0:04 simard: right, manually

0:05 brehaut: should be easy enough to define a macro that takes a list of math operators and defs a bunch of inline functions that do that

0:06 amalloy: brehaut: it occurs to me: suppose we had some number of operations we wanted to perform in mod-N arithmetic. this seems like the sort of thing you could do with a monad

0:06 chain together a bunch of operations with a reduce-to-base-N thingy

0:08 brehaut: yeah you could

0:08 but you wouldnt do it that way if you want it fast ;)

0:09 * amalloy is trying to practice spotting places where a monad would be appropriate/helpful

0:12 pdk: (doc println)

0:12 clojurebot: "([& more]); Same as print followed by (newline)"

0:12 pdk: (doc print)

0:12 clojurebot: "([& more]); Prints the object(s) to the output stream that is the current value of *out*. print and println produce output for human consumption."

0:12 pdk: ,(println 1 2 3)

0:12 clojurebot: 1 2 3

0:12 pdk: never knew it padded with spaces before

0:12 amalloy: &(prn 1 2 3)

0:12 sexpbot: ⟹ 1 2 3 nil

0:13 amalloy: &(pr-str 1 2 3)

0:13 sexpbot: ⟹ "1 2 3"

0:13 amalloy: hm. i thought it didn't always

0:16 brehaut: amalloy: (defn mod-n-m [n] (monad [m-result (fn [x] (mod x n)) m-bind (fn [v f] (mod (f v) n))]))

0:16 then you can do (def mod-2-m (mod-n-m 2))

0:17 (domonad mod-2-m [a (m-result 1) b (inc a)] b)

0:17 and it does what you want

0:18 the haskell nerd in me suggests that you would be better off with an applicative functor though

0:18 amalloy: brehaut: mrrrg. bind and result always confuse me. i don't see why you need two mod operators - can't m-result just be identity?

0:18 since bind is doing the mod, that is

0:18 brehaut: amalloy: im not sharp enough on the math to say for sure

0:19 cdddr: Why does ({} key default) work, whereas ([] index default) doesn't? Especially since once can pass a default to nth?

0:20 brehaut: is (mod (some-op? (mod x n)) n) always equivalent to (mod (some-op?) n) ?

0:20 oops

0:20 that last one should be (some-op x)

0:20 ihodes: not always

0:20 brehaut: ihodes: thanks. in that case you cannot get away with m-result being identity

0:21 ihodes: e.g. a mod a / 2 is not the same as a/2 mod a.

0:21 brehaut: m-result has the responsibilty of introducing a value into the monadic context such that any following operation defined in that context will acceptit

0:22 whereas m-bind passes some previous known-safe context into a new function that in tern must return something in that context

0:22 however i have screwed up

0:22 amalloy: ihodes: i don't think that's an example of what he asked

0:23 ihodes: i may have misunderstood his question. i also left of parens in my example

0:24 off* should have been (a mod a)/2 != (a/2 mod a).

0:24 brehaut: corrected monad (defn mod-n-m [n] (monad [m-result (fn [x] (mod x n)) m-bind (fn [v f] (f v))]))

0:24 example of use

0:24 (domonad mod-2-m [a (m-result 2) b ((m-lift 1 inc) a)] b)

0:24 ihodes: but i'm not familiar with category theory, so i'm not following the monad discussion. i'm more of a set and number guy ;)

0:24 amalloy: ah. brehaut, that correction makes me much happier

0:25 brehaut: amalloy: yeah, it also makes the use of the monad basicly pointless ;) you have to m-lift everything

0:25 the only advantage you get is that the base is now determined by the monad, not by the code

0:25 i dunno if you think thats an advantage, i consider it a lot of overhead for not much gain

0:27 amalloy: brehaut: no, not much. but it's really a special case of restricting the operand in some way, by calling (f val) before passing it along

0:27 brehaut: yup for sure

0:34 trying to write the applicative version of this is horrible.

0:35 amalloy: brehaut: i think you can avoid the lifting by causing the monad to operate on functions instead of values, and eventually return a function that does all the operations including mod

0:36 brehaut: amalloy: that would be an approximation of the state monad

0:36 amalloy: i'll take your word for it. it sounds pretty bizarre to me

0:36 brehaut: it gets a bit squiffy without a type system to help keep you sane

0:37 amalloy: *laugh*

0:38 brehaut: heh :)

0:39 we'll its quite important that every function that is bound takes 1 argument from the non-monadic context, and returns one value in the monadic context

0:40 ie the haskell type sig is Monad m => a -> m b

0:40 tomoj: how could cake automatically pull native deps for jiraph?

0:40 does it peek into the jar for project.clj?

0:41 nothing in the pom about jtokyocabinet

0:41 brehaut: in clojure, that constraint isnt enforced, this you could actually bind a function of type a -> b into the monad and it will run, but you could create an error

0:41 * amalloy feels that haskell type signatures are "squiffy"

0:41 tomoj: huh, nothing in jiraph's project.clj either..

0:41 brehaut: amalloy: fair enough :) it still wigs me out that haskell's types are curried

0:42 amalloy: tomoj: transitive dependency?

0:43 brehaut: amalloy: by which i mean if you have a type :: T a b c

0:43 tomoj: amalloy: hmm

0:43 brehaut: which means a type T that is generalised over parametric types a b and c

0:43 brehaut: you can define something as :: T int int

0:43 tomoj: jiraph has that directly in :dependencies

0:44 odd

0:44 brehaut: whic returns a new anonymous type that needs to be parameterised over one more type

0:44 aaand thats enough of that

0:45 * amalloy has fallen asleep

0:45 amalloy: summary: haskell -> confusing

0:45 brehaut: (defn haskell [brain] (squish brain))

0:49 tomoj: do "OOP corresponds to a modeling paradigm" and "prolog corresponds to a modeling: logic" (correspondences being loose of course) make sense?

0:49 if so, what corresponds to clojure?

0:50 amalloy: i think you mean prolog corresponds to a logic paradigm, but it's all rather vague and fluffy

0:51 tomoj: I meant "a modeling paradigm: logic"

0:51 brehaut: im confused

0:54 jimbostrudel: lisp corresponds to algebra. rules and operations for for transformation of data

0:54 feel free to remove one of those "for"s. I don't care which

0:55 amalloy: rules and operations for for transmation of data? jimbostrudel, that makes no sense :)

0:55 jimbostrudel: ;)

0:56 transmation, definitely

0:57 tomoj: certainly the modeling paradigm has got to have a little more to say about what those rules are and operations do?

0:57 of course it does

0:57 algebra has plenty to say

0:59 jimbostrudel: sure. any specific language is going to have a lot of rules and the operations are the functions you define and the standard library

1:00 tomoj: I'm not sure it can be that specific

1:01 nevermind, I see you're right again

1:11 it is bothersome that cake-suitable native dep jars aren't necessarily lein-suitable

1:14 jiraph's cake dev-dep on clojure-protobuf also requires leiners to add clojure-protobuf to :dependencies

1:15 amalloy: tomoj: lein has dev-dependencies, doesn't it?

1:15 tomoj: .. didn't try that

1:16 amalloy: technomancy: come quick, someone is badmouthing leiningen :)

1:17 tomoj: to dev-deps works too

1:17 I don't understand why

1:17 I thought dev-deps were for lein's VM

1:19 I see they're on the classpath though

1:20 amalloy: tomoj: i think they're supposed to be for "stuff you only need when hacking on the project"

1:21 tomoj: sounds about like what I thought

1:21 I wasn't hacking, merely useing jiraph.graph

1:22 so if dev-deps are left out of jars, my project will break?

1:22 (.. are dev-deps left out of jars? I should know that..)

1:23 s/jars/uberjars/

1:24 amalloy: *shrug* i don't deal with this stuff really

1:29 ossareh: tomoj: dev-deps are left out of Jars.

1:29 more specifically uberjars

1:30 tomoj: so I bet I do have to add it to :dependencies

1:31 but not due to cake incompatibility

1:31 ossareh: sorry, I've dropped in midway through this - best I can advise is if you're uberjaring and need a library that isn't defined upstream as a dependency then yes, you need to include it in your dependencies.

5:24 xkb: hi, I want to do something like this: (repeat 10 (rand-int dim))

5:24 only with rand-int each time :)

5:24 how do I do that?

5:25 fliebel: xkb: repeatedly

5:25 xkb: ahh

5:25 that was it

5:38 thanks

5:40 clgv: &(doc repeatedly)

5:40 sexpbot: ⟹ "([f] [n f]); Takes a function of no args, presumably with side effects, and returns an infinite (or length n if supplied) lazy sequence of calls to it"

5:40 clgv: &(doc repeat)

5:40 sexpbot: ⟹ "([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs."

5:41 clgv: &(repeat 10 (rand-int 100))

5:41 sexpbot: ⟹ (86 86 86 86 86 86 86 86 86 86)

5:41 clgv: lol k. I get it ^^

5:42 fliebel: clgv: Did you solve the table problem yet? (or am I confusing people again?)

5:42 \$source range

5:42 sexpbot: range is http://is.gd/OEN10A

5:43 __name__: is there any mvc web framework for clojure?

5:43 fliebel: __name__: You mean actual mvc, or just a good separation of concerns?

5:44 __name__: fliebel: i meant former but latter is fine with me as well

5:44 ejackson: __name__: enlive + compojure

5:45 fliebel: __name__: There is Compojure, which seems to be the most like Django, and there are a couple of others that take the Pyramid approach, eg, throw some libs together yourself and have it work.

5:46 __name__: does clojure webdev expect you to write your templates in lisp rather than embed code in html as others do?

5:47 ah, okay, enlive somewhat injects content into a html file

5:47 fliebel: __name__: Only Hiccup does that. Enlive does not, really. There are a couple of others, that work more like classic PHP-style templating.

5:47 Mustache comes to mind. https://github.com/fhd/clostache

5:48 __name__: thanks

6:23 iwillig: hi guys, i want to extend a Java class to implement clojures Iseq... is proxy the best (or only) thing to use?

6:23 opqdonut: reify is ok too

6:24 iwillig: with reify you can only extend interfaces right?

6:24 opqdonut: oh you want to actually subclass it and not wrap? then proxy yeah

6:25 iwillig: thanks opqdonut

6:26 clgv: fliebel: tableproblem?

6:27 fliebel: clgv: Hmmm, yea, 25 students on tables of 5, lots of valid positions.

6:27 clgv: fliebel: that wasnt me. but I dont remember the name of the guy asking

6:28 * fliebel looks at chat hostory

6:28 fliebel: ah, it was jcromartie

6:29 clgv: I did something on the logic puzzle. but didnt manage to complete it yet

6:30 fliebel: clgv: I've been doing logic programming for the last few days… I'm thinking that should be useful, though there aren't any numbers involved :(

6:31 clgv: fliebel: I did implement the first two criteria. but on the third my table has more columns than the one shown in the solution

6:31 fliebel: clgv: Did you look at the JS source?

6:32 clgv: fliebel: not thouroughly

6:33 khaliG: is everyone using (setq lisp-indent-offset 2) for slime? i just discovered it

6:34 clgv: khaliG: I am not using emacs at all ;)

6:34 khaliG: which are you using?

6:34 clgv: eclipse CCW ;)

6:46 raek: khaliG: what does it do?

6:47 khaliG: raek, as far as i can tell, indents forms in lets/fns better

6:47 so they dont end up all the way across the right of the page

6:48 raek: all I use is clojure-mode-use-backtracking-indent, which makes proxy and defrecord indent properly

6:49 let, fn and defn use 2 spaces of indentation for me...

6:52 ah, you said slime. I was thinking of clojure-mode, clojure source files rather than the repl

6:52 khaliG: yep :)

6:53 it almost does the right thing but not quite, off by one space in the var defns in (let [...] form) but at last form lines up correctly

6:53 s/last/least

6:53 sexpbot: <khaliG> it almost does the right thing but not quite, off by one space in the var defns in (let [...] form) but at least form lines up correctly

6:55 raek: hrm. I recall having read that someone managed to get clojure-mode working in the repl.

7:13 ejackson: raek: My emacsfu is weak, but I just leached this: https://github.com/spicycode/the-greatest-and-best-emacs-configuration-ever-devised-by-man which gives me clojure-mode in the repl etc etc

7:24 thorwil: i really need a way to diagnose why slime likes to hang here. if only it would produce error messages

7:25 raek: thorwil: how did you install slime? from elpa?

7:27 thorwil: raek: no, ubuntu package.

7:27 also cl-swank

7:28 guess i try removing those packages, then

7:29 raek: you could try installing slime from elpa instread. I have no idea if that will change anything, but I think it's more common to use this variant

7:29 cl-swank sounds like swank for Common Lisp...

7:30 thorwil: I would recommend these instructions: https://github.com/technomancy/swank-clojure

7:31 section Connecting with SLIME

7:31 thorwil: yes. i had a brief look into cl after reading land of lisp

7:31 raek: I should really buy that book...

7:33 thorwil: it's quite entertaining and to me rather eye-opening, not knowing much that much about lisp beforehand

7:34 but reading through the examples, i always had the impression that CL is a bit much on grown side

7:55 iwillig: do methods on a proxy take "this" as an argument ?

7:57 khaliG: they can, if that's what you're asking

7:58 iwillig: "Each method fn takes an additional implicit first arg, which is bound to 'this."

7:58 mmm

7:58 k

7:59 i don't understand... i am getting an invalid argument error.... but its not clear to me why

8:02 raek: iwillig: iirc, you don't write the 'this' parameter in the parameter list explicitly. 'this' will automatically be bound to the instance

8:03 iwillig: yeah thats what the docs say thanks

8:03 okay really dumb question... with proxy are you allow to add new methods to your object ? or just override existing methods ?

8:06 raek: I suspect the latter, but I'm not sure

8:08 proxy is a java interop feature, and for java code to use a method of a class, it has to know about that class at compile time

8:08 khaliG: you can add a new method if its part of an additional interface

8:08 at least that's how i've been doing it but i should probably check out protocols

8:09 raek: so it doesn't seem like it would be easy to call such a method, if you coould define it

8:09 if you don't use this for java interop, then you should use protocols

8:11 iwillig: okay thanks guys

8:13 raek: regardless whether you use proxy or reify, you can extract code that methods have in common to an ordinary clojure function (if that was the concern)

8:21 khaliG: it's scary that i've almost got a working program in less than 350 lines of clojure...

8:23 ejackson: khaliG: keep coding and it'll get smaller, and smaller. I'm always afraid of working on any piece of clojure too long in case I create a singularity.

8:23 khaliG: haha i have that feeling ejackson :)

9:01 abedra: technomancy, should lein uberjar swallow compilation errors?

9:06 rhebus: hello

9:07 I'm trying to get started with clojure and Midje.sweet

9:07 but I really don't understand things

9:08 I've got as far as a system where I can do (require 'midje.sweet) and (midje.sweet/fact (+ 1 1) => 2) but if I try (:use midje.sweet) I get a ClassNotFoundException

9:08 I have clojure, clojure-contrib, midje and unifycle jars in ~/.clojure

9:08 and \$HOME/.clojure/* on the classpath in my clj bash script

9:08 why am I getting a ClassNotFoundException when I try (:use midje.sweet)?

9:10 http://pastebin.com/7L6iDd6t shows my clojure session

9:10 fliebel: rhebus: Have you tried cake or lein? Manually managing the classpath is not ideal.

9:10 clgv: try (use midje.sweet) instead

9:11 the keyword syntax is only used within an ns-statement

9:11 rhebus: (use midje.sweet) gives the same error

9:11 fliebel: maybe i should try that

9:11 clgv: oh sorry forgot one thing

9:11 fliebel: clgv: Your code needs a quote. (use 'midje.sweet)

9:11 clgv: now its correct (use 'midje.sweet)

9:11 rhebus: wooo that works perfectly thanks

9:12 ok so let me get this straight

9:12 clgv: probably you should get one of those introductory books for clojure ;)

9:12 rhebus: when do I use (:use foo.bar) and when (use 'foo.bar)?

9:13 if those books tell you how to set up your system

9:13 clgv: first one within an ns-statement. last one if you type it on repl

9:13 rhebus: and those are the only use cases?

9:13 that I am likely to come across in my first month of clojure, that is...

9:14 clgv: well you could use the last one on every position where you can write statements, but that would be bad style in general I guess

9:14 rhebus: ok

9:14 clgv: try using it within an ns-statement when you code files

9:17 rhebus: I started with one of the books and that speeded up learning a lot ;)

9:17 rhebus: i'll be ok once I'm bootstrapped

9:17 clgv: just an advice ;)

9:18 rhebus: getting a usable environment is a necessary requirement

9:18 i do have a pragprog clojure book but it's in the office

9:18 clgv: ahkk

9:18 cdddr: clgv: Are any of them good for people who know their share of FP, but are just new to Clojure?

9:19 clgv: cdddr: humm I guess so. "Programming Clojure" was my start

9:20 cdddr: I dont think it is explaining too much general theory on FP.

9:20 cdddr: Ooh, somewhat affiliated with the Pragmatic guys. Works for me.

9:21 And they ship PDFs, too. Excellent.

9:21 fliebel: I thin the world could use a "7 functional languages in 7 weeks/hours/years"

9:22 clgv: I didnt have to buy it since our department already owned a hardcopy :)

9:22 cdddr: If it's years, I'd be inclined to +1.

9:22 I've come to hate those "24h" bullshit books.

9:22 clgv: Hahaha, that's always preferable. :>

9:23 clgv: yes indeed :)

9:23 uhh now I have a serious performance issue

9:23 cdddr: Kept a head to something obnoxiously huge? ;)

9:25 clgv: I am using filter like follows: (filter #(criterion? param1 param2 % param4 param 5) (filter #(contains? unused-set (:bla %)) coll))

9:27 and it tells me that it needs 6s in total (~30.000 calls to that function) but the criterion? only takes 1s in total

9:27 does filter has this big perfomance overhead internally?

9:27 or what might be the problem?

9:27 cdddr: Shouldn't. You could combine the two tests, though.

9:28 clgv: the criterion? test is more expansive

9:28 s/expansive/expensive

9:28 sexpbot: <clgv> the criterion? test is more expensive

9:29 cdddr: clgv: I meant using comp to combine them, but erh, yeah, I see.

9:30 clgv: cdddr: maybe an and-statement would be shorter if it already returns false after first parameter evaluation

9:30 but why is there a gab of almost 5s?

9:30 *gap

9:31 I have a doall statement around it to be able to measure the time

9:32 cdddr: Wait, well if 1s is spent in the oter filter, then logicall the other 5s is spent in the inner one, no?

9:32 arturop: hello, I'm a newbie looking for a bit of help

9:32 clgv: the inner one is a simple contains? on a set

9:33 the set contains at most 150 elements

9:33 cdddr: Uh, wait, I need to indent. :>

9:33 clgv: the collection also contains at most 150 elements

9:34 just doing a lein compile to look at the java classes

9:34 cdddr: clgv: Humor me here, try to measure just the inner filter.

9:34 arturop: I'm trying to install the clojure koans but can't figure out how to do it

9:34 cdddr: Because ~5s for filter overhead definitely sounds wrong.

9:35 clgv: cdddr: ok I'll do

9:35 yes I definitely think the is something wrong

9:35 with my code - not clojure ;)

9:37 cdddr: Heheheh, blaming the language is *almost* never right. :)

9:37 I did find a gcc bug once, though. :D

9:37 clgv: especially if you just got started some months ago ;)

9:37 rhebus: fliebel: ooh, playing with lein and it's very nice indeed

9:37 clgv: I did find several borland c++ 4.0 compiler bugs ;)

9:38 cdddr: C++ is almost cheating. ;)

9:39 clgv: cdddr: inner filter criterion takes around 6ms in total

9:39 clgv: so there is something wrong with my expression in terms of performance

9:43 cdddr: clgv: Could try with that and, it does short-circuit on false.

9:44 clgv: cdddr: humm ok I did an error when measuring time. it takes indeed 2s

9:44 so 1s+2s = 6s? :(

9:46 cdddr: Well, if the functions are crazy fast, half overhead isn't all that unrealistic.

9:47 So anding them together might work out better.

9:47 clgv: I'll try now^^

9:50 cdddr: And in other news, I was kind of braindead, trying to look for a first value in coll for which fn returns something non-false.

9:50 clgv: does the definition via #(dosomething %) maybe cause performance overhead?

9:50 cdddr: clgv: It shoudn't, it's only defined once.

9:51 What I tried - some ungodly mess of drop-while, complement and some stuff I'd rather not remember.

9:51 clgv: is it really? even if it's a closure?

9:53 cdddr: clgv: I'm inclined to do some hand-waving and argumentum and JITium when all else fails, but, well, you could just try and see. ;)

9:53 What I should have done - (first (filter identity (map f coll))).

9:55 clgv: that looks odd - why filter identity? what about "some"?

9:55 * cdddr tries really hard to rememer clojure is lazy

9:55 Chousuke: clojure is not lazy, sequences are lazy :)

9:55 cdddr: clgv: Yeah, that's even better.

9:56 clgv: If it wasn't clear, I'm only doing this for like two days. ;)

9:56 clgv: kk

9:56 cdddr: clgv: but... but... I feel cheated!

9:57 I do remember doing ctrl+f "first" on that page. :(

9:57 I blame my broswer. ;)

9:59 Chousuke: Ah, right. :>

10:30 clgv: ok, the #(criterion? %) approach for filter is ok

10:30 changing that to a defn and a partial only makes it worse

10:52 TimMc: I'm looking for a macro that is like `and` but returns the last true value it received.

10:52 fliebel: &(and 1 2 3)

10:52 sexpbot: ⟹ 3

10:52 TimMc: &(and 1 2 3 false)

10:52 sexpbot: ⟹ false

10:52 TimMc: ^ doesn't return 3

10:53 fliebel: ah, like that.

10:54 TimMc: I'm trying to write a macro, but I'm still new to this.

10:54 fliebel: &(last (take-while identity [1 2 3 false]))

10:54 sexpbot: ⟹ 3

10:54 fliebel: TimMc: No need to use macroes for everything.

10:55 TimMc: fliebel: I want to delay evaluation of the arguments.

10:55 fliebel: &(source and)

10:55 sexpbot: java.lang.Exception: Unable to resolve symbol: source in this context

10:56 TimMc: I should explain my intent -- I have a GUI program with a number of updater functions. There's a cascade of state changes, and I want to avoid recomputing all the dependent state info if the source state info hasn't changed.

10:56 edoloughlin: TimMc: How do you know what your last true value is if you're not evaluating?

10:56 TimMc: edoloughlin: Evaluate each item as I come to it, and then decide whether to keep evaluating or not.

10:57 clgv: how about ##(some identity (reverse [1 2 3 false]))

10:57 sexpbot: ⟹ 3

10:57 clgv: &(doc reverse)

10:57 sexpbot: ⟹ "([coll]); Returns a seq of the items in coll in reverse order. Not lazy."

10:57 clgv: oh its not lazy...

10:58 could have been on an array but not on a seq.. ;)

10:58 TimMc: Lazy isn't what I need -- all the "arguments" will be function calls.

10:58 (changes (update-foo!) (update-bar!) (update-qux!))

10:59 Huh. I suppose if none of my updaters take arguments, I can just pass the functions in...

10:59 fliebel: So you want to keep updating untill you get false?

10:59 TimMc: Yeah, and then return true if any of them did.

10:59 (changes update-foo! update-bar! update-qux!) <- Look ma, no macros!

11:00 fliebel: &(last (take-while #(%) [+ * :a]))

11:00 sexpbot: java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :a

11:00 TimMc: I won't even need an accumulator -- no need for tail recursion here.

11:00 (I won't be using long lists of functions.)

11:09 fliebel: This works: https://gist.github.com/829621

11:14 clgv: TimMc: you might get problems with your recursion if you have a bigger number of elements in that list. and you are returning the result of the first call and not the last one

11:19 abedra: and you are returning the result of the first call and not the last one

11:19 and you are returning the result of the first call and not the last one

11:19 and you are returning the result of the first call and not the last one

11:22 clgv: there seems to be an echo ;)

11:30 TimMc: clgv: This is for hardcoded lists, not lists that are passed in.

11:30 I could add an accumulator helper if it became a problem.

11:32 clgv: ok. but you are returning the wrong result

11:39 TimMc: clgv: Wrong result? I did switch to returning the value instead of literally true or false.

11:39 Oh, I see -- yes.

11:40 I'll return (if fv true false) instead.

11:43 cdddr: Is there any (de-facto?) standard for naming functions in Clojure?

11:52 fliebel: cdddr: lower-case-hymphenized seems to be the norm.

11:53 cdddr: Unless you wanted to know about earmuffs and star functions.

11:55 rhebus: question marks on predicates seem to be the done thing too

11:56 cdddr: So all in all, rather lax? :)

11:56 rhebus: don't ask me, i'm new here :

11:56 :)

11:56 fliebel: cdddr: Oh, yea, question marks for predicates.

11:57 cdddr: rhebus: That makes the two of us. :)

11:57 rhebus: does anyone use midje? I'm having trouble using (unfinished) on a function which I want to use in a src file and (provided) results in a test file

11:58 if I put (unfinished foo) in the test file, the src file complains that foo isn't defined

11:58 i can provide an example if this isn't clear

12:01 bortreb: normally you just have a function called "thing" instead of "get-thing"

12:03 cdddr: So if I have a function that goobles a coll of widgets and produces a whatchamacallit, I'd probably just call it whatchamacallit? ;)

12:06 rhebus: ah, i found my midje problem; you have to remove the (unfinished foo) when you start doing (provided (foo x) => bar)

12:19 &(* 1 (repeat 5 2))

12:19 sexpbot: java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.Number

12:19 rhebus: what am I doing wrong? how do i "flatten" the list to allow * to see the elements of the repeat?

12:19 &(* (repeat 5 2))

12:19 sexpbot: java.lang.ClassCastException: Cannot cast clojure.lang.LazySeq to java.lang.Number

12:20 rhebus: hmm, I should apply reduce shouldn't i

12:20 amalloy: rhebus: or just apply *

12:20 rhebus: &(reduce * (repeat 5 2)

12:20 sexpbot: java.lang.Exception: EOF while reading

12:20 amalloy: &(apply * (repeat 5 2))

12:20 sexpbot: ⟹ 32

12:20 rhebus: &(reduce * (repeat 5 2))

12:20 sexpbot: ⟹ 32

12:20 * rhebus heads to the docs

12:21 amalloy: rhebus: mine is "like" (* 2 2 2 2 2), yours is ##(reduce list '* (repeat 5 2))

12:21 sexpbot: ⟹ (((((* 2) 2) 2) 2) 2)

12:21 rhebus: what about with the extra element? ##(apply (cons 1 (repeat 5 2)))

12:21 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core\$apply

12:21 rhebus: &(apply * (cons 1 (repeat 5 2)))

12:21 sexpbot: ⟹ 32

12:22 amalloy: &(reduce (partial list '*) (repeat 5 2))

12:22 sexpbot: ⟹ (* (* (* (* 2 2) 2) 2) 2)

12:22 arturop: hello

12:22 I'm having classpath problems

12:22 amalloy: arturop: are you using lein or cake? if not, i suggest you do so

12:22 arturop: I am using lein

12:23 I am trying to run the clojure koans project

12:23 and I'm using eclipse and ccw

12:23 I've been all day with it but it's beating me

12:23 khaliG: is there a stylistic guide to writing clojure code?

12:24 arturop: in the eclipse project it seems to be right the folder is there

12:24 rhebus: which is less ugly, ##(apply * (cons 1 (repeat 5 2))) or #(* 1 (apply * (repeat 5 2))) ?

12:24 sexpbot: ⟹ 32

12:24 arturop: but nothing

12:25 rhebus: &(apply * 1 (repeat 5 2))

12:25 sexpbot: ⟹ 32

12:25 rhebus: huh, that's the best way then :)

12:26 arturop: any ideas before I jump off a bridge

12:27 amalloy: cdddr: (filter identity (map f coll)) is (keep f coll)

12:30 well. except that keep will include false elements, removing only nil

12:30 cdddr: amalloy: Yeah, I suck and I really wanted (some f coll).

12:31 technomancy: khaliG: there are coding guidelines on the assembla wiki

12:32 khaliG: the library coding standards page?

12:33 ok just scanned through that and it didnt answer my question

12:33 i'm wondering whether it's good practice to use the doto form even just for one thing?

12:33 amalloy: khaliG: sure

12:34 khaliG: amalloy, to make it clear to the reader that you're doing some sort of mutation?

12:35 amalloy: that's one reason. the alternative, (let [x (f)] (hack-up x) x)), is rather more verbose and less clear

12:36 technically, the fact that there are two exprs inside a let implies side effects, but doto is more explicit

12:36 (and means you don't have to type "x" three times :P)

12:37 arturop: even if no one can help me

12:37 can anyone suggest any investigation route

12:37 cdddr: amalloy: Wouldn't one normally want to bind x in the [] section every time? I know I do.

12:38 khaliG: hm amalloy well what if you dont even care about x after evaluation?

12:39 eg, (.setText month-label (get-month month)) vs (doto month-label (.setText (get-month month))

12:39 amalloy: cdddr: (defn make-me-a-window [name] (doto (JFrame.) (.setTitle name)))

12:39 khaliG: ah. in that case...probably not

12:39 khaliG: amalloy, i'm easy either way, just trying to learn best practice

12:39 cdddr: amalloy: Yeah, but I meant the hack-up alternative with let.

12:40 ogonzalez: arturop, is your problem with ccw only? you should be able to run the clojure koans without it

12:40 amalloy: cdddr: you were saying that you always want to bind x, and i demonstrated that you don't. i guess i don't understand what you're getting at

12:40 arturop: I've tried from the command line

12:40 and I get something else

12:41 Exception in thread "main" java.lang.NoClassDefFoundError: and

12:41 ...

12:41 Could not find the main class: and. Program will exit.

12:42 cdddr: amalloy: What I meant was that if I wanted to hack up x with let, I'd do it in the [] section both times.

12:42 amalloy: cdddr: you mean like (let [x (f), x (hack-up x)] ...)?

12:43 cdddr: Yup.

12:43 ogonzalez: arturop, does it fail without having modified any koan?

12:43 cdddr: Seems more explicit.

12:43 amalloy: cdddr: but it's wrong

12:43 (.setTitle x "hello") doesn't return x, it returns void. that's why the doto macro is so useful

12:44 cdddr: Ahh, I see. Thanks.

12:45 amalloy: &(let [x (java.util.ArrayList.) x (.add x 10)] x)

12:45 sexpbot: ⟹ true

12:45 amalloy: &(let [x (java.util.ArrayList.) _ (.add x 10)] x)

12:45 sexpbot: ⟹ #<ArrayList [10]>

12:45 amalloy: &(doto (java.util.ArrayList.) (.add 10))

12:45 sexpbot: java.lang.IllegalArgumentException: Malformed member expression

12:45 amalloy: whoa what?

12:46 arturop: ogonzalez: yes

12:46 I haven't been able to run it even once

12:48 ogonzalez: arturop, are these ones http://github.com/relevance/functional-koans.git? They work fine for me; just script/run and first error appears

12:49 arturop: well

12:49 breakthrough

12:49 I did this

12:49 and now it works...

12:50 and to be precise it's https://github.com/functional-koans/clojure-koans.git

12:50 in any case

12:51 thx a lot indeed

12:54 x6763: hi everyone. I'm considering using Clojure for developing on the Android platform. Anyone know of any issues I should be aware of?

12:55 lucian: x6763: clojure's bootstrap is very gc-intensive, but android's gc is optimised for very low memory usage and memory sharing, not high peformance

12:56 technomancy: x6763: it's got a pretty lousy boot time and bloats up the application size by many mega-bytes.

12:56 lucian: the net result is that clojure takes a very, very long time to start up on andrid

12:58 x6763: ah, i see...that probably won't be very acceptable for a lot of our users

12:58 thanks lucian and technomancy

13:06 khaliG: lucian_, are those obstacles solvable or it's likely to persist?

13:10 dnolen: khaliG: the obstacle is solvable with faster mobile hardware, at the rate things are moving this won't much of a wait.

13:11 khaliG: thats good to hear dnolen

13:12 i'm actually looking forward to running my clojure app on different machiens to see how it performs, i have a netbook and access to an ipad

13:16 fliebel: hey dnolen :)

13:17 I came across cond-i, and noticed there is none in Logos. Why?

13:18 dnolen: fliebel: cond-i is interleaves goals, in the latest version of miniKanren that is the default.

13:19 fliebel: cond-e *is* cond-i

13:20 fliebel: dnolen: That is cool… I guess, but also somewhat confusing :)

13:22 dnolen: fliebel: cond-e in TRS preserves Prolog depth-first search. They introduce cond-i to show the benefits of interleaving search. Later they decided they preferred interleaving search and made it the default, which simplifies the implementation (since they only support one kind of search instead of two).

13:22 fliebel: Ah, I see

13:23 dnolen: Meanwhile I'm still thinking about the finite domain thing. It would be nice to be able to do (run* [q] (add-o 2 q 5)) => 3

13:26 dnolen: fliebel: I'm not even sure it's possible to do that efficiently. TRS shows you how to build relational arithmetic operators. Beautiful code, but too slow to be even remotely useful.

13:27 fliebel: Whoa, it's actually in the book? nice :) Why is it so slow?

13:28 dnolen: fliebel: it uses a binary numerical representation and relational operators based on hardware adders.

13:31 fliebel: dnolen: I will get there, I hope :) I was thinking you could limit the possibilities a lot with a range-like cond-e. (cond-r start end step number)

13:32 jweiss: looking for a little advice - trying to put together a tree datastructure, each node contains a keyword for a particular page in the web app i'm testing, and a function that will navigate there. and then a list of "child" pages that you can navigate to from that page. i want to be able to walk the tree, and 'comp' all those functions together to navigate from root to leaf.

13:33 not sure if each node should be a map and have a :children key with a list in it, or what

13:34 dnolen: fliebel: you probably could I haven't thought about it enough, Art of the Propagator and Chapter 9 and 12 of this http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.102.7366&rep=rep1&type=pdf, get into that.

13:35 fliebel: dnolen: I'll add it to the list. TRS is first :)

13:36 #### < marker for my chat history ;)

13:49 amalloy: jweiss: maybe ##(doc tree-seq)?

13:49 sexpbot: ⟹ "([branch? children root]); Returns a lazy sequence of the nodes in a tree, via a depth-first walk. branch? must be a fn of one arg that returns true if passed a node that can have children (but may not). children must be a fn of one arg that returns a sequence of th... http://gist.github.com/829892

13:49 jweiss: amalloy: will take a look, thanks

13:52 lucian_: khaliG: i doubt android's gc will get much faster any time soon, really

13:53 lucian: khaliG: clojure's bootstrap could be improved, however

13:53 and there isn't really any chance of getting it on an ipad

13:55 cinch: jweiss: for walking a tree, clojure.zip is great. i have a similar web app with a tree structure for pages and folders, the code is here: https://github.com/cinch/sicnarf-blog

14:07 odyssomay: Hi, how can I call the superclass of a gen-class?

14:15 rmarianski: odyssomay: i think you can use exposes-methods to do that

14:20 odyssomay: rmarianski, thx, got it

14:20 jweiss: is it possible to retrieve the names of the arguments that an anonymous fn takes?

14:20 say if i want to automatically roll a series of functions up into one

14:22 eg, i have 3 functions f1, f2, f3 that take [x] [] and [y z], and i want to create one function (fn [x y z] (f1 x) (f2) (f3 y z))

14:24 rmarianski: i'm not sure if you can do that generally

14:24 jweiss: i suppose i could add meta to them

14:25 but that seems redundant

14:26 amalloy: jweiss: this sounds like a bad idea. for example, a function can take more than one set of args, even an anonymous function

14:26 if you really want to, then adding :how-to-roll-me-up meta seems like the way to go

14:27 jweiss: amalloy: that's true - i suppose i could have callers pass a map to the rolled-up fn and each piece could pull its args from the map

14:28 no way to tell in advance whether the caller supplied all the necessary args though, for that i guess i'd need meta.

14:28 amalloy: jweiss: consider also (fn [[x y] count])

14:29 in general if you want to mess with "names" you're in for a world of pain; dealing with "number of args" is somewhat less awful

16:31 octe: is there a way to define a java-compatible interface in clojure, that extends an existing java interface?

16:31 brehaut: (doc definterface)

16:31 clojurebot: "([name & sigs]); "

16:31 fliebel: octe: deftype, and all the others are java compatible, as far as I know.

16:31 octe: brehaut, yeah, i found that, seems very undocumented.. doesn't seem you can extend an existing interface with it

16:31 brehaut: thats a remarkably empty doc

16:32 fliebel: brehaut: It;s used by defprotcol, which generates both a protocol and an interface.

16:32 brehaut: fliebel: ah right cheers

16:33 fliebel: "defprotocol will automatically generate a corresponding interface" ##(doc defprotocol)

16:33 sexpbot: ⟹ "Macro ([name & opts+sigs]); A protocol is a named set of named methods and their signatures: (defprotocol AProtocolName ;optional doc string \"A doc string for AProtocol abstraction\" ;method signatures (bar [this a b] \"bar docs\") (baz [this a] [this a b] [this a ... http://gist.github.com/830255

16:34 octe: still doesn't extend and existing interface?

16:34 fliebel: octe: it does, you can extend protocols and interfaces.

16:36 raek: but a protocol interface cannot extend another interface in the ordinary java sense, right?

16:37 I mean, you can create a protocol implementation for objects that implement a certain interface, but that's outside the jvm type system

16:37 fliebel: raek: rly? Well, I trust you on that.

16:37 raek: octe: also, why do you need it?

16:38 fliebel: raek: Oh yea, you're right.

16:39 raek: since the extention would be performed after the interface was defined, that would imply that you could change a detail of a type

16:39 octe: raek, playing around with jna

16:50 raek: octe: you should be able to generate an interface that extends another with gen-interface, but that requires compilation

16:51 mattrepl: whatever happened to streams?

17:10 jweiss: i'm a little stumped here. i have a macro that outputs ~(map keyword args) but in the output the args aren't turned into keywords at all, they're still symbols. change it to a (for [arg args] (keyword arg)) somehow fixes it.

17:11 raek: jweiss: paste?

17:12 that sounds weird

17:12 jweiss: raek: https://gist.github.com/830354

17:12 that's the for version

17:12 (see line 5)

17:15 raek: erm, now changing it back to map, seems to still work. i... don't get it

17:16 oh wait, no didn't work

17:16 raek: jweiss: you also have to reevaluate any code that uses the macro

17:16 jweiss: raek: it's really just a data structure that uses the macro

17:17 raek: what would a typical call look like?

17:17 jweiss: raek - (page :mypage (fn [arg] (browser click arg)))

17:18 raek - edited the gist to the version that doesn't work

17:18 markskilbeck: Morning, all.

17:18 jweiss: expands to {:req-args [arg], :page :mypage, :fn (fn [arg] (browser click arg))}

17:18 why isn't it :req-args [:arg] ?

17:19 raek: jweiss: you are using the name map in your let

17:19 jweiss: doohhhhhh

17:19 markskilbeck: Say I have a vector of vectors (the vector type isn't important, I guess) and each element is something like: [1 2]. How do I map a function to the second element of each vector?

17:19 octe: is there a way to cast/coerce an int into a byte i clojure? (cast Byte 0xFF) throws a class cast exception.

17:20 markskilbeck: Oh, I guess I'd use an anonymous function for map.

17:20 raek: and you don't have to syntaxquote hashmaps

17:20 ,(let [x 1] [`{:foo ~x} {:foo x}])

17:20 clojurebot: [{:foo 1} {:foo 1}]

17:20 jweiss: thanks raek, i probably would have caught that map thing if it hadn't broken in such a small way

17:20 * jweiss should have tried a list of more than 1 arg

17:22 jweiss: much appreciated raek, looks better without the extra quoting and unquoting, and map actually works.

17:23 raek: markskilbeck: anonymous function + map => for

17:23 usually indents prettier too

17:23 markskilbeck: Ah. Thanks raek

17:24 ndimiduk: is there an example of using ring's warp-cookies middleware in an application someplace handy?

17:25 raek: markskilbeck: update-in can be used if you only want to update one element

17:41 jweiss: if i have a macro and i call it with arguments that contain another call to the same macro, is there any guarantee that the argument will be expanded first?

17:41 amalloy: jweiss: it is guaranteed not to happen, if i understand what you're saying

17:42 jweiss: amalloy: ok then, will it happen *after* my top-level expansion?

17:43 amalloy: that is, (mymac (mymac 10)) will be called first with argument '(mymac 10), and then whatever that results in (which may or may not include (mymac 10)) will be expanded

17:43 shachaf: jweiss: A macro gets its arguments completely unexpanded, no?

17:43 jweiss: Then whatever it returns is evaluated.

17:43 jweiss: shachaf: i guess that makes sense, so i guess my macro has to treat it's self-call as "pre-expanded"

17:44 amalloy: markskilbeck: ##(for [[a b] (partition 2 (range 10))] [a (inc b)])?

17:44 sexpbot: ⟹ ([0 2] [2 4] [4 6] [6 8] [8 10])

17:45 markskilbeck: Cool amalloy :)

17:47 amalloy: alternatively, ##(for [pair (partition 2 range)] (update-in pair [1] inc))

17:47 sexpbot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core\$range

17:47 amalloy: except that partition is giving seqs, not vecs :P

17:47 &(for [pair (partition 2 range)] (update-in (vec pair) [1] inc))

17:47 sexpbot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core\$range

17:48 amalloy: oh. haha whoops. anyway you get the idea, i hope

18:09 TimMc: Any idea why I'd suddenly start getting a NoSuchMethodError when calling a record's constructor that was working when I last checked it into source control?

18:09 Exception in thread "AWT-EventQueue-0" java.lang.NoSuchMethodError: timmcHW3.core.GUI.<init>(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V at timmcHW3.core\$init_gui\$fn__43.invoke(core.clj:35)

18:10 This is from calling (GUI. nil nil nil nil nil nil nil)

18:17 GRah, nasty evil transient errors...

18:49 bmh: Can incanter find inverse matrices?

18:50 simard: what's the most efficient way to test if a number is a palindrome ? I thought about using Integer/toString, then .split, and then (nth) and then =

18:50 bmh: simard: In what base?

18:50 simard: b

18:50 well.. 10

18:50 ;)

18:50 but I know Integer/ supports converting to a string of base b if required

18:51 amalloy: TimMc: are you AOT compiling? sounds like a class file versioning issue

18:51 simard: i have a tiny little github repo that converts a number into and out of base N

18:52 giving you a seq of its digits

18:52 it's pretty trivial, but http://github.com/amalloy/bit-packer

18:52 simard: well I'm here to learn you know, so trivial will do

18:52 thanks

18:55 bmh: ah-ha. Incanter can find matrix inverses, it's just called "solve"

19:10 amalloy: simard: so palindrome-checking in base 10 probably looks like (apply = ((juxt identity reverse) (pack x 10)))

19:40 TimMc: amalloy: A lein clean did the trick.

19:40 amalloy: so that's a yes, re aot?

19:41 TimMc: Well, I had been using lein run exclusively.

19:41 So, I suppose no AOT.

19:42 amalloy: hm. i don't really know how lein run works

19:42 TimMc: Interestingly, lein uberjar may be what actually cleared up the issue... weird.

19:42 No wait, I had been doing some lein compile.

19:42 So yes, probably a class versioning issue.

19:43 technomancy: if you have :main set, it will assume you need AOT and will compile for you automatically.

19:44 of course, if the .clj has a newer mod time than the .class file, it should force a recompile

19:49 TimMc: technomancy: Aha! I did a git reset --hard HEAD^ to try something out -- must have rolled back the .clj file mtime as well.

20:11 amalloy: does the compiler do any clever caching of constant values for me? eg, if i write ((juxt identity reverse) my-seq) inside a function, does it rewrite that to (let [fn1 (juxt identity reverse)] (fn [my-seq] (fn1 my-seq))), or reconstruct the juxt function every time i call my function?

20:11 also, simard, ##(doc floor)

20:11 sexpbot: java.lang.Exception: Unable to resolve var: floor in this context

20:11 amalloy: hm

20:17 TimMc: floor?

20:17 Isn't that a Math/ function?

20:18 amalloy: TimMc: Math works exclusively with doubles, and gives doubles back

20:18 clojure.contrib.math has a version that gives you sensible types

20:18 TimMc: nice

20:18 amalloy: &(Math/floor (/ 5 2))

20:18 sexpbot: ⟹ 2.0

20:19 amalloy: &(do (use 'clojure.contrib.math) (floor (/ 5 2)))

20:19 sexpbot: java.io.FileNotFoundException: Could not locate clojure/contrib/math__init.class or clojure/contrib/math.clj on classpath:

20:21 octe: is there anyway to create an alias for a symbol?

20:22 ihodes: i know this is off-topic, but i'm new to irssi. does anyone know how to search back through the chat with it? i had little luck with the online docs

20:22 hiredman: resolution is symbol -> var, there is no symbol -> symbol resolution

20:22 octe: ihodes, you can use /lastlog text-to-search-for max-number-of-hits-to-show

20:22 oh, parameters are other way around

20:26 ihodes: octe: sweet-thanks! is there anyway to pipe that output to another irssi window?

20:26 octe: no idea

20:26 ihodes: fair enough. i'll search around. that's quite helpful already, though. thanks :)

20:42 TimMc: octe: Just run /lastlog from window 1, after selecting the correct network.

21:31 krumholt: Hi. I don't have a better solution but it's kind of confusing that (+ Integer/MAX_VALUE Integer/MAX_VALUE) produces an exception while (+ Integer/MAX_VALUE 4294967294) does not.

21:48 TimMc: ,Integer/MAX_VALUE

21:48 clojurebot: 2147483647

21:49 TimMc: ,(+ Integer/MAX_VALUE 2147483647)

21:49 clojurebot: 4294967294

21:49 DespiteItAll: ,(+ Integer/MAX_VALUE (int 2147483647))

21:49 clojurebot: java.lang.ArithmeticException: integer overflow

21:50 DespiteItAll: Seems to me, you're forcing it to be an int

21:50 dnolen: ,*clojure-version*

21:50 clojurebot: {:major 1, :minor 2, :incremental 0, :qualifier ""}

21:50 TimMc: And Clojure 1.3 will behave differently for this, yeah?

21:56 dnolen: (+ Integer/MAX_VALUE Integer/MAX_VALUE) does not produce an exception in 1.3.0.

22:28 krumholt: nice i like it. if this changes in 1.3.0

22:37 pdk: yknow what i realized

22:37 it's probably disturbing how much i look to use -> and ->> in places now

22:37 backwards unnested nested code!

22:42 krumholt: + really changed for the better in 1.3.0

22:49 Null-A: I want to define a type which is java serializable. Can I define it with deftype?

22:49 _na_ka_na_: Null-A, yes

22:49 Null-A: _na_ka_na_: not defprotocol though?

22:50 defrecord* _na_ka_na_

22:51 _na_ka_na_: Null-A, no don't think you can extend protocols like you can extend interfaces in Java, if that's what you mean

22:51 pdk: ok here's something to chew on

22:51 Null-A: _na_ka_na_: sorry I meant defrecord, which autogenerates the hash function, et al

22:51 pdk: i'm trying to hit on some form that'd work like adding the forms arguments to a doto call programmatically without being totally ugly and inscrutable

22:51 _na_ka_na_: I think can you make a defrecord also serializable

22:52 pdk: and i was wondering if the use of ` and doto here might be considered ugly http://pastebin.com/5dZkFCue

22:52 Null-A: k

22:52 thanks _na_ka_na_

22:52 pdk: let alone be sure to work :p

22:52 maybe an atom + doseq would fit the bill more cleanly

22:52 oh welp

22:53 guess that settles it since (apply doto ... is already an error being a macro

22:54 that and i assume doto expects the object to be mutable

22:55 _na_ka_na_: pdk, yes I think doto is for mutable java objects

22:55 pdk: atom + doseq it is

22:55 amalloy: pdk: doto doesn't care about the underlying object at all, and indeed doesn't know about it

22:56 ,(doto (inc 10) println)

22:56 clojurebot: 11

22:56 11

22:56 _na_ka_na_: ,(doto (atom 10) (swap! inc) (swap! inc))

22:56 clojurebot: #<Atom@91cceb: 12>

22:56 pdk: well doto is basically accumulating state with that object before returning it

22:56 _na_ka_na_: ,(macroexpand-1 '(doto (inc 10) println))

22:56 clojurebot: (clojure.core/let [G__1263 (inc 10)] (println G__1263) G__1263)

22:56 pdk: so you probably end up with only the last change applied being seen if you pass it something immutable i'd imagine :p

22:56 amalloy: pdk: no, that is one way to use doto. doto just reorganizes the forms

22:57 pdk: ,(doto {} (assoc 1 2) (assoc 3 4) (println))

22:57 clojurebot: {}

22:57 {}

22:57 pdk: ,(doto {} (assoc 1 2) (assoc 3 4))

22:57 amalloy: doseq and an atom is disgusting. you probably want reduce or iterate

22:57 clojurebot: {}

22:57 _na_ka_na_: so its just like -> I guess

22:57 pdk: -> nests em

22:57 _na_ka_na_: expect that it doesn't pass the previous form to the next etc.

22:57 pdk: doto just seems to run each form sequentially

22:57 _na_ka_na_: ya

22:58 pdk: (doc iterate)

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

22:59 amalloy: your problem looks like it wants to be solved with reduce, but it's hard to see what you're trying to do

23:01 pdk: cool beans

23:02 popped in reduce and it did the trick though i wasn't holding up hope since the function insert-pair was going to be inserting/updating various values in a map of maps depending on whether new insertions were already present

23:02 though since it worked immutably already i guess there was no cause for concern about that

23:03 amalloy: indeed

23:09 simard: I'm trying to solve the collatz problem (from euler project) with clojure.. right now I know exactly how I'd do it in C or any language that would allow for mutable data (ie, have an 1 by N array and fill cases when necessary)

23:09 I'd like to do it in a clojury way though, but efficiently

23:10 any suggestions ?

23:11 amalloy: simard: i suggest you stop worrying about efficiency so much when you're learning a language

23:11 simard: lol

23:11 my engineering background programming microcontrollers perhaps

23:12 amalloy: *shrug* and your vague belief that infinite sequences will be slow

23:12 i have a collatz implementation in a gist somewhere if you want to use it for inspiration

23:12 simard: sure

23:13 pdk: situations with potentially infinite seqs = time to fall back on lazy seq idioms

23:14 bortreb: ?

23:14 pdk: !

23:15 amalloy: simard: you can memoize the collatz function if you want to trade memory for time, but it's not really worth it

23:15 simard: really I'd rather not trade anything

23:15 I'm pretty sure I can do that quick and with not much memory.. with an array :P

23:16 bortreb: lol the hailstone numbers --- this problem me very sad, as even the best clojure solution I could make that was backed with an array took 13 secs, while my c and FORTRAN versions took only 3 milliseconds :(

23:16 simard: yeah

23:16 more like I would expect

23:19 dnolen: simard: you should be able to get that to Java speeds, but if you're on 1.2.0 you're going to need a lot more type-hinting.

23:21 simard: nothing dirty about Java arrays in Clojure. Those methods are there for a reason.

23:26 simard: there's a number of things that are slow in your int-array solution.

23:28 simard: dnolen: what ?

23:29 dnolen: simard: aset-int is ridiculously slow, you need to type-hint all arithmetic operations in 1.2.0, you need to type-hint primitive array.

23:30 simard: oh

23:30 yeah, I'll be doing it in C

23:30 :)

23:30 just this time

23:31 dnolen: simard: stack-into-array, banging on a mutable array from within the realization lazy-sequence adds needless overhead.

23:41 pdk: 1.3.0 is making changes with how it handles primitives and boxing

23:42 ideally boxing a lot less internally