#clojure log - May 02 2012

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

0:02 devn: arohner_: thanks. I'm using (line-seq (io/reader (io/file filename)))

0:02 arohner_: does that look "new" and shiny?

0:03 arohner_: devn: yes, but you should use with-open on that reader

0:03 devn: arohner: ah! right. thanks.

0:04 arohner: (with-open [f (io/file filename)] (line-seq (io/reader f)))), yeah?

0:04 mefesto: (line-seq f)

0:05 err...

0:05 devn: open the reading in the with-open bindings

0:05 arohner: (with-open [r (io/reader (io/file filename))] (line-seq r))

0:05 mefesto: (with-open [rdr (io/reader (io/file filename))] ...)

0:06 arohner: and you'll want to force that lazy-seq before the with-open closes

0:06 so doall, or doseq or along those lines

1:07 felideon: if lein deps brings in a lib for my project

1:07 what's the best way to modify that lib? caan i just edit the code in the jar and recompile?

1:22 hmm i guess i'm looking for :java-source-path ?

1:32 meh i have no idea how this works

1:33 raek: felideon: editing the jars is not a good idea

1:34 felideon: raek: yeah, that's what i figure. it's that that's where M-. takes me so it's so tempting

1:34 raek: felideon: do you want to modify the source of a library that you are using? or do you just want to have java source code in your project?

1:34 felideon: raek: the former

1:34 _KY_: What format escape code should I use to printf a clojure term?

1:35 felideon: raek: i.e. i am have a korma dependency, and i want to modify korma

1:36 s/am//

1:36 raek: felideon: then you need to clone the korma git repo, make the changes, and run lein install in your clone

1:36 felideon: oh ok lein install

1:36 raek: felideon: you can also use the "checkouts" feature of Leiningen

1:36 felideon: and then from my project, I just recompile?

1:37 raek: no, you have to run lein deps and restart your repl

1:37 felideon: wat

1:37 raek: but with checkouts you don't have to run install and deps

1:37 felideon: and what about the :dependencies part of project.clj, that stays the sam?

1:38 raek: yes

1:38 but it's probably wise to change the group name of korma in your own modified version

1:39 felideon: group name?

1:39 raek: so when is :source-paths used?

1:40 raek: always, but you need to restart your repl for it to work

1:40 felideon: I think checkouts is what you want here

1:40 felideon: raek: yeah looking into tha

1:40 raek: felideon: it is explained here https://github.com/technomancy/leiningen

1:40 (search for "checkouts" on that page)

1:40 felideon: i see what it means by 'install/switch/deps/restart' now

1:41 raek: yeah thanks

1:41 raek: it will add the correct source path for the korma project to your other project

1:42 felideon: what about if i want to use a newer jdbc driver for postgres? that's a jar, how would I use that?

1:42 raek: the group identifier is the optional part before the slash in a dependency name

1:42 does that version exist in the maven repos?

1:43 using "free floating jars" is discouraged

1:43 it is motivated here https://github.com/technomancy/leiningen/wiki/Repeatability

1:45 felideon: oh i see

1:46 raek: well thank yoiu

1:48 raek: _KY_: to correctly print a clojure form you need to use one of pr, prn, or pr-str

1:48 felideon: np

1:49 _KY_: (printf "a form: %s" (pr-str a-form)) will work, but (do (print "a form: ") (pr a-form)) will be more efficient

1:50 _KY_: I see....

1:50 raek: but this might not be an issue unless the forms are very large

1:50 _KY_: I was just thinking there may be a % something

1:51 raek: that would be convenient I guess, but currently the format string is processed by java

1:52 java.util.Formatter is used as it is

1:54 felideon: raek: so once i add a checkouts folder and symlink, do i still need to do a lein deps again?

1:55 raek: felideon: I don't think so. but you do need to restart your clojure instance

1:56 if you run "lein classpath", the checkout project should be there

1:59 felideon: raek: i see. yes it works now

2:00 I can M-./hack/C-c C-c and it does teh right thing :)

2:01 raek: don't forget to make a pull request and/or open a issue when you have a fix for korma...

2:02 felideon: yeah was about to open an issue. :)

2:07 i guess i might as well just pull request

2:11 hmm should i create a branch for this even if it's one commit?

2:20 done https://github.com/ibdknox/Korma/pull/59

2:51 anekos: ls

2:55 LuminousMonkey: AccountsSystem Documentation Jobcard dotfiles

2:55 /home/anekos/ $:

2:55 :P

2:56 anekos: LuminousMonkey: Thanks :D

3:21 _ulises: I'm having issues running tests (using clojure.test) in heroku while the tests run (and pass) just fine locally. Is there anything special about the Heroku setup whereby tests would fail with java.io.FileNotFoundException?

3:56 fliebel: What is the core.reduce thing about?

4:08 amalloy: fliebel: i think the idea is to get a version of map and reduce and similar functions that don't use any more intermediate sequences/objects than necessary

4:10 eg, (magic-reduce + 0 (magic-map inc (magic-map inc xs))) being equivalent to (loop [acc 0, xs xs] (if-let [[x & xs] (seq xs)] (recur (+ acc (inc (inc x))) xs) acc))

4:30 fliebel: amalloy: hm, interesting.

4:33 devn: hmph -- not sure what changed, but all of a sudden my clojure repl in emacs doesn't open a buffer with the stacktrace of the error with info

4:33 it just prints ";; Evaluation aborted", no temporary buffer

4:33 anyone have any ideas?

4:40 ugh, this feels so ugly...

4:40 (defrecord Node [depth interpreted-type interpreted directive? selector attributes content])

