#clojure log - Sep 05 2015

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

1:14 reutermj: How do you add metadata to a macro with a def? `(def ^{:some-meta 4} ~name 4) doesn't work.

1:19 amalloy: reutermj: http://stackoverflow.com/a/11920022/625403

1:23 reutermj: amalloy: ok so when I set *print-meta* and change the macro to `(def ~(vary-meta name assoc :some-meta 4) 4) it prints the correct meta data. But, calling (meta some-name) returns nil

1:24 amalloy: (meta #'some-name)

1:25 reutermj: ok that was mentioned earlier. What exactly does that reader macro do?

1:30 amalloy: ,'#'x

1:30 clojurebot: (var x)

1:31 reutermj: thanks

1:31 (inc amalloy)

1:31 lazybot: ⇒ 300

2:42 TEttinger: (identity amalloy)

2:42 lazybot: amalloy has karma 300.

2:42 TEttinger: congrats

3:58 Quasimodem: I have experience with programming, java, c++, Pascal(good intro for me). I think what essentially is true in programming, is that it's more based on mindset, and how you use the language to benefit you.

6:21 ashwink005: can I convert a list of HashMaps, to a vector of HashMaps?

6:24 Rurik: ashwink005, yes, wrap the list in vec

6:24 ,(vec ())

6:24 clojurebot: []

6:27 mavbozo: ,(vec '({:a 1} {:b 2}))

6:27 clojurebot: [{:a 1} {:b 2}]

6:42 irctc: Hello everyone, is there any reason why clojure is not implemented in clojure?

6:42 Rurik: irctc, it is implemented in clojure

6:43 irctc, https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj

6:43 irctc: but why does 60% of the code base is written in java ?

6:44 luxbock: Rurik: it's only partly implemented in Clojure, though there is a separate projects that can read, analyze and emit JVM bytecode

6:45 I wonder why the Clojure jar doesn't include the java files btw

6:45 it would be nice if I could jump to the Java source location from my editor

7:00 sobel: there may be a distribution that includes source in the same jar but typically sources are omitted for brevity

7:05 clj-beginner: Hello.

7:06 Can try take multiple expressions?

7:06 Most of the examples that I have seen uses only one expression before catching

7:06 is it possible to use multiple?

7:07 I tried experimenting but I kept on getting a class cast exception error

7:07 luxbock: sobel: looking here I see that such a .jar exists https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0/

7:08 but using [org.clojure/clojure "1.7.0-sources"] doesn't seem to work, nor does it mention sources in the pom file

7:08 amalloy: http://central.maven.org/maven2/org/clojure/clojure/1.7.0/clojure-1.7.0-sources.jar

7:08 luxbock: it's not a differently-named artifact

7:08 it's the same artifact with a different qualifier - look up how to get sources from maven in general

7:08 or maybe classifier? i forget

7:09 luxbock: amalloy: ok thanks

7:09 mavbozo: ,(try (inc 1) (inc 2))

7:09 sobel: luxbock: sorry, i don't have the details, and i actually don't hope to step into Clojure code if I can help it :)

7:09 clojurebot: 3

7:19 luxbock: I think :classifier "sources" is right, but I get the following stacktrace when I try to start my REPL: https://gist.github.com/luxbock/b78272185608adb6b7b8

7:20 No matching method: unsignedShiftRight, compiling:(clojure/core.clj:1337)

7:21 I feel like it's taunting me

7:23 it did download the clojure-1.7.0-sources.jar though

7:27 so I guess the -sources .jar only includes the sources and not the class files

7:29 so you can't even start a REPL with it via clojure.main

10:40 ashwink005: can anyone give me a simple example how return a string containing "foo" x number of times

10:40 *how to

10:42 Rurik: ,(apply str (repeat 3 "foo"))

10:42 clojurebot: "foofoofoo"

10:42 rhg135: (apply str (repeat 10 "foo"))

10:42 Rurik: ashwink005, this works? ^

10:42 ashwink005: Rurik: this can be done without loop?

10:43 cool

10:43 yup thanks

10:48 tomjack: should there be a "confirm before running a template you just downloaded" option for lein?

10:59 sobel: why?

10:59 clojurebot: sobel: because you can't handle the truth!

10:59 sobel: ...guess i asked for that

11:00 tomjack: it's a CLI development tool. i'm thinking, probably not.

11:01 justin_smith: I could imagine a "delete this code that breaks the project to prove you've read the code the template generates"

11:02 but that would be weird

11:05 tomjack: I'm imagining camping in clojars on many distance 1 edits of popular templates..

11:06 justin_smith: oh, template-name typos

11:06 sobel: the correct way to manage that is to stop it at the source so the fewest number of people would be affected. beyond that, my strategy is don't take risks on precious machines. my code has been unpredictable in the past...

11:07 justin_smith: so "lein new rung" would send all your private ssh keys to my obfuscated email

11:07 sobel: the threat is within, i guess, is the lesson i take to security. there are also external threats but they are less likely to really mess things up for me.

11:07 justin_smith: tomjack: the problem is that a template can do arbitrary code at creation time - just cloning is enough to be screwed

11:08 s/cloning/using the template/

11:08 really, there should at least be an easy way to browse and approve a template before using (especially since versions are implicit...)

11:08 tomjack: right, in the lein new code it's "download, then immediately (require 'leiningen.new.whatever)"

11:09 sobel: this is perfect timing, as i contemplate converting a config file reader from to eval so i can put more interesting expressions in it

11:09 slurping edn, as it were

11:10 justin_smith: there's definitely room for an alternate, non-turing-complete template tool in the clojure ecosystem

11:10 sobel: think i'm gonna run with it, dangerous as it is. but i wonder what more cautious developers would do here, before exposing eval to essentially random files

11:10 i used to like the Velocity template language but most impls let you call into the host language from its ECMA-like macro language

11:10 other than that, i think it had a long of things right

11:11 justin_smith: sobel: my preference would be to let the user supply a function explicitly to be run

11:11 without having to just evaluate file contents - let them provide some implementation of a configuring protocol

11:12 sobel: so basically whitelist some functions

11:12 justin_smith: that's not what I said at all

11:12 sobel: figured. i don't exactly follow what you said.

11:12 justin_smith: if they want to run arbitrary code, use a code oriented interface, not eval on a text file

11:13 define a protocol that is used for config, and let them provide an implementation of that protocol

11:13 patrkris: does anyone here know how to specify an optional keyword in a map that includes a ? character in herbert?

11:15 sobel: er, "dependency injection in clojure" just crossed my search results. of all the things i am pretty damn sure i don't need in clojure, that tops my list.

11:16 justin_smith: sobel: running eval on a config file is dependency injection. In fact it is the worst kind of dependency injection.

11:17 sobel: that's one way to look at it

11:17 degenerate DI

11:17 maybe it's the DI framework i don't need. obviously i employ the concept liberally.

11:18 or non-obviously

11:18 justin_smith: sobel: I think with higher order functions available, DI is trivial

11:18 no more special than a loop

11:18 sobel: exactly

11:19 everything i used DI for in java is obviated by clojure

11:19 mavbozo: i call it Devilish Injection

11:19 justin_smith: I agree that we don't need frameworks in order to do it, but I still think it's better to define a protocol that a user can implement and pass to your code, rather than running an eval on a special file

11:19 sobel: it's a valuable practice in Java

11:20 justin_smith: fortunately i can get by with read rather than eval, but agreed

11:21 oddcully: patrkris: does adding two ? work (:lerl??)

11:22 patrkris: oddcully: it does. should've tried it. that's the obvious way :D thanks.

11:38 ashwink005: whats the clojure way of getting all rows in a db WHERE column example "contains" a substring

11:38 the best way I mean

11:40 anyone? someone knows mysql/sqlite?

11:41 mavbozo: ashwink005, what's wrong with select * from user where name LIKE '%jure%'

11:42 ashwink005: actually I have many such columns and many such values

11:42 was wondering if there was a cleaner way

11:43 mavbozo: cleaner way to generate the query?

11:44 or the fastest query?

11:53 sdegutis: Wouldn't (defn ^:memoize foo [bar] ...) be so cool?

11:54 ashwink005: mavbozo: nope a shorter way

12:03 mavbozo: ashwink005, i usually create a function that generates the query string

12:04 ashwink005: mavbozo: yeah actually now I'm doing the same :)

12:04 thanks

12:05 sdegutis: Is there a more condensed or idiomatic way to do this? (set! (. Stripe apiKey) secret-key)

12:06 mavbozo: ashwink005, it's the same thing i did in other prog-langs. I still haven't found the idiomatic clojure way.

12:06 ashwink005: mavbozo: hmmm

12:16 one small doubt, how do I change the value of a string in its lexical scope?

12:17 (str symbol "something") returns the concatenated string but doesn't append "something" to the beginning of symbol

12:18 some help please

12:19 google can't

12:22 RedNifre: maybe (str (str symbol) "something") ?

12:22 nvm I think I missunderstood what you are trying to do.

12:23 justin_smith: RedNifre: fyi (str (str x) y) is the same as (str x y)

12:23 mavbozo: ,(let [c "c"] (str s "=me"))