4:41 then a moment later: (let [[a b c d e f g h] (re-find #"complicated-regex"))

4:41 except imagine a-h are those long names above

4:41 anyone have any suggested refactorings?

4:49 tsdh: devn: Wrt. the ";; Evaluation aborted" issue, I've had similar problems with certain errors. The reason was that there was a buggy clj-stacktrace version packaged in leiningen. Not exactly sure, but I think it slurped backtraces containing nested classes like Foo$Bar.

4:49 devn: But you should be able to see the backtrace in the *swank* buffer.

5:00 echo-area: swank-clojure uses Clojure 1.2; how to let it use Clojure 1.4?

5:07 devn: echo-area: dont use swank-clojure unless you are installing it as a lein plugin

5:07 like lein-swank

5:08 echo-area: devn: But I'm using it as a lein plugin

5:08 creese: I have a function that looks like (apply merge (map #(hash-map % (first z8)) (first x8)))

5:09 it works if I only use the first elements of z8 and x8, how can I make it work for all of them?

5:15 kij: creese: (apply merge (map #(hash-map % [:a :b :c]) ["a" "b" "c"]))

5:15 -> {"a" [:a :b :c], "b" [:a :b :c], "c" [:a :b :c]}

5:17 creese: z8 looks like ("one" "two"), x8 looks like ((1 2 3) (4 5 6))

5:17 I want the "one" to go with the (1 2 3) and the "two" to go with the (4 5 6)

5:21 kij: (map #(hash-map %1 %2) '("one" "two") '((1 2 3) (4 5 6)))

5:24 creese: I think I wasn't clear on what I want

5:25 let's the inputs are x8= ((1 2 3) (4 5 6))

5:25 z8= #{"abc" "def"}

5:25 I want the output to be a hash

5:26 {1 "abc" 2 "abc" 3 "abc" 4 "def" 5 "def" 6 "def"}

5:42 wei_: I'm trying to call a Java function with this signature: public void emit(final String event, final Object... args), but (.emit socket "msg" "3232") gives a ClassCastException. what gives?

5:44 tsdh: wei_: Object... is an object array. So you want (.emit socket "msg" (to-array ["3232"]))

5:45 wei_: oh, that works. thanks! got confused since i thought … meant arbitrary arity in Java

5:46 tsdh: wei_: Yes, it means arbitrary arity in Java. But on the bytecode level, it's a method that receives an array as last parameter.

5:48 wei_: the java compiler's transforming the last params into an array, i see

5:59 creese: (let [a [[1 2 3] [4 5 6]]

5:59 b ["abc" "def"]]

5:59 (apply hash-map (flatten (mapcat #(map (fn [k] (list k %2)) %1) a b))))

6:00 -> {1 "abc", 2 "abc", 3 "abc", 4 "def", 5 "def", 6 "def"}

6:03 creese: what happens if the a is [[1 2 3] [1 5 6]] ?

6:03 does the 2nd "1" clobber the first?

6:04 duplicate key error

6:08 if I have a duplicate key, do I have take these into the hash at different times. I want to store both results, so the vals of the hash are a set

6:49 michaelr525: any way to specify a string with qoutes without escaping them?

6:54 creese: example?

6:54 clojurebot: examples is api examples

7:15 fliebel: michaelr525: Not really. No multiline string syntax like Python or something like that.

7:21 michaelr525: yeah

7:22 what would be a good way to perform multiple operations on a map?

7:22 nm

7:22 antares_: michaelr525: it depends on what operations

7:23 michaelr525: ok

7:23 {:url :a :b :c}

7:23 creese: I have a hash or sets created as a ref with empty sets. I want to fill them.

7:23 michaelr525: i want to url-decode :url and then conj :d :e :f to the map

7:24 creese: set looks like: { a #{ } b #{ } c #{ } }

7:24 fliebel: michaelr525: Have a look at &(doc ->)

7:24 michaelr525: {:url "http://som%et%hing" :a 1 :b 2 } -> {:url "http://something" :a 1 :b 2 :d 3}

7:25 fliebel: &(doc ->)

7:25 lazybot: ⇒ "Macro ([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."

7:25 antares_: michaelr525: you can do (-> m (update-in :url (fn [s] …)) (assoc :d :e)), for example

7:25 michaelr525: fliebel: my problem is that assoc does not mutate but rather returns a new map

7:25 ah

7:25 update-in

7:25 creese: (conj (@hash 1) "aaa") allows me to write but not persistently, how do I use (do sync (alter __some stuff with conj___) to get this to work?

7:26 michaelr525: thanks. :)

7:26 antares_: creese: you need to use alter! and merge-with. Here is an example that uses a custom fn + atoms: https://github.com/michaelklishin/validateur/blob/master/src/validateur/validation.clj#L76-98

7:27 wei_: creese: to answer your previous question, (let [a [[1 2 3] [1 5 6]] b ["abc" "def"]] (into {} (mapcat #(map (fn [k] [k %2]) %1) a b)))

7:27 antares_: creese: looks like alter doc example has almost what you need? http://clojuredocs.org/clojure_core/clojure.core/alter

7:29 creese: antares_: almost, but the extra level of hierarchy introduces enough of a difference that I can't get it to work

7:32 michaelr525: does a function already exist which returns a [key val] pair from a map by the key?

7:32 of course it's not hard to write one but I wonder whether there is already something in clojure.core

7:34 creese: michaelr525, have you looked here? http://clojure.org/cheatsheet

7:34 michaelr525: (select-keys)

7:34 haha

7:34 just what i need

7:35 cheatsheet looks useful too :)

7:36 creese: I have found it to be

7:37 so if I, (conj (@words \b) "aaa"), I can write to the data structure, but changes don't stick

7:38 how can I wrap this inside a dosync( alter … ) ?

7:38 antares_: creese: in clojure, conj produces "copies"

7:38 creese: that's the whole point of immutable data structures and it makes a whole class of concurrency problems go away

7:41 creese: https://gist.github.com/747fd0d63e25b2fc1ebf

7:41 creese: are you sure you need to use refs? unless you coordinate these updates with something else, an atom will do

7:42 creese: I'm not sure which one I need

7:43 antares_: creese: when not sure, start with an atom

7:44 creese: update-in

7:44 thanks

7:45 antares_: creese: here's a similar example with atoms (it could also be done with update-in): https://github.com/michaelklishin/validateur/blob/master/src/validateur/validation.clj#L76

7:45 creese: if I use an atom, alter -> swap! and I remove dosync?

7:49 antares_: creese: right

7:50 creese: why do I want to use atoms instead?

7:53 antares_: creese: because STM has certain limitations and overhead atoms don't have, so if you don't need coordination, why use refs

8:14 jweiss: is it correct that code passed to a macro may or may not have had its macros expanded already?

8:16 i guess what i'm asking is, if my macro just removes code that contained another macro call, will that prevent that macro call from ever happening?

8:18 jayunit100: is there a way to abort a filter

8:18 i.e. (filter-until)

8:18 jweiss: jayunit100: yes, use take-while

8:19 jayunit100: ah ok . but take doesn't filter...

8:19 thats fine.

8:19 jweiss: ,(take-while even? (filter #(> % 0) [-1 -3 4 -5 6 -3 3 8 9]))

8:20 clojurebot: (4 6)

8:20 jweiss: jayunit100: you're depending on lazy evaluation there.

8:20 so it won't go through your whole sequence

8:20 jayunit100: oh ok so it doesnt start the while condition until "true" ...

8:21 i mean, it doesnt start checking to abort until the condition is found to be true.

8:21 jweiss: jayunit100: filter produces a lazy sequence - meaning each item in the result isn't fetched until (take-while ...) asks for it.

8:21 jayunit100: ah nm : you apply the filter first.

8:21 yup

8:22 jweiss: ,(take-while #(< % 10) (range 1000000))

8:22 clojurebot: (0 1 2 3 4 ...)

8:23 jweiss: ,(take-while #(< % 3) (range 1000000))

8:23 clojurebot: (0 1 2)

8:23 jweiss: notice the huge list of a million numbers is never created

8:23 ,(take-while #(< % 3) (range 100000000))

8:23 clojurebot: (0 1 2)

8:25 jayunit100: yup

8:25 thanx

8:25 jweiss: np

8:38 espeed: In Emacs SLIME, I can C-c, C-c over a print statement and it will display the output in the SLIME REPL. How do you display a functions value in the REPL without using print?

8:49 creese: espeed: just evaluate at the command line, the return value of the function is printed

8:55 espeed: Well C-M-x displays the value in the minibuffer

9:10 Frozenlock: I have a problem with Seesaw... the hyperlink function doesn't behave like expected. In its own example, (hyperlink :text "Click Me" :uri "http://google.com") gives a link with the URI as the clickable text, instead of "Click me". Any workaround?

9:43 wmealing: ok, this might be a too lazy of question, but can i get the output of the command lein midje --lazytest in my emacs window ?

9:43 kaoD: hello :)

9:44 is there any way, given a symbol (+, /, *) to "cast" it to a function? using '(+ 1 3) treats + as symbol not as a function

9:49 okay "resolve" does the trick

9:57 gfredericks: kaoD: depending on what you're doing, you might need to be aware that resolve is relative to a namespace

9:59 kaoD: gfredericks: nah, it's for 4clojure (a clojure problem collection, in case you don't know) but it caps resolve in the sandbox too so I ended up resolving it to a map {'* * '+ +...}

9:59 which is what I wanted to avoid

10:00 thanks anyways :)

10:08 cduffy: mefesto: any thoughts on providing a public mechanism to rebind *connection* and kin with pre-built AMQConnection objects (and similar) rather than requiring a new broker/connection/&c. to be made every time one wants to bring them into scope?

10:12 tomoj: `cljsc '{:optimizations :advanced}' foo.cljs` doesn't seem to work for me

10:12 the args passed to transform-cl-args in cljsc.clj are ("{:optimizations" ":advanced}" "foo.cljs")

10:13 any clue why? this used to work, I'm sure...

10:14 oh

10:14 `cljsc foo.cljs '{:optimizations :advanced}'`

10:14 d'oh

10:43 michaelr`: devn: you here?

10:58 jweiss: is there any functional difference between (ns blah (:use 'otherthing)) and (ns blah) (use 'otherthing) ? for instance maybe the macro saves some computation or loading if the current namespace gets reloaded? or is it just sugar?

10:59 i notice the macro calls with-loading-context, but i'm not sure what that does exactly.

11:13 devn: gah! michaelr` shows up and then he's gone

11:13 blast.

11:13 TimMc: Short-timers.

11:55 dnolen: jonasen: ibdknox: open to your guys thoughts about the CLJS AST based on rhickey's post since you all are consuming that stuff. children -> children keys + whatever extra data is necessary to make it work sounds like it solves a) and b)

12:06 fliebel: dnolen: What post?

12:07 dnolen: fliebel: clojure-dev post

12:08 fliebel: k

12:08 dnolen: thread on fixing on the AST emitted by the CLJS analyzer

12:08 fixing the AST

12:08 gfredericks: fliebel: http://groups.google.com/group/clojure-dev/msg/8d62c000aa9ac80b I assume

12:14 melipone: how can I modify the slots of a defstruct object? Forex, I have (def myrect (struct rect :width 5)) and I want to modify the width slot while keeping the same object.

12:15 TimMc: melipone: Does assoc do it?

12:15 Oh wait, mutation?

12:16 fliebel: melipone: Not, you can't modify a struct

12:16 melipone: fliebel: I can't? I know I program like Java :(

12:16 fliebel: melipone: What do you want to do?

12:17 TimMc: melipone: And I'm pretty sure structs are deprecated.

12:17 melipone: I just want to modify one slot while keeping the other slots identical

12:17 TimMc: deprecated? replaced by what?

12:17 S11001001: so assoc and use the new object

12:18 fliebel: melipone: I mean, why do you need to modify the object, instead of continue what you where doing with the new version?

12:18 melipone: defrecord

12:18 dnolen: melipone: defstruct is deprecated

12:18 melipone: fliebel: really, defrecord?

12:19 but defstruct has been there since C ...

12:19 fliebel: melipone: A clojure struct isn;t the same thing I believe.

12:19 S11001001: truth

12:19 gfredericks: melipone: if you don't have a particular reason to use a struct/record, you're probably better off with a map

12:20 fliebel: You can take a java.util variety if you *really* need the mutation, or stick it in an atom or something, but most likely you *think* you need to mutate it.

12:22 I think of it like this. if I do (+ 2 1) do I change 2, or do I get a new number, 3?

12:22 melipone: ok, ok ...

12:24 technomancy: _ulises: leiningen on heroku runs with LEIN_NO_DEV=y in order to keep tests off the classpath during production

12:25 _ulises: there are a few ways to work around that depending on what you're shooting for

12:46 jonasen: dnolen: I still don't see what :children-keys would give us.

12:47 dnolen: jonasen: a way to walk the AST without knowing anything.

12:48 jonasen: The children of an expression can't be described as just a vector of keys

12:48 dnolen: jonasen: yes, we know that. I'm just suggesting that we think about what it should look like.

12:49 jonasen: another approach would be to (merge {:op ...} (delay {:children ...}))

12:50 dnolen: jonasen: that doesn't avoid the problem with the multimethod issue

12:51 jonasen: dnolen: that's probably true

12:52 platzhirsch: I have a checked out a clojure project and just get started, is lein the preferred tool to deal with clojure projects? Currently I just have generated the pom file and work on the maven stack

12:53 mefesto: platzhirsch: lein is preferred

12:53 RickInGA: I am playing around with an example, trying to simulate defmacro... I can build the function but can't assign any meta data https://refheap.com/paste/2505

12:53 TEttinger: platzhirsch, both are usable, maven may be more usable for mixed java/clojure projects, but lein is generally better

12:54 jonasen: dnolen: what about *include-children*?

12:54 platzhirsch: TEttinger: ideal, good to know

12:57 TEttinger: platzhirsch, lein uses maven internally, so pretty much anything maven can do, clojure can do with a fraction of the configuration

12:57 aphyr: Is there any reason to prefer EPL over apache v2, for clojure projects?

12:57 TEttinger: *lein can do with a fraction

12:58 technomancy: aphyr: apache technically requires annoying license boilerplate in every file

12:58 aphyr: also EPL makes users share the modifications they make to the project

12:58 pjstadig: technomancy: huh?

12:58 i don't think v2 does

12:59 technomancy: pjstadig: that was one of the points against it when we were considering how to license mirah

12:59 I think we ended up just pretending it didn't say that though.

13:01 pjstadig: well regardless some kind of license notice at the top of every file isn't a bad idea in my mind

13:01 if people want to crib just one file and not the whole project, it lets people know how it's licensed

13:01 ibdknox: Raynes: technomancy: finally updated lein-noir

13:02 pjstadig: but yeah technomancy's second point is the biggest difference, EPL is weak copyleft, so changes to the original project must be shared

13:02 technomancy: yeah, I don't think the boilerplate issue is a big deal since there is probably nothing wrong with ignoring it outright =)

13:03 *probably* nothing, don't trust legal advice you get on IRC, etc.

13:03 aphyr: Naturally.

13:03 Company I work for uses apachev2 for all their OSS stuff, but Riemann is already licensed under EPL.

13:03 technomancy: ibdknox: great; thanks. will be nice to be able to specify the shorter invocation for docs and stuff

13:03 muhoo: people have gotten rather lax in recent yearss with license stuff

13:03 aphyr: Trying to figure out if I should relicense it or just keep going.

13:04 technomancy: muhoo: yeah, the number of completely unlicensed projects on github freaks me out

13:04 Miko2: I prefer using BSD as I simply don't care what people do with my code.

13:04 technomancy: Miko2: BSD has no patent protection, so watch out

13:05 someone could submit a patch in good faith and if their employer got acquired by a hostile corp your users could be in trouble

13:05 pjstadig: i lean more towards public domain (like creative commons CC0) but there are issues with that, and of course patents are a problem

13:05 technomancy: I'm a big fan of the EPL; I like everything about it except the name =)

13:06 RickInGA: you can pretend the e stands for emacs

13:06 no one will know :)

13:06 Miko2: technomancy: You mean, someone could take my code and create a patent over it and then sue me? :P

13:06 pjstadig: technomancy: yeah, but it requires distribution of changes to the original project

13:07 which isn't a terrible thing, but i'd prefer not to force people to release their code if they don't want to

13:08 aphyr: Yeah, good point. It's probably OK if I don't follow the rules of the apache license re attributing *every change* in each file, license headers on each file, etc.

13:08 solussd_: I'm trying to add some items to my 'head' section using enlive's "append" transformer. The values are coming from hiccup.page/include-js, but append escapes the angle brackets. Does anyone have any insight into this?

13:08 aphyr: I would prefer to let people make private changes.

13:08 Otherwise EPL fits my needs pretty well.

13:09 technomancy: Miko2: they could use a patent that applied to their contribution that you accepted

13:09 pjstadig: I actually like the CDDL better than EPL as a weak copy-left license

13:09 technomancy: RickInGA: haha

13:10 pjstadig: only slightly, though, and only in the way that people can "like" open source licenses

13:10 Miko2: technomancy: Can you really make a patent out of something that is already out there as open source?

13:10 technomancy: pjstadig: what's the difference?

13:10 muhoo: i like open source licenses a LOT better than i like closed licenses

13:10 technomancy: Miko2: it's amazing what you can get away with

13:10 amazing/depressing

13:11 Miko2: I think in Finland that's not possible, but may be in USA. :/

13:11 muhoo: but the whole licensing issue often feels like incidental complexity to me

13:11 technomancy: probably true; the USA is particularly insane in that regard

13:11 EPL and apache make it so if you submit a patch, you must also grant a license for any patents you own that may be covered by that patch.

13:14 Miko2: And adding that clause to BSD license would probably require an army of lawyers.

13:15 ibdknox: is there a completely open (e.g. BSD) license that has patent protection?

13:15 pjstadig: the CDDL provides a way for you to modify it if you want to, and also gives you the ability to choose a legal venue

13:15 having the ability to evolve the license removes one of the major reasons people tend to have CAs

13:16 dnolen: jonasen: no configurability

13:17 pjstadig: CDDL is also file based which makes it easier for people to use just one file from your project, and also to add a file licensed under a different license to your project

13:17 or something...i don't know IANAL

13:17 felideon: ibdknox: i would appreciate your comments on https://github.com/ibdknox/Korma/pull/59 when you get a chance :)

13:18 Miko2: I hate it there's no way to just contribute something to the world without thinking about legal issues.

13:19 ibdknox: felideon: looks like a good idea to me :)

13:19 felideon: woot

13:19 :)

13:19 pjstadig: Miko2: yeah i know, that's why i've been leaning more towards public domain or a public domain like license like CC0

13:20 Miko2: And if my code happens to have a dependency to some other open source project, I have to read hundreds of pages of legal jargon that I don't understand. Usually faster to implement your own.

13:21 fdaoud: WTFPL ftw

13:24 Miko2: pjstadig: Doesn't that also have the patent issue?

13:25 pjstadig: Miko2: right, public domain only deals with copyright issues, not patents

13:25 so it's not ideal

13:27 but the reality is that even if an OS license has some kind of patent clause, the software could still infringe on the patents of some third-party

13:27 so if you're going to be worried about it, then you do your homework

13:27 and you'd do the same homework with public domain so maybe it works just as well

13:29 Miko2: I'm not worried, I'm just disappointed that there is such possibility.

13:36 technomancy: ibdknox: apache2 is the closest thing to BSD+patent protection

13:37 Leiningen's own dependencies are nearly all licensed EPL or Apache2

13:37 lein1 had a few oddballs (including one public domain, so I guess I can't distribute the Leiningen uberjar in Germany)

13:37 Miko2: you can avoid lots of issues by just not caring about what those crazy americans do =)

13:38 pjstadig: doing your homework re: patents makes you liable for triple damages if you're found to be infringing, so it's not the safest thing to recommend

13:38 felideon: what's the problem with public domain in germany?

13:38 technomancy: felideon: it's not recognized.

13:39 IIUC German copyright law is phrased in terms of inalienable "moral rights"

13:39 felideon: an

13:39 ah*

13:39 Miko2: technomancy: Yeah, I've been following that advice very successfully. :) But of course, if the users could have an issue, then I have an issue.

13:39 technomancy: you can't give them up even voluntarily

13:39 there are a few other countries without public domain too

13:40 jonasen: I'm playing with himera which uses cljsbuild. Every time I run lein cljsbuild one it deletes parts of resources/public which is needed by the app. Anyone knows what to about that?

13:53 Miko2: Hmm... Is Clojure clever enough to "cache" functions returned by functions? I have some code that matches strings against a vector of rules. Those rules are given as functions, but I create those functions with another function. So, I guess, what I'm asking is, if I call "create-some-rule" repeatedly, can I improve the performance by (def some-rule (create-some-rule)) and referring that instead?

13:54 TimMc: No sneaky automatic caching, no.

13:54 technomancy: Miko2: function classes are created at compile time, so there shouldn't be any overhead in something like that unless you're using eval

13:54 dnolen: jonasen: that seems really weird

13:55 S11001001: Miko2: you can't compare two functions

13:55 jonasen: dnolen: it doesn't happen the first time I run it. But if I change the cljs source it does

13:56 TimMc: Haha, we just answered 3 completely different aspects of miko's question.

13:56 I wonder which one is relevant? :-P

13:57 technomancy: ,(let [f-maker (fn [] #(apply + %&))] (identical? (f-maker) (f-maker)))

13:57 clojurebot: false

13:58 TimMc: Miko2: memoize may be of interest to you.

13:58 technomancy: ,(let [f-maker (fn [] #(apply + %&))] (= (class (f-maker)) (class (f-maker)))) ; is what I meant

13:58 clojurebot: true

13:58 S11001001: I'm just saying that it's algorithmically impossible for function combinators to cache generically. You can cache based on function identity, and possibly function-class identity and captured binding equality, or even expression equality, but not in general. memoize will get you the former

13:58 Miko2: Okay, so...

13:58 TimMc: S11001001: I'm guessing intensional identity is sufficient here.

13:58 technomancy: Miko2: creating a new function object is just instantiating a pre-existing class, which is super cheap

13:59 Miko2: Well, that answers the question. :)

14:01 I'm actually happy that it doesn't have impact, as it'd be quite tedious to "def" everything beforehand.

14:01 technomancy: yes, it's very important for functions to be cheap when doing functional programming =)

14:03 Miko2: Yeah, I was just guessing that calling a function that creates functions about 50 * 20000 times is costly. :)

14:04 mdeboard: pff, that's only a million

14:05 pjstadig: re: public domain, if you're going to go that way I think it's best to use something like CC0 or Unlicense that acts like a permissive license in countries without public domain

14:06 Miko2: I guess the biggest slowdown in my implementation isn't the algorithm, but the startup cost and reading of input.

14:07 cduffy: mefesto: I'm trying to use wabbitmq from an agent without needing to generate a whole new connection for each message. Does https://gist.github.com/279a5192f1305a898c2f look sane, or can you suggest something better?

14:09 Miko2: Plus printing the output.

14:13 Borkdude: I'm trying to make an example why auto-gensym is necessary. So I found this On Lisp example: http://www.bookshelf.jp/texi/onlisp/onlisp_10.html

14:14 and I'm wondering: is there anything in Clojure that looks like Common Lisp's do?

14:15 any other example of variable capture is also good

14:17 S11001001: Borkdude: sure: (let [&env 42] (defmacro forty-two [] &env)) (forty-two)

14:17 ,(do (let [&env 42] (defmacro forty-two [] &env)) (forty-two))

14:17 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

14:17 S11001001: heh

14:17 anyway try that

14:22 gfredericks: Borkdude: I'd think you could contrive an example easily; e.g., rewrite with-out-str to use generic local names like foo and bar instead of autogensym

14:22 * gfredericks hasn't actually looked at the src of with-out-str

14:23 Borkdude: gfredericks: ok, good suggestion

14:23 TimMc: "it"

14:24 (my-with-out-str (println "hello") (count it))

14:24 Borkdude: gfredericks: hmm, it has no auto-gensyms

14:25 * gfredericks goes to look

14:25 Borkdude: gfredericks: with-out I mean

14:25 gfredericks: what is with-out-str.. never heard of it

14:25 gfredericks: a macro

14:25 Borkdude: gfredericks: with-open I mean

14:25 TimMc: &(count (with-out-str (println "hi")))

14:25 lazybot: java.lang.SecurityException: You tripped the alarm! pop-thread-bindings is bad!

14:26 TimMc: ,(count (with-out-str (println "hi")))

14:26 clojurebot: 3

14:26 Borkdude: gfredericks: ah great

14:26 gfredericks: it does use a gensym also

14:26 mefesto: nDuff: ping

14:26 Borkdude: gfredericks: I see, yes

14:26 nDuff: mefesto: pong

14:27 mefesto: nDuff: just glanced at your gist. i'm wondering if a bound-fn might be a better fit?

14:27 ,(doc bound-fn)

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

14:28 mefesto: not sure tho, i haven't personally tried this

14:28 nDuff: mefesto: oooh, nice; that _does_ make much sense.

14:28 (will need to think about how it'll work with reconnecting on error conditions, though)

14:30 gfredericks: fntail is an odd arg-name there

14:37 Borkdude: this is a quite simple example: http://cljbin.com/paste/4fa17c6de4b08bad0592745d

15:31 daniel: ,(clojure.contrib.math/ceil (/ 63 4))

15:31 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.contrib.math>

15:31 gfredericks: ~contrib

15:31 clojurebot: Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

15:31 AimHere: contib is out of date

15:31 daniel: thought so, but i cant find where this has moved

15:32 AimHere: Java floating point Math/ceil is still there

15:32 gfredericks: $findfn 63/4 16

15:32 lazybot: [clojure.core/unchecked-inc-int]

15:32 AimHere: I don't know if that's the same as the function you're after

15:33 daniel: seems to give the desired result

15:33 $findfc 63/2 32

15:33 $findfn 63/2 32

15:33 lazybot: [clojure.core/unchecked-inc-int]

15:33 daniel: cheers

15:34 amalloy: wait what the hell. that's not the ceil function, guys

15:35 gfredericks: lol; I was hoping nobody got that impression

15:35 I'm still not sure why that works

15:35 amalloy: because it casts to int and then adds one

15:35 gfredericks: what happens when you cast a ratio to int?

15:35 amalloy: it rounds down

15:36 so it works fine for every number that isn't an integer

15:36 but for integers it adds one

15:36 TimMc: &(map unchecked-inc-int [3 3.5])

15:36 lazybot: ⇒ (4 4)

15:36 gfredericks: are we using "cast" loosely and not in the sense of (Foo)bar?

15:36 amalloy: yes

15:36 TimMc: .intValue, perhaps

15:36 gfredericks: and "unchecked" means it lets you overflow

15:37 now I understand everything!

15:37 amalloy: &(instance? Number 1/2)

15:37 lazybot: ⇒ true

15:38 amalloy: i guess i never thought about that, TimMc. of course ratios are numbers

15:39 gfredericks: now I understand even more than that!

15:41 TimMc: amalloy: It is implemented in Java as x + y, where x and y are ints.

15:41 So I guess java handles the "casting".

15:41 *the JVM

15:42 amalloy: no, clojure has to do it somewhere, probably in the reflection code for finding the right java method from the clojure function

15:43 daniel: what function will map (range 0 7) -> 1 (range 8 15) -> 2 (range 16 23) -> 3

15:43 my IQ is not high enough to work this out right now

15:43 amalloy: ie, i'm pretty sure you can't call bar(x) with a Ratio if it expects an int (or an Integer), so clojure must be making it an int first

15:44 S11001001: daniel: head map floordiv 8

15:44 +1

15:44 TimMc: amalloy: Hmm, you're right -- Java doesn't allow 5 + new BigInteger("6")

15:45 oh, and of course you're right about the method's params

15:46 daniel: S11001001: i guess i have to implement head and floordiv?

15:47 i don't want it to literally map the range to the result, i want any input from within the range to give me the result

15:47 S11001001: head is first, floordiv is floor /

15:48 daniel: right, i thought head might be first

15:48 but i dont want to map the range, i mean to take any input from the range

15:48 S11001001: right, that's what first is for

15:48 daniel: first takes the first number in the range doesnt it?

15:48 S11001001: yep

15:48 daniel: ,(first (range 0 7))

15:48 S11001001: so it works both ways

15:48 clojurebot: 0

15:49 daniel: but what if i dont have a range, but i want to map 5 -> 1

15:49 oh i see

15:50 emezeske: daniel: It sounds like you just want the quotient...?

15:50 jonasen: dnolen: I added a :children-keys colummn to the document

15:51 emezeske: &[(quot 3 8) (quot 11 8) (quot 20 8)]

15:51 lazybot: ⇒ [0 1 2]

15:51 daniel: ,(map #(floor (/ % 8) (range 0 7)))

15:51 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: floor in this context, compiling:(NO_SOURCE_PATH:0)>

15:51 daniel: emezeske: yes!

15:51 jonasen: emezeske: Have you tried himera with cljsbuild?

15:51 dnolen: jonasen: have you followed the latest bits of the thread? sounds like just moving those key-values into :children might be cleaner and nicer.

15:52 jonasen: dnolen: I have followed the thread. I'm not fast enough to reply to all the ideas :D

15:52 emezeske: jonasen: You mean as a compiler backend?

15:53 jonasen: dnolen: no, just running 'lein cljsbuild once' on it

15:53 sorry emezeske: ^

15:53 emezeske: jonasen: ^_^

15:54 jonasen: emezeske: I deletes some of the files in resources/public which are needed by the app for me

15:54 emezeske: jonasen: Oh? That is not good. Let me glance at the source real quick

15:55 jonasen: emezeske: It happens after some .cljs files are edited

15:55 emezeske: jonasen: Hmm, I see that :output-dir is set to resources/public

15:55 jonasen: cljsbuild deletes the :output-dir before compiling

15:56 jonasen: emezeske: ok. there are a few files there that should not be deleted

15:57 emezeske: jonasen: Would it be possible to set the :output-dir to something else? Maybe resources/public/js or something?

15:57 jonasen: emezeske: probably. I'll take a look. Thanks!

15:58 emezeske: jonasen: NP. I probably should make the "delete first" behavior optional at some point. It's the default right now, though, because it makes the builds more solid, especially in the case that the compiler crashed or something and left output files in a weird state.

15:58 robermann: hello, could anyone help me in understanding why [~@ks] returns the map values? See http://pastebin.com/KQUJDi1x

16:00 that example is from "Clojure Programming" book, page 252

16:01 metellus: robermann: it's "unquote splicing" http://clojuredocs.org/clojure_core/clojure.core/unquote-splicing

16:01 daniel: i've forgotten how to go from (range 0 100) -> (10, 20, 30, 40, 50 ... 100)

16:01 metellus: but I don't know enough to tell you more than that

16:01 gfredericks: robermann: you're asking why it's the values instead of the keys?

16:01 hiredman: ,(doc range)

16:01 clojurebot: "([] [end] [start end] [start end step]); Returns a lazy seq of nums from start (inclusive) to end (exclusive), by step, where start defaults to 0, step to 1, and end to infinity."

16:01 daniel: ooh it has step

16:02 great, thanks

16:03 robermann: gfredericks: yes, I woud expect the keys

16:03 would

16:04 gfredericks: robermann: because the keys are being emitted unquoted, they get eval'd to the values

16:04 robermann: note the '~ks is quoted but [~@ks] is not

16:05 (defmacro whatisthis [arg] `['~arg ~arg]) (whatisthis (+ 1 1))

16:08 robermann: In general I can understand that ({:a "a" :b "b"} :a) => "a" , but why in the macro if keys are unquoted I get their values? The first paramater is not the whole map, but just its keys

16:09 N8Dawg: Hello room

16:10 daniel: this is producing a lazyseq: https://gist.github.com/2579844 I want it to act on the same board for each iteration of for

16:10 board is a 64 bit long and this function needs to return a 64 bit long

16:11 gfredericks: robermann: this has more to do with macros than it does maps

16:11 in particular the &env parameter

16:12 AimHere: daniel > for returns a sequence of the evaluated things in the body

16:12 rewriting that with 'reduce' might be what you want

16:12 N8Dawg: I was wondering if someone could point me in the right direction, I had a question around form analysis for macros

16:13 austinh: ~anyone

16:13 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

16:13 daniel: AimHere: yeah, i can (reduce bit-or #())

16:13 thanks

16:14 gfredericks: robermann: a key in the &env map represents a local name. When you emit it from the macro, it's just like using it in code. So the call to (spy-env) in your code gets expanded to (prn '(y x) [y x])

16:14 so it prints (y x) [2 1]

16:14 N8Dawg: I writing a lazy-let macro, which performs lazy evaluation of the bindings, i need to rewrite terms, but symbols may be shadowed / redefined

16:15 so I can't just do a clojure.walk/replace is there any library to help do a lexically scoped replace on a form?

16:15 robermann: gfredericks: ah I see now: it is evaluating a local, instead of doing a map lookup! Thank you :)

16:16 gfredericks: robermann: yep that's it

16:16 amalloy: N8Dawg: symbol-macrolet

16:16 see https://github.com/flatland/useful/blob/develop/src/useful/utils.clj#L201 for example

16:17 N8Dawg: amalloy: awesome thanks!

16:19 dnolen: mmarczyk: thx for fixing the ICounted bug. I'd like to remove extend-type default for IReduce and IIndexed as well.

16:20 N8Dawg: amalloy: amazing, the answer in seconds, and the function i wanted! woot for the Clojure community

16:20 mmarczyk: dnolen: hi! np

16:21 dnolen: yeah, IReduce and IIndexed make no sense at all for default

16:22 dnolen: especially IIndexed -- that totally breaks the promise of constant time lookup

16:24 dnolen: mmarczyk: I think it's there for expedience (since we don't have inheritance), but easy enough to remove (I've successfully done so in a branch after many strange resulting bugs & teeth gnashing).

16:25 beffbernard: There must be a cleaner way to do this - https://refheap.com/paste/2512

16:25 I'm pass in a sorted list of keywords that are the map and return a sort list of values from that map

16:25 that are in the map and return a sorted list of values from that map*

16:26 mmarczyk: dnolen: yeah, though in both cases we can basically assume the argument is either IReduce / IIndexed or ISeqable

16:28 raek: beffbernard: (defn sort-with-order [order item] (map val (sort-by (comp (zipmap order (range)) key) item))

16:29 mmarczyk: dnolen: I'm curious about the strange bugs though -- and I'm sure happy you've gone through the gnashing of teeth :-)

16:29 dnolen: will you be merging that branch then?

16:33 beffbernard: raek: fancy.. seems like there would be a function that did this: (zipmap order (range)) ?

16:34 dspiteself: Would anyone be able to suggest a way to retain the power of Datomic and while adding an authorization layer. I was playing around with the idea of adding access control list facts and use macros to convert a query and a user and by adding proper expressions and unifications to ensure authorization. Is this a pipe dream i have and has played with similar security concepts?

16:36 ibdknox: dspiteself: you're probably better off asking in #datomic

16:36 devn: Anyone know what fogus used to generate this video? chouser, do you know? http://www.youtube.com/watch?v=pTETlppW-u4

16:36 dakrone: devn: gource

16:36 dspiteself: ok sorry

16:37 devn: dakrone: awesome! thanks.

16:37 ibdknox: dspiteself: nothing to be sorry about, just think you might have a better chance of getting an answer :)

16:37 dspiteself: and when i ask it there maybe i can spit proper English out;-)

16:37 devn: dakrone: i just submitted an issue on clojuredocs -- maybe you know where the link is, but on the api.clojuredocs.org page the link to clojuredocs-client is incorrect (it's still pointing at cd-client pre-rename)

16:37 technomancy: gource is lots of fun

16:37 devn: dakrone: do you know where to change it?

16:37 dakrone: devn: yes, I'll fix it

16:38 devn: dakrone: where is it out of curiosity? I couldn't find it.

16:39 dakrone: devn: https://github.com/dakrone/cd-wsapi/blob/master/resources/index.html

16:40 mmarczyk: dnolen: just fixed the reify warning -- http://dev.clojure.org/jira/browse/CLJS-233

16:43 robermann: dakrone: I was just looking on it this morning, the last version is https://github.com/dakrone/cd-client or https://github.com/Raynes/cd-client ?

16:43 mmarczyk: dnolen: actually wait, I think I missed something

16:43 dnolen: will comment on the ticket once I'm sure it works.

16:48 dakrone: robermann: neither, https://github.com/dakrone/clojuredocs-client

16:52 robermann: dakrone: BTW I noted that doing a (browse-to symbol) goes to the 1.2 version of it ?

16:53 dakrone: robermann: yea, there's a problem with the URLs that I need to fix

16:53 robermann: I worked around it with this hook: http://pastebin.com/jnHkgjrt

16:54 (maybe dirty, but I was just studying these hook questions)

16:56 In general why for browse-to do you use *examples-api* and not *search-api*?

16:58 dakrone: it needs some love and updating, I haven't touched it for quite a while, so I don't recall exactly

17:01 jonaskoelker: Hi all. Suppose I have an quoted expr in my toy language, say '(+ (d 6) (d 6) (d 6))---and I want to write that syntax in some-namespace, and I want eval on that to call some-other-namespace/d. What's the best way to do that?

17:02 And is that even the right way to do things? I'm very new to clojure... My best guess would be to either (use) or (require), the one which is similar to "from pkg import *" in python

17:03 that feels dirty and ghetto, however

17:04 sattvik: jonaskoelker: Well, the closest thing to "from pkg import *" is (use), though a blanket (use 'some.ns) seems to be discouraged these days.

17:05 mmarczyk: dnolen: posted a correct patch @ CLJS-233 (I think) -- after gnashing my teeth a bit and dealing with some strange bugs :-)

17:05 sattvik: I think with Clojure 1.4 you can now just get a few named symbols from a namespace. The alternative is to use (require) which ensures they are available.

17:06 jonaskoelker: I'm on clojure 1.3 ...

17:06 sattvik: OK, well, let's just say you used the namespace. What you probably want to syntax quote rather than quote.

17:06 That is: `(+ (d 6) ...)

17:07 jonaskoelker: that _sounds_ right, though I have no context for which to evaluate it

17:07 dnolen: mmarczyk: I don't think that will work with advanced compilation right?

17:07 jonaskoelker: what's the semantic diff?

17:07 mmarczyk: sattvik: get a few named symbols? how do you mean?

17:07 sattvik: The reader will namespace-qualify the symbols.

17:07 mmarczyk: Well, specific vars.

17:07 mmarczyk: dnolen: oh. I think you're right

17:08 jonaskoelker: so if I'm in namespace foo, `(+ (d 6)) will become (+ (foo/d 6))?

17:08 mmarczyk: dnolen: wasn't my first approach, just the first one which (1) gets rid of the warning, (2) doesn't break unscientific tests at the REPL, (3) doesn't break core_test

17:08 dnolen: back to the drawing board then :-P

17:08 sattvik: jonaskoelker: So '(+ d) turns into just (quote (+ d)), but `(+ d) becomes something like (clojure.core/+ some.ns/d)

17:08 yes.

17:08 mmarczyk: sattvik: as in (use '[foo.core :only [...]]) ?

17:09 sattvik: or alias after require

17:09 jonaskoelker: sattvik: ... it sounds like it'll become (clojure.core/+ test/d) when I want (clojure.core/+ mylib/d) ?

17:10 when I write `(+ d) in my test namespace

17:10 dnolen: mmarczyk: yeah it won't break it'll just never cache the type.

17:10 sattvik: mmarczyk: I think so. Oh, I think I remember what was different in 1.4, it wasn't use that got something new, but require? Something like require with refer?

17:10 mmarczyk: sattvik: the new thing is (:require [foo.core :refer [...]]), but that's a step towards deprecating the still-available and for some reason much-despised use

17:11 sattvik: cache the type...?

17:11 dnolen, I mean, and I got it now :-P

17:11 dnolen: mmarczyk: sorry for caching the definition of the constructor.

17:11 mmarczyk: yeah

17:11 got mixed up re: which conversation this was part of

17:12 sattvik: jonaskoelker: That's a little more difficult. You can, of course, namespace qualify a symbol and just do something like '(+ mylib/d), but I don't know off-hand how that will work when evaluated.

17:12 mmarczyk: and yeah, that's a problem -- I'll find another approach

17:13 jonaskoelker: sattvik: I guess I'll just import everything---can namespaces set export controls? Then whatever lump of code that needs short names can dirty itself

17:14 I could presumably re-namespace the symbols, but that feels hacky and brittle

17:14 sattvik: jonaskoelker: Well, namespaces can make vars private, which just means they are not visible by default, rather than inaccessible.

17:15 jonaskoelker: so there's a gentleman's agreement but no contract? :)

17:15 brehaut: some people like to create an internal NS that contains the stuff you dont want people importing

17:16 jonaskoelker: and evilly rename it from release to release? :->

17:16 brehaut: haha

17:16 i think anyone importing from foo.internal deserves the pain they get

17:17 jonaskoelker: that's what she said!

17:17 sattvik: jonaskoelker: Well, it isn't straightforward to get to a private var, but it's not impossible

17:18 jonaskoelker: introflection and all that jazz?

17:18 sattvik: So, I wouldn't count on it for security.

17:18 brehaut: ,clojure.core/sig

17:18 jonaskoelker: sure

17:18 clojurebot: #<CompilerException java.lang.RuntimeException: No such var: clojure.core/sig, compiling:(NO_SOURCE_PATH:0)>

17:18 brehaut: ,#'clojure.core/sig

17:18 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve var: clojure.core/sig in this context, compiling:(NO_SOURCE_PATH:0)>

17:18 brehaut: bah

17:19 ,#'clojure.core/sigs

17:19 clojurebot: #'clojure.core/sigs

17:19 jonaskoelker: a more mundane problem, I'm doing (:use clojure.contrib.combinatorics) after upgrading clj 1.0->1.3 and contrib 1.0.0 to 1.1.0 and it no worky. Whys?

17:19 brehaut: ~contrib

17:19 clojurebot: Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

17:20 jonaskoelker: Oh look, a manual! :)

17:20 technomancy: manual is kind of a strong term

17:20 brehaut: its more like a divining rod

17:21 not to diminish the work seancorfield has done

17:25 mmarczyk: dnolen: posted a new patch -- hopefully this one will work -- what do you think?

17:26 dnolen: mmarczyk: yep, looks ok.

17:26 mmarczyk: dnolen: whew. :-)

17:26 jonaskoelker: bah, anybody care to help me not have to beat my head against the wall?

17:26 mmarczyk: a hairier ball than I originally suspected

17:27 dnolen: mmarczyk: at some point we're going to have to sort out this namespace / locals masking issue - but that's another series of tickets.

17:27 mmarczyk: dnolen: I was actually thinking about this the other day

17:27 jonaskoelker: mylib @ http://paste.debian.net/167049/ --- tests @ http://paste.debian.net/167050/ --- ./roll.clj compile error @ http://paste.debian.net/167051/

17:28 mmarczyk: dnolen: I've got some design notes

17:28 dnolen: mmarczyk: rewriting local names that are known to be nses?

17:28 mmarczyk: dnolen: could tidy them up a bit and post them to ggroup / Confluence (assuming I've got the perms)

17:28 dnolen: yeah, plus interop story around that

17:29 dnolen: mmarczyk: is it big enough of an issue for Confluence? :) I'd just add those notes to the existing ticket.

17:29 mmarczyk: unless it is a bigger issue.

17:29 mmarczyk: dnolen: not really, but it's bound to complicate calling into cljs from js a (very little) bit

17:29 dnolen: which I'm not really worried about :-)

17:30 dnolen: I missed the existing ticket though, if there is one surely it's the best place for this :-)

17:30 sattvik: jonaskoelker: How are you running your program?

17:30 jonaskoelker: "./roll.clj"

17:31 with envvar CLASSPATH=/usr/share/java/clojure1.3.jar:/usr/share/java/clojure.jar:/usr/share/java/clojure-contrib.jar:.

17:31 dnolen: mmarczyk: http://dev.clojure.org/jira/browse/CLJS-180

17:31 mmarczyk: dnolen: thanks! will post a comment there in a little while

17:31 jonaskoelker: btw, 'sattvik', is that norwegian? It sounds that way to my (danish) ear...

17:32 mmarczyk: dnolen: ah, btw -- so do you have a patch for 232? could have a go at writing one in the spirit of the ICounted patch unless you're planning to do it today

17:33 dnolen: mmarczyk: it mixed in with some other stuff, so I don't have a patch handy.

17:34 sattvik: jonaskoelker: Well, I'm not what the problem is. It seems like it can't find the combinatorics class... It's hard to tell if the path is being set up properly within the program.

17:34 jonaskoelker: Oh, it's Sanskrit.

17:34 mmarczyk: dnolen: well, I'll look into how much of a hairball would result from just wiring in a satisfies? check and a linear traversal helper

17:35 jonaskoelker: oh ok; in my brain it kinda' pattern-matches against boddhiSATTVa, FWIW

17:35 dnolen: marchdown: minor thing - for your patches mind adding the ticket # in the commit message?

17:35 jonaskoelker: sattvik: path is being set up properly <-- me no gets?

17:35 i.e. System/getProperty "java.class.path" ?

17:35 sattvik: jonaskoelker: Yes.

17:35 mmarczyk: in an hour or so, probably, since I suddenly came over all peckish -- need to take care of that now

17:38 sattvik: jonaskoelker: You could try adding a line to print out that property right before your ns declaration in roll.clj, that would at least help eliminate that possibility.

17:39 jonaskoelker: sattvik: /usr/share/java/clojure-1.3.jar:/usr/share/java/clojure.jar:/usr/share/java/clojure-contrib.jar:.

17:40 but I have clojure-contrib 1.1.0, in which combinatorics is still in clojure/contrib/

17:40 ^_^

17:40 sattvik: jonaskoelker: Ah, that may be the problem.

17:40 mmarczyk: dnolen: oh, did you mean me about the ticket # ? sure, could add that

17:40 dnolen: mmarczyk: yeah

17:40 mmarczyk: ok, will do

17:41 jonaskoelker: ... debian only has clojure-contrib 1.2 ?! (:must :use :newer :technology)

17:42 AimHere: There's no later version of clojure.contrib

17:42 sattvik: Well, you could try to continue using the old contrib (which may or may not work), but you'll have to use the old namespace.

17:42 An alternative is to use something like Leiningen, which can help you manage your dependencies.

17:42 mmarczyk: bbl.

17:43 jonaskoelker: it may in particular not work: java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V

17:43 amalloy: jonaskoelker: debian is great for OS components, but for keeping on top of developments in a programming language it's an awful choice

17:43 just install lein and let it do all the work you're trying to do by hand

17:44 jonaskoelker: amalloy: I'll try and store that, so that when I'm finally tired of doing stuff by hand I'll remember what you said :)

17:44 amalloy: that's the spirit!

17:46 raek: jasonbray: the "RestFn" error is known to happen when you are trying to run code ahead-of-time compiled for one clojure version on another clojure version

17:46 sorry

17:46 jonaskoelker: ^

17:46 jonaskoelker: raek: hm?!

17:46 is it also known _why_?

17:47 raek: AOT compiled code is no guaranteed to be compatible between clojure versions

17:47 jonaskoelker: sure, but why specifically RestFn(I)V?

17:47 raek: most libraries don't need to be AOT compiled, but a few parts of contrib did

17:47 amalloy: that just happens to be the first incompatibility it finds

17:48 jonaskoelker: fair 'nuff

17:48 amalloy: raek: i thought contrib was just AOT compiled for performance/size

17:48 raek: condition and error-kit needed it, afaik

17:49 since they provide new classes that have to be available statically

17:50 jonaskoelker: anyone care to help me de-boilerplate my code in a way that could earn the Good Clojurekeeping Seal of Approval? ;-)

17:51 I want to write a static analysis for my language, 'stats', which outputs the probability distribution described by a dice roll formula, e.g. "d2 + d2" -- or '(+ (d 2) (d 2)) -- should output {2 1/4, 3 1/2, 4 1/4}

17:52 I have a _lot_ of functions (addition is a good example) where I just want to apply the function to the keys in some other maps, multiply the probabilities, and add that into a new map (roughly speaking)

17:53 I have a lot of "} else if (function == 10) { do function 10;"-ish code going over all the functions; I was thinking about putting them in a set, but what do I put? Symbols, functions, ...?

17:53 strings?!

17:54 madsy: Humble question. What is the most straight-forward way to use OpenGL with Seesaw? Would I need to make my own OpenGL-enabled frame from scratch by using Swing and jOGL?

18:22 gfredericks: jonaskoelker: depending on where the code is coming from, you might make a map from symbols to functions

18:22 {'+ (fn [a b] ... add a and b somehow ...), '- (fn [a b] subtract...), ...}

18:23 jonaskoelker: gfredericks: I'm writing all of it. That sounds like a fair idea

18:26 gfredericks: jonaskoelker: and if a lot of the functions do the same kinds of things, a higher-order-function can probably help DRY it up

18:26 jonaskoelker: in C terms, how do I make a variable static to a function? e.g. what I mean by (let [fun-data 0] (defn foo [] (increment fun-data)))

18:26 DRY = don't repeat yourself?

18:26 gfredericks: yeah

18:26 jonaskoelker: i.e. express `for' in terms of `while' -style xforms?

18:27 gfredericks: I'm not exactly sure what you're asking wrt making a variable "static to a function". If I had to guess what that meant, it'd be something like your (let ... (defn ...))

18:28 brehaut: you probably dont want to do this but

18:28 ,(let [c (atom 3)] (while (< 0 @c) (prn (swap! c dec))))

18:28 clojurebot: 2

18:28 1

18:28 0

18:28 technomancy: jonaskoelker: functional languages don't let your change the value of locals

18:29 jonaskoelker: technomancy: the impure ones do :) [and anyways the change wasn't the point, the visibility was, but yeah, my example was bad]

18:29 gfredericks: technomancy: sounds more like unfunctional languages then amirite

18:29 technomancy: sorite

18:29 jonaskoelker: I think you mean `dysfunctional languages' ;-)

18:29 technomancy: "static" is such a nonsense word in Java

18:29 madsy: jonaskoelker: What exactly do you want to do?

18:30 jonaskoelker: gfredericks idea works for me

18:30 gfredericks: I think (let [...] (defn ...)) is good idiomatic stuff

18:30 jonaskoelker: I must have typoed it when I did it the first time around

18:30 madsy: If you just need a for-loop there are better ways.

18:30 gfredericks: brehaut: crickey I didn't even know we had while

18:30 jonaskoelker: nah, I just want to make a big data structure visible to only one function, but not computed on every invocation

18:31 brehaut: gfredericks: thats the correct response ;)

18:31 gfredericks: ive used it once ever, and thats for a logging loop in an IRC bot

18:31 madsy: jonaskoelker: Then use a closure

18:31 gfredericks: brehaut: I probably could have used it a few times when I did a (loop [] ...)

18:31 brehaut: hah yes

18:32 jonaskoelker: madsy: how'd that look?

18:33 brehaut: gfredericks: https://github.com/brehaut/burningbot/blob/master/src/burningbot/logging.clj#L105-109

18:33 madsy: ,((fn[x] #(fn[] x)))

18:33 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: sandbox$eval53$fn>

18:33 madsy: ,((fn[x] #(fn[] x)) 1)

18:33 clojurebot: #<sandbox$eval85$fn__86$fn__87 sandbox$eval85$fn__86$fn__87@1556157>

18:33 jonaskoelker: madsy: would gfredericks (let ... (defn ...)) be another way of essentially the same?

18:34 madsy: Yes, sure.

18:34 gfredericks: depends on if your data structure is constant and hard-coded or if you want to make them on the fly

18:34 brehaut: this "burningbot" is some kind of terrorist I assume?

18:34 madsy: Wow.. I screwed up my example pretty bad there.

18:35 brehaut: gfredericks: ircbot for the burning wheel RPG channel

18:35 amalloy: technomancy: "static" is worse in C :P

18:35 jonaskoelker: gfredericks: basically, it's a sym-fn map, {'+ +, '- -, 'pow pow, ...}

18:35 gfredericks: brehaut: this must be one of those "video james" I've been hearing about

18:36 jonaskoelker: static is teh win in C ;)

18:36 ejackson: folks, is it to be expected that AOT breaks map->R ?

18:36 hiredman: 1d6+5

18:36 clojurebot: 11

18:36 jonaskoelker: ^_^

18:36 amalloy: jonaskoelker: it means three or four completely unrelated things depending on context

18:36 gfredericks: hiredman and clojurebot have a very strange relationship

18:36 jonaskoelker: three

18:36 brehaut: gfredericks: tabletop

18:36 jonaskoelker: 1d6+5

18:36 clojurebot: 8

18:36 jonaskoelker: wth...

18:37 gfredericks: 1d6+8

18:37 clojurebot: 9

18:37 brehaut: hiredman: is clojurebots dice just NdSides + mod?

18:37 jonaskoelker: 6*3d6

18:37 3d6

18:37 clojurebot: 6

18:37 hiredman: yes

18:37 jonaskoelker: 6#3d6

18:37 blah

18:38 amalloy: at least I count three: static functions, static globals and static locals

18:40 ejackson: check out a minimal example: https://github.com/ejackson/aotquestion/blob/master/src/aots/death.clj#L9

18:40 the other file, core.clj is not AOT'd and the class of map->R is what you'd expect.

18:41 but death.clj is AOT'd, and map->R barfs.

18:41 while (merge (R. ...) {...}) behaves as expected.

18:47 no takers ? Cowards :D

18:56 * ejackson hangs his head for killing the lively conversation.

19:11 gfredericks: you could analyze irc logs to identify the most egregious conversation killers

19:22 wmealing: I'm usually an instigator.

19:23 gfredericks: "Instagator: for when you can't find a gator fast enough!"

19:24 wmealing: when you absolutely need a reptile.

19:24 right now.

19:24 gfredericks: if only you could make money merely for having killer original business ideas

19:27 technomancy: why is it the javax.servlet/servlet-api jar is distributed without a license?

19:27 does the javax package name somehow imply it shares a license with the JDK?

19:31 wmealing: careful, oracle may be listening.

19:31 SurlyFrog: Hi all, is there a way I can specify the Clojure version that Leiningen should be using? I've got clojure 1.4.0 downloaded and can start it directly, but using `lein repl` causes it to use version 1.2.1.

19:32 wmealing: you mean for the project or for lein itself ?

19:33 SurlyFrog: um…both I guess.

19:33 (i'm *just* getting started with this)

19:33 wmealing: dont worry about modifying lein, it'll work as is,

19:33 but you can add :dependencies [[org.clojure/clojure "1.3.0"]]

19:33 to your projects.clj

19:34 i can paste my entire project.clj for reference if you wish

19:34 SurlyFrog: I guess what I'm wondering is how does lein know which clojure to load?

19:35 wmealing: it reads it from project.clj

19:35 sritchie: do any of you guys use leiningen 2 with intellij?

19:35 SurlyFrog: in the event that you don't start with a project, but just use `lein repl` or, simply fire up Swank...

19:36 wmealing: lein looks up itself in its script

19:36 the lein executable should just be text

19:36 CLOJURE_JAR in this example

19:36 SurlyFrog, is there a specific need for a version ?

19:36 xeqi: SurlyFrog: lein 1.x uses clojure 1.2.1 for itself

19:37 SurlyFrog: um, not necessarily, well, not that I know of yet. I'm just getting started and just trying to make sure I understand how things are pulled together. I'll do a bit more reading.

19:37 :-)

19:38 wmealing: ok

19:42 Roxxi: Is there a clojure idiom similar to the scheme receive-values syntax? Or a clear cut mechanism to return a set of values that are bound individually explicitly without processing a list (e.g. (receive (x1 x2 x3) (values 10 20 30) body ...))

19:45 gfredericks: Roxxi: is that like destructuring?

19:46 &(let [nums (range 3), [x y z] nums] (+ x y z))

19:46 lazybot: ⇒ 3

19:47 Roxxi: Hmm

19:47 yeah

19:49 Yeah, that works great! Thanks gfredericks

19:56 mrakan: I cannot seem to find a function to compute n^x (n to the power of x). What is its name? Thanks.

19:57 wmealing: Going to take a punt and say its Math/Pow

19:57 i'm not a java programmer though

19:57 mrakan: Ah, I had assumed it was a part of clojure.core. Okay, thanks.

19:57 wmealing: it may be,

19:58 LuminousMonkey: http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Math.html

19:58 sritchie: &(Math/pow 10)

19:58 lazybot: java.lang.IllegalArgumentException: No matching method: pow

19:58 wmealing: there is

19:58 http://richhickey.github.com/clojure-contrib/generic.math-functions-api.html#clojure.contrib.generic.math-functions/pow

19:58 lazybot: Nooooo, that's so out of date! Please see instead http://clojure.github.com/clojure-contrib/generic.math-functions-api.html#clojure.contrib.generic.math-functions/pow and try to stop linking to rich's repo.

19:58 LuminousMonkey: Ha!

19:58 wmealing: mrakan, there is a native. one apparntly

19:58 * wmealing looks at lazybot

19:58 wmealing: (pow x y)

19:59 mrakan: Ah, great! Thanks!

19:59 sritchie: &(Math/exp 10)

19:59 lazybot: ⇒ 22026.465794806718

19:59 sritchie: whoops :)

19:59 metellus: ,(pow 2 3)

19:59 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: pow in this context, compiling:(NO_SOURCE_PATH:0)>

19:59 sritchie: oh, of course

19:59 &(Math/pow 10 2)

19:59 lazybot: ⇒ 100.0

20:00 wmealing: ,(clojure.contrib.generic.math-functions/pow 2 2)

20:00 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.contrib.generic.math-functions>

20:00 LuminousMonkey: Looks like it's just a wrapper for Math/pow anyway.

20:00 wmealing: yeah, probably is

20:00 * wmealing ponders where they went

20:00 brehaut: technomancy: lein-licenses is a great idea

20:00 LuminousMonkey: The source uses a defmathfn-2 macro

20:00 technomancy: brehaut: thanks!

20:01 wmealing: whats that do monkey ?

20:01 brehaut: technomancy: i see amalloy needs to pick up his game and license useful though ;)

20:01 technomancy: brehaut: I remember spending a few hours tracking that down manually at my last job, but I figured now it could be automated with pomegranate

20:01 brehaut: oh yeah absolutely =)

20:01 ivan: &((fn [n x] (eval (cons '* (repeat x n)))) 10 2)

20:01 lazybot: java.lang.SecurityException: You tripped the alarm! eval is bad!

20:01 brehaut: technomancy: oh man. doing it manual? thats got to be death

20:02 technomancy: it sucked =\

20:03 wmealing: mrakan, http://clojure.github.com/algo.generic/clojure.algo.generic.math-functions-api.html#clojure.algo.generic.math-functions/pow is the more recent way to do it.

20:03 LuminousMonkey: wmealing: I'm not entirely too sure, macros are still a bit magical to me.

20:04 wmealing: i'm slowly beginning to understand them..

20:07 LuminousMonkey: &(symbol "java.lang.Math" "pow")

20:07 lazybot: ⇒ java.lang.Math/pow

20:07 LuminousMonkey: Nifty.

20:14 mrakan: Is there a way I can simply install all of the clojure.contrib libraries?

20:17 gfredericks: mrakan: I don't think so

20:17 clojure and its libraries aren't usually "installed"

20:18 mrakan: I can automatically download what I need with Leiningen, perhaps? I add the library name into the dependencies in the project file? (Yes, I'm new. :))

20:18 ivan: yes

20:18 mrakan: Great, thanks.

20:21 LuminousMonkey: [org.clojure.contrib/standalone "1.3"] or similar?

20:24 wmealing: i have a long running process and want to deal with plugins that can be downloaded/added at runtime

20:24 is there an existing project that does something similar ?

20:24 * wmealing has something working, just not happy with it

20:31 xeqi: ~contrib

20:31 clojurebot: Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

20:31 jroes: so we've got compojure and we have ring and we have noir

20:32 so I get that ring is like rack / wsgi

20:32 what are compojure and noir equivalent to?

20:32 brehaut: compojure is the routing layer

20:32 weavejester: jroes: Kinda equivalent to Sinatra

20:32 brehaut: i believe its roughly comparable to sinatra in design?

20:32 jroes: gotcha

20:32 brehaut: noir is kind of like icing ontop of compojure

20:32 gfredericks: it's like sinatra

20:32 jroes: are there any other frameworks of note?

20:33 (web)

20:33 gfredericks: less frameworks more libraries

20:33 weavejester: brehaut: Noir's more like Sinatra I think. Compojure's perhaps a little lower level since it doesn't have the helpers that Sinatra and Noir do.

20:33 brehaut: weavejester: ah thanks

20:33 muhoo: oh gawd, i never want to deal with a framework again

20:33 brehaut: jroes: there are some older frameworks that try to be more rails like, but they arent noteworthy

20:33 jroes: gfredericks: gotcha, if it's not idiomatic to do something like Rails in Clojure, that's understandable

20:33 brehaut: muhoo: seconded

20:34 weavejester: A lot of things in Rails tend to be counter to Clojure's philosophy, I think.

20:34 gfredericks: I think you more pick-and-choose the features you want via middleware

20:34 brehaut: likewise django things

20:35 gfredericks: likewise TI-BASIC things

20:35 jroes: I see. that philosophy seems a bit closer to node's as well

20:35 brehaut: due to the design of compojure (and moustache, an parallel library) middlewares are much more versatile than in other systems

20:35 jroes: (not that anyone here wants to be associated with the node community ;))

20:35 brehaut: well, the design of ring and compojure

20:36 weavejester: I'd say it's more Clojure itself that makes middleware so simple to use. In Ruby middleware is similar, but because it's all objects and there's no immutable data structures it doesn't work as well.

20:36 Rack's design works better in Clojure than Ruby, IMO :)

20:36 brehaut: lol

20:36 weavejester: Or maybe it's that HTTP is more suited to Clojure

20:36 brehaut: everytime i write a django middleware i get really furious

20:36 jroes: well geez, weavejester over seems to be the original author of most of the web-related libraries, haha :)

20:37 brehaut: half of

20:37 if you go by original author, but most of if you go by major contributor ;)

20:38 weavejester: A few. There's also Mark McGranaghan and Chris Granger who do a lot of stuff of note

20:40 jroes: so how about a lot of the typical things you need in a web app - authentication, authorization. is sandbar still the standard (doesn't have very many recent commits)?

20:40 gfredericks: isn't that what cemerick's friend does?

20:41 weavejester: jroes: Chas Emerick recently released Friend, which is maybe a more idiomatic approach to auth

20:41 brehaut: i dont think sandbar was ever a standard. it is/was popular though

20:41 jroes: gotcha, I'll check that out

20:41 gfredericks: sandbar good for regular session/flash stuff

20:41 weavejester: There are parts about Friend I'm uncertain about, but I can't think of any better way of doing them :)

20:42 brehaut: yes, cemerick was brave taking on that particular beast

20:43 weavejester: brehaut: Definitely! One need only look at all the Java auth frameworks to see how badly it can be messed up :)

20:44 brehaut: haha yes

20:45 one thing i like about the clojure web ecosystem is how the highly decoupled nature of things has let stuff like this develop gradually and with less baked in mistakes

20:45 * brehaut has django battlescars

20:45 gfredericks: is core.logic/logic-programming-in-general appropriate for searching a very large search space with heuristics?

20:45 brehaut: yes??

20:45 lazybot: brehaut: Definitely not.

20:45 mdeboard: brehaut: What ever could you mean? Django is an enlightened web framework that perfectly encap-- I just wet myself.

20:46 brehaut: mdeboard: django was great in 2005

20:46 gfredericks: I wasn't sure if it was perhaps only for situations where you can afford exhaustive dumb searches

20:46 brehaut: i am of the opinion that it has rusted

20:46 emezeske: I'm a huge fan of the decoupled nature of clojure web libraries, but I must admit it does make it a bit difficult to get started

20:47 brehaut: moar docs!

20:47 emezeske: Yeah, I think more full-featured example projects would be really beneficial

20:47 weavejester: Decoupling does make it trivial to factor out components into separate services, which I especially like.

20:47 mdeboard: I'm of the opinion that it is a kitchen-sink approach that is great when you are starting a project and want to get it up & iterate quickly. After that phase though it's time to move on to something else. The entire Django ecosystem spawns these huge, tightly coupled apps that try to do everything and wind up falling apart at a certain level of complexity.

20:48 weavejester: But I agree it's currently hard to get started.

20:48 brehaut: noir is a great aid here

20:48 weavejester: Noir makes it a lot easier

20:48 brehaut: it hits a bit of a sweet spot of enough stuff together to get started, without being overbearing

20:48 LuminousMonkey: mdeboard: That's what I found with Rails, it was great when I first started my project, but when I progressed onto needing to do things differently, it became harder to do.

20:49 brehaut: ive been promising ibdknox that i'd write a follow up to my ring post about noir, but i have yet to write anything that is better than his existing docs

20:49 ibdknox: I have some thoughts on doing all of this better

20:49 this being web programming in Clojure

20:49 brehaut: i also think i sold compojure a little short in my ring article and that needs to be addressed

20:49 ibdknox: I'm not happy yet

20:50 weavejester: The only thing I don't really like about Noir is the way routes are set globally. But admittedly it does make it easier to get started.

20:50 ibdknox: weavejester: yeah it has advantages and disadvantages

20:50 brehaut: thats what i dont like about noir either ;) it solves a non-problem for me. i like centralised route config

20:50 (though i can understand why you might not)

20:51 ibdknox: well recently I've been of the opinion that I shouldn't have to write routes at all

20:51 brehaut: really‽

20:51 hiredman: routing via namespaces?

20:51 ibdknox: nope

20:52 jroes: the interesting thing for me is that as a Rails dev by day, whenever I found that I was doing something that went against "The Rails Way" I questioned whether my approach was correct in the first place. many times I found that I could solve the problem in another way that played nicer with the framework and made my life easier

20:52 ibdknox: urls have become artifacts for the most part

20:52 weavejester: I'm kinda of the opinion that you should be able to break up a web site into services as easily as you can split up a namespace.

20:52 ibdknox: they no longer correctly map to the functionality of the things we build

20:52 mrakan: Leiningen successfuly downloaded org.clojure/algo.generic for me, but I can seem to require it in my projects. The compiler complains it cannot find it in the classpath. (:require [clojure.algo.generic.math-functions :as math]) What am I doing wrong?

20:52 *can't

20:52 ibdknox: we're not building hyperlinked pages anymore

20:52 mdeboard: who's we? :P

20:52 The royal we

20:52 hiredman: ibdknox: interesting

20:53 ibdknox: Lift has some neat ideas

20:53 Meteor has some more

20:53 weavejester: ibdknox: I'm still a hyperlink fan, even if it's only for web services.

20:53 ibdknox: but I don't think either of those have it quite yet either

20:53 mdeboard: We definitely utilize links & URLs to a great extent

20:53 ibdknox: weavejester: well to be fair, I'm not saying get rid of it, but that our work shouldn't centralize around it

20:54 mdeboard: shoot where the pucks going to be ;)

20:54 LuminousMonkey: jroes: Sure, but I also have a problem with ORM which is very much the Rails way? Recently I've been thinking that more logic should be moved into the database than what Rails does.

20:54 mdeboard: in my particular domain at work, the puck is dollars and they want SEO :P

20:54 weavejester: ibdknox: My thought is that the idea of identity and state in clojure ties very closely to the ideas of URIs and resources in HTTP.

20:55 mdeboard: although frankly our URLs are just Solr queries.

20:55 ibdknox: :p

20:55 weavejester: how so?

20:55 mdeboard: e.g. /ibm/careers/indianapolis/indiana/usa/jobs/

20:56 jroes: LuminousMonkey: a lot of the most recent literature points toward modeling domain objects in your primary development language and not in your persistence layer

20:56 weavejester: ibdknox: Well, a HTTP request or response is effectively an immutable value - you can't alter it after it's been sent.

20:56 ibdknox: A resource is an identity, equivalent to a ref in Clojure, in that it contains a value bound to a range of time.

20:57 ibdknox: You can say, "This identity had the value X from time t1 to t2"

20:57 ibdknox: My favorite color was red from 2010 to 2011 or something like that.

20:57 ibdknox: yeah

20:57 weavejester: ibdknox: A URI is similar to a namespaced var.

20:58 mdeboard: hm.

20:58 ibdknox: that's true so long as you're building pages

20:58 weavejester: If you're building web services that return resources as well.

20:58 mdeboard: interesting way of thinking about it, and especially applicable to views like http://jobs.jobs/new-york/new-york/usa/jobs/communication-jobs/new-jobs/deloitte/careers/

20:58 @ weavejester

21:00 weavejester: mdeboard: Yep

21:00 technomancy: the difference between a resource and a representation is very key to this

21:00 weavejester: A representation is just a serialization of a data structure IMO

21:01 ibdknox: Out of interest, when do you think it isn't true?

21:02 ibdknox: I guess it's true if you assume that those "vars" are always functions to execute

21:03 I thought you were suggesting they were values

21:03 weavejester: ibdknox: I am

21:03 ibdknox: hm, that's not true if I think of it as "I click this link, which adds an element to the page"

21:04 that url is probably something like /blah/add

21:04 weavejester: But isn't that something for Java/Clojurescript to handle?

21:04 mrakan: Why does Clojure silently convert the following into a double? (class (Math/pow (java.math.BigDecimal. 2) (java.math.BigDecimal. 48))) I'd like an exact 2^48 integer value, but I'm not sure how to accomplish that.

21:04 ibdknox: no

21:04 not if it needs to be synced across the state of the application

21:05 hiredman: mrakan: Math/pow only does doubles

21:05 weavejester: I mean, the Javascript would make an appropriate resource update.

21:05 So you'd click a link, and then you'd POST to /blah to create a new /blah resource

21:05 I mean, the JS would POST in the background

21:06 hiredman: clojure is actually converting your bigdecimals to doubles too, because math/pow only takes doubles as arguments and returns doubles

21:06 ibdknox: weavejester: sure, that sounds like a function to me though, I didn't access a value

21:06 mrakan: hiredman: Ah, I see. How would one then get an exact 2^48 value, using Clojure? The algo.generic library just aliases pow to Math/pow, so I see no alternatives...

21:07 hiredman: mrakan: read the docs on bigdecimals

21:07 ibdknox: weavejester: I don't really think that distinction matters though, your argument makes good sense both ways

21:07 weavejester: ibdknox: Well, the analogy falls down a little because you don't often create vars programmatically in Clojure.

21:07 And in practice, you wouldn't represent routes as vars because there's too many of them

21:08 dnolen: mmarczyk: new CLJS optimization idea

21:08 mmarczyk: making satisfies? use bit testing

21:08 mmarczyk: hidden field on deftype and defrecord for storing the protocols integer

21:08 gfredericks: mrakan: and of course there is ##(apply * (repeat 48 2N))

21:08 lazybot: ⇒ 281474976710656N

21:08 weavejester: But in principle you're either creating, deleting or modifying an identity with a new immutable value in HTTP

21:08 mmarczyk: dnolen: ohhhh, that's very cool

21:08 dnolen: reserved for core protocols I guess?

21:09 weavejester: Oh, on a different topic, has anyone written a dynamically-compiling caching ClojureScript middleware?

21:09 mmarczyk: dnolen: of which we have ~40, a quick M-x occur tells me

21:10 gfredericks: which lib should I look at for examples of requiring and instantiating a gclosure class? for some reason I never get this right the first try...

21:10 ibdknox: weavejester: absolutely, but I think there's something that can live on top of that abstraction too - I'm not sure I should have to think about http anymore. And how I'm considering that might look actually plays really nicely with what you're talking about.

21:10 mrakan: gfredericks: That's probably rather slow, surely? (bit-shift-left 1 48) comes to mind, but I'll into the docs to see a more readable example.

21:11 mmarczyk: dnolen: (incidentally, I've posted patches on the IReduce & IIndexed tickets, plus the cljs.reader ticket -- CLJS-225)

21:11 gfredericks: mrakan: definitely, so depends on how often you do it

21:11 weavejester: ibdknox: I'd be interested in hearing more, if you're willing.

21:11 ibdknox: weavejester: I was basically thinking of abstracting routes behind symbols that mapped to vars on the server using CLJ/CLJS

21:13 weavejester: ibdknox: How would it work with a route like "/users/N" where N can be any number?

21:13 ibdknox: weavejester: that's a function to me :) and so you'd just say (users 5)

21:13 vars can hold any value, right?

21:13 the atom one is much more interestin

21:13 g

21:14 if you have either websockets or a polling scheme, you could keep the atom sync'd

21:14 weavejester: ibdknox: Right. And… what would you get out? A ref of some description? Something derefable at least?

21:14 ibdknox: weavejester: you'd get whatever that route would return

21:16 weavejester: ibdknox: Ah, okay. I was thinking of taking it a step futher, and instead of just returning a value, return a ref that includes some sort of time data.

21:16 ibdknox: ah

21:16 interesting

21:16 wmealing: i have a long running process and want to deal with plugins that can be downloaded/added at runtime is there an existing clojure project which does a live .. check'n' load ? ala plugin ?

21:16 weavejester: So you'd not only have a value, but also a time when that value was valid.

21:17 Which would be useful for caching

21:17 dnolen: mmarczyk: yes JS doesn't have an efficient way to test interfaces like Java.

21:18 mmarczyk: looking for a value further up the prototype chain is not particularly fast.

21:18 weavejester: ibdknox: But I agree that binding a route to a var is likely where we want to go.

21:18 dnolen: mmarczyk: JS only has 32bit ints when doing bit ops.

21:18 mmarczyk: my thought was to keep the optimization modest for now.

21:18 mmarczyk: only handle the most commmon protocols, specifically the ones we have predicates for that we call all the time.

21:18 ibdknox: weavejester: and cljs can make that completely transparent

21:18 which is the exciting part

21:18 weavejester: Right :)

21:19 mmarczyk: dnolen: ok, so just a short list of, say, ISeq, ISeqable, ICounted, IIndexed, possibly IRecord?

21:20 weavejester: It would be nice to be able to hit a route via cljs, and get back a ref representing that resource.

21:20 Which could then be derefed anywhere in the cljs code into a value.

21:20 dnolen: mmarczyk: something like that

21:21 mmarczyk: dnolen: then for those protocols we could see if a given objects prototype hasOwnProperty of, say, cljs$protocols_mask$ (which all deftype'd / defrecord'd things will have) and bit-and against that if yes

21:21 dnolen: does that sound about right?

21:21 ibdknox: weavejester: yeah, definitely something to think more about :)

21:21 I think we can beat folks like meteor at their own game pretty easily

21:23 dnolen: mmarczyk: I think the hasOwnProperty test was a mistake on my part

21:23 weavejester: Clojure's concepts of identity and state and value are basically mappable directly onto REST and HTTP

21:23 mmarczyk: yeah, we'll be the titanic batter who bats the meteor away and proceeds to complete a home run

21:23 (if my understanding of baseball is correct)

21:23 dnolen: marchdown: I want to remove hasOwnProperty completely. I just added that so type ctors can printable - but I think that should be handled differently.

21:23 weavejester: Languages with mutable data structures tend not to map so well.

21:24 dnolen: mmarczyk: oops that ^ was for you. hasOwnProperty tests are also not that fast.

21:24 mmarczyk: dnolen: hm, ok

21:25 dnolen: so just do a straight lookup and check for undefined?

21:25 dnolen: mmarczyk: we'll still do all the slow tests, but if we see that it's a matching protocol, we add the fast test first.

21:26 not nil && (bit test || prototype chain)

21:26 mmarczyk: dnolen: oh wait, (bit-and js/undefined 12354) works fine

21:26 dnolen: right

21:27 brehaut: it mgiht be the confirmation bias talking, but i agree with weavejester

21:29 mmarczyk: dnolen: actually there's no reason not to nominate 32 protos for the fast path -- changing our mind later will be no problem

21:29 dnolen: (defprotocol ^:bitmasked ISeq ...) ?

21:30 dnolen: results unspecified if >= 32 protos marked this way

21:31 dnolen: mmarczyk: haha, I don't want to leak the implementation yet :)

21:31 mmarczyk: this about making idiomatic CLJS fast

21:32 mmarczyk: deftype performance is great - but idiomatic CLJS still leaves much to be desired.

21:33 mmarczyk: dnolen: I'm not proposing that this be advertised as available for use outside of core :-)

21:33 dgrnbrg: How do I write (symbol (name (ns-name *ns*)) (name (gensym))) idiomatically?

21:33 dnolen: mmarczyk: even that's too much for my tastes.

21:33 dgrnbrg: ,(symbol (name (ns-name *ns*)) (name (gensym)))

21:33 dnolen: mmarczyk: I prefer a map in the core.clj macros file for now.

21:33 clojurebot: sandbox/G__29

21:34 mmarczyk: dnolen: sure, definitely less tempting

21:35 dnolen: is this applicable to native types? that is, should IIndexed hang something on String.prototype, say?

21:35 dnolen: mmarczyk: I'm fine with slow path for native types for now.

21:36 mmarczyk: what drives me crazy is seq? on types we've already wrapped with IndexedSeq

21:36 mmarczyk: dnolen: well yes

21:36 dnolen: for example this is what we basically should do in the optimized rest fn case.

21:37 mmarczyk: IFn should definitely make the list, btw

21:37 dnolen: mmarczyk: yeah

21:39 mrakan: How come (java.math.BigDecimal. 5) works, but (java.math.BigInteger. 5) complains of a missing constructor? I tried importing by adding (:import [java.math.BigInteger]), but none of the constructors are available even then.

21:40 mmarczyk: dnolen: ok, so for now it would be (1) a fast-path-protocols map in core.clj; (2) an extra condition in the if in satisfies? right after x# -- with a bit-and; (3) extend-type needs also to be aware and attach a bitmap when extending to a fast path proto

21:41 LuminousMonkey: mrakan: (java.math.BigInteger. "5") works...

21:41 mrakan: http://docs.oracle.com/javase/1.4.2/docs/api/java/math/BigInteger.html

21:41 mrakan: LuminousMonkey: Ahhh, thanks!

21:41 http://clojure.github.com/algo.generic/clojure.algo.generic.math-f

21:41 mmarczyk: dnolen: does this sound about right? if so, could do a quick proof of concept

21:41 mrakan: Whoops.

21:42 dnolen: mmarczyk: cool, let me commit some optimization to satisfied right now.

21:43 mmarczyk: dnolen: great

21:43 dnolen: I'll solicit extend-type's cooperation then

21:45 dnolen: mmarczyk: k pushed to master, satisfies? should be free of calls to truth_

21:46 mmarczyk: in your experiments you should eliminate the hasOwnProperty test of course.

21:46 gotta run.

21:46 mmarczyk: dnolen: looks greats

21:46 ^great

21:46 dnolen: ok, see you later

21:46 dnolen: I'll do a POC and create a ticket then

21:46 dnolen: cool

21:52 muhoo: technomancy: deploying an app to a different heroku account than my own. is this really the most current way to do that? http://www.aeonscope.net/2010/02/22/managing-multiple-heroku-accounts/

21:55 mrakan: I'm new to Clojure. Is it expected that the core library is lacking somewhat, because it's still a rather new language? For instance, bit-shift-right doesn't work with clojure.lang.BigInts. I *could* just use all the java.math.BigInteger methods to manipulate the numbers, but it would be a lot uglier.

21:58 LuminousMonkey: mrakan: I don't know if that's something that core would take care of? If it existed it would be something in contrib?

22:00 mrakan: Like pow, etc, that's in clojure.math.numeric-tower

22:01 aphyr: Not gonna lie, I *really* want early return right now.

22:02 LuminousMonkey: mrakan: http://dev.clojure.org/display/doc/Documentation+for+1.3+Numerics

22:02 mrakan: I think you'll have to resort to Java.

22:04 creese: I need to create a function that takes a set of words and returns a hash with the letters of those words as keys.

22:05 I have something that works but feels like clojure anti-pattern

22:06 brehaut: ,(do (require 'clojure.string) (frequencies (clojure.string/join #{"hello" "world"})))

22:06 clojurebot: {\h 1, \e 1, \l 3, \o 2, \w 1, ...}

22:07 brehaut: you didnt say what you wanted the values of the hash to be

22:08 Raynes: aphyr: I doubt that.

22:09 aphyr: Raynes: Yeah, I do too!

22:09 Raynes: (f1 (f2 (f3)))

22:09 Raynes: each of f1, f2, and f3 can throw an exception

22:09 and need *separate* try/catch blocks

22:10 returning from each catch block

22:10 creese: #{"cat" "hat"} -> {\a #{"cat" "hat"} \c #{"cat" "hat"} \h #{"hat"} \t #{"cat" "hat"}}

22:10 that's what I want

22:11 set -> hash where letters are keys and values are sets of words

22:11 aphyr: Raynes: as far as I can tell, I need to either re-raise a unique exception from each layer, abuse dynamic bindings, or return [ok, x] [error, z] tuples from each stage which get automatically handled by some macro.

22:12 emezeske: aphyr: Returning an ok/error tuple is a very normal thing to do in a functional language

22:13 aphyr: emezeske: yeah, I'm used to it in erlang. I'm considering writing a macro to automatically unwind the call sequence if it sees an error in one of the inside calls.

22:13 reduce through the chain, basically.

22:14 emezeske: aphyr: Should be simple to do. I wrote a macro kind of like that, but only for boolean results (not ok/error tuples), and it was just a few lines

22:14 aphyr: I feel like this is a common enough pattern that someone has already solved it.

22:14 Should I use a condition library?

22:14 emezeske: aphyr: I think the premade solution is the maybe monad

22:15 aphyr: Oh, of course! /me digs up the docs

22:16 emezeske: I'm not sure if maybe-m allows information about the error to be kept around, though

22:16 <-- not a monad expert

22:16 brehaut: it doesnt

22:16 the error is just nil; its a short circuit

22:16 creese: does that clarify what I'm trying to do?

22:16 brehaut: however its trivial to make an error-m that does

22:17 mmarczyk: that's what either-m is for

22:17 leo2007: is var more like a global constant?

22:17 mmarczyk: not sure if algo.monads provides that -- probably does

22:17 but Either's used for short-circuiting computations w/ some error state in Haskell

22:17 * brehaut spelunks

22:18 brehaut: no either-m is present

22:18 mmarczyk: one returns Right value in case of success, Left errorValue for error; >>= passes through the first Left

22:19 oh.

22:19 brehaut: http://brehaut.net/blog/2011/error_monads_revisited

22:20 (and for context http://brehaut.net/blog/2011/error_monads )

22:21 i was just using it to allow xml-rpc stuff that threw Fault records back to short circuit handlers

22:22 mmarczyk: cool

22:22 brehaut: i do like that the clojure monads imp allows you to define them parametrically

22:26 creese: (zipmap (seq (first seuss)) (repeat 3 (first seuss)))

22:26 {\t "cat", \a "cat", \c "cat"}

22:27 how can I use 'merge' to get the rest of the words into the hash?

22:28 aphyr: creese: I'd use merge-with

22:28 (apply merge-with concat (map-of-chars-to-each-word))

22:32 ooh: https://github.com/scgilardi/slingshot

22:32 xeqi: &(reduce (partial merge-with clojure.set/union) (map (fn [w] (reduce #(assoc %1 %2 #{w}) {} w)) (clojure.string/split "the cat in the hat" #" ")))

22:32 lazybot: ⇒ {\i #{"in"}, \n #{"in"}, \c #{"cat"}, \a #{"cat" "hat"}, \e #{"the"}, \h #{"the" "hat"}, \t #{"the" "cat" "hat"}}

22:33 LuminousMonkey: That's just cool.

22:34 creese: &(map #(zipmap (seq %) (repeat 3 (hash-set %))) #{"cat" "hat"})

22:34 lazybot: ⇒ ({\t #{"cat"}, \a #{"cat"}, \c #{"cat"}} {\t #{"hat"}, \a #{"hat"}, \h #{"hat"}})

22:35 creese: I can't get yours to compile: java.lang.ClassNotFoundException: clojure.set

22:35 what do I need in ns?

22:35 brehaut: (require 'clojure.set)

22:36 oh, thats repl not ns

22:36 creese: I'm compiling into the repl so it should be okay

22:38 :require [clojure.set :as set]

22:38 ?

22:38 brehaut: sure

22:38 xeqi: that would work, just shorten the ns in what I pasted

22:40 muhoo: this is interesting. i installed heroku accounts plugin via this martyhaught.com/articles/2010/12/14/managing-multiple-heroku-accounts/

22:41 set it up, and now, it can't find and won't let me access the 2 clojure apps i deployed

22:41 it does, however, show an ancient ruby app i worked on years ago.

22:41 creese: why does the repl need clojure.set but not clojure.string?

22:42 muhoo: i suspect i must have been logged in as someone else, who now has my apps :-O

22:42 and i can't get them back :-(

22:42 xeqi: creese: perhaps you have transatively required clojure.string already

22:43 * muhoo tries #heroku

22:44 creese: I don't follow

22:49 xeqi: when you require a namespace that namespace can require others, and so on

22:51 creese: I see

22:51 &(apply merge-with set/union (map #(zipmap (seq %) (repeat 3 (hash-set %))) seuss))

22:51 lazybot: java.lang.RuntimeException: No such namespace: set

22:52 creese: &(apply merge-with clojure.set/union (map #(zipmap (seq %) (repeat 3 (hash-set %))) #{"cat" "hat"}))

22:52 lazybot: ⇒ {\h #{"hat"}, \t #{"cat" "hat"}, \a #{"cat" "hat"}, \c #{"cat"}}

22:55 xeqi: close

22:55 creese: mine only works with 2 words, right?

22:55 xeqi: words of length <= 3

22:55 creese: and 3 letters long

22:56 ha!

22:56 it works for any number of words

22:58 technomancy: muhoo: you don't need a plugin to deploy an app owned by a different account, you just need that account to add you as a collaborator

22:58 creese: yeah, I can't see how to get the 3 out

22:59 xeqi: &(doc repeat)

22:59 lazybot: ⇒ "([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs."

23:00 leo2007: has lein been replaced by something else?

23:01 jodaro: i'm going back to ant

23:01 cuz i love writing xml

23:02 creese: wow

23:03 I'm astounded

23:03 leo2007: me 2

23:06 xeqi: maybe by lein 2.0 previews

23:06 muhoo: technomancy: oh, but they haven't added the project. i have to add it.

23:06 while logged in as them

23:06 then i can add myself as a collaborator.

23:06 creese: &(apply merge-with set/union (map #(zipmap (seq %) (repeat (hash-set %))) #{"the" "cat" "in" "the" "hat"))

23:06 lazybot: java.lang.RuntimeException: Unmatched delimiter: )

23:06 creese: (apply merge-with set/union (map #(zipmap (seq %) (repeat (hash-set %))) #{"the" "cat" "in" "the" "hat"}))

23:07 &(apply merge-with set/union (map #(zipmap (seq %) (repeat (hash-set %))) #{"the" "cat" "in" "the" "hat"}))

23:07 lazybot: java.lang.IllegalArgumentException: Duplicate key: the

23:07 creese: &(apply merge-with set/union (map #(zipmap (seq %) (repeat (hash-set %))) #{"cat" "in" "the" "hat"}))

23:07 lazybot: java.lang.RuntimeException: No such namespace: set

23:07 creese: "_"

23:07 : &(apply merge-with clojure.set/union (map #(zipmap (seq %) (repeat (hash-set %))) #{"cat" "in" "the" "hat"}))

23:08 &(apply merge-with clojure.set/union (map #(zipmap (seq %) (repeat (hash-set %))) #{"cat" "in" "the" "hat"}))

23:08 lazybot: ⇒ {\c #{"cat"}, \a #{"cat" "hat"}, \t #{"the" "cat" "hat"}, \h #{"the" "hat"}, \e #{"the"}, \n #{"in"}, \i #{"in"}}

23:08 creese: whew

23:09 muhoo: technomancy: nm, i found the problem. i had 2 accounts, different emails

23:21 creese: when I try to assign it to an atom, I get 'nil' instead of the hash. What is wrong with this?

23:22 https://refheap.com/paste/2518

23:23 brehaut: creese: apply merge-with is passing a hash into swap! …

23:23 ,(swap! (atom {}) {:foo 1})

23:23 clojurebot: nil

23:23 creese: what should I be passing to it?

23:23 brehaut: creese: a function of the old map to the new map

23:24 ,(swap! (atom {}) (fn [m] (assoc m :foo 1)))

23:24 clojurebot: {:foo 1}

23:24 xeqi: &(doc constantly)

23:24 lazybot: ⇒ "([x]); Returns a function that takes any number of arguments and returns x."

23:24 brehaut: weeell no

23:24 you probably want reset! at that point

23:25 ,(reset! (atom {}) {:foo 1})

23:25 clojurebot: {:foo 1}

23:25 brehaut: but reset! kinda violates how atoms are intended to be used

23:25 (doc reset!)

23:25 clojurebot: "([atom newval]); Sets the value of atom to newval without regard for the current value. Returns newval."

23:25 brehaut: violates is too strong

23:26 if you are using reset! a lot, you are probably not using atoms the way they are intended

23:27 creese: initially, the hash will be empty and I need to populate it

23:27 later, I will delete keys and/or values

23:27 brehaut: right

23:28 if you can call atom with the initial value that would be better, but one call to reset! at the start is ok

23:28 creese: oh

23:28 ok

23:29 but if I call atom inside a function, will it be globally available to other functions?

23:29 brehaut: if you replace line 3's (atom {}) with (atom …)

23:29 then yeah you'll be fine

23:30 creese: what does … mean?

23:30 brehaut: your code to generate het initial state

23:31 creese: are saying delete { } and put … or put nothing?

23:32 brehaut: put whatever you would be putting in the reset! in where … is

23:33 creese: what if I used assoc and gave swap! a list of keys?

23:33 brehaut: thats fine

23:52 ivan: &(*' 99999999999 99999999999)

23:52 lazybot: ⇒ 9999999999800000000001N

23:52 ivan: wtf. that overflows here

23:52 ,(*' 99999999999 99999999999)

23:52 clojurebot: 9999999999800000000001N

23:52 Raynes: The bots never overflow.

23:53 ivan: maybe this is some terrible Java 7 / Windows thing

23:54 user=> (*' 99999999999 99999999999)

23:54 ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1388)

23:55 wei_: is there a good way to halt execution if any agent in a list has failed?

23:56 xeqi: &*clojure-version*

23:56 lazybot: ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}

23:56 ivan: oh, I am an idiot who redefined *' for kicks yesterday

23:57 the wonders of not closing your REPL

23:57 the nil (doc *') should have given it away

23:58 Swing is so weird. How does a keystroke event in one window bubble up to a completely different process?

Logging service provided by n01se.net