12:24 clojurebot: #error {\n :cause "Unable to resolve symbol: s in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: s in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: s in this context"\n ...

12:24 justin_smith: ashwink005: strings are immutable

12:24 mavbozo: ,(let [c "c"] (str c "=me"))

12:24 clojurebot: "c=me"

12:24 justin_smith: ashwink005: if you want something you can mutate, consider a functional restructuring using recursion perhaps, or you can use a StringBuilder

12:24 mavbozo: ashwink005, do you want the value of c becomes "c=me"?

12:24 justin_smith: $javadoc StringBuilder

12:24 lazybot: http://docs.oracle.com/javase/6/docs/api/java/lang/StringBuilder.html

12:24 ashwink005: mavbozo: yes

12:25 justin_smith: so I'll have to use a stringbuilder

12:25 or I can create a new variable?

12:26 justin_smith: ashwink005: sure, that too

12:26 ashwink005: okok got it strings are imutable.. like in java

12:26 justin_smith: ,(let [a "c" b (str a \= a) c (str b \& b)] c)

12:26 clojurebot: "c=c&c=c"

12:26 justin_smith: ashwink005: in fact... ##(type "")

12:26 lazybot: ⇒ java.lang.String

12:26 justin_smith: they are java strings :)

12:27 ashwink005: justin_smith: yeah I reckoned

12:27 thanks!

12:33 tmtwd_: , (list 'if true (cons 'do (println "yay")))

12:33 clojurebot: yay\n(if true (do))

12:34 tmtwd_: why is there the (if true (do)) there?

12:34 hyPiRion: because (println "yay") prints yay and returns nil

12:34 justin_smith: tmtwd_: that's the return value of he expression

12:34 ,(cons 'anything nil)

12:35 clojurebot: (anything)

12:38 tmtwd_: oh

13:20 thesaskwatch: Hi .. I'd like to run some i/o tasks - a lot of them. Is there a way to partition them and run in let's say n threads at once?

13:24 Ok ... I guess it's just a partition, map and run a future

13:27 skeuomorf: So, I need to get the skinny on Clojure's concurrency story, from threads to core.async, any resources? Terseness with examples preferred

13:33 Terseness and examples along with it*

13:36 justin_smith: skeuomorf: start with the docs on http://clojure.org/documentation for refs, agents, and atoms, then check out the relevant functions on http://conj.io

13:37 conj.io has more examples, but clojure.org is the better big-picture

13:38 also note that refs, agents, and atoms are three different strategies for managing concurrency, and each has their use cases (see also core.async, which is a whole other can of worms and also has its use cases)

13:39 skeuomorf: justin_smith: I read all these docs yesterday, haven't read the core.async ones

13:39 justin_smith: They didn't mention any "threads", most of the talk was about how to "share" or "not share" resources in a sense

13:39 justin_smith: it's a whole other parallel system - you can use them together, but each (refs, agents, atoms, core.async) are usable on their own

13:40 skeuomorf: the simple way to make a thread is via future

13:40 skeuomorf: also, agents use a pool of threads for all operations - with agents the way to use a thread is hand a task to the agent

13:40 skeuomorf: Will take a look at that as well as the core.asyync docs

13:40 justin_smith: the agent will find and use a thread

13:41 skeuomorf: I see

13:41 justin_smith: skeuomorf: most of the time in my code, the threads are started by an http request (new client gets allocated a thread)

13:41 or a websocket connection

13:41 etc.

13:42 skeuomorf: Yeah, what I have in mind is something close, I will be using UDP though

13:42 I am mostly trying to formulate my ideas in term of clojure abstractions instead of "objects" interacting with each other

13:43 justin_smith: UDP doesn't have connections though - so I guess it's more a thread per message

13:43 skeuomorf: Yeah, I will "fire off" multicast messages and occasional single destination ones

13:43 justin_smith: skeuomorf: you might want to check out aleph if you are listening for messages as well

13:44 skeuomorf: I stumbled upon that and it seemed interesting, will check it out

13:45 When should one use defrecord instead of making a (defn make-record [] {:myid id :whatever 1})

13:46 justin_smith: skeuomorf: once you go so far as having a special constructor, use a defrecord

13:46 skeuomorf: if you are creating maps ad-hoc, maybe you don't need a record

13:46 of course the real clincher is if you want to use protocols so that clients can provide behaviors in some system - then you really want defrecord

13:47 skeuomorf: nah, I am kinda making "instances" of a certain map structure

13:47 Yeah, I will mostly define a protocol

13:47 justin_smith: skeuomorf: "instances" is enough reason to make a defrecord. If you are formalizing it, go ahead and formalizing it.

13:47 skeuomorf: for a protocol you need a defrecord because protocols dispatch by type, not keys

13:48 skeuomorf: Yeah, I figured that much

13:48 justin_smith: records are pretty lightweight, and mostly maps in every way that is useful, so I would jump over to using one as soon as you would give it a special name or constructor

13:48 skeuomorf: I see

13:49 justin_smith: skeuomorf: but the other thing you were talking about was being less OO

13:49 I think the key to that is think less about data types, and more about flows of data

13:49 *one key, at least

13:49 skeuomorf: Well,,

13:50 I am thinking in flows of data alright, my problem is that I will have multiple "instances" and each one will affect the other in the same function

13:51 so, 2 instances > function > 2 new instances

13:51 justin_smith: skeuomorf: I have a middleware that attaches a creation time, unique id, and client id to messages. This is fp because I ignore the type of the thing coming in (it just needs to be a type that lets me assoc). This is in contrast to expecting message senders to use my constructor which attaches that data.

13:51 skeuomorf: counting instances of things - so these things are tied to side effects and/ or state?

13:52 skeuomorf: well, both

13:52 I am implementing SCAMP

13:52 Which is a probabilistic gossip protocol

13:52 re: http://research.microsoft.com/pubs/67296/ieee_tocs.pdf

13:52 justin_smith: OK - this is a different sense of "protocol" than I was using earlier

13:53 skeuomorf: oh, I know, don't worry

13:53 :)

13:53 justin_smith: just making sure signals aren't getting crossed

13:53 skeuomorf: Yeah yeah, I got you

13:53 justin_smith: skeuomorf: a great idea I picked up from stuartsierra is that you should use FP for logic and computation and use OO for state.

13:54 and clojure has various ways of helping bring those together

13:54 a consequence of that, is the OO part of your code will often be singletons

13:54 (and of course in pure FP the concept of a singleton makes no sense)

13:55 joncol: Is there any way of having "lein new app" create a Mercurial repository instead of Git?

13:55 skeuomorf: well, let me tell you the mutable state "behavior" in this protocol

13:55 justin_smith: anyway - stepping away from the keyboard, but will be around later

13:55 go ahead and describe, I just can't reply right away

13:55 skeuomorf: justin_smith: Ok, nvm then, thanks for helping :)

13:55 justin_smith: maybe someone else here is interested too

13:55 skeuomorf: I will mess around anyways

13:56 maybe will do an impl tonight

13:58 oddcully: joncol: lein new does not create a git repo (at least not for me)

13:58 joncol: but it creates a .hgignore file (beside a .gitignore one)

13:58 joncol: oddcully: Oh, missed that :)

14:07 sineer: Hey hey! I got a question about CPU load averages

14:08 when running inside a KVM my server is idle yet I see varying CPU load averages... Is it that I somehow see the load average of a CPU that I'm sharing with another KVM instance?

14:09 I have the same idle server image running on two different KVM host and the load averages are always very much diferent, one can be at 0.95 while other is at 0.10 for instance

14:09 kitallis: I get a "java.lang.ClassNotFoundException: jsr166y.ForkJoinPool" when running lein repl, anyone know what that means?

14:10 Rurik: kitallis, are you running it in a project dir?

14:10 kitallis: yeah

14:11 don't understand, this was fine a while back, not sure what I changed

14:12 Rurik: google says jsr166y is some concurrency library

14:12 oddcully: kitallis: bisect it

14:12 kitallis: yeah it says "java.lang.ClassNotFoundException: jsr166y.ForkJoinPool, compiling:(clojure/core/reducers.clj:56:21)"

14:13 it's happening on all projects

14:13 oddcully: kitallis: same as here maybe? http://grokbase.com/t/gg/clojure/12c9wa1haj/exception-when-loading-clojure-core-reducers

14:13 kitallis: I think it's some global thing I messed up

14:13 oddcully: java version then?

14:37 dfens: If I have a map {:a 1} why do both (:a {:a 1}) and ({:a 1} :a) work? Isn't it confusing to have two ways to get the value of :a?

14:39 amalloy: dfens: why does (+ 1 5) work as well as (+ 5 1)? that's gotta be confusing too, right?

14:40 keywords and maps are both functions, because it may be convenient to use either of them as functions in different contexts

14:41 dfens: amalloy: Ok sure thing. I guess I'll have a better grasp of that when I come across these different contexts :)

14:42 amalloy: dfens: well, examples are easy: ##[(map {:a 1, :b 2} [:a :b]) (map :a [{:a 1 :b 2} {:a 2 :b 1}])]

14:42 lazybot: ⇒ [(1 2) (1 2)]

16:00 cryptack: looking for some understanding between just deffn inside a function and using letfn?

16:01 justin_smith: cryptack: defn inside a function makes a top level binding

16:02 cryptack: letfn makes multiple functions, with only local bindings, which can refer to each other recursively without declarations needed

16:03 cryptack: so if I were to do (defn f1 [x] (defn f2 [y] y) (f2 x)) then that means that f2 can be called from outside of f1?

16:03 justin_smith: ,(letfn [a ([x] (b (b x))) b ([x] (+ x 21))] (a 0))

16:03 clojurebot: #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Symbol"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Symbol"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.lang.RT first "RT.java" 661]\n [clojure.core$fi...

16:03 justin_smith: cryptack: yes

16:03 cryptack: got it

16:03 I’m assuming the same with just fn then?

16:03 justin_smith: ,(letfn [(a [x] (b (b x))) (b [x] (+ x 21))] (a 0))

16:03 clojurebot: 42

16:03 cryptack: like an named fn

16:04 justin_smith: cryptack: (let [a (fn [x] (b (b x))) b ([x] (+ x 21))] (a 0))

16:04 err

16:04 ,(let [a (fn [x] (b (b x))) b ([x] (+ x 21))] (a 0))

16:04 clojurebot: #error {\n :cause "Unable to resolve symbol: b in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: b in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: b in this context"\n ...

16:04 justin_smith: cryptack: unlike fn and let, letfn lets you forward reference

16:04 eg. for mutal recursion

16:05 cryptack: ok

16:05 justin_smith: notice the let version of my prior letfn fails because of the binding order

16:05 cryptack: justin_smith: okay

16:06 justin_smith:

16:06 justin_smith: thanks!

16:41 irctc: hello

16:43 is there a way to replace the current process with an other one in clojure

16:43 pretty much like exec() in C

16:44 i'd like a clojure script to ... just become a python script :p

16:55 skeuomorf: irctc: I don't know about "replace the current process" but checkout https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html

16:55 irctc: You'd access that via the Clojure Java interop facilities

16:56 irctc: hmmm

16:56 but i don't know any clojure :/

16:56 skeuomorf: Then, what are you doing writing clojure?

16:57 * skeuomorf afk

16:57 irctc: it's for a code golf achievement

16:58 i need to find a solution to a problem in clojure

16:58 i solved the problem in python

16:58 want to write a clojure script that would call my python scipt

16:58 :P

16:58 just did that with the bash achievement

17:01 justin_smith: (do (clojure.java.shell/sh "your-script.sh") (shutdown-agents) (System/exit 0))

17:02 that exits after the script instead of before though

17:02 there's no way in java to do a normal exec because windows sucks

17:59 xzilend: Hi there, I'm relatively new to clojure/functional/declarative programming, and was wondering if anyone could suggest improvements to this gist (https://gist.github.com/adairdavid/f7983b15f63773340151) to better follow a functional/declarative style?

18:03 justin_smith: xzilend: instead of nested if you could try cond - I'm not sure if that is more functional, but I find it easier to parse

18:05 neoncontrails: Could someone help me understand the control flow of a function that evaluates serially, but rebinds in parallel?

18:05 ,(doc recur)

18:05 clojurebot: No entiendo

18:06 justin_smith: neoncontrails: well, you can't do what you are describing with recur

18:06 neoncontrails: recur

18:06 (recur exprs*)

18:06 Special Form

18:06 Evaluates the exprs in order, then, in parallel, rebinds the bindings of the recursion point to the values of the exprs.

18:06 justin_smith: recur only works in the tail position, so can't be invoked in parallel

18:06 neoncontrails: Execution then jumps back to the recursion point, a loop or fn method.

18:06 justin_smith: err, oh that's a different kind of parallel...

18:07 neoncontrails: what it means is that the recur bindings are not applied in series the way let bindings are

18:07 neoncontrails: in let, you can refer to the value of other bindings in the same let binding block, because they are evaluated in series

18:07 neoncontrails: I thought I understood this, but I'm getting some funny outputs which might be explained by semi-arbitrary ordering of variable rebindings on the recursion

18:07 justin_smith: ,(let [a 0 b (inc a) c (inc b)] c)

18:07 clojurebot: 2

18:08 justin_smith: neoncontrails: the bindings inside recur don't refer to the values of other bindings in the recur

18:08 they refer to the values in scope when recur is called

18:09 neoncontrails: I see. Gotcha. So no referring to the (first s) of some sequence that's getting repeatedly dropped on the recursion, then

18:10 Within the recur statement, that is

18:10 justin_smith: ,(loop [a 0 b 10] (if (> a b) (+ a b) (recur (* a b) (* b 0.9)))

18:10 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

18:10 sg2002: Hello. Anyone having any problems with the latest cider? I get No active nREPL connection even though there is one.

18:10 justin_smith: neoncontrails: well you can refer to first s, just be aware of which s it binds to

18:11 neoncontrails: inside the recur it will be whatever s was bound when this recursive call started

18:11 inside the loop declaration, it is only the initializer and doesn't effect future values when recurring

18:11 sg2002: I find that when cider does that I need to clean up my elc files, restart emacs, then reinstall cider

18:12 neoncontrails: Hmm. Let me pastebin my function, maybe you can tell me if I'm doing something illegal inside the recur statement

18:12 justin_smith: sg2002: #clojure-emacs might be able to offer more help, I stopped using cider because of how often it broke backward compatibility.

18:13 sg2002: justin_smith: Oh, never knew about that channel. Thank's for the tip, there are some weird byte-compile bugs that happen once in a blue moon.

18:14 justin_smith: sg2002: in my experience what was happening is that they were breaking api compatibility with their old code versions, which made the byte compiled code break

18:14 and like every release would do this

18:16 neoncontrails: justin_smith: http://pastebin.com/4dtCrL7G

18:17 justin_smith: neoncontrails: those bindings should work...

18:17 neoncontrails: It's perfectly likely there's just a bug in the logic, I just want to make sure I'm using the primitives correctly

18:17 justin_smith: yeah, that looks like a perfectly cromulent usage of recur

18:17 neoncontrails: Okay, cool. I'll treat it as a bug in the logic then. :)

18:17 Thanks!

18:17 (inc justin_smith)

18:17 justin_smith: the thing about parallel vs. serial bindings is a bit of a finicky point

18:17 lazybot: ⇒ 294

18:17 sg2002: justin_smith: That's pretty weird, since package.el generally recompiles that stuff every time.

18:18 justin_smith: sg2002: maybe they don't describe their dependencies properly...

18:18 because I definitely fixed my problems by wiping out my package managed elisp code

18:18 neoncontrails: Yeah, what... precisely does it mean, exactly?

18:18 I understand the difference between serial and parallel

18:19 amalloy: neoncontrails: (= (count s) < 3) ??

18:19 justin_smith: what it means is that in eg. let one let binding can refer to the value of the one right before it

18:19 lazybot: amalloy: What are you, crazy? Of course not!

18:19 neoncontrails: I am not sure what it means to interleave them

18:19 justin_smith: oh, yeah that is super weird!

18:19 (inc amalloy)

18:19 lazybot: ⇒ 301

18:19 justin_smith: I missed that one

18:19 you likely want (< (count s) 3)

18:20 what you did was test if (count s), <, and 3 are all the same

18:20 which of course is trivially false

18:20 (unless someone is doing bad bad things to your comparison operators)

18:20 amalloy: and the (second uncompressed) looks like it ought to be (first compressed)

18:21 neoncontrails: you know there is a much easier way to implement RLE, right? you are just doing it this way as a loop/recur exercise?

18:21 neoncontrails: amalloy: Do tell!

18:22 I am doing this as an exercise, but I'm always interested in learning efficient, better ways to solve problems. :)

18:22 amalloy: look at ##((fn rle [s] (apply str (mapcat (juxt count identity) (partition-by identity s)))) "aaabddcejkkeddddddd")

18:22 lazybot: ⇒ "3(\\a \\a \\a)1(\\b)2(\\d \\d)1(\\c)1(\\e)1(\\j)2(\\k \\k)1(\\e)7(\\d \\d \\d \\d \\d \\d \\d)"

18:22 amalloy: er

18:22 ##((fn rle [s] (apply str (mapcat (juxt count first) (partition-by identity s)))) "aaabddcejkkeddddddd")

18:22 lazybot: ⇒ "3a1b2d1c1e1j2k1e7d"

18:23 justin_smith: you clojure wizards and your fancy repl tricks

18:23 I tell ya what

18:23 neoncontrails: Too cool. I'm going to meditate on that one for a bit, brb

18:24 justin_smith: neoncontrails: many of those functions are worth a very deep meditation and practice and mastery

18:24 (inc juxt)

18:24 lazybot: ⇒ 23

18:24 justin_smith: (inc comp)

18:24 lazybot: ⇒ 2

18:25 neoncontrails: Wait what's going on. Are you giving the language primitives karma

18:25 oddcully: we give even rubber ducks karma

18:25 justin_smith: yes, it's a tridition here

18:25 (inc rubberduck)

18:25 lazybot: ⇒ 6

18:25 justin_smith: *tradition

18:26 while I'm at it

18:26 (dec flatten)

18:26 lazybot: ⇒ -7

18:26 neoncontrails: Hahahahaha. Clojurians, you crack me up. :)

18:26 amalloy: RIP flatten. never forget

18:26 oddcully: boo flatten

18:26 amalloy: (dec tridition)

18:26 lazybot: ⇒ -1

18:27 justin_smith: amalloy: sometimes I also pronounce things atrociously, it's like I have a gibberish demon trying to crawl its way out

18:28 amalloy: i spell concise right about one time in three

18:28 got it wrong here, before backspacing

18:29 justin_smith: also my handwriting is very bad (though I have been trying to improve that lately because it's a nice break from screen/keyboard oriented stuff) - so all methods of conveying words have an added noise layer

19:18 Matachines: hey guys, new-ish to clojure/cljs, was wondering what the commonly used library for generating statistics is (stuff like mean/standard deviation, etc)

19:19 bacon1989: interesting, I don't even know what scientific libraries there are

19:19 justin_smith: Matachines: yeah, there's incanter for that http://incanter.org/

19:19 Matachines: thanks justin_smith

19:19 !

19:19 justin_smith: it does graphing too

19:19 Matachines: perfect

19:20 justin_smith: I do graph analysis for my day job, we've been intending to start adding statistical analysis to our bag of tools for making metrics

19:21 bacon1989: justin_smith: you ever use gorilla repl for fast sketches?

19:21 justin_smith: bacon1989: no, I've intended to try it but haven't yet

19:21 bacon1989: and there's another similar one, the name is escaping me...

19:21 bacon1989: i've used it before, and found it pretty awesome

19:21 especially when working with people who don't know clojure

19:22 justin_smith: seems like it would be a kickass learning tool

19:22 bacon1989: ya def, I agree

19:23 justin_smith: though my tried and true is to only do things that work when you run "java -jar clojure.jar" because eliminating tooling problems from teaching is so nice

20:20 neoncontrails: ##(let [m (java.util.HashMap.)] (.put m :a 0) (.put m :b 1) m)

20:20 lazybot: ⇒ {:b 1, :a 0}

21:06 justin_smith: ,@(reify clojure.lang.IDeref (deref [this] "OK"))

21:06 clojurebot: "OK"

22:36 justin_smith: woohoo, just got my delivery estimate for "Clojure Applied" - I guess that means they have an official book release date.

23:17 neoncontrails: How would you express this logic more beautifully? http://pastebin.com/5C8sMp9i

23:17 I know I'm making it about 4 times more complicated than it needs to be

23:23 bacon1989: oh neat function

23:24 neoncontrails: Thanks -- just a little exercise from 'Cracking the Coding Interview'

23:25 TEttinger: ,((fn [v colls] (map #(if (some #{v} %) (repeat (count %) v) (seq %)) colls)) 5 [[1 2 3] [4 5 6] [7 0 8]])

23:25 clojurebot: ((1 2 3) (5 5 5) (7 0 8))

23:25 amalloy: (defn if-any-then-all [x colls] (for [coll colls] (if (some #(= % x) coll) (map (constantly x coll)) coll)))

23:26 TEttinger: you have to be careful with #{x}: what if someone calls this with x=nil?

23:26 TEttinger: ah, I was wondering which was preferred

23:26 neoncontrails: nice! I like the comparison of your approaches

23:26 TEttinger: (inc amalloy)

23:26 lazybot: ⇒ 302

23:27 neoncontrails: (inc amalloy)

23:27 lazybot: ⇒ 303

23:27 neoncontrails: (inc TEttinger)

23:27 lazybot: ⇒ 65

23:27 TEttinger: I haven't seen (constantly x coll) before

23:27 (doc constantly)

23:27 clojurebot: "([x]); Returns a function that takes any number of arguments and returns x."

23:28 TEttinger: ... possibly for good reason

23:28 ,(constantly 5 [1 2 3])

23:28 clojurebot: #error {\n :cause "Wrong number of args (2) passed to: core/constantly"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (2) passed to: core/constantly"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 36]\n [sandbox$eval76 invokeStatic "NO_SOURCE_FILE" 0]\n [sandb...

23:30 neoncontrails: I was *just* about to ask about that

23:31 I understand it at each step of the way, but there

23:31 TEttinger: ,(defn if-any-then-all [x colls] (for [coll colls] (if (some #(= % x) coll) (map (constantly x)) coll)))

23:31 clojurebot: #'sandbox/if-any-then-all

23:31 TEttinger: ,(if-any-then-all 5 [[1 2 3] [4 5 6] [7 0 8]])

23:31 clojurebot: ([1 2 3] #object[clojure.core$map$fn__4537 0x29a1cd66 "clojure.core$map$fn__4537@29a1cd66"] [7 0 8])

23:31 TEttinger: ugh

23:31 ,(defn if-any-then-all [x colls] (for [coll colls] (if (some #(= % x) coll) (map (constantly x) coll) coll)))

23:31 clojurebot: #'sandbox/if-any-then-all

23:31 TEttinger: ,(if-any-then-all 5 [[1 2 3] [4 5 6] [7 0 8]])

23:31 clojurebot: ([1 2 3] (5 5 5) [7 0 8])

23:32 TEttinger: it was a misplaced paren is all

23:33 amalloy: ah, indeed. i'm just mashing stuff out in irc

23:33 hm, maybe it's time to look back into erc

23:33 neoncontrails: Constantly works in an interesting way, I notice

23:33 ,(map #(constantly %) (range 10))

23:33 clojurebot: (#object[clojure.core$constantly$fn__4371 0x432ae0b5 "clojure.core$constantly$fn__4371@432ae0b5"] #object[clojure.core$constantly$fn__4371 0x3406ad86 "clojure.core$constantly$fn__4371@3406ad86"] #object[clojure.core$constantly$fn__4371 0x226a5319 "clojure.core$constantly$fn__4371@226a5319"] #object[clojure.core$constantly$fn__4371 0x72759ff5 "clojure.core$constantly$fn__4371@72759ff5"] #object[clo...

23:34 bacon1989: man, what other channels let's you mess around with the language in them?

23:34 fucking clojure

23:34 TEttinger: ,(map constantly (range 10))

23:34 clojurebot: (#object[clojure.core$constantly$fn__4371 0x28b15282 "clojure.core$constantly$fn__4371@28b15282"] #object[clojure.core$constantly$fn__4371 0x119fe9ad "clojure.core$constantly$fn__4371@119fe9ad"] #object[clojure.core$constantly$fn__4371 0x19a665e5 "clojure.core$constantly$fn__4371@19a665e5"] #object[clojure.core$constantly$fn__4371 0x7b6baa8a "clojure.core$constantly$fn__4371@7b6baa8a"] #object[clo...

23:34 amalloy: bacon1989: a lot of them

23:34 bacon1989: like what?

23:34 amalloy: haskell, python, java are a few i know of

23:34 TEttinger: haskell has lambdabot

23:34 amalloy: probably ruby, i would be very surprised if not

23:34 bacon1989: oh right

23:35 I guess they're all interpreted

23:35 TEttinger: (lambdabot is apparently very hard to change by anyone who didn't write it, despite being open source)

23:35 amalloy: no, java isn't

23:35 neither is clojure really, we just have eval

23:35 TEttinger: haskell is compiled, but it does have a REPL

23:35 scala has a bot

23:36 multibot IIRC, it can do multi-line output to a certain limit

23:36 bacon1989: interesting

23:36 amalloy: anyway, an irc bot is a pretty standard thing for a programming language, because programmers want it so badly

23:36 TEttinger: perl6 has camelia and glrelia, the latter of which is meant to show changes made in the GLR branch of the code

23:36 bacon1989: also, isn't Java9 supposed to have a repl soon?

23:37 amalloy: plot twist: java 9 is groovy

23:37 neoncontrails: Heh, cute

23:37 ,(reduce + (map (constantly 1) [:a :b :c]))

23:37 clojurebot: 3

23:37 bacon1989: amalloy: haha

23:37 TEttinger: you can compile java 9 today, it actually isn't as hard as 7 or 8

23:37 (and yes, it starts up faster)

23:37 bacon1989: TEttinger: that is exciting

23:37 TEttinger: they reorganized a lot of stuff, and still are, so it only loads core modules at startup

23:38 bacon1989: so that should mean clojure will start faster?

23:38 I wonder if i'll ever see the day when clojure can be used for command-line tools

23:38 TEttinger: somewhat yes. clojure still has its own lib to run, but less overhead from the JVM itself should help

23:38 pixie or an SSD :)

23:39 bacon1989: been looking at pixie

23:39 also, been looking at racket

23:39 (since John Carmack seems to like it)

23:39 TEttinger: I'm looking at None, which has unfortunately less clojure influence, more traditional scheme (no immutable stuff that I can tell)

23:41 it's very early in development it seems, but if you're targeting specifically the things that clojure doesn't (real-time low-level stuff), then None seems like a decent Lisp to use? https://bitbucket.org/duangle/none/overview

23:43 bacon1989: neat, i'll check it out

23:44 TEttinger: I suspect None will be more usable in a few months

23:46 bacon1989: personally I find it interesting because i've done a lot of work in lua

Logging service provided by n01se.